97 lines
4.0 KiB
Go
97 lines
4.0 KiB
Go
|
|
// 功能描述:推荐归属过滤、分类排序、分页和公开资料回归;版本: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)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
}
|