identity_test.go

  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}