1package identity
2
3import (
4 "encoding/json"
5 "testing"
6
7 "github.com/stretchr/testify/require"
8
9 "github.com/MichaelMure/git-bug/entity"
10 "github.com/MichaelMure/git-bug/repository"
11)
12
13// Test the commit and load of an Identity with multiple versions
14func TestIdentityCommitLoad(t *testing.T) {
15 mockRepo := repository.NewMockRepoForTest()
16
17 // single version
18
19 identity := &Identity{
20 id: entity.UnsetId,
21 versions: []*Version{
22 {
23 name: "René Descartes",
24 email: "rene.descartes@example.com",
25 },
26 },
27 }
28
29 err := identity.Commit(mockRepo)
30
31 require.NoError(t, err)
32 require.NotEmpty(t, identity.id)
33
34 loaded, err := ReadLocal(mockRepo, identity.id)
35 require.NoError(t, err)
36 commitsAreSet(t, loaded)
37 require.Equal(t, identity, loaded)
38
39 // multiple version
40
41 identity = &Identity{
42 id: entity.UnsetId,
43 versions: []*Version{
44 {
45 time: 100,
46 name: "René Descartes",
47 email: "rene.descartes@example.com",
48 keys: []*Key{
49 {PubKey: "pubkeyA"},
50 },
51 },
52 {
53 time: 200,
54 name: "René Descartes",
55 email: "rene.descartes@example.com",
56 keys: []*Key{
57 {PubKey: "pubkeyB"},
58 },
59 },
60 {
61 time: 201,
62 name: "René Descartes",
63 email: "rene.descartes@example.com",
64 keys: []*Key{
65 {PubKey: "pubkeyC"},
66 },
67 },
68 },
69 }
70
71 err = identity.Commit(mockRepo)
72
73 require.NoError(t, err)
74 require.NotEmpty(t, identity.id)
75
76 loaded, err = ReadLocal(mockRepo, identity.id)
77 require.NoError(t, err)
78 commitsAreSet(t, loaded)
79 require.Equal(t, identity, loaded)
80
81 // add more version
82
83 identity.addVersionForTest(&Version{
84 time: 201,
85 name: "René Descartes",
86 email: "rene.descartes@example.com",
87 keys: []*Key{
88 {PubKey: "pubkeyD"},
89 },
90 })
91
92 identity.addVersionForTest(&Version{
93 time: 300,
94 name: "René Descartes",
95 email: "rene.descartes@example.com",
96 keys: []*Key{
97 {PubKey: "pubkeyE"},
98 },
99 })
100
101 err = identity.Commit(mockRepo)
102
103 require.NoError(t, err)
104 require.NotEmpty(t, identity.id)
105
106 loaded, err = ReadLocal(mockRepo, identity.id)
107 require.NoError(t, err)
108 commitsAreSet(t, loaded)
109 require.Equal(t, identity, loaded)
110}
111
112func TestIdentityMutate(t *testing.T) {
113 identity := NewIdentity("René Descartes", "rene.descartes@example.com")
114
115 require.Len(t, identity.versions, 1)
116
117 identity.Mutate(func(orig Mutator) Mutator {
118 orig.Email = "rene@descartes.fr"
119 orig.Name = "René"
120 orig.Login = "rene"
121 return orig
122 })
123
124 require.Len(t, identity.versions, 2)
125 require.Equal(t, identity.Email(), "rene@descartes.fr")
126 require.Equal(t, identity.Name(), "René")
127 require.Equal(t, identity.Login(), "rene")
128}
129
130func commitsAreSet(t *testing.T, identity *Identity) {
131 for _, version := range identity.versions {
132 require.NotEmpty(t, version.commitHash)
133 }
134}
135
136// Test that the correct crypto keys are returned for a given lamport time
137func TestIdentity_ValidKeysAtTime(t *testing.T) {
138 identity := Identity{
139 id: entity.UnsetId,
140 versions: []*Version{
141 {
142 time: 100,
143 name: "René Descartes",
144 email: "rene.descartes@example.com",
145 keys: []*Key{
146 {PubKey: "pubkeyA"},
147 },
148 },
149 {
150 time: 200,
151 name: "René Descartes",
152 email: "rene.descartes@example.com",
153 keys: []*Key{
154 {PubKey: "pubkeyB"},
155 },
156 },
157 {
158 time: 201,
159 name: "René Descartes",
160 email: "rene.descartes@example.com",
161 keys: []*Key{
162 {PubKey: "pubkeyC"},
163 },
164 },
165 {
166 time: 201,
167 name: "René Descartes",
168 email: "rene.descartes@example.com",
169 keys: []*Key{
170 {PubKey: "pubkeyD"},
171 },
172 },
173 {
174 time: 300,
175 name: "René Descartes",
176 email: "rene.descartes@example.com",
177 keys: []*Key{
178 {PubKey: "pubkeyE"},
179 },
180 },
181 },
182 }
183
184 require.Nil(t, identity.ValidKeysAtTime(10))
185 require.Equal(t, identity.ValidKeysAtTime(100), []*Key{{PubKey: "pubkeyA"}})
186 require.Equal(t, identity.ValidKeysAtTime(140), []*Key{{PubKey: "pubkeyA"}})
187 require.Equal(t, identity.ValidKeysAtTime(200), []*Key{{PubKey: "pubkeyB"}})
188 require.Equal(t, identity.ValidKeysAtTime(201), []*Key{{PubKey: "pubkeyD"}})
189 require.Equal(t, identity.ValidKeysAtTime(202), []*Key{{PubKey: "pubkeyD"}})
190 require.Equal(t, identity.ValidKeysAtTime(300), []*Key{{PubKey: "pubkeyE"}})
191 require.Equal(t, identity.ValidKeysAtTime(3000), []*Key{{PubKey: "pubkeyE"}})
192}
193
194// Test the immutable or mutable metadata search
195func TestMetadata(t *testing.T) {
196 mockRepo := repository.NewMockRepoForTest()
197
198 identity := NewIdentity("René Descartes", "rene.descartes@example.com")
199
200 identity.SetMetadata("key1", "value1")
201 assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
202 assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
203
204 err := identity.Commit(mockRepo)
205 require.NoError(t, err)
206
207 assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
208 assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
209
210 // try override
211 identity.addVersionForTest(&Version{
212 name: "René Descartes",
213 email: "rene.descartes@example.com",
214 })
215
216 identity.SetMetadata("key1", "value2")
217 assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
218 assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value2")
219
220 err = identity.Commit(mockRepo)
221 require.NoError(t, err)
222
223 // reload
224 loaded, err := ReadLocal(mockRepo, identity.id)
225 require.NoError(t, err)
226
227 assertHasKeyValue(t, loaded.ImmutableMetadata(), "key1", "value1")
228 assertHasKeyValue(t, loaded.MutableMetadata(), "key1", "value2")
229}
230
231func assertHasKeyValue(t *testing.T, metadata map[string]string, key, value string) {
232 val, ok := metadata[key]
233 require.True(t, ok)
234 require.Equal(t, val, value)
235}
236
237func TestJSON(t *testing.T) {
238 mockRepo := repository.NewMockRepoForTest()
239
240 identity := &Identity{
241 id: entity.UnsetId,
242 versions: []*Version{
243 {
244 name: "René Descartes",
245 email: "rene.descartes@example.com",
246 },
247 },
248 }
249
250 // commit to make sure we have an Id
251 err := identity.Commit(mockRepo)
252 require.NoError(t, err)
253 require.NotEmpty(t, identity.id)
254
255 // serialize
256 data, err := json.Marshal(identity)
257 require.NoError(t, err)
258
259 // deserialize, got a IdentityStub with the same id
260 var i Interface
261 i, err = UnmarshalJSON(data)
262 require.NoError(t, err)
263 require.Equal(t, identity.id, i.Id())
264
265 // make sure we can load the identity properly
266 i, err = ReadLocal(mockRepo, i.Id())
267 require.NoError(t, err)
268}
269
270func TestIdentityRemove(t *testing.T) {
271 repo := repository.CreateGoGitTestRepo(false)
272 remoteA := repository.CreateGoGitTestRepo(true)
273 remoteB := repository.CreateGoGitTestRepo(true)
274 defer repository.CleanupTestRepos(repo, remoteA, remoteB)
275
276 err := repo.AddRemote("remoteA", remoteA.GetLocalRemote())
277 require.NoError(t, err)
278
279 err = repo.AddRemote("remoteB", remoteB.GetLocalRemote())
280 require.NoError(t, err)
281
282 // generate an identity for testing
283 rene := NewIdentity("René Descartes", "rene@descartes.fr")
284 err = rene.Commit(repo)
285 require.NoError(t, err)
286
287 _, err = Push(repo, "remoteA")
288 require.NoError(t, err)
289
290 _, err = Push(repo, "remoteB")
291 require.NoError(t, err)
292
293 _, err = Fetch(repo, "remoteA")
294 require.NoError(t, err)
295
296 _, err = Fetch(repo, "remoteB")
297 require.NoError(t, err)
298
299 err = RemoveIdentity(repo, rene.Id())
300 require.NoError(t, err)
301
302 _, err = ReadLocal(repo, rene.Id())
303 require.Error(t, ErrIdentityNotExist, err)
304
305 _, err = ReadRemote(repo, "remoteA", string(rene.Id()))
306 require.Error(t, ErrIdentityNotExist, err)
307
308 _, err = ReadRemote(repo, "remoteB", string(rene.Id()))
309 require.Error(t, ErrIdentityNotExist, err)
310
311 ids, err := ListLocalIds(repo)
312 require.NoError(t, err)
313 require.Len(t, ids, 0)
314}