Skip to content

Commit 223387b

Browse files
committed
test: platform-scope regression guard for auth paths (T2-4)
2 parents cb9bfca + 7796bc2 commit 223387b

1 file changed

Lines changed: 82 additions & 0 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package identity_test
2+
3+
import (
4+
"context"
5+
"testing"
6+
"time"
7+
8+
"github.com/stretchr/testify/mock"
9+
"github.com/stretchr/testify/require"
10+
11+
"github.com/BEDOLAGA-DEV/RemnaCore/internal/domain/identity"
12+
"github.com/BEDOLAGA-DEV/RemnaCore/pkg/tenantctx"
13+
)
14+
15+
// These tests guard against the regression class that broke the deploy: the
16+
// pre-auth identity paths read/write identity.platform_users, which is FORCE
17+
// RLS with NO tenant_id-IS-NULL read branch. Under the non-superuser runtime
18+
// role they see ZERO rows unless the platform sentinel GUC is set. The bug was
19+
// forgetting RunInTx(WithPlatformScope(ctx)); a plain ctx silently ran unscoped.
20+
//
21+
// Each test asserts the CONTEXT passed to the repository carries the platform
22+
// sentinel. If someone removes the WithPlatformScope wrap, the matcher stops
23+
// matching and the test fails at merge — without needing a real database.
24+
25+
// platformScoped matches a context whose app.tenant_id resolves to the platform
26+
// sentinel ("*"). NoopTxRunner passes the RunInTx context straight through, so
27+
// the repository sees exactly what the service scoped it with.
28+
var platformScoped = mock.MatchedBy(func(ctx context.Context) bool {
29+
return tenantctx.TenantIDFromContext(ctx) == tenantctx.PlatformScopeSentinel
30+
})
31+
32+
func TestPlatformScope_SetupNeeded(t *testing.T) {
33+
svc, repo, _ := newTestService(t)
34+
repo.On("CountAdmins", platformScoped).Return(int64(1), nil)
35+
36+
needed, err := svc.SetupNeeded(context.Background())
37+
require.NoError(t, err)
38+
require.False(t, needed)
39+
repo.AssertExpectations(t) // fails if CountAdmins wasn't called platform-scoped
40+
}
41+
42+
func TestPlatformScope_Login(t *testing.T) {
43+
svc, repo, pub := newTestService(t)
44+
hash := hashedPassword(t)
45+
user := &identity.PlatformUser{ID: "u1", Email: "a@b.com", PasswordHash: hash, Role: identity.RoleCustomer}
46+
47+
repo.On("GetUserByEmail", platformScoped, "a@b.com").Return(user, nil)
48+
repo.On("CreateSession", mock.Anything, mock.AnythingOfType("*aggregate.Session")).Return(nil)
49+
pub.On("Publish", mock.Anything, mock.AnythingOfType("domainevent.Event")).Return(nil)
50+
51+
_, err := svc.Login(context.Background(), identity.LoginInput{Email: "a@b.com", Password: "StrongP4ss"})
52+
require.NoError(t, err)
53+
repo.AssertExpectations(t)
54+
}
55+
56+
func TestPlatformScope_RefreshToken(t *testing.T) {
57+
svc, repo, pub := newTestService(t)
58+
user := &identity.PlatformUser{ID: "u1", Email: "a@b.com", Role: identity.RoleCustomer}
59+
session := &identity.Session{ID: "s1", UserID: "u1", RefreshToken: "rt", ExpiresAt: time.Now().Add(time.Hour)}
60+
61+
repo.On("GetSessionByRefreshToken", mock.Anything, "rt").Return(session, nil)
62+
repo.On("GetUserByID", platformScoped, "u1").Return(user, nil)
63+
repo.On("DeleteSession", mock.Anything, "s1").Return(nil)
64+
repo.On("CreateSession", mock.Anything, mock.AnythingOfType("*aggregate.Session")).Return(nil)
65+
pub.On("Publish", mock.Anything, mock.AnythingOfType("domainevent.Event")).Return(nil)
66+
67+
_, err := svc.RefreshToken(context.Background(), "rt")
68+
require.NoError(t, err)
69+
repo.AssertExpectations(t)
70+
}
71+
72+
func TestPlatformScope_Register(t *testing.T) {
73+
svc, repo, pub := newTestService(t)
74+
repo.On("GetUserByEmail", platformScoped, "new@b.com").Return(nil, identity.ErrNotFound)
75+
repo.On("CreateUser", platformScoped, mock.AnythingOfType("*aggregate.PlatformUser")).Return(nil)
76+
repo.On("CreateEmailVerification", platformScoped, mock.AnythingOfType("*aggregate.EmailVerification")).Return(nil)
77+
pub.On("Publish", mock.Anything, mock.AnythingOfType("domainevent.Event")).Return(nil)
78+
79+
_, err := svc.Register(context.Background(), identity.RegisterInput{Email: "new@b.com", Password: "StrongP4ss"})
80+
require.NoError(t, err)
81+
repo.AssertExpectations(t)
82+
}

0 commit comments

Comments
 (0)