1package identity
2
3import (
4 "encoding/json"
5 "testing"
6
7 "github.com/MichaelMure/git-bug/entity"
8 "github.com/MichaelMure/git-bug/repository"
9 "github.com/stretchr/testify/assert"
10)
11
12// Test the commit and load of an Identity with multiple versions
13func TestIdentityCommitLoad(t *testing.T) {
14 mockRepo := repository.NewMockRepoForTest()
15
16 // single version
17
18 identity := &Identity{
19 id: entity.UnsetId,
20 versions: []*Version{
21 {
22 name: "René Descartes",
23 email: "rene.descartes@example.com",
24 },
25 },
26 }
27
28 err := identity.Commit(mockRepo)
29
30 assert.Nil(t, err)
31 assert.NotEmpty(t, identity.id)
32
33 loaded, err := ReadLocal(mockRepo, identity.id)
34 assert.Nil(t, err)
35 commitsAreSet(t, loaded)
36 assert.Equal(t, identity, loaded)
37
38 // multiple version
39
40 identity = &Identity{
41 id: entity.UnsetId,
42 versions: []*Version{
43 {
44 time: 100,
45 name: "René Descartes",
46 email: "rene.descartes@example.com",
47 keys: []Key{
48 {PubKey: "pubkeyA"},
49 },
50 },
51 {
52 time: 200,
53 name: "René Descartes",
54 email: "rene.descartes@example.com",
55 keys: []Key{
56 {PubKey: "pubkeyB"},
57 },
58 },
59 {
60 time: 201,
61 name: "René Descartes",
62 email: "rene.descartes@example.com",
63 keys: []Key{
64 {PubKey: "pubkeyC"},
65 },
66 },
67 },
68 }
69
70 err = identity.Commit(mockRepo)
71
72 assert.Nil(t, err)
73 assert.NotEmpty(t, identity.id)
74
75 loaded, err = ReadLocal(mockRepo, identity.id)
76 assert.Nil(t, err)
77 commitsAreSet(t, loaded)
78 assert.Equal(t, identity, loaded)
79
80 // add more version
81
82 identity.AddVersion(&Version{
83 time: 201,
84 name: "René Descartes",
85 email: "rene.descartes@example.com",
86 keys: []Key{
87 {PubKey: "pubkeyD"},
88 },
89 })
90
91 identity.AddVersion(&Version{
92 time: 300,
93 name: "René Descartes",
94 email: "rene.descartes@example.com",
95 keys: []Key{
96 {PubKey: "pubkeyE"},
97 },
98 })
99
100 err = identity.Commit(mockRepo)
101
102 assert.Nil(t, err)
103 assert.NotEmpty(t, identity.id)
104
105 loaded, err = ReadLocal(mockRepo, identity.id)
106 assert.Nil(t, err)
107 commitsAreSet(t, loaded)
108 assert.Equal(t, identity, loaded)
109}
110
111func commitsAreSet(t *testing.T, identity *Identity) {
112 for _, version := range identity.versions {
113 assert.NotEmpty(t, version.commitHash)
114 }
115}
116
117// Test that the correct crypto keys are returned for a given lamport time
118func TestIdentity_ValidKeysAtTime(t *testing.T) {
119 identity := Identity{
120 id: entity.UnsetId,
121 versions: []*Version{
122 {
123 time: 100,
124 name: "René Descartes",
125 email: "rene.descartes@example.com",
126 keys: []Key{
127 {PubKey: "pubkeyA"},
128 },
129 },
130 {
131 time: 200,
132 name: "René Descartes",
133 email: "rene.descartes@example.com",
134 keys: []Key{
135 {PubKey: "pubkeyB"},
136 },
137 },
138 {
139 time: 201,
140 name: "René Descartes",
141 email: "rene.descartes@example.com",
142 keys: []Key{
143 {PubKey: "pubkeyC"},
144 },
145 },
146 {
147 time: 201,
148 name: "René Descartes",
149 email: "rene.descartes@example.com",
150 keys: []Key{
151 {PubKey: "pubkeyD"},
152 },
153 },
154 {
155 time: 300,
156 name: "René Descartes",
157 email: "rene.descartes@example.com",
158 keys: []Key{
159 {PubKey: "pubkeyE"},
160 },
161 },
162 },
163 }
164
165 assert.Nil(t, identity.ValidKeysAtTime(10))
166 assert.Equal(t, identity.ValidKeysAtTime(100), []Key{{PubKey: "pubkeyA"}})
167 assert.Equal(t, identity.ValidKeysAtTime(140), []Key{{PubKey: "pubkeyA"}})
168 assert.Equal(t, identity.ValidKeysAtTime(200), []Key{{PubKey: "pubkeyB"}})
169 assert.Equal(t, identity.ValidKeysAtTime(201), []Key{{PubKey: "pubkeyD"}})
170 assert.Equal(t, identity.ValidKeysAtTime(202), []Key{{PubKey: "pubkeyD"}})
171 assert.Equal(t, identity.ValidKeysAtTime(300), []Key{{PubKey: "pubkeyE"}})
172 assert.Equal(t, identity.ValidKeysAtTime(3000), []Key{{PubKey: "pubkeyE"}})
173}
174
175// Test the immutable or mutable metadata search
176func TestMetadata(t *testing.T) {
177 mockRepo := repository.NewMockRepoForTest()
178
179 identity := NewIdentity("René Descartes", "rene.descartes@example.com")
180
181 identity.SetMetadata("key1", "value1")
182 assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
183 assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
184
185 err := identity.Commit(mockRepo)
186 assert.NoError(t, err)
187
188 assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
189 assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
190
191 // try override
192 identity.AddVersion(&Version{
193 name: "René Descartes",
194 email: "rene.descartes@example.com",
195 })
196
197 identity.SetMetadata("key1", "value2")
198 assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
199 assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value2")
200
201 err = identity.Commit(mockRepo)
202 assert.NoError(t, err)
203
204 // reload
205 loaded, err := ReadLocal(mockRepo, identity.id)
206 assert.Nil(t, err)
207
208 assertHasKeyValue(t, loaded.ImmutableMetadata(), "key1", "value1")
209 assertHasKeyValue(t, loaded.MutableMetadata(), "key1", "value2")
210}
211
212func assertHasKeyValue(t *testing.T, metadata map[string]string, key, value string) {
213 val, ok := metadata[key]
214 assert.True(t, ok)
215 assert.Equal(t, val, value)
216}
217
218func TestJSON(t *testing.T) {
219 mockRepo := repository.NewMockRepoForTest()
220
221 identity := &Identity{
222 id: entity.UnsetId,
223 versions: []*Version{
224 {
225 name: "René Descartes",
226 email: "rene.descartes@example.com",
227 },
228 },
229 }
230
231 // commit to make sure we have an Id
232 err := identity.Commit(mockRepo)
233 assert.Nil(t, err)
234 assert.NotEmpty(t, identity.id)
235
236 // serialize
237 data, err := json.Marshal(identity)
238 assert.NoError(t, err)
239
240 // deserialize, got a IdentityStub with the same id
241 var i Interface
242 i, err = UnmarshalJSON(data)
243 assert.NoError(t, err)
244 assert.Equal(t, identity.id, i.Id())
245
246 // make sure we can load the identity properly
247 i, err = ReadLocal(mockRepo, i.Id())
248 assert.NoError(t, err)
249}