7a09d1537c
Service 单元测试(SQLite in-memory): - auth: 登录成功/失败/禁用账号,token 刷新 - stock: 入库审核、出库审核(含库存不足)、单号生成 - license: 激活、设备绑定验证、过期检测 Handler 集成测试(httptest + SQLite): - auth: 登录 API 成功/401 场景 - product: CRUD 完整流程 + hotel_id 隔离验证 - stock_in: 创建→提交→审核完整流程 - stock_out: 完整流程 + 库存不足 400 - inventory: 库存查询/过滤/盘点创建 - warehouse: CRUD 覆盖率:service 90.4%,handler 56.1% 共 50 个测试用例,全部 PASS Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
224 lines
5.7 KiB
Go
224 lines
5.7 KiB
Go
package service
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/wangjia/jiu/backend/internal/model"
|
|
"github.com/wangjia/jiu/backend/testutil"
|
|
)
|
|
|
|
func TestLicenseService_Activate_Success(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC001")
|
|
|
|
// 创建许可证
|
|
expiry := time.Now().Add(30 * 24 * time.Hour)
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "AAAAA-BBBBB-CCCCC-DDDDD",
|
|
IsActive: true,
|
|
ExpiresAt: &expiry,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Activate("AAAAA-BBBBB-CCCCC-DDDDD", "device-001")
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
assert.Equal(t, "device-001", result.DeviceID)
|
|
assert.NotNil(t, result.ActivatedAt)
|
|
}
|
|
|
|
func TestLicenseService_Activate_AlreadyBoundToDifferentDevice(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC002")
|
|
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "EEEEE-FFFFF-GGGGG-HHHHH",
|
|
DeviceID: "existing-device",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Activate("EEEEE-FFFFF-GGGGG-HHHHH", "new-device")
|
|
|
|
assert.Error(t, err)
|
|
assert.Equal(t, ErrDeviceMismatch, err)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestLicenseService_Activate_SameDevice(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC003")
|
|
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "IIIII-JJJJJ-KKKKK-LLLLL",
|
|
DeviceID: "same-device",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
// 同一设备重新激活应该成功
|
|
result, err := svc.Activate("IIIII-JJJJJ-KKKKK-LLLLL", "same-device")
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
assert.Equal(t, "same-device", result.DeviceID)
|
|
}
|
|
|
|
func TestLicenseService_Activate_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Activate("NONEX-ISTEN-TTTTT-LICCC", "device-001")
|
|
|
|
assert.Error(t, err)
|
|
assert.Equal(t, ErrLicenseNotFound, err)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestLicenseService_Activate_Inactive(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC004")
|
|
|
|
// 先创建激活的许可证,再禁用(避免 GORM 零值跳过问题)
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "MMMMM-NNNNN-OOOOO-PPPPP",
|
|
IsActive: true,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
// 禁用
|
|
require.NoError(t, db.Model(lic).Update("is_active", false).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Activate("MMMMM-NNNNN-OOOOO-PPPPP", "device-001")
|
|
|
|
assert.Error(t, err)
|
|
assert.Equal(t, ErrLicenseInactive, err)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestLicenseService_Activate_Expired(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC005")
|
|
|
|
// 已过期
|
|
expiry := time.Now().Add(-24 * time.Hour)
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "QQQQQ-RRRRR-SSSSS-TTTTT",
|
|
IsActive: true,
|
|
ExpiresAt: &expiry,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Activate("QQQQQ-RRRRR-SSSSS-TTTTT", "device-001")
|
|
|
|
assert.Error(t, err)
|
|
assert.Equal(t, ErrLicenseExpired, err)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestLicenseService_Verify_Success(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC006")
|
|
|
|
expiry := time.Now().Add(30 * 24 * time.Hour)
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "UUUUU-VVVVV-WWWWW-XXXXX",
|
|
DeviceID: "my-device",
|
|
IsActive: true,
|
|
ExpiresAt: &expiry,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Verify(hotel.ID, "my-device")
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
assert.Equal(t, "my-device", result.DeviceID)
|
|
}
|
|
|
|
func TestLicenseService_Verify_Expired(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC007")
|
|
|
|
// 已过期
|
|
expiry := time.Now().Add(-1 * time.Hour)
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "YYYYY-ZZZZZ-AAAAA-BBBBB",
|
|
DeviceID: "expired-device",
|
|
IsActive: true,
|
|
ExpiresAt: &expiry,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Verify(hotel.ID, "expired-device")
|
|
|
|
assert.Error(t, err)
|
|
assert.Equal(t, ErrLicenseExpired, err)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestLicenseService_Verify_NotFound(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC008")
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Verify(hotel.ID, "nonexistent-device")
|
|
|
|
assert.Error(t, err)
|
|
assert.Equal(t, ErrLicenseNotFound, err)
|
|
assert.Nil(t, result)
|
|
}
|
|
|
|
func TestLicenseService_Verify_NoExpiry(t *testing.T) {
|
|
db := testutil.SetupTestDB()
|
|
hotel := testutil.CreateTestHotel(db, "LIC009")
|
|
|
|
// 永久许可证(无过期时间)
|
|
lic := &model.License{
|
|
HotelID: hotel.ID,
|
|
LicenseKey: "CCCCC-DDDDD-EEEEE-FFFFF",
|
|
DeviceID: "lifetime-device",
|
|
IsActive: true,
|
|
ExpiresAt: nil,
|
|
}
|
|
require.NoError(t, db.Create(lic).Error)
|
|
|
|
svc := NewLicenseService(db)
|
|
result, err := svc.Verify(hotel.ID, "lifetime-device")
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, result)
|
|
}
|
|
|
|
func TestGenerateKey(t *testing.T) {
|
|
testutil.InitConfig()
|
|
|
|
expiry := time.Now().Add(30 * 24 * time.Hour)
|
|
key := GenerateKey(1, "annual", &expiry)
|
|
|
|
assert.NotEmpty(t, key)
|
|
// 格式:XXXXX-XXXXX-XXXXX-XXXXX
|
|
assert.Equal(t, 23, len(key)) // 4*5 + 3 dashes = 23
|
|
assert.Equal(t, '-', rune(key[5]))
|
|
assert.Equal(t, '-', rune(key[11]))
|
|
assert.Equal(t, '-', rune(key[17]))
|
|
}
|