// internal/handlers/bookmark_test.go package handlers_test import ( "bytes" "encoding/json" "fmt" "net/http" "net/http/httptest" "testing" "git.zzyxyz.com/zzy/zzyxyz_go_api/gen/api" "git.zzyxyz.com/zzy/zzyxyz_go_api/internal/handlers" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) type BookmarkTestSuite struct { suite.Suite server *gin.Engine bookmarks *handlers.BookMarksImpl testDBPath string } func (suite *BookmarkTestSuite) SetupSuite() { // 使用内存数据库进行测试 suite.testDBPath = ":memory:" // 设置Gin为测试模式 gin.SetMode(gin.TestMode) var err error suite.bookmarks, err = handlers.NewBookMarks(suite.testDBPath) assert.NoError(suite.T(), err) suite.server = gin.New() api.RegisterHandlers(suite.server, suite.bookmarks) } func (suite *BookmarkTestSuite) TestCreateBookmark() { // 准备测试数据 detail := "Test detail" description := "Test description" link := "https://example.com" request := api.BookmarkRequest{ Name: "Test Bookmark", Detail: &detail, Description: &description, Link: &link, } // 将请求转换为JSON jsonData, _ := json.Marshal(request) req, _ := http.NewRequest("POST", "/bookmarks/v1/data", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") // 发送请求 resp := httptest.NewRecorder() suite.server.ServeHTTP(resp, req) // 验证响应 assert.Equal(suite.T(), http.StatusCreated, resp.Code) var response api.BookmarkResponse err := json.Unmarshal(resp.Body.Bytes(), &response) assert.NoError(suite.T(), err) assert.Equal(suite.T(), request.Name, response.Name) assert.Equal(suite.T(), *request.Detail, *response.Detail) assert.Equal(suite.T(), *request.Description, *response.Description) assert.Equal(suite.T(), int64(1), response.ParentPathId) // 默认根目录 } func (suite *BookmarkTestSuite) TestGetBookmark() { // 先创建一个书签 detail := "Test detail for get" description := "Test description for get" link := "https://example.com/get" request := api.BookmarkRequest{ Name: "Test Get Bookmark", Detail: &detail, Description: &description, Link: &link, } jsonData, _ := json.Marshal(request) req, _ := http.NewRequest("POST", "/bookmarks/v1/data", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") resp := httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusCreated, resp.Code) var createdBookmark api.BookmarkResponse err := json.Unmarshal(resp.Body.Bytes(), &createdBookmark) assert.NoError(suite.T(), err) // 获取创建的书签 req, _ = http.NewRequest("GET", fmt.Sprintf("/bookmarks/v1/data/%d", createdBookmark.Id), nil) resp = httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusOK, resp.Code) var response api.BookmarkResponse err = json.Unmarshal(resp.Body.Bytes(), &response) assert.NoError(suite.T(), err) assert.Equal(suite.T(), createdBookmark.Id, response.Id) assert.Equal(suite.T(), request.Name, response.Name) } func (suite *BookmarkTestSuite) TestCreateFolder() { // 准备测试数据 request := api.FolderRequest{ Name: "Test Folder", } // 将请求转换为JSON jsonData, _ := json.Marshal(request) req, _ := http.NewRequest("POST", "/bookmarks/v1/folder", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") // 发送请求 resp := httptest.NewRecorder() suite.server.ServeHTTP(resp, req) // 验证响应 assert.Equal(suite.T(), http.StatusCreated, resp.Code) var response api.FolderResponse err := json.Unmarshal(resp.Body.Bytes(), &response) assert.NoError(suite.T(), err) assert.Equal(suite.T(), request.Name, response.Name) assert.Equal(suite.T(), int64(1), response.ParentPathId) // 默认根目录 } func (suite *BookmarkTestSuite) TestGetFolderInfo() { // 先创建一个文件夹 request := api.FolderRequest{ Name: "Test Get Folder", } jsonData, _ := json.Marshal(request) req, _ := http.NewRequest("POST", "/bookmarks/v1/folder", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") resp := httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusCreated, resp.Code) var createdFolder api.FolderResponse err := json.Unmarshal(resp.Body.Bytes(), &createdFolder) assert.NoError(suite.T(), err) // 获取创建的文件夹信息 req, _ = http.NewRequest("GET", fmt.Sprintf("/bookmarks/v1/folder/%d", createdFolder.Id), nil) resp = httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusOK, resp.Code) var response api.FolderResponse err = json.Unmarshal(resp.Body.Bytes(), &response) assert.NoError(suite.T(), err) assert.Equal(suite.T(), createdFolder.Id, response.Id) assert.Equal(suite.T(), request.Name, response.Name) assert.Equal(suite.T(), 0, response.BookmarkCount) assert.Equal(suite.T(), 0, response.SubFolderCount) } func (suite *BookmarkTestSuite) TestGetFolderContent() { // 创建一个文件夹 folderRequest := api.FolderRequest{ Name: "Content Test Folder", } folderJson, _ := json.Marshal(folderRequest) req, _ := http.NewRequest("POST", "/bookmarks/v1/folder", bytes.NewBuffer(folderJson)) req.Header.Set("Content-Type", "application/json") resp := httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusCreated, resp.Code) var createdFolder api.FolderResponse err := json.Unmarshal(resp.Body.Bytes(), &createdFolder) assert.NoError(suite.T(), err) // 在该文件夹中创建一个书签 detail := "Bookmark in folder" description := "Test bookmark in folder" link := "https://example.com/folder" bookmarkRequest := api.BookmarkRequest{ Name: "Folder Bookmark", Detail: &detail, Description: &description, Link: &link, ParentPathId: &createdFolder.Id, } bookmarkJson, _ := json.Marshal(bookmarkRequest) req, _ = http.NewRequest("POST", "/bookmarks/v1/data", bytes.NewBuffer(bookmarkJson)) req.Header.Set("Content-Type", "application/json") resp = httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusCreated, resp.Code) // 获取文件夹内容 req, _ = http.NewRequest("GET", fmt.Sprintf("/bookmarks/v1/folder/%d/content", createdFolder.Id), nil) resp = httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusOK, resp.Code) var response api.FolderContentResponse err = json.Unmarshal(resp.Body.Bytes(), &response) assert.NoError(suite.T(), err) assert.Len(suite.T(), response.Bookmarks, 1) assert.Equal(suite.T(), "Folder Bookmark", response.Bookmarks[0].Name) assert.Len(suite.T(), response.SubFolders, 0) } func (suite *BookmarkTestSuite) TestUpdateBookmark() { // 先创建一个书签 detail := "Original detail" description := "Original description" link := "https://example.com/original" request := api.BookmarkRequest{ Name: "Original Bookmark", Detail: &detail, Description: &description, Link: &link, } jsonData, _ := json.Marshal(request) req, _ := http.NewRequest("POST", "/bookmarks/v1/data", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") resp := httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusCreated, resp.Code) var createdBookmark api.BookmarkResponse err := json.Unmarshal(resp.Body.Bytes(), &createdBookmark) assert.NoError(suite.T(), err) // 更新书签 newName := "Updated Bookmark" newDetail := "Updated detail" updateRequest := api.BookmarkRequest{ Name: newName, Detail: &newDetail, } updateJson, _ := json.Marshal(updateRequest) req, _ = http.NewRequest("PUT", fmt.Sprintf("/bookmarks/v1/data/%d", createdBookmark.Id), bytes.NewBuffer(updateJson)) req.Header.Set("Content-Type", "application/json") resp = httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusOK, resp.Code) var response api.BookmarkResponse err = json.Unmarshal(resp.Body.Bytes(), &response) assert.NoError(suite.T(), err) assert.Equal(suite.T(), newName, response.Name) assert.Equal(suite.T(), newDetail, *response.Detail) // FIXME 确保更新时间发生了变化 时钟粒度不足 // assert.True(suite.T(), response.UpdatedAt.After(response.CreatedAt) || response.UpdatedAt.Equal(response.CreatedAt)) } func (suite *BookmarkTestSuite) TestUpdateFolder() { // 先创建一个文件夹 request := api.FolderRequest{ Name: "Original Folder", } jsonData, _ := json.Marshal(request) req, _ := http.NewRequest("POST", "/bookmarks/v1/folder", bytes.NewBuffer(jsonData)) req.Header.Set("Content-Type", "application/json") resp := httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusCreated, resp.Code) var createdFolder api.FolderResponse err := json.Unmarshal(resp.Body.Bytes(), &createdFolder) assert.NoError(suite.T(), err) // 更新文件夹 newName := "Updated Folder" updateRequest := api.FolderRequest{ Name: newName, } updateJson, _ := json.Marshal(updateRequest) req, _ = http.NewRequest("PUT", fmt.Sprintf("/bookmarks/v1/folder/%d", createdFolder.Id), bytes.NewBuffer(updateJson)) req.Header.Set("Content-Type", "application/json") resp = httptest.NewRecorder() suite.server.ServeHTTP(resp, req) assert.Equal(suite.T(), http.StatusOK, resp.Code) var response api.FolderResponse err = json.Unmarshal(resp.Body.Bytes(), &response) assert.NoError(suite.T(), err) assert.Equal(suite.T(), newName, response.Name) // 确保更新时间发生了变化 assert.True(suite.T(), response.UpdatedAt.After(response.CreatedAt) || response.UpdatedAt.Equal(response.CreatedAt)) } func TestBookmarkTestSuite(t *testing.T) { suite.Run(t, new(BookmarkTestSuite)) }