identity_test.go

  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					{armoredPublicKey: repository.CreatePubkey(t)},
 49				},
 50			},
 51			{
 52				time:  200,
 53				name:  "René Descartes",
 54				email: "rene.descartes@example.com",
 55				keys: []*Key{
 56					{armoredPublicKey: repository.CreatePubkey(t)},
 57				},
 58			},
 59			{
 60				time:  201,
 61				name:  "René Descartes",
 62				email: "rene.descartes@example.com",
 63				keys: []*Key{
 64					{armoredPublicKey: repository.CreatePubkey(t)},
 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	loadKeys(loaded)
 79	assert.Equal(t, identity, loaded)
 80
 81	// add more version
 82
 83	identity.Mutate(func(orig Mutator) Mutator {
 84
 85		return orig
 86	})
 87
 88	identity.addVersionForTest(&Version{
 89		time:  201,
 90		name:  "René Descartes",
 91		email: "rene.descartes@example.com",
 92		keys: []*Key{
 93			{armoredPublicKey: repository.CreatePubkey(t)},
 94		},
 95	})
 96
 97	identity.addVersionForTest(&Version{
 98		time:  300,
 99		name:  "René Descartes",
100		email: "rene.descartes@example.com",
101		keys: []*Key{
102			{armoredPublicKey: repository.CreatePubkey(t)},
103		},
104	})
105
106	err = identity.Commit(mockRepo)
107
108	assert.Nil(t, err)
109	assert.NotEmpty(t, identity.id)
110
111	loaded, err = ReadLocal(mockRepo, identity.id)
112	assert.Nil(t, err)
113	commitsAreSet(t, loaded)
114	loadKeys(loaded)
115	assert.Equal(t, identity, loaded)
116}
117
118func loadKeys(identity *Identity) {
119	for _, v := range identity.versions {
120		for _, k := range v.keys {
121			k.publicKey()
122		}
123	}
124}
125
126func commitsAreSet(t *testing.T, identity *Identity) {
127	for _, version := range identity.versions {
128		assert.NotEmpty(t, version.commitHash)
129	}
130}
131
132// Test that the correct crypto keys are returned for a given lamport time
133func TestIdentity_ValidKeysAtTime(t *testing.T) {
134	identity := Identity{
135		id: entity.UnsetId,
136		versions: []*Version{
137			{
138				time:  100,
139				name:  "René Descartes",
140				email: "rene.descartes@example.com",
141				keys: []*Key{
142					{armoredPublicKey: "pubkeyA"},
143				},
144			},
145			{
146				time:  200,
147				name:  "René Descartes",
148				email: "rene.descartes@example.com",
149				keys: []*Key{
150					{armoredPublicKey: "pubkeyB"},
151				},
152			},
153			{
154				time:  201,
155				name:  "René Descartes",
156				email: "rene.descartes@example.com",
157				keys: []*Key{
158					{armoredPublicKey: "pubkeyC"},
159				},
160			},
161			{
162				time:  201,
163				name:  "René Descartes",
164				email: "rene.descartes@example.com",
165				keys: []*Key{
166					{armoredPublicKey: "pubkeyD"},
167				},
168			},
169			{
170				time:  300,
171				name:  "René Descartes",
172				email: "rene.descartes@example.com",
173				keys: []*Key{
174					{armoredPublicKey: "pubkeyE"},
175				},
176			},
177		},
178	}
179
180	assert.Nil(t, identity.ValidKeysAtTime(10))
181	assert.Equal(t, identity.ValidKeysAtTime(100), []*Key{{armoredPublicKey: "pubkeyA"}})
182	assert.Equal(t, identity.ValidKeysAtTime(140), []*Key{{armoredPublicKey: "pubkeyA"}})
183	assert.Equal(t, identity.ValidKeysAtTime(200), []*Key{{armoredPublicKey: "pubkeyB"}})
184	assert.Equal(t, identity.ValidKeysAtTime(201), []*Key{{armoredPublicKey: "pubkeyD"}})
185	assert.Equal(t, identity.ValidKeysAtTime(202), []*Key{{armoredPublicKey: "pubkeyD"}})
186	assert.Equal(t, identity.ValidKeysAtTime(300), []*Key{{armoredPublicKey: "pubkeyE"}})
187	assert.Equal(t, identity.ValidKeysAtTime(3000), []*Key{{armoredPublicKey: "pubkeyE"}})
188}
189
190// Test the immutable or mutable metadata search
191func TestMetadata(t *testing.T) {
192	mockRepo := repository.NewMockRepoForTest()
193
194	identity := NewIdentity("René Descartes", "rene.descartes@example.com")
195
196	identity.SetMetadata("key1", "value1")
197	assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
198	assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
199
200	err := identity.Commit(mockRepo)
201	assert.NoError(t, err)
202
203	assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
204	assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value1")
205
206	// try override
207	identity.addVersionForTest(&Version{
208		name:  "René Descartes",
209		email: "rene.descartes@example.com",
210	})
211
212	identity.SetMetadata("key1", "value2")
213	assertHasKeyValue(t, identity.ImmutableMetadata(), "key1", "value1")
214	assertHasKeyValue(t, identity.MutableMetadata(), "key1", "value2")
215
216	err = identity.Commit(mockRepo)
217	assert.NoError(t, err)
218
219	// reload
220	loaded, err := ReadLocal(mockRepo, identity.id)
221	assert.Nil(t, err)
222
223	assertHasKeyValue(t, loaded.ImmutableMetadata(), "key1", "value1")
224	assertHasKeyValue(t, loaded.MutableMetadata(), "key1", "value2")
225}
226
227func assertHasKeyValue(t *testing.T, metadata map[string]string, key, value string) {
228	val, ok := metadata[key]
229	assert.True(t, ok)
230	assert.Equal(t, val, value)
231}
232
233func TestJSON(t *testing.T) {
234	mockRepo := repository.NewMockRepoForTest()
235
236	identity := &Identity{
237		id: entity.UnsetId,
238		versions: []*Version{
239			{
240				name:  "René Descartes",
241				email: "rene.descartes@example.com",
242			},
243		},
244	}
245
246	// commit to make sure we have an Id
247	err := identity.Commit(mockRepo)
248	assert.Nil(t, err)
249	assert.NotEmpty(t, identity.id)
250
251	// serialize
252	data, err := json.Marshal(identity)
253	assert.NoError(t, err)
254
255	// deserialize, got a IdentityStub with the same id
256	var i Interface
257	i, err = UnmarshalJSON(data)
258	assert.NoError(t, err)
259	assert.Equal(t, identity.id, i.Id())
260
261	// make sure we can load the identity properly
262	i, err = ReadLocal(mockRepo, i.Id())
263	assert.NoError(t, err)
264}