Files
platforms/backend/api/internal/logic/client/user/recommendation_test.go

97 lines
4.0 KiB
Go
Raw Normal View History

// 功能描述推荐归属过滤、分类排序、分页和公开资料回归版本1.0.0。
package user
import (
"encoding/json"
"fmt"
"github.com/DATA-DOG/go-sqlmock"
"strings"
"testing"
)
// 两种入口均排除本人购物车收藏入口另排除本人收藏ORDER CASE必须实际进入查询。
func TestRecommendationsScopeAndPagination(t *testing.T) {
for _, source := range []string{"cart", "favorites"} {
t.Run(source, func(t *testing.T) {
mock := primaryTestDB(t)
expectAddressAccount(mock)
query := `SELECT .* FROM "ec_product" WHERE \(status = \$1 AND stock_quantity > 0\).*NOT EXISTS .*ec_cart c.*c.user_account_id = \$2 AND c.status = \$3`
if source == "favorites" {
query += `.*NOT EXISTS .*ec_favorite f.*f.user_account_id = \$4 AND f.status = \$5`
}
query += `.*ec_product"\."deleted_at" IS NULL ORDER BY CASE WHEN EXISTS .*FROM ec_`
if source == "cart" {
query += `cart`
} else {
query += `favorite`
}
query += ` r .*r.user_account_id = .*AND r.status = .*THEN 0 ELSE 1 END, ec_product.updated_at desc, ec_product.identity LIMIT .* OFFSET`
expected := mock.ExpectQuery(query)
if source == "favorites" {
expected.WithArgs(1, 1, 1, 1, 1, 1, 1, 3, 2)
} else {
expected.WithArgs(1, 1, 1, 1, 1, 3, 2)
}
expected.WillReturnRows(sqlmock.NewRows([]string{"id", "identity", "name", "ec_category_id", "price_amount", "stock_quantity"}).AddRow(3, "p3", "减压阀", 7, 3900, 4).AddRow(5, "p5", "燃气管", 7, 5900, 9).AddRow(6, "p6", "更多", 8, 1900, 2))
mock.ExpectQuery(`SELECT .* FROM "ec_product_image".*ec_product_id IN`).WithArgs(3, 5, 6, 1).WillReturnRows(sqlmock.NewRows([]string{"ec_product_id", "image_uri"}).AddRow(3, "/cover.png").AddRow(5, "/five.png").AddRow(3, "/other.png"))
mock.ExpectQuery(`SELECT .* FROM "ec_category".*id IN`).WithArgs(7, 8, 1).WillReturnRows(sqlmock.NewRows([]string{"id", "name"}).AddRow(7, "配件"))
ctx, response := addressContext("", "")
ctx.Request.URL.RawQuery = fmt.Sprintf("source=%s&page=2&page_size=2", source)
Recommendations(ctx)
var body struct {
Code int `json:"code"`
Details struct {
Items []map[string]any `json:"items"`
Page int `json:"page"`
More bool `json:"has_more"`
} `json:"details"`
}
if err := json.Unmarshal(response.Body.Bytes(), &body); err != nil {
t.Fatal(err)
}
if body.Code != 0 || body.Details.Page != 2 || !body.Details.More || len(body.Details.Items) != 2 {
t.Fatal(response.Body.String())
}
first := body.Details.Items[0]
if first["identity"] != "p3" || first["image_url"] != "/cover.png" || first["category_name"] != "配件" || first["price_amount"] != float64(3900) || body.Details.Items[1]["image_url"] != "/five.png" {
t.Fatal(response.Body.String())
}
for _, row := range body.Details.Items {
for _, key := range []string{"id", "ec_category_id", "user_account_id"} {
if _, ok := row[key]; ok {
t.Fatal("泄露内部字段", key)
}
}
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatal(err)
}
})
}
}
func TestRecommendationsEmptyAndInvalidQuery(t *testing.T) {
for _, query := range []string{"", "source=other", "page=0", "page=10001", "page_size=21", "page_size=-1"} {
t.Run(query, func(t *testing.T) {
mock := primaryTestDB(t)
expectAddressAccount(mock)
if query == "" {
mock.ExpectQuery(`SELECT .* FROM "ec_product".*ORDER BY CASE`).WithArgs(1, 1, 1, 1, 1, 3).WillReturnRows(sqlmock.NewRows([]string{"id"}))
}
ctx, response := addressContext("", "")
ctx.Request.URL.RawQuery = query
Recommendations(ctx)
if query == "" {
if !strings.Contains(response.Body.String(), `"items":[]`) || !strings.Contains(response.Body.String(), `"has_more":false`) {
t.Fatal(response.Body.String())
}
} else if !strings.Contains(response.Body.String(), `"code":1704`) {
t.Fatal(response.Body.String())
}
if err := mock.ExpectationsWereMet(); err != nil {
t.Fatal(err)
}
})
}
}