test: add RevokeAllTokens error handling test cases
- Add test for ListTokens error propagation - Add test for partial revoke failure (continues processing)
- commit
- 45e4796435aaab39b49c9570d2e59f81f3b62094
- author
- brice · · 2026-01-17 09:22 UTC
- parent
- 9ed3e41
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
1 file · +60 -0
M internal/usecase/auth/service_test.go +60 -0
| @@ -2,6 +2,7 @@ package auth | |||
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | 4 | "context" | |
| 5 | + | "errors" | |
| 5 | 6 | "testing" | |
| 6 | 7 | "time" | |
| 7 | 8 | ||
| @@ -616,6 +617,65 @@ func TestService_RevokeAllTokens(t *testing.T) { | |||
| 616 | 617 | require.NoError(t, err) | |
| 617 | 618 | assert.Equal(t, 0, count) | |
| 618 | 619 | }) | |
| 620 | + | ||
| 621 | + | t.Run("returns error when ListTokens fails", func(t *testing.T) { | |
| 622 | + | tokenStore := mocks.NewMockTokenStore(t) | |
| 623 | + | ||
| 624 | + | tokenStore.EXPECT(). | |
| 625 | + | ListTokens(mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })). | |
| 626 | + | Return(nil, errors.New("storage unavailable")) | |
| 627 | + | ||
| 628 | + | svc := NewService(Config{ | |
| 629 | + | Enabled: true, | |
| 630 | + | AuthType: domain.AuthTypeToken, | |
| 631 | + | }, tokenStore, zerowrap.Default()) | |
| 632 | + | ||
| 633 | + | ctx := testContext() | |
| 634 | + | count, err := svc.RevokeAllTokens(ctx) | |
| 635 | + | ||
| 636 | + | require.Error(t, err) | |
| 637 | + | assert.Contains(t, err.Error(), "failed to list tokens") | |
| 638 | + | assert.Equal(t, 0, count) | |
| 639 | + | }) | |
| 640 | + | ||
| 641 | + | t.Run("continues on partial revoke failure", func(t *testing.T) { | |
| 642 | + | tokenStore := mocks.NewMockTokenStore(t) | |
| 643 | + | ||
| 644 | + | tokens := []domain.Token{ | |
| 645 | + | {ID: "token-1", Subject: "user1", Revoked: false}, | |
| 646 | + | {ID: "token-2", Subject: "user2", Revoked: false}, | |
| 647 | + | {ID: "token-3", Subject: "user3", Revoked: false}, | |
| 648 | + | } | |
| 649 | + | ||
| 650 | + | tokenStore.EXPECT(). | |
| 651 | + | ListTokens(mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })). | |
| 652 | + | Return(tokens, nil) | |
| 653 | + | ||
| 654 | + | // First token succeeds | |
| 655 | + | tokenStore.EXPECT(). | |
| 656 | + | Revoke(mock.Anything, "token-1"). | |
| 657 | + | Return(nil) | |
| 658 | + | // Second token fails | |
| 659 | + | tokenStore.EXPECT(). | |
| 660 | + | Revoke(mock.Anything, "token-2"). | |
| 661 | + | Return(errors.New("revoke failed")) | |
| 662 | + | // Third token succeeds | |
| 663 | + | tokenStore.EXPECT(). | |
| 664 | + | Revoke(mock.Anything, "token-3"). | |
| 665 | + | Return(nil) | |
| 666 | + | ||
| 667 | + | svc := NewService(Config{ | |
| 668 | + | Enabled: true, | |
| 669 | + | AuthType: domain.AuthTypeToken, | |
| 670 | + | }, tokenStore, zerowrap.Default()) | |
| 671 | + | ||
| 672 | + | ctx := testContext() | |
| 673 | + | count, err := svc.RevokeAllTokens(ctx) | |
| 674 | + | ||
| 675 | + | // Should not return error, but count only successful revokes | |
| 676 | + | require.NoError(t, err) | |
| 677 | + | assert.Equal(t, 2, count) | |
| 678 | + | }) | |
| 619 | 679 | } | |
| 620 | 680 | ||
| 621 | 681 | func TestService_ListTokens(t *testing.T) { | |
| @@ -2,6 +2,7 @@ package auth | |||||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | "context" | 4 | "context" | ||
| 5 | + | "errors" | |||
| 5 | "testing" | 6 | "testing" | ||
| 6 | "time" | 7 | "time" | ||
| 7 | 8 | ||||
| @@ -616,6 +617,65 @@ func TestService_RevokeAllTokens(t *testing.T) { | |||||
| 616 | require.NoError(t, err) | 617 | require.NoError(t, err) | ||
| 617 | assert.Equal(t, 0, count) | 618 | assert.Equal(t, 0, count) | ||
| 618 | }) | 619 | }) | ||
| 620 | + | ||||
| 621 | + | t.Run("returns error when ListTokens fails", func(t *testing.T) { | |||
| 622 | + | tokenStore := mocks.NewMockTokenStore(t) | |||
| 623 | + | ||||
| 624 | + | tokenStore.EXPECT(). | |||
| 625 | + | ListTokens(mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })). | |||
| 626 | + | Return(nil, errors.New("storage unavailable")) | |||
| 627 | + | ||||
| 628 | + | svc := NewService(Config{ | |||
| 629 | + | Enabled: true, | |||
| 630 | + | AuthType: domain.AuthTypeToken, | |||
| 631 | + | }, tokenStore, zerowrap.Default()) | |||
| 632 | + | ||||
| 633 | + | ctx := testContext() | |||
| 634 | + | count, err := svc.RevokeAllTokens(ctx) | |||
| 635 | + | ||||
| 636 | + | require.Error(t, err) | |||
| 637 | + | assert.Contains(t, err.Error(), "failed to list tokens") | |||
| 638 | + | assert.Equal(t, 0, count) | |||
| 639 | + | }) | |||
| 640 | + | ||||
| 641 | + | t.Run("continues on partial revoke failure", func(t *testing.T) { | |||
| 642 | + | tokenStore := mocks.NewMockTokenStore(t) | |||
| 643 | + | ||||
| 644 | + | tokens := []domain.Token{ | |||
| 645 | + | {ID: "token-1", Subject: "user1", Revoked: false}, | |||
| 646 | + | {ID: "token-2", Subject: "user2", Revoked: false}, | |||
| 647 | + | {ID: "token-3", Subject: "user3", Revoked: false}, | |||
| 648 | + | } | |||
| 649 | + | ||||
| 650 | + | tokenStore.EXPECT(). | |||
| 651 | + | ListTokens(mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil })). | |||
| 652 | + | Return(tokens, nil) | |||
| 653 | + | ||||
| 654 | + | // First token succeeds | |||
| 655 | + | tokenStore.EXPECT(). | |||
| 656 | + | Revoke(mock.Anything, "token-1"). | |||
| 657 | + | Return(nil) | |||
| 658 | + | // Second token fails | |||
| 659 | + | tokenStore.EXPECT(). | |||
| 660 | + | Revoke(mock.Anything, "token-2"). | |||
| 661 | + | Return(errors.New("revoke failed")) | |||
| 662 | + | // Third token succeeds | |||
| 663 | + | tokenStore.EXPECT(). | |||
| 664 | + | Revoke(mock.Anything, "token-3"). | |||
| 665 | + | Return(nil) | |||
| 666 | + | ||||
| 667 | + | svc := NewService(Config{ | |||
| 668 | + | Enabled: true, | |||
| 669 | + | AuthType: domain.AuthTypeToken, | |||
| 670 | + | }, tokenStore, zerowrap.Default()) | |||
| 671 | + | ||||
| 672 | + | ctx := testContext() | |||
| 673 | + | count, err := svc.RevokeAllTokens(ctx) | |||
| 674 | + | ||||
| 675 | + | // Should not return error, but count only successful revokes | |||
| 676 | + | require.NoError(t, err) | |||
| 677 | + | assert.Equal(t, 2, count) | |||
| 678 | + | }) | |||
| 619 | } | 679 | } | ||
| 620 | 680 | ||||
| 621 | func TestService_ListTokens(t *testing.T) { | 681 | func TestService_ListTokens(t *testing.T) { | ||