646deeda41acf413379416c392bf6071833cc392
[WebKit-https.git] / Websites / perf.webkit.org / unit-tests / commit-set-tests.js
1 "use strict";
2
3 const assert = require('assert');
4 require('../tools/js/v3-models.js');
5 const MockModels = require('./resources/mock-v3-models.js').MockModels;
6 const MockRemoteAPI = require('../unit-tests/resources/mock-remote-api.js').MockRemoteAPI;
7
8 function createPatch()
9 {
10     return UploadedFile.ensureSingleton(453, {'createdAt': new Date('2017-05-01T19:16:53Z'), 'filename': 'patch.dat', 'extension': '.dat', 'author': 'some user',
11         size: 534637, sha256: '169463c8125e07c577110fe144ecd63942eb9472d438fc0014f474245e5df8a1'});
12 }
13
14 function createAnotherPatch()
15 {
16     return UploadedFile.ensureSingleton(454, {'createdAt': new Date('2017-05-01T19:16:53Z'), 'filename': 'patch.dat', 'extension': '.dat', 'author': 'some user',
17         size: 534611, sha256: '169463c8125e07c577110fe144ecd63942eb9472d438fc0014f474245e5dfaaa'});
18 }
19
20 function createRoot()
21 {
22     return UploadedFile.ensureSingleton(456, {'createdAt': new Date('2017-05-01T21:03:27Z'), 'filename': 'root.dat', 'extension': '.dat', 'author': 'some user',
23         size: 16452234, sha256: '03eed7a8494ab8794c44b7d4308e55448fc56f4d6c175809ba968f78f656d58d'});
24 }
25
26 function createAnotherRoot()
27 {
28     return UploadedFile.ensureSingleton(457, {'createdAt': new Date('2017-05-01T21:03:27Z'), 'filename': 'root.dat', 'extension': '.dat', 'author': 'some user',
29         size: 16452111, sha256: '03eed7a8494ab8794c44b7d4308e55448fc56f4d6c175809ba968f78f656dbbb'});
30 }
31
32 function createSharedRoot()
33 {
34     return UploadedFile.ensureSingleton(458, {'createdAt': new Date('2017-05-01T22:03:27Z'), 'filename': 'root.dat', 'extension': '.dat', 'author': 'some user',
35         size: 16452111, sha256: '03eed7a8494ab8794c44b7d4308e55448fc56f4aac175809ba968f78f656dbbb'});
36 }
37
38 function customCommitSetWithoutOwnedCommit()
39 {
40     const customCommitSet = new CustomCommitSet;
41     customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
42     customCommitSet.setRevisionForRepository(MockModels.webkit, '200805');
43     return customCommitSet;
44 }
45
46 function customCommitSetWithOwnedCommit()
47 {
48     const customCommitSet = new CustomCommitSet;
49     customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
50     customCommitSet.setRevisionForRepository(MockModels.ownerRepository, 'OwnerRepository-r0');
51     customCommitSet.setRevisionForRepository(MockModels.ownedRepository, 'OwnedRepository-r0', null, 'OwnerRepository-r0');
52     return customCommitSet;
53 }
54
55 function customCommitSetWithPatch()
56 {
57     const customCommitSet = new CustomCommitSet;
58     const patch = createPatch();
59     customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
60     customCommitSet.setRevisionForRepository(MockModels.webkit, '200805', patch);
61     return customCommitSet;
62 }
63
64 function customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository()
65 {
66     const customCommitSet = new CustomCommitSet;
67     customCommitSet.setRevisionForRepository(MockModels.osx, '10.11.4 15E65');
68     customCommitSet.setRevisionForRepository(MockModels.webkit, '200805');
69     customCommitSet.setRevisionForRepository(MockModels.ownedWebkit, 'owned-200805', null, '10.11.4 15E65');
70     return customCommitSet;
71 }
72
73 function ownerCommit()
74 {
75     return CommitLog.ensureSingleton(5, {
76         repository: MockModels.ownerRepository,
77         revision: 'owner-commit-0',
78         ownsCommits: true,
79         time: null,
80     });
81 }
82
83 function partialOwnerCommit()
84 {
85     return CommitLog.ensureSingleton(5, {
86         repository: MockModels.ownerRepository,
87         revision: 'owner-commit-0',
88         ownsCommits: null,
89         time: +(new Date('2016-05-13T00:55:57.841344Z')),
90     });
91 }
92
93 function ownedCommit()
94 {
95     return new CommitLog(6, {
96         repository: MockModels.ownedRepository,
97         revision: 'owned-commit-0',
98         ownsCommits: null,
99         time: 1456932774000
100     });
101 }
102
103 function webkitCommit()
104 {
105     return CommitLog.ensureSingleton(2017, {
106         repository: MockModels.webkit,
107         revision: 'webkit-commit-0',
108         ownsCommits: false,
109         time: 1456932773000
110     });
111 }
112
113 function anotherWebKitCommit()
114 {
115     return CommitLog.ensureSingleton(2018, {
116         repository: MockModels.webkit,
117         revision: 'webkit-commit-1',
118         ownsCommits: false,
119         time: 1456932773000
120     });
121 }
122
123 function commitWithSVNRevision()
124 {
125     return CommitLog.ensureSingleton(2019, {
126         repository: MockModels.webkit,
127         revision: '12345',
128         ownsCommits: false,
129         time: 1456932773000
130     });
131 }
132
133 function anotherCommitWithSVNRevision()
134 {
135     return CommitLog.ensureSingleton(2020, {
136         repository: MockModels.webkit,
137         revision: '45678',
138         ownsCommits: false,
139         time: 1456932773000
140     });
141 }
142
143 function commitWithGitRevision()
144 {
145     return CommitLog.ensureSingleton(2021, {
146         repository: MockModels.webkitGit,
147         revision: '13a0590d34f26fda3953c42ff833132a1a6f6f5a',
148         ownsCommits: false,
149         time: 1456932773000
150     });
151 }
152
153 function anotherCommitWithGitRevision()
154 {
155     return CommitLog.ensureSingleton(2022, {
156         repository: MockModels.webkitGit,
157         revision: '2f8dd3321d4f51c04f4e2019428ce9ffe97f1ef1',
158         ownsCommits: false,
159         time: 1456932773000
160     });
161 }
162
163 describe('CommitSet', () => {
164     MockRemoteAPI.inject();
165     MockModels.inject();
166
167     function oneCommitSet()
168     {
169         return CommitSet.ensureSingleton(1, {
170             revisionItems: [{ commit: webkitCommit(), requiresBuild: false }],
171             customRoots: []
172         });
173     }
174
175     function anotherCommitSet()
176     {
177         return CommitSet.ensureSingleton(2, {
178             revisionItems: [{ commit: webkitCommit(), requiresBuild: false }],
179             customRoots: []
180         });
181     }
182
183     function commitSetWithPatch()
184     {
185         return CommitSet.ensureSingleton(3, {
186             revisionItems: [{ commit: webkitCommit(), requiresBuild: false, patch: createPatch() }],
187             customRoots: []
188         });
189     }
190
191     function commitSetWithAnotherPatch()
192     {
193         return CommitSet.ensureSingleton(4, {
194             revisionItems: [{ commit: webkitCommit(), requiresBuild: false, patch: createAnotherPatch() }],
195             customRoots: []
196         });
197     }
198
199     function commitSetWithRoot()
200     {
201         return CommitSet.ensureSingleton(5, {
202             revisionItems: [{ commit: webkitCommit(), requiresBuild: false }],
203             customRoots: [createRoot()]
204         });
205     }
206
207     function anotherCommitSetWithRoot()
208     {
209         return CommitSet.ensureSingleton(6, {
210             revisionItems: [{ commit: webkitCommit(), requiresBuild: false }],
211             customRoots: [createAnotherRoot()]
212         });
213     }
214
215     function commitSetWithTwoRoots()
216     {
217         return CommitSet.ensureSingleton(7, {
218             revisionItems: [{ commit: webkitCommit(), requiresBuild: false }],
219             customRoots: [createRoot(), createSharedRoot()]
220         });
221     }
222
223     function commitSetWithAnotherWebKitCommit()
224     {
225         return CommitSet.ensureSingleton(8, {
226             revisionItems: [{ commit: anotherWebKitCommit(), requiresBuild: false }],
227             customRoots: []
228         });
229     }
230
231     function commitSetWithAnotherCommitPatchAndRoot()
232     {
233         return CommitSet.ensureSingleton(9, {
234             revisionItems: [{ commit: anotherWebKitCommit(), requiresBuild: true, patch: createPatch()}],
235             customRoots: [createRoot(), createSharedRoot()]
236         });
237     }
238
239     function commitSetWithSVNCommit()
240     {
241         return CommitSet.ensureSingleton(10, {
242             revisionItems: [{ commit: commitWithSVNRevision(), requiresBuild: false }],
243             customRoots: []
244         });
245     }
246
247     function anotherCommitSetWithSVNCommit()
248     {
249         return CommitSet.ensureSingleton(11, {
250             revisionItems: [{ commit: anotherCommitWithSVNRevision(), requiresBuild: false }],
251             customRoots: []
252         });
253     }
254
255     function commitSetWithGitCommit()
256     {
257         return CommitSet.ensureSingleton(12, {
258             revisionItems: [{ commit: commitWithGitRevision(), requiresBuild: false }],
259             customRoots: []
260         });
261     }
262
263     function anotherCommitSetWithGitCommit()
264     {
265         return CommitSet.ensureSingleton(13, {
266             revisionItems: [{ commit: anotherCommitWithGitRevision(), requiresBuild: false }],
267             customRoots: []
268         });
269     }
270
271     function commitSetWithTwoCommits()
272     {
273         return CommitSet.ensureSingleton(14, {
274             revisionItems: [{ commit: commitWithGitRevision(), requiresBuild: false }, { commit: commitWithSVNRevision(), requiresBuild: false }],
275             customRoots: []
276         });
277     }
278
279     function anotherCommitSetWithTwoCommits()
280     {
281         return CommitSet.ensureSingleton(15, {
282             revisionItems: [{ commit: anotherCommitWithGitRevision(), requiresBuild: false }, { commit: anotherCommitWithSVNRevision(), requiresBuild: false }],
283             customRoots: []
284         });
285     }
286
287     function oneMeasurementCommitSet()
288     {
289         return MeasurementCommitSet.ensureSingleton(1, [
290             [2017, 11, 'webkit-commit-0', null, 1456932773000]
291         ]);
292     }
293
294     describe('equals', () => {
295         it('should return false if patches for same repository are different', () => {
296             assert(!commitSetWithPatch().equals(commitSetWithAnotherPatch()));
297             assert(!commitSetWithAnotherPatch().equals(commitSetWithPatch()));
298         });
299
300         it('should return false if patch is only specified in one commit set', () => {
301             assert(!oneCommitSet().equals(commitSetWithPatch()));
302             assert(!commitSetWithPatch().equals(oneCommitSet()));
303         });
304
305         it('should return false if roots for same repository are different', () => {
306             assert(!commitSetWithRoot().equals(anotherCommitSetWithRoot()));
307             assert(!anotherCommitSetWithRoot().equals(commitSetWithRoot()));
308         });
309
310         it('should return false if root is only specified in one commit set', () => {
311             assert(!commitSetWithRoot().equals(oneCommitSet()));
312             assert(!oneCommitSet().equals(commitSetWithRoot()));
313         });
314
315         it('should return true when comparing two identical commit set', () => {
316             assert(oneCommitSet().equals(oneCommitSet()));
317             assert(anotherCommitSet().equals(anotherCommitSet()));
318             assert(commitSetWithPatch().equals(commitSetWithPatch()));
319             assert(commitSetWithAnotherPatch().equals(commitSetWithAnotherPatch()));
320             assert(oneMeasurementCommitSet().equals(oneMeasurementCommitSet()));
321             assert(commitSetWithRoot().equals(commitSetWithRoot()));
322             assert(anotherCommitSetWithRoot().equals(anotherCommitSetWithRoot()));
323         });
324
325         it('should be able to compare between CommitSet and MeasurementCommitSet', () => {
326             assert(oneCommitSet().equals(oneMeasurementCommitSet()));
327             assert(oneMeasurementCommitSet().equals(oneCommitSet()));
328         });
329     });
330
331     describe('containsRootOrPatchOrOwnedCommit', () => {
332         it('should return false if commit does not contain root, patch or owned commit', () => {
333             assert.ok(!oneCommitSet().containsRootOrPatchOrOwnedCommit());
334             assert.ok(!anotherCommitSet().containsRootOrPatchOrOwnedCommit());
335             assert.ok(!commitSetWithAnotherWebKitCommit().containsRootOrPatchOrOwnedCommit());
336             assert.ok(!commitSetWithSVNCommit().containsRootOrPatchOrOwnedCommit());
337             assert.ok(!anotherCommitSetWithSVNCommit().containsRootOrPatchOrOwnedCommit());
338             assert.ok(!commitSetWithGitCommit().containsRootOrPatchOrOwnedCommit());
339             assert.ok(!anotherCommitSetWithGitCommit().containsRootOrPatchOrOwnedCommit());
340             assert.ok(!commitSetWithTwoCommits().containsRootOrPatchOrOwnedCommit());
341             assert.ok(!anotherCommitSetWithTwoCommits().containsRootOrPatchOrOwnedCommit());
342             assert.ok(!oneMeasurementCommitSet().containsRootOrPatchOrOwnedCommit());
343         });
344
345         it('should return true if commit contains root, patch or owned commit', () => {
346             assert.ok(commitSetWithPatch().containsRootOrPatchOrOwnedCommit());
347             assert.ok(commitSetWithAnotherPatch().containsRootOrPatchOrOwnedCommit());
348             assert.ok(commitSetWithRoot().containsRootOrPatchOrOwnedCommit());
349             assert.ok(anotherCommitSetWithRoot().containsRootOrPatchOrOwnedCommit());
350             assert.ok(commitSetWithTwoRoots().containsRootOrPatchOrOwnedCommit());
351             assert.ok(commitSetWithAnotherCommitPatchAndRoot().containsRootOrPatchOrOwnedCommit());
352         });
353     });
354
355     describe('hasSameRepositories', () => {
356         it('should return true if two commit sets have same repositories', () => {
357             assert.ok(oneCommitSet().hasSameRepositories(anotherCommitSet()));
358             assert.ok(commitSetWithGitCommit().hasSameRepositories(anotherCommitSetWithGitCommit()));
359             assert.ok(oneCommitSet().hasSameRepositories(oneCommitSet()));
360         });
361
362         it('should return false if two commit sets have differen repositories', () => {
363             assert.ok(!commitSetWithGitCommit().hasSameRepositories(commitSetWithSVNCommit()));
364             assert.ok(!commitSetWithTwoCommits().hasSameRepositories(commitSetWithGitCommit()));
365         });
366     });
367
368     describe('diff',  () => {
369         it('should describe patch difference', () => {
370             assert.equal(CommitSet.diff(commitSetWithPatch(), commitSetWithAnotherPatch()), 'WebKit: patch.dat - patch.dat (2)');
371         });
372
373         it('should describe root difference', () => {
374             assert.equal(CommitSet.diff(commitSetWithRoot(), anotherCommitSetWithRoot()), 'Roots: root.dat - root.dat (2)');
375             assert.equal(CommitSet.diff(commitSetWithRoot(), commitSetWithTwoRoots()), 'Roots: none - root.dat');
376             assert.equal(CommitSet.diff(commitSetWithTwoRoots(), oneCommitSet()), 'Roots: root.dat, root.dat (2) - none');
377         });
378
379         it('should describe commit difference', () => {
380             assert.equal(CommitSet.diff(oneCommitSet(), commitSetWithAnotherWebKitCommit()), 'WebKit: webkit-commit-0 - webkit-commit-1');
381             assert.equal(CommitSet.diff(commitSetWithSVNCommit(), anotherCommitSetWithSVNCommit()), 'WebKit: r12345-r45678');
382             assert.equal(CommitSet.diff(commitSetWithGitCommit(), anotherCommitSetWithGitCommit()), 'WebKit-Git: 13a0590d..2f8dd332');
383             assert.equal(CommitSet.diff(commitSetWithTwoCommits(), anotherCommitSetWithTwoCommits()), 'WebKit: r12345-r45678 WebKit-Git: 13a0590d..2f8dd332');
384         });
385
386         it('should describe commit root and patch difference', () => {
387             assert.equal(CommitSet.diff(oneCommitSet(), commitSetWithAnotherCommitPatchAndRoot()), 'WebKit: webkit-commit-0 with none - webkit-commit-1 with patch.dat Roots: none - root.dat, root.dat (2)');
388         });
389     });
390 });
391
392 describe('IntermediateCommitSet', () => {
393     MockRemoteAPI.inject();
394     MockModels.inject();
395
396     describe('setCommitForRepository', () => {
397         it('should allow set commit for owner repository', () => {
398             const commitSet = new IntermediateCommitSet(new CommitSet);
399             const commit = ownerCommit();
400             commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
401             assert.equal(commit, commitSet.commitForRepository(MockModels.ownerRepository));
402         });
403
404         it('should allow set commit for owned repository', () => {
405             const commitSet = new IntermediateCommitSet(new CommitSet);
406             const commit = ownerCommit();
407
408             const fetchingPromise = commit.fetchOwnedCommits();
409             const requests = MockRemoteAPI.requests;
410             assert.equal(requests.length, 1);
411             assert.equal(requests[0].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
412             assert.equal(requests[0].method, 'GET');
413
414             requests[0].resolve({commits: [{
415                 id: 233,
416                 repository: MockModels.ownedRepository.id(),
417                 revision: '6f8b0dbbda95a440503b88db1dd03dad3a7b07fb',
418                 time: +(new Date('2016-05-13T00:55:57.841344Z')),
419             }]});
420
421             return fetchingPromise.then(() => {
422                 const ownedCommit = commit.ownedCommits()[0];
423                 commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
424                 commitSet.setCommitForRepository(MockModels.ownedRepository, ownedCommit);
425                 assert.equal(commit, commitSet.commitForRepository(MockModels.ownerRepository));
426                 assert.equal(ownedCommit, commitSet.commitForRepository(MockModels.ownedRepository));
427                 assert.deepEqual(commitSet.repositories(), [MockModels.ownerRepository, MockModels.ownedRepository]);
428             });
429         });
430     });
431
432     describe('fetchCommitLogs', () => {
433
434         it('should fetch CommitLog object with owned commits information',  () => {
435             const commit = partialOwnerCommit();
436             assert.equal(commit.ownsCommits(), null);
437             const owned = ownedCommit();
438
439             const commitSet = CommitSet.ensureSingleton('53246456', {revisionItems: [{commit}, {commit: owned, ownerCommit: commit}]});
440             const intermediateCommitSet =new IntermediateCommitSet(commitSet);
441             const fetchingPromise = intermediateCommitSet.fetchCommitLogs();
442
443             const requests = MockRemoteAPI.requests;
444             assert.equal(requests.length, 2);
445             assert.equal(requests[0].url, '/api/commits/111/owner-commit-0');
446             assert.equal(requests[0].method, 'GET');
447             assert.equal(requests[1].url, '/api/commits/112/owned-commit-0');
448             assert.equal(requests[1].method, 'GET');
449
450             requests[0].resolve({commits: [{
451                 id: 5,
452                 repository: MockModels.ownerRepository,
453                 revision: 'owner-commit-0',
454                 ownsCommits: true,
455                 time: +(new Date('2016-05-13T00:55:57.841344Z')),
456             }]});
457             requests[1].resolve({commits: [{
458                 id: 6,
459                 repository: MockModels.ownedRepository,
460                 revision: 'owned-commit-0',
461                 ownsCommits: false,
462                 time: 1456932774000,
463             }]});
464
465             return MockRemoteAPI.waitForRequest().then(() => {
466                 assert.equal(requests.length, 3);
467                 assert.equal(requests[2].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
468                 assert.equal(requests[2].method, 'GET');
469
470                 requests[2].resolve({commits: [{
471                     id: 6,
472                     repository: MockModels.ownedRepository.id(),
473                     revision: 'owned-commit-0',
474                     ownsCommits: false,
475                     time: 1456932774000,
476                 }]});
477                 return fetchingPromise;
478             }).then(() => {
479                 assert(commit.ownsCommits());
480                 assert.equal(commit.ownedCommits().length, 1);
481                 assert.equal(commit.ownedCommits()[0], owned);
482                 assert.equal(owned.ownerCommit(), commit);
483                 assert.equal(owned.repository(), MockModels.ownedRepository);
484                 assert.equal(intermediateCommitSet.commitForRepository(MockModels.ownedRepository), owned);
485                 assert.equal(intermediateCommitSet.ownerCommitForRepository(MockModels.ownedRepository), commit);
486                 assert.deepEqual(intermediateCommitSet.repositories(), [MockModels.ownerRepository, MockModels.ownedRepository]);
487             });
488         });
489     });
490
491     describe('updateRevisionForOwnerRepository', () => {
492
493         it('should update CommitSet based on the latest invocation', () => {
494             const commitSet = new IntermediateCommitSet(new CommitSet);
495             const firstUpdatePromise = commitSet.updateRevisionForOwnerRepository(MockModels.webkit, 'webkit-commit-0');
496             const secondUpdatePromise = commitSet.updateRevisionForOwnerRepository(MockModels.webkit, 'webkit-commit-1');
497             const requests = MockRemoteAPI.requests;
498
499             assert(requests.length, 2);
500             assert.equal(requests[0].url, '/api/commits/11/webkit-commit-0');
501             assert.equal(requests[0].method, 'GET');
502             assert.equal(requests[1].url, '/api/commits/11/webkit-commit-1');
503             assert.equal(requests[1].method, 'GET');
504
505             requests[1].resolve({commits: [{
506                 id: 2018,
507                 repository: MockModels.webkit.id(),
508                 revision: 'webkit-commit-1',
509                 ownsCommits: false,
510                 time: 1456932774000,
511             }]});
512
513             let commit = null;
514             return secondUpdatePromise.then(() => {
515                 commit = commitSet.commitForRepository(MockModels.webkit);
516
517                 requests[0].resolve({commits: [{
518                     id: 2017,
519                     repository: MockModels.webkit.id(),
520                     revision: 'webkit-commit-0',
521                     ownsCommits: false,
522                     time: 1456932773000,
523                 }]});
524
525                 assert.equal(commit.revision(), 'webkit-commit-1');
526                 assert.equal(commit.id(), 2018);
527
528                 return firstUpdatePromise;
529             }).then(() => {
530                 const currentCommit = commitSet.commitForRepository(MockModels.webkit);
531                 assert.equal(commit, currentCommit);
532             });
533         });
534
535     });
536
537     describe('removeCommitForRepository', () => {
538         it('should remove owned commits when owner commit is removed', () => {
539             const commitSet = new IntermediateCommitSet(new CommitSet);
540             const commit = ownerCommit();
541
542             const fetchingPromise = commit.fetchOwnedCommits();
543             const requests = MockRemoteAPI.requests;
544             assert.equal(requests.length, 1);
545             assert.equal(requests[0].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
546             assert.equal(requests[0].method, 'GET');
547
548             requests[0].resolve({commits: [{
549                 id: 233,
550                 repository: MockModels.ownedRepository.id(),
551                 revision: '6f8b0dbbda95a440503b88db1dd03dad3a7b07fb',
552                 ownsCommits: true
553             }]});
554
555             return fetchingPromise.then(() => {
556                 commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
557                 commitSet.setCommitForRepository(MockModels.ownedRepository, commit.ownedCommits()[0]);
558                 commitSet.removeCommitForRepository(MockModels.ownerRepository);
559                 assert.deepEqual(commitSet.repositories(), []);
560             });
561         });
562
563         it('should not remove owner commits when owned commit is removed', () => {
564             const commitSet = new IntermediateCommitSet(new CommitSet);
565             const commit = ownerCommit();
566
567             const fetchingPromise = commit.fetchOwnedCommits();
568             const requests = MockRemoteAPI.requests;
569             assert.equal(requests.length, 1);
570             assert.equal(requests[0].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
571             assert.equal(requests[0].method, 'GET');
572
573             requests[0].resolve({commits: [{
574                 id: 233,
575                 repository: MockModels.ownedRepository.id(),
576                 revision: '6f8b0dbbda95a440503b88db1dd03dad3a7b07fb',
577                 time: +(new Date('2016-05-13T00:55:57.841344Z')),
578             }]});
579
580             return fetchingPromise.then(() => {
581                 commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
582                 commitSet.setCommitForRepository(MockModels.ownedRepository, commit.ownedCommits()[0]);
583                 commitSet.removeCommitForRepository(MockModels.ownedRepository);
584                 assert.deepEqual(commitSet.repositories(), [MockModels.ownerRepository]);
585             });
586         });
587
588         it('should not update commit set for repository if removeCommitForRepository called before updateRevisionForOwnerRepository finishes', () => {
589             const commitSet = new IntermediateCommitSet(new CommitSet);
590             const commit = webkitCommit();
591             commitSet.setCommitForRepository(MockModels.webkit, commit);
592             const updatePromise = commitSet.updateRevisionForOwnerRepository(MockModels.webkit, 'webkit-commit-1');
593
594             commitSet.removeCommitForRepository(MockModels.webkit);
595
596             const requests = MockRemoteAPI.requests;
597             assert.equal(requests[0].url, '/api/commits/11/webkit-commit-1');
598             assert.equal(requests[0].method, 'GET');
599
600             requests[0].resolve({commits: [{
601                 id: 2018,
602                 repository: MockModels.webkit.id(),
603                 revision: 'webkit-commit-1',
604                 ownsCommits: false,
605                 time: 1456932774000,
606             }]});
607
608             return updatePromise.then(() => {
609                 assert.deepEqual(commitSet.repositories(), []);
610                 assert(!commitSet.commitForRepository(MockModels.webkit));
611             });
612         });
613
614     });
615
616 });
617
618 describe('CustomCommitSet', () => {
619     MockModels.inject();
620
621     describe('Test custom commit set without owned commit', () => {
622         it('should have right revision for a given repository', () => {
623             const commitSet = customCommitSetWithoutOwnedCommit();
624             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
625             assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
626         });
627
628         it('should have no patch for any repository', () => {
629             const commitSet = customCommitSetWithoutOwnedCommit();
630             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
631             assert.equal(commitSet.patchForRepository(MockModels.webkit), null);
632         });
633
634         it('should have no owner revision for a given repository', () => {
635             const commitSet = customCommitSetWithoutOwnedCommit();
636             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
637             assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
638         });
639
640         it('should return all repositories in it', () => {
641             const commitSet = customCommitSetWithoutOwnedCommit();
642             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit]);
643         });
644
645         it('should return only top level repositories', () => {
646             const commitSet = customCommitSetWithoutOwnedCommit();
647             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.webkit]);
648         });
649     });
650
651     describe('Test custom commit set with owned commit', () => {
652         it('should have right revision for a given repository', () => {
653             const commitSet = customCommitSetWithOwnedCommit();
654             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
655             assert.equal(commitSet.revisionForRepository(MockModels.ownerRepository), 'OwnerRepository-r0');
656             assert.equal(commitSet.revisionForRepository(MockModels.ownedRepository), 'OwnedRepository-r0');
657         });
658
659         it('should have no patch for any repository', () => {
660             const commitSet = customCommitSetWithOwnedCommit();
661             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
662             assert.equal(commitSet.patchForRepository(MockModels.ownerRepository), null);
663             assert.equal(commitSet.patchForRepository(MockModels.ownedRepository), null);
664         });
665
666         it('should have right owner revision for an owned repository', () => {
667             const commitSet = customCommitSetWithOwnedCommit();
668             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
669             assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownerRepository), null);
670             assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownedRepository), 'OwnerRepository-r0');
671         });
672
673         it('should return all repositories in it', () => {
674             const commitSet = customCommitSetWithOwnedCommit();
675             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.ownerRepository, MockModels.ownedRepository]);
676         });
677
678         it('should return only top level repositories', () => {
679             const commitSet = customCommitSetWithOwnedCommit();
680             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.ownerRepository]);
681         });
682     });
683
684     describe('Test custom commit set with patch', () => {
685         it('should have right revision for a given repository', () => {
686             const commitSet = customCommitSetWithPatch();
687             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
688             assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
689         });
690
691         it('should have a patch for a repository with patch specified', () => {
692             const commitSet = customCommitSetWithPatch();
693             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
694             assert.deepEqual(commitSet.patchForRepository(MockModels.webkit), createPatch());
695         });
696
697         it('should have no owner revision for a given repository', () => {
698             const commitSet = customCommitSetWithPatch();
699             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
700             assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
701         });
702
703         it('should return all repositories in it', () => {
704             const commitSet = customCommitSetWithPatch();
705             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit]);
706         });
707
708         it('should return only top level repositories', () => {
709             const commitSet = customCommitSetWithPatch();
710             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.webkit]);
711         });
712     });
713
714     describe('Test custom commit set with owned repository has same name as non-owned repository',  () => {
715         it('should have right revision for a given repository', () => {
716             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
717             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
718             assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
719             assert.equal(commitSet.revisionForRepository(MockModels.ownedWebkit), 'owned-200805');
720         });
721
722         it('should have no patch for any repository', () => {
723             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
724             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
725             assert.equal(commitSet.patchForRepository(MockModels.webkit), null);
726             assert.equal(commitSet.patchForRepository(MockModels.ownedWebkit), null);
727         });
728
729         it('should have right owner revision for an owned repository', () => {
730             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
731             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
732             assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
733             assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownedWebkit), '10.11.4 15E65');
734         });
735
736         it('should return all repositories in it', () => {
737             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
738             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit, MockModels.ownedWebkit]);
739         });
740
741         it('should return only top level repositories', () => {
742             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
743             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.webkit]);
744         });
745     });
746
747     describe('Test custom commit set equality function', () => {
748         it('should be equal to same custom commit set', () => {
749             assert.deepEqual(customCommitSetWithoutOwnedCommit(), customCommitSetWithoutOwnedCommit());
750             assert.deepEqual(customCommitSetWithOwnedCommit(), customCommitSetWithOwnedCommit());
751             assert.deepEqual(customCommitSetWithPatch(), customCommitSetWithPatch());
752             assert.deepEqual(customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository(),
753                 customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository());
754         });
755
756         it('should not be equal even if non-owned revisions are the same', () => {
757             const commitSet0 = customCommitSetWithoutOwnedCommit();
758             const commitSet1 = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
759             assert.equal(commitSet0.equals(commitSet1), false);
760         });
761     });
762
763     describe('Test custom commit set custom root operations', () => {
764         it('should return empty custom roots if no custom root specified', () => {
765             assert.deepEqual(customCommitSetWithoutOwnedCommit().customRoots(), []);
766         });
767
768         it('should return root if root is added into commit set', () => {
769             const commitSet = customCommitSetWithoutOwnedCommit();
770             commitSet.addCustomRoot(createRoot());
771             assert.deepEqual(commitSet.customRoots(), [createRoot()]);
772         });
773     });
774 });