A vibe coded tangled fork which supports pijul.
1package oauth
2
3import (
4 "testing"
5)
6
7func TestAccountRegistry_AddAccount(t *testing.T) {
8 tests := []struct {
9 name string
10 initial []AccountInfo
11 addDid string
12 addHandle string
13 addSessionId string
14 wantErr error
15 wantLen int
16 wantSessionId string
17 }{
18 {
19 name: "add first account",
20 initial: []AccountInfo{},
21 addDid: "did:plc:abc123",
22 addHandle: "alice.bsky.social",
23 addSessionId: "session-1",
24 wantErr: nil,
25 wantLen: 1,
26 wantSessionId: "session-1",
27 },
28 {
29 name: "add second account",
30 initial: []AccountInfo{
31 {Did: "did:plc:abc123", SessionId: "session-1", AddedAt: 1000},
32 },
33 addDid: "did:plc:def456",
34 addHandle: "bob.bsky.social",
35 addSessionId: "session-2",
36 wantErr: nil,
37 wantLen: 2,
38 wantSessionId: "session-2",
39 },
40 {
41 name: "update existing account session",
42 initial: []AccountInfo{
43 {Did: "did:plc:abc123", SessionId: "old-session", AddedAt: 1000},
44 },
45 addDid: "did:plc:abc123",
46 addHandle: "alice.bsky.social",
47 addSessionId: "new-session",
48 wantErr: nil,
49 wantLen: 1,
50 wantSessionId: "new-session",
51 },
52 }
53
54 for _, tt := range tests {
55 t.Run(tt.name, func(t *testing.T) {
56 registry := &AccountRegistry{Accounts: tt.initial}
57 err := registry.AddAccount(tt.addDid, tt.addHandle, tt.addSessionId)
58
59 if err != tt.wantErr {
60 t.Errorf("AddAccount() error = %v, want %v", err, tt.wantErr)
61 }
62
63 if len(registry.Accounts) != tt.wantLen {
64 t.Errorf("AddAccount() len = %d, want %d", len(registry.Accounts), tt.wantLen)
65 }
66
67 found := registry.FindAccount(tt.addDid)
68 if found == nil {
69 t.Errorf("AddAccount() account not found after add")
70 return
71 }
72
73 if found.SessionId != tt.wantSessionId {
74 t.Errorf("AddAccount() sessionId = %s, want %s", found.SessionId, tt.wantSessionId)
75 }
76 })
77 }
78}
79
80func TestAccountRegistry_AddAccount_MaxLimit(t *testing.T) {
81 registry := &AccountRegistry{Accounts: make([]AccountInfo, 0, MaxAccounts)}
82
83 for i := range MaxAccounts {
84 err := registry.AddAccount("did:plc:user"+string(rune('a'+i)), "handle", "session")
85 if err != nil {
86 t.Fatalf("AddAccount() unexpected error on account %d: %v", i, err)
87 }
88 }
89
90 if len(registry.Accounts) != MaxAccounts {
91 t.Errorf("expected %d accounts, got %d", MaxAccounts, len(registry.Accounts))
92 }
93
94 err := registry.AddAccount("did:plc:overflow", "overflow", "session-overflow")
95 if err != ErrMaxAccountsReached {
96 t.Errorf("AddAccount() error = %v, want %v", err, ErrMaxAccountsReached)
97 }
98
99 if len(registry.Accounts) != MaxAccounts {
100 t.Errorf("account added despite max limit, got %d", len(registry.Accounts))
101 }
102}
103
104func TestAccountRegistry_RemoveAccount(t *testing.T) {
105 tests := []struct {
106 name string
107 initial []AccountInfo
108 removeDid string
109 wantLen int
110 wantDids []string
111 }{
112 {
113 name: "remove existing account",
114 initial: []AccountInfo{
115 {Did: "did:plc:abc123", SessionId: "s1"},
116 {Did: "did:plc:def456", SessionId: "s2"},
117 },
118 removeDid: "did:plc:abc123",
119 wantLen: 1,
120 wantDids: []string{"did:plc:def456"},
121 },
122 {
123 name: "remove non-existing account",
124 initial: []AccountInfo{
125 {Did: "did:plc:abc123", SessionId: "s1"},
126 },
127 removeDid: "did:plc:notfound",
128 wantLen: 1,
129 wantDids: []string{"did:plc:abc123"},
130 },
131 {
132 name: "remove last account",
133 initial: []AccountInfo{
134 {Did: "did:plc:abc123", SessionId: "s1"},
135 },
136 removeDid: "did:plc:abc123",
137 wantLen: 0,
138 wantDids: []string{},
139 },
140 {
141 name: "remove from empty registry",
142 initial: []AccountInfo{},
143 removeDid: "did:plc:abc123",
144 wantLen: 0,
145 wantDids: []string{},
146 },
147 }
148
149 for _, tt := range tests {
150 t.Run(tt.name, func(t *testing.T) {
151 registry := &AccountRegistry{Accounts: tt.initial}
152 registry.RemoveAccount(tt.removeDid)
153
154 if len(registry.Accounts) != tt.wantLen {
155 t.Errorf("RemoveAccount() len = %d, want %d", len(registry.Accounts), tt.wantLen)
156 }
157
158 for _, wantDid := range tt.wantDids {
159 if registry.FindAccount(wantDid) == nil {
160 t.Errorf("RemoveAccount() expected %s to remain", wantDid)
161 }
162 }
163
164 if registry.FindAccount(tt.removeDid) != nil && tt.wantLen < len(tt.initial) {
165 t.Errorf("RemoveAccount() %s should have been removed", tt.removeDid)
166 }
167 })
168 }
169}
170
171func TestAccountRegistry_FindAccount(t *testing.T) {
172 registry := &AccountRegistry{
173 Accounts: []AccountInfo{
174 {Did: "did:plc:first", SessionId: "s1", AddedAt: 1000},
175 {Did: "did:plc:second", SessionId: "s2", AddedAt: 2000},
176 {Did: "did:plc:third", SessionId: "s3", AddedAt: 3000},
177 },
178 }
179
180 t.Run("find existing account", func(t *testing.T) {
181 found := registry.FindAccount("did:plc:second")
182 if found == nil {
183 t.Fatal("FindAccount() returned nil for existing account")
184 }
185 if found.SessionId != "s2" {
186 t.Errorf("FindAccount() sessionId = %s, want s2", found.SessionId)
187 }
188 })
189
190 t.Run("find non-existing account", func(t *testing.T) {
191 found := registry.FindAccount("did:plc:notfound")
192 if found != nil {
193 t.Errorf("FindAccount() = %v, want nil", found)
194 }
195 })
196
197 t.Run("returned pointer is mutable", func(t *testing.T) {
198 found := registry.FindAccount("did:plc:first")
199 if found == nil {
200 t.Fatal("FindAccount() returned nil")
201 }
202 found.SessionId = "modified"
203
204 refetch := registry.FindAccount("did:plc:first")
205 if refetch.SessionId != "modified" {
206 t.Errorf("FindAccount() pointer not referencing original, got %s", refetch.SessionId)
207 }
208 })
209}