refac: hardening pass with multiple overhauls

This commit is contained in:
fsylvain committed 2026-09-29 10:55:23 +02:00
1 parent b0f7b7892b
commit da36c78bc0
28 files changed
+1375 -39

No files matched your search

+41 -7
View File
@@ -52,6 +52,7 @@ func newAcceptInviteFixture(t *testing.T, maxAttempts int) *acceptInviteFixture
hasher: &stubHasher{},
token: jwtauth.New("HS256", []byte("test-secret"), nil),
}
f.invites.users = f.users
getUser := useCases.NewGetUserUseCase(f.users)
acceptHandler := auth.NewAcceptInviteHandler(
useCases.NewGetInviteUseCase(f.invites, f.hasher),
@@ -420,7 +421,7 @@ func TestAcceptInvitationHttp(t *testing.T) {
}
})
t.Run("A failure after the user is created leaves the invite pending and no user behind", func(t *testing.T) {
t.Run("A failure while accepting leaves the invite pending and no user behind", func(t *testing.T) {
f := newAcceptInviteFixture(t, 100)
stored := f.seedPending()
f.invites.fail.failNext("MarkAccepted")
@@ -496,6 +497,7 @@ func TestAcceptInvitationHttp(t *testing.T) {
func TestAcceptInviteUseCase(t *testing.T) {
newUseCase := func() (*useCases.AcceptInviteUseCase, *mockUserRepo, *inviteFakeRepo, *stubHasher) {
users, invites, hasher := inviteInviterRepo(""), newInviteFakeRepo(), &stubHasher{}
invites.users = users
return useCases.NewAcceptInviteUseCase(users, invites, hasher), users, invites, hasher
}
command := useCases.AcceptInviteCommand{Code: acceptCode, Username: "lea", Password: acceptPassword}
@@ -558,6 +560,24 @@ func TestAcceptInviteUseCase(t *testing.T) {
}
})
t.Run("an address that got an account because the invite was just accepted is invalid", func(t *testing.T) {
users, invites, hasher := inviteInviterRepo(""), newInviteFakeRepo(), &stubHasher{}
invites.users = users
stored := pendingInvite(acceptEmail)
stored.HashedCode = "hashed:" + acceptCode
seeded := invites.seed(stored)
racing := &atomicInviteRepoDecorator{Repository: invites, afterGetAll: func() {
acceptedAt := time.Now()
seeded.AcceptedAt = &acceptedAt
invites.invites[seeded.ID] = seeded
users.users[8] = user.User{ID: 8, Username: "lea2", Email: acceptEmail}
}}
uc := useCases.NewAcceptInviteUseCase(users, racing, hasher)
if _, err := uc.AcceptInvite(command); !errors.Is(err, invite.ErrInviteInvalid) {
t.Errorf("expected ErrInviteInvalid, got %v", err)
}
})
t.Run("hash failure creates nothing", func(t *testing.T) {
uc, users, invites, hasher := newUseCase()
stored := pendingInvite(acceptEmail)
@@ -580,16 +600,30 @@ func TestAcceptInviteUseCase(t *testing.T) {
}
})
t.Run("rollback failure is joined with the accept failure", func(t *testing.T) {
t.Run("accept failure leaves no user and no delete call", func(t *testing.T) {
uc, users, invites, _ := newUseCase()
stored := pendingInvite(acceptEmail)
stored.HashedCode = "hashed:" + acceptCode
seeded := invites.seed(stored)
invites.fail.failNextWith("MarkAccepted", errors.New("mark down"))
users.fail.failNextWith("Delete", errors.New("delete down"))
_, err := uc.AcceptInvite(command)
if err == nil || !strings.Contains(err.Error(), "mark down") || strings.Contains(err.Error(), "delete down") {
t.Errorf("unexpected error %v", err)
}
if len(users.users) != 1 || invites.invites[seeded.ID].AcceptedAt != nil {
t.Errorf("expected no user and a pending invite")
}
})
t.Run("an invite that was taken meanwhile is invalid", func(t *testing.T) {
uc, users, invites, _ := newUseCase()
stored := pendingInvite(acceptEmail)
stored.HashedCode = "hashed:" + acceptCode
invites.seed(stored)
invites.fail.failNextWith("MarkAccepted", errors.New("mark down"))
users.fail.failNextWith("Delete", errors.New("delete down"))
_, err := uc.AcceptInvite(command)
if err == nil || !strings.Contains(err.Error(), "mark down") || !strings.Contains(err.Error(), "delete down") {
t.Errorf("unexpected error %v", err)
invites.fail.failNextWith("MarkAccepted", invite.ErrInviteNotFound)
if _, err := uc.AcceptInvite(command); !errors.Is(err, invite.ErrInviteInvalid) || len(users.users) != 1 {
t.Errorf("expected ErrInviteInvalid, got %v", err)
}
})
}