Files
wxapp-guantong/backend/internal/service/phone_test.go
T
2026-09-22 22:51:19 +08:00

147 lines
4.1 KiB
Go

package service
import (
"context"
"database/sql"
"io"
"path/filepath"
"testing"
_ "modernc.org/sqlite"
"github.com/sirupsen/logrus"
)
func TestBindPhoneReassignsDuplicatePhoneToLatestOpenID(t *testing.T) {
svc, database, closeDB := newTestService(t)
defer closeDB()
ctx := context.Background()
first, err := svc.Login(ctx, "first")
if err != nil {
t.Fatalf("login first user: %v", err)
}
second, err := svc.Login(ctx, "second")
if err != nil {
t.Fatalf("login second user: %v", err)
}
if _, err := svc.BindPhone(ctx, first.User.Openid, "13900001111"); err != nil {
t.Fatalf("bind first phone: %v", err)
}
if _, err := svc.BindPhone(ctx, second.User.Openid, "13900001111"); err != nil {
t.Fatalf("bind second phone: %v", err)
}
var phoneOwners int
if err := database.QueryRowContext(ctx, `
SELECT COUNT(*)
FROM users
WHERE phone = ?`, "13900001111").Scan(&phoneOwners); err != nil {
t.Fatalf("count phone owners: %v", err)
}
if phoneOwners != 1 {
t.Fatalf("phone owner count = %d, want 1", phoneOwners)
}
firstUser, err := svc.Q.GetUserByOpenID(ctx, first.User.Openid)
if err != nil {
t.Fatalf("reload first user: %v", err)
}
if firstUser.Phone.Valid {
t.Fatalf("first user phone = %#v, want cleared", firstUser.Phone)
}
records, err := svc.AdminPhoneRecords(ctx)
if err != nil {
t.Fatalf("list admin phone records: %v", err)
}
if len(records) != 1 {
t.Fatalf("admin phone records = %d, want 1", len(records))
}
if records[0].OpenID != second.User.Openid || records[0].Phone != "13900001111" {
t.Fatalf("admin phone record = %#v, want latest openid with bound phone", records[0])
}
}
func TestCreatePriceInquiryUpdatesDuplicateSubmissionTimestamp(t *testing.T) {
svc, database, closeDB := newTestService(t)
defer closeDB()
ctx := context.Background()
session, err := svc.Login(ctx, "price_inquiry_duplicate")
if err != nil {
t.Fatalf("login user: %v", err)
}
if _, err := svc.BindPhone(ctx, session.User.Openid, "13900005555"); err != nil {
t.Fatalf("bind phone: %v", err)
}
req := CreatePriceInquiryRequest{
OpenID: session.User.Openid,
Province: "上海市",
City: "上海市",
District: "浦东新区",
ProjectName: "牙齿种植",
}
first, err := svc.CreatePriceInquiry(ctx, req)
if err != nil {
t.Fatalf("create first inquiry: %v", err)
}
if _, err := database.ExecContext(ctx, `
UPDATE price_inquiries
SET status = 'assigned', created_at = '2026-07-01 10:00:00', updated_at = '2026-07-01 10:00:00'
WHERE id = ?`, first.ID); err != nil {
t.Fatalf("set deterministic timestamps: %v", err)
}
second, err := svc.CreatePriceInquiry(ctx, req)
if err != nil {
t.Fatalf("create duplicate inquiry: %v", err)
}
if second.ID != first.ID {
t.Fatalf("duplicate inquiry id = %q, want existing id %q", second.ID, first.ID)
}
if second.CreatedAt != "2026-07-01 10:00:00" {
t.Fatalf("duplicate inquiry created_at = %q, want original created_at", second.CreatedAt)
}
if second.UpdatedAt == "" || second.UpdatedAt == "2026-07-01 10:00:00" {
t.Fatalf("duplicate inquiry updated_at = %q, want refreshed timestamp", second.UpdatedAt)
}
if second.Status != "assigned" {
t.Fatalf("duplicate inquiry status = %q, want assigned", second.Status)
}
var count int
if err := database.QueryRowContext(ctx, `
SELECT COUNT(*)
FROM price_inquiries
WHERE phone = ? AND province = ? AND city = ? AND district = ? AND project_name = ?`,
"13900005555", "上海市", "上海市", "浦东新区", "牙齿种植").Scan(&count); err != nil {
t.Fatalf("count price inquiries: %v", err)
}
if count != 1 {
t.Fatalf("price inquiry count = %d, want 1", count)
}
}
func newTestService(t *testing.T) (*Service, *sql.DB, func()) {
t.Helper()
database, err := sql.Open("sqlite", ":memory:")
if err != nil {
t.Fatalf("open sqlite: %v", err)
}
ctx := context.Background()
schemaPath := filepath.Join("..", "..", "migrations", "schema.sql")
if err := ApplySchema(ctx, database, schemaPath); err != nil {
database.Close()
t.Fatalf("apply schema: %v", err)
}
log := logrus.New()
log.SetOutput(io.Discard)
return New(database, log), database, func() { database.Close() }
}