-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpasswordless_test.go
117 lines (100 loc) · 3.28 KB
/
passwordless_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package passwordless_test
import (
"context"
"testing"
"time"
"github.com/rlnorthcutt/go-passwordless"
"github.com/rlnorthcutt/go-passwordless/store"
"github.com/rlnorthcutt/go-passwordless/transport"
)
// Custom LogTransport that stores the code for testing
type TestTransport struct {
LastCode string
}
func (tt *TestTransport) Send(ctx context.Context, recipient, code string) error {
tt.LastCode = code // Capture the code here
return nil
}
func TestPasswordlessFlow(t *testing.T) {
ctx := context.Background()
memStore := store.NewMemStore()
testTransport := &TestTransport{}
mgr := passwordless.NewManager(memStore, testTransport)
email := "[email protected]"
t.Run("StartLogin", func(t *testing.T) {
tokenID, err := mgr.StartLogin(ctx, email)
if err != nil {
t.Fatalf("StartLogin returned error: %v", err)
}
if tokenID == "" {
t.Fatal("Expected a non-empty tokenID")
}
t.Run("RetrieveToken", func(t *testing.T) {
tok, err := memStore.Exists(ctx, tokenID)
if err != nil {
t.Fatalf("Failed to retrieve token: %v", err)
}
if tok.Recipient != email {
t.Errorf("Expected recipient %q, got %q", email, tok.Recipient)
}
t.Run("VerifyIncorrectCode", func(t *testing.T) {
success, err := mgr.VerifyLogin(ctx, tokenID, "wrongcode")
if err == nil {
t.Fatal("Expected an error for incorrect code, got nil")
}
if success {
t.Fatal("Expected verification to fail for incorrect code")
}
})
t.Run("VerifyCorrectCode", func(t *testing.T) {
correctCode := testTransport.LastCode // Use captured code
success, err := mgr.VerifyLogin(ctx, tokenID, correctCode)
if err != nil {
t.Fatalf("Verification failed unexpectedly: %v", err)
}
if !success {
t.Fatal("Expected verification to succeed")
}
})
t.Run("VerifyExpiredToken", func(t *testing.T) {
tok.ExpiresAt = time.Now().Add(-1 * time.Minute)
_ = memStore.Store(ctx, *tok)
success, err := mgr.VerifyLogin(ctx, tokenID, testTransport.LastCode)
if err == nil {
t.Fatal("Expected an error for expired token, got nil")
}
if success {
t.Fatal("Expected verification to fail for expired token")
}
})
})
})
t.Run("NewManagerWithConfig", func(t *testing.T) {
memStore := store.NewMemStore()
logTransport := &transport.LogTransport{}
// Start with blanks to test the defaults
customConfig := passwordless.Config{
CodeLength: 0,
TokenExpiry: 0,
IDGenerator: func() string { return "customID" },
CodeCharset: "",
MaxFailedAttempts: 0,
}
mgr := passwordless.NewManagerWithConfig(memStore, logTransport, customConfig)
if mgr.Config.CodeLength != 6 {
t.Errorf("Expected CodeLength to be 6, got %d", mgr.Config.CodeLength)
}
if mgr.Config.TokenExpiry != 15*time.Minute {
t.Errorf("Expected TokenExpiry to be 15 minutes, got %v", mgr.Config.TokenExpiry)
}
if mgr.Config.IDGenerator() != "customID" {
t.Errorf("Expected IDGenerator to return 'customID', got %s", mgr.Config.IDGenerator())
}
if mgr.Config.CodeCharset != "0123456789" {
t.Errorf("Expected CodeCharset to be '0123456789', got %s", mgr.Config.CodeCharset)
}
if mgr.Config.MaxFailedAttempts != 3 {
t.Errorf("Expected MaxFailedAttempts to be 3, got %d", mgr.Config.MaxFailedAttempts)
}
})
}