| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- //go:build integration
- package repository
- import (
- "context"
- "fmt"
- "strings"
- "testing"
- "time"
- "github.com/Wei-Shaw/sub2api/internal/service"
- "github.com/stretchr/testify/require"
- )
- func TestCreateGroupFromSourceRollsBackWhenOutboxInsertFails(t *testing.T) {
- ctx := context.Background()
- client := testEntClient(t)
- repo := newGroupRepositoryWithSQL(client, integrationDB)
- suffix := time.Now().UnixNano()
- operationID := strings.Repeat("b", 64)
- source, err := client.Group.Create().
- SetName(fmt.Sprintf("duplicate-rollback-source-%d", suffix)).
- SetPlatform(service.PlatformAnthropic).
- Save(ctx)
- require.NoError(t, err)
- account, err := client.Account.Create().
- SetName(fmt.Sprintf("duplicate-rollback-account-%d", suffix)).
- SetPlatform(service.PlatformAnthropic).
- SetType(service.AccountTypeOAuth).
- Save(ctx)
- require.NoError(t, err)
- _, err = client.AccountGroup.Create().
- SetAccountID(account.ID).
- SetGroupID(source.ID).
- SetPriority(29).
- Save(ctx)
- require.NoError(t, err)
- functionName := fmt.Sprintf("fail_group_duplicate_outbox_%d", suffix)
- triggerName := fmt.Sprintf("fail_group_duplicate_outbox_trigger_%d", suffix)
- _, err = integrationDB.ExecContext(ctx, fmt.Sprintf(`
- CREATE FUNCTION %s() RETURNS trigger LANGUAGE plpgsql AS $$
- BEGIN
- IF NEW.group_id IS NOT NULL AND EXISTS (
- SELECT 1 FROM groups
- WHERE id = NEW.group_id AND duplicate_operation_id = '%s'
- ) THEN
- RAISE EXCEPTION 'forced duplicate outbox failure';
- END IF;
- RETURN NEW;
- END;
- $$`, functionName, operationID))
- require.NoError(t, err)
- _, err = integrationDB.ExecContext(ctx, fmt.Sprintf(
- "CREATE TRIGGER %s BEFORE INSERT ON scheduler_outbox FOR EACH ROW EXECUTE FUNCTION %s()",
- triggerName,
- functionName,
- ))
- require.NoError(t, err)
- duplicateName := fmt.Sprintf("duplicate-rollback-copy-%d", suffix)
- t.Cleanup(func() {
- _, _ = integrationDB.ExecContext(context.Background(), fmt.Sprintf("DROP TRIGGER IF EXISTS %s ON scheduler_outbox", triggerName))
- _, _ = integrationDB.ExecContext(context.Background(), fmt.Sprintf("DROP FUNCTION IF EXISTS %s()", functionName))
- _, _ = integrationDB.ExecContext(context.Background(), "DELETE FROM scheduler_outbox WHERE group_id = $1", source.ID)
- _, _ = integrationDB.ExecContext(context.Background(), "DELETE FROM account_groups WHERE account_id = $1", account.ID)
- _, _ = integrationDB.ExecContext(context.Background(), "DELETE FROM accounts WHERE id = $1", account.ID)
- _, _ = integrationDB.ExecContext(context.Background(), "DELETE FROM groups WHERE name IN ($1, $2)", source.Name, duplicateName)
- })
- duplicate := &service.Group{
- Name: duplicateName,
- Platform: source.Platform,
- RateMultiplier: 1,
- Status: "inactive",
- SubscriptionType: service.SubscriptionTypeStandard,
- DuplicateOperationID: operationID,
- }
- err = repo.CreateFromSource(ctx, duplicate, source.ID)
- require.ErrorContains(t, err, "forced duplicate outbox failure")
- var groupCount, bindingCount, outboxCount int
- require.NoError(t, integrationDB.QueryRowContext(ctx, "SELECT COUNT(*) FROM groups WHERE name = $1", duplicateName).Scan(&groupCount))
- require.NoError(t, integrationDB.QueryRowContext(ctx, "SELECT COUNT(*) FROM account_groups WHERE group_id = $1", duplicate.ID).Scan(&bindingCount))
- require.NoError(t, integrationDB.QueryRowContext(ctx, "SELECT COUNT(*) FROM scheduler_outbox WHERE group_id = $1", duplicate.ID).Scan(&outboxCount))
- require.Zero(t, groupCount)
- require.Zero(t, bindingCount)
- require.Zero(t, outboxCount)
- }
|