Files
zzyxyz_go_api/internal/handlers/bookmark_test.go
zzy 7ff8591be8 ```
feat(api): 初始化项目基础结构与API定义

新增 `.gitignore` 文件,忽略编译输出、生成代码及数据库文件。
新增 `README.md`,包含 Gin 框架和 Swagger 工具的安装与使用说明。
新增 `config/api.yaml`,定义 bookmarks 相关的文件夹与书签操作的 OpenAPI 3.0 接口规范。
新增 `config/cfg.yaml`,配置 oapi-codegen 工具生成 Gin 服务和模型代码。
新增 `go.mod` 和 `go.sum` 文件,初始化 Go 模块并引入 Gin、GORM、SQLite 及 oapi-codegen 等依赖。
```
2025-09-21 00:20:29 +08:00

311 lines
9.7 KiB
Go

// 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)
// 确保更新时间发生了变化
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))
}