75 lines
1.9 KiB
Go
75 lines
1.9 KiB
Go
package testkit
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
|
|
"galaxy/authsession/internal/ports"
|
|
)
|
|
|
|
// RecordingMailSender is a deterministic MailSender double that records every
|
|
// delivery request, including the auth challenge-derived idempotency key, and
|
|
// returns preconfigured outcomes or errors.
|
|
type RecordingMailSender struct {
|
|
mu sync.Mutex
|
|
|
|
// Results stores queued results consumed by SendLoginCode before
|
|
// DefaultResult is used.
|
|
Results []ports.SendLoginCodeResult
|
|
|
|
// DefaultResult stores the result used when Results is empty.
|
|
DefaultResult ports.SendLoginCodeResult
|
|
|
|
// Err is returned directly from SendLoginCode when set.
|
|
Err error
|
|
|
|
recordedInputs []ports.SendLoginCodeInput
|
|
}
|
|
|
|
// SendLoginCode records input and returns the next configured result.
|
|
func (s *RecordingMailSender) SendLoginCode(ctx context.Context, input ports.SendLoginCodeInput) (ports.SendLoginCodeResult, error) {
|
|
if err := ctx.Err(); err != nil {
|
|
return ports.SendLoginCodeResult{}, err
|
|
}
|
|
if err := input.Validate(); err != nil {
|
|
return ports.SendLoginCodeResult{}, err
|
|
}
|
|
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
s.recordedInputs = append(s.recordedInputs, input)
|
|
if s.Err != nil {
|
|
return ports.SendLoginCodeResult{}, s.Err
|
|
}
|
|
|
|
if len(s.Results) > 0 {
|
|
result := s.Results[0]
|
|
s.Results = s.Results[1:]
|
|
if err := result.Validate(); err != nil {
|
|
return ports.SendLoginCodeResult{}, err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
result := s.DefaultResult
|
|
if result.Outcome == "" {
|
|
result.Outcome = ports.SendLoginCodeOutcomeSent
|
|
}
|
|
if err := result.Validate(); err != nil {
|
|
return ports.SendLoginCodeResult{}, err
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
// RecordedInputs returns a stable snapshot of every recorded mail request.
|
|
func (s *RecordingMailSender) RecordedInputs() []ports.SendLoginCodeInput {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
|
|
return append([]ports.SendLoginCodeInput(nil), s.recordedInputs...)
|
|
}
|
|
|
|
var _ ports.MailSender = (*RecordingMailSender)(nil)
|