218 lines
8.5 KiB
Go
218 lines
8.5 KiB
Go
package policyconfig
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"testing"
|
|
|
|
"github.com/DATA-DOG/go-sqlmock"
|
|
"hyapp-admin-server/internal/integration/activityclient"
|
|
activityv1 "hyapp.local/api/proto/activity/v1"
|
|
)
|
|
|
|
func TestGetTemplateJoinsVersionByTemplateCodeAndVersion(t *testing.T) {
|
|
adminDB, mock, closeDB := newPolicySQLMock(t)
|
|
defer closeDB()
|
|
svc := NewService(adminDB, nil, nil, nil)
|
|
|
|
mock.ExpectQuery(`(?s)JOIN admin_policy_template_versions v ON v\.template_code = t\.template_code AND v\.template_version = t\.template_version.*WHERE t\.template_code = \? AND v\.template_version = \?`).
|
|
WithArgs("huwaa_point_policy", "v2").
|
|
WillReturnRows(sqlmock.NewRows([]string{
|
|
"template_id",
|
|
"version_id",
|
|
"template_code",
|
|
"template_version",
|
|
"name",
|
|
"status",
|
|
"rule_json",
|
|
"description",
|
|
"created_at_ms",
|
|
"updated_at_ms",
|
|
}).AddRow(1, 22, "huwaa_point_policy", "v2", "Huwaa Point Policy", "active", `{"tasks":{"reward_asset_type":"POINT"}}`, "version scoped", int64(1700000000000), int64(1700000001000)))
|
|
|
|
got, err := svc.getTemplate(context.Background(), "huwaa_point_policy", "v2")
|
|
if err != nil {
|
|
t.Fatalf("getTemplate failed: %v", err)
|
|
}
|
|
if got.TemplateCode != "huwaa_point_policy" || got.TemplateVersion != "v2" || got.VersionID != 22 {
|
|
t.Fatalf("template version join result mismatch: %+v", got)
|
|
}
|
|
if err := mock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("admin sql expectations mismatch: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestPublishRuntimeWritesWalletRowsAndActivityTaskRewardPolicy(t *testing.T) {
|
|
walletDB, walletMock, closeWallet := newPolicySQLMock(t)
|
|
defer closeWallet()
|
|
activity := &fakePolicyActivityClient{}
|
|
svc := NewService(nil, walletDB, nil, activity)
|
|
ctx := context.Background()
|
|
nowMS := int64(1700000005000)
|
|
item := policyInstanceRow{
|
|
AppCode: "huwaa",
|
|
InstanceCode: "huwaa-point-live",
|
|
TemplateCode: "huwaa_point_policy",
|
|
TemplateVersion: "v2",
|
|
Status: policyStatusActive,
|
|
EffectiveFromMS: 1700000000000,
|
|
EffectiveToMS: 0,
|
|
}
|
|
compiled := compiledPolicy{
|
|
HostPointRatioPPM: 700000,
|
|
PointsPerUSD: 100000,
|
|
WithdrawFeeBPS: 500,
|
|
TaskRewardAssetType: "POINT",
|
|
RuleJSON: []byte(`{"tasks":{"reward_asset_type":"POINT"},"host":{"point_ratio_percent":70}}`),
|
|
}
|
|
|
|
walletMock.ExpectExec(`(?s)CREATE TABLE IF NOT EXISTS wallet_policy_instances`).WillReturnResult(sqlmock.NewResult(0, 0))
|
|
walletMock.ExpectBegin()
|
|
walletMock.ExpectExec(`DELETE FROM wallet_policy_instances WHERE app_code = \? AND instance_code = \?`).
|
|
WithArgs("huwaa", "huwaa-point-live").
|
|
WillReturnResult(sqlmock.NewResult(0, 2))
|
|
for _, regionID := range []int64{0, 12} {
|
|
walletMock.ExpectExec(`(?s)INSERT INTO wallet_policy_instances`).
|
|
WithArgs(
|
|
"huwaa",
|
|
"huwaa-point-live",
|
|
"huwaa_point_policy",
|
|
"v2",
|
|
regionID,
|
|
policyStatusActive,
|
|
int64(1700000000000),
|
|
int64(0),
|
|
int64(700000),
|
|
int64(100000),
|
|
int64(500),
|
|
string(compiled.RuleJSON),
|
|
uint(90001),
|
|
nowMS,
|
|
nowMS,
|
|
nowMS,
|
|
).
|
|
WillReturnResult(sqlmock.NewResult(1, 1))
|
|
}
|
|
walletMock.ExpectCommit()
|
|
|
|
if err := svc.publishWalletRuntime(ctx, item, compiled, []int64{0, 12}, 90001, nowMS); err != nil {
|
|
t.Fatalf("publishWalletRuntime failed: %v", err)
|
|
}
|
|
if err := svc.publishActivityRuntime(ctx, item, compiled, 90001, nowMS); err != nil {
|
|
t.Fatalf("publishActivityRuntime failed: %v", err)
|
|
}
|
|
if activity.last == nil ||
|
|
activity.last.GetMeta().GetAppCode() != "huwaa" ||
|
|
activity.last.GetInstanceCode() != "huwaa-point-live" ||
|
|
activity.last.GetTemplateCode() != "huwaa_point_policy" ||
|
|
activity.last.GetTemplateVersion() != "v2" ||
|
|
activity.last.GetStatus() != policyStatusActive ||
|
|
activity.last.GetRewardAssetType() != "POINT" ||
|
|
activity.last.GetOperatorAdminId() != 90001 ||
|
|
activity.last.GetPublishedAtMs() != nowMS {
|
|
t.Fatalf("activity task reward policy payload mismatch: %+v", activity.last)
|
|
}
|
|
if err := walletMock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("wallet sql expectations mismatch: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateInstanceStatusSyncsWalletRuntimeAndActivityRuntime(t *testing.T) {
|
|
adminDB, adminMock, closeAdmin := newPolicySQLMock(t)
|
|
defer closeAdmin()
|
|
walletDB, walletMock, closeWallet := newPolicySQLMock(t)
|
|
defer closeWallet()
|
|
activity := &fakePolicyActivityClient{}
|
|
svc := NewService(adminDB, walletDB, nil, activity)
|
|
ctx := context.Background()
|
|
ruleJSON := `{"points_per_usd":100000,"host":{"point_ratio_percent":70,"withdraw_fee_bps":500},"tasks":{"reward_asset_type":"POINT"}}`
|
|
|
|
adminMock.ExpectQuery(`(?s)SELECT instance_id, app_code, instance_code, template_code, template_version, region_scope, status,\s+effective_from_ms, effective_to_ms\s+FROM admin_policy_instances\s+WHERE app_code = \? AND instance_id = \?`).
|
|
WithArgs("huwaa", uint64(9)).
|
|
WillReturnRows(sqlmock.NewRows([]string{
|
|
"instance_id",
|
|
"app_code",
|
|
"instance_code",
|
|
"template_code",
|
|
"template_version",
|
|
"region_scope",
|
|
"status",
|
|
"effective_from_ms",
|
|
"effective_to_ms",
|
|
}).AddRow(9, "huwaa", "huwaa-point-live", "huwaa_point_policy", "v2", "all_active_regions", policyStatusActive, int64(1700000000000), int64(0)))
|
|
adminMock.ExpectQuery(`(?s)SELECT COALESCE\(CAST\(rule_json AS CHAR\), '\{\}'\)\s+FROM admin_policy_template_versions\s+WHERE template_code = \? AND template_version = \?`).
|
|
WithArgs("huwaa_point_policy", "v2").
|
|
WillReturnRows(sqlmock.NewRows([]string{"rule_json"}).AddRow(ruleJSON))
|
|
adminMock.ExpectExec(`(?s)UPDATE admin_policy_instances\s+SET status = \?, updated_by_admin_id = \?, updated_at_ms = \?\s+WHERE app_code = \? AND instance_id = \?`).
|
|
WithArgs(policyStatusDisabled, uint(90002), sqlmock.AnyArg(), "huwaa", uint64(9)).
|
|
WillReturnResult(sqlmock.NewResult(0, 1))
|
|
walletMock.ExpectExec(`(?s)CREATE TABLE IF NOT EXISTS wallet_policy_instances`).WillReturnResult(sqlmock.NewResult(0, 0))
|
|
walletMock.ExpectExec(`(?s)UPDATE wallet_policy_instances\s+SET status = \?, updated_at_ms = \?\s+WHERE app_code = \? AND instance_code = \?`).
|
|
WithArgs(policyStatusDisabled, sqlmock.AnyArg(), "huwaa", "huwaa-point-live").
|
|
WillReturnResult(sqlmock.NewResult(0, 1))
|
|
adminMock.ExpectQuery(`(?s)SELECT instance_id, app_code, instance_code, template_code, template_version, region_scope, status,\s+effective_from_ms, effective_to_ms, publish_status, publish_error, last_published_at_ms,\s+created_at_ms, updated_at_ms\s+FROM admin_policy_instances\s+WHERE app_code = \? AND instance_id = \?`).
|
|
WithArgs("huwaa", uint64(9)).
|
|
WillReturnRows(sqlmock.NewRows([]string{
|
|
"instance_id",
|
|
"app_code",
|
|
"instance_code",
|
|
"template_code",
|
|
"template_version",
|
|
"region_scope",
|
|
"status",
|
|
"effective_from_ms",
|
|
"effective_to_ms",
|
|
"publish_status",
|
|
"publish_error",
|
|
"last_published_at_ms",
|
|
"created_at_ms",
|
|
"updated_at_ms",
|
|
}).AddRow(9, "huwaa", "huwaa-point-live", "huwaa_point_policy", "v2", "all_active_regions", policyStatusDisabled, int64(1700000000000), int64(0), publishStatusPublished, "", int64(1700000005000), int64(1700000000000), int64(1700000006000)))
|
|
|
|
got, err := svc.UpdateInstanceStatus(ctx, " Huwaa ", 90002, 9, "disabled")
|
|
if err != nil {
|
|
t.Fatalf("UpdateInstanceStatus failed: %v", err)
|
|
}
|
|
if got.Status != policyStatusDisabled {
|
|
t.Fatalf("instance status mismatch: %+v", got)
|
|
}
|
|
if activity.last == nil ||
|
|
activity.last.GetMeta().GetAppCode() != "huwaa" ||
|
|
activity.last.GetInstanceCode() != "huwaa-point-live" ||
|
|
activity.last.GetStatus() != policyStatusDisabled ||
|
|
activity.last.GetRewardAssetType() != "POINT" {
|
|
t.Fatalf("activity status sync payload mismatch: %+v", activity.last)
|
|
}
|
|
if err := adminMock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("admin sql expectations mismatch: %v", err)
|
|
}
|
|
if err := walletMock.ExpectationsWereMet(); err != nil {
|
|
t.Fatalf("wallet sql expectations mismatch: %v", err)
|
|
}
|
|
}
|
|
|
|
type fakePolicyActivityClient struct {
|
|
activityclient.Client
|
|
last *activityv1.PublishTaskRewardPolicyRequest
|
|
}
|
|
|
|
func (f *fakePolicyActivityClient) PublishTaskRewardPolicy(_ context.Context, req *activityv1.PublishTaskRewardPolicyRequest) (*activityv1.PublishTaskRewardPolicyResponse, error) {
|
|
f.last = req
|
|
return &activityv1.PublishTaskRewardPolicyResponse{
|
|
AppCode: req.GetMeta().GetAppCode(),
|
|
InstanceCode: req.GetInstanceCode(),
|
|
Status: req.GetStatus(),
|
|
RewardAssetType: req.GetRewardAssetType(),
|
|
PublishedAtMs: req.GetPublishedAtMs(),
|
|
}, nil
|
|
}
|
|
|
|
func newPolicySQLMock(t *testing.T) (*sql.DB, sqlmock.Sqlmock, func()) {
|
|
t.Helper()
|
|
db, mock, err := sqlmock.New()
|
|
if err != nil {
|
|
t.Fatalf("create sql mock failed: %v", err)
|
|
}
|
|
return db, mock, func() { _ = db.Close() }
|
|
}
|