Extend create-analysis-test API to be able to create with confirming test group.
[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     describe('revisionSetsFromCommitSets', () => {
392         it('should create revision sets from commit sets', () => {
393             assert.deepEqual(CommitSet.revisionSetsFromCommitSets([oneCommitSet(), commitSetWithRoot(), commitSetWithTwoRoots()]),
394                 [{'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}},
395                     {'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}, customRoots: [456]},
396                     {'11': { revision: 'webkit-commit-0', ownerRevision: null, patch: null}, customRoots: [456, 458]}]);
397         });
398     });
399 });
400
401 describe('IntermediateCommitSet', () => {
402     MockRemoteAPI.inject();
403     MockModels.inject();
404
405     describe('setCommitForRepository', () => {
406         it('should allow set commit for owner repository', () => {
407             const commitSet = new IntermediateCommitSet(new CommitSet);
408             const commit = ownerCommit();
409             commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
410             assert.equal(commit, commitSet.commitForRepository(MockModels.ownerRepository));
411         });
412
413         it('should allow set commit for owned repository', () => {
414             const commitSet = new IntermediateCommitSet(new CommitSet);
415             const commit = ownerCommit();
416
417             const fetchingPromise = commit.fetchOwnedCommits();
418             const requests = MockRemoteAPI.requests;
419             assert.equal(requests.length, 1);
420             assert.equal(requests[0].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
421             assert.equal(requests[0].method, 'GET');
422
423             requests[0].resolve({commits: [{
424                 id: 233,
425                 repository: MockModels.ownedRepository.id(),
426                 revision: '6f8b0dbbda95a440503b88db1dd03dad3a7b07fb',
427                 time: +(new Date('2016-05-13T00:55:57.841344Z')),
428             }]});
429
430             return fetchingPromise.then(() => {
431                 const ownedCommit = commit.ownedCommits()[0];
432                 commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
433                 commitSet.setCommitForRepository(MockModels.ownedRepository, ownedCommit);
434                 assert.equal(commit, commitSet.commitForRepository(MockModels.ownerRepository));
435                 assert.equal(ownedCommit, commitSet.commitForRepository(MockModels.ownedRepository));
436                 assert.deepEqual(commitSet.repositories(), [MockModels.ownerRepository, MockModels.ownedRepository]);
437             });
438         });
439     });
440
441     describe('fetchCommitLogs', () => {
442
443         it('should fetch CommitLog object with owned commits information',  () => {
444             const commit = partialOwnerCommit();
445             assert.equal(commit.ownsCommits(), null);
446             const owned = ownedCommit();
447
448             const commitSet = CommitSet.ensureSingleton('53246456', {revisionItems: [{commit}, {commit: owned, ownerCommit: commit}]});
449             const intermediateCommitSet =new IntermediateCommitSet(commitSet);
450             const fetchingPromise = intermediateCommitSet.fetchCommitLogs();
451
452             const requests = MockRemoteAPI.requests;
453             assert.equal(requests.length, 2);
454             assert.equal(requests[0].url, '/api/commits/111/owner-commit-0');
455             assert.equal(requests[0].method, 'GET');
456             assert.equal(requests[1].url, '/api/commits/112/owned-commit-0');
457             assert.equal(requests[1].method, 'GET');
458
459             requests[0].resolve({commits: [{
460                 id: 5,
461                 repository: MockModels.ownerRepository,
462                 revision: 'owner-commit-0',
463                 ownsCommits: true,
464                 time: +(new Date('2016-05-13T00:55:57.841344Z')),
465             }]});
466             requests[1].resolve({commits: [{
467                 id: 6,
468                 repository: MockModels.ownedRepository,
469                 revision: 'owned-commit-0',
470                 ownsCommits: false,
471                 time: 1456932774000,
472             }]});
473
474             return MockRemoteAPI.waitForRequest().then(() => {
475                 assert.equal(requests.length, 3);
476                 assert.equal(requests[2].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
477                 assert.equal(requests[2].method, 'GET');
478
479                 requests[2].resolve({commits: [{
480                     id: 6,
481                     repository: MockModels.ownedRepository.id(),
482                     revision: 'owned-commit-0',
483                     ownsCommits: false,
484                     time: 1456932774000,
485                 }]});
486                 return fetchingPromise;
487             }).then(() => {
488                 assert(commit.ownsCommits());
489                 assert.equal(commit.ownedCommits().length, 1);
490                 assert.equal(commit.ownedCommits()[0], owned);
491                 assert.equal(owned.ownerCommit(), commit);
492                 assert.equal(owned.repository(), MockModels.ownedRepository);
493                 assert.equal(intermediateCommitSet.commitForRepository(MockModels.ownedRepository), owned);
494                 assert.equal(intermediateCommitSet.ownerCommitForRepository(MockModels.ownedRepository), commit);
495                 assert.deepEqual(intermediateCommitSet.repositories(), [MockModels.ownerRepository, MockModels.ownedRepository]);
496             });
497         });
498     });
499
500     describe('updateRevisionForOwnerRepository', () => {
501
502         it('should update CommitSet based on the latest invocation', () => {
503             const commitSet = new IntermediateCommitSet(new CommitSet);
504             const firstUpdatePromise = commitSet.updateRevisionForOwnerRepository(MockModels.webkit, 'webkit-commit-0');
505             const secondUpdatePromise = commitSet.updateRevisionForOwnerRepository(MockModels.webkit, 'webkit-commit-1');
506             const requests = MockRemoteAPI.requests;
507
508             assert(requests.length, 2);
509             assert.equal(requests[0].url, '/api/commits/11/webkit-commit-0');
510             assert.equal(requests[0].method, 'GET');
511             assert.equal(requests[1].url, '/api/commits/11/webkit-commit-1');
512             assert.equal(requests[1].method, 'GET');
513
514             requests[1].resolve({commits: [{
515                 id: 2018,
516                 repository: MockModels.webkit.id(),
517                 revision: 'webkit-commit-1',
518                 ownsCommits: false,
519                 time: 1456932774000,
520             }]});
521
522             let commit = null;
523             return secondUpdatePromise.then(() => {
524                 commit = commitSet.commitForRepository(MockModels.webkit);
525
526                 requests[0].resolve({commits: [{
527                     id: 2017,
528                     repository: MockModels.webkit.id(),
529                     revision: 'webkit-commit-0',
530                     ownsCommits: false,
531                     time: 1456932773000,
532                 }]});
533
534                 assert.equal(commit.revision(), 'webkit-commit-1');
535                 assert.equal(commit.id(), 2018);
536
537                 return firstUpdatePromise;
538             }).then(() => {
539                 const currentCommit = commitSet.commitForRepository(MockModels.webkit);
540                 assert.equal(commit, currentCommit);
541             });
542         });
543
544     });
545
546     describe('removeCommitForRepository', () => {
547         it('should remove owned commits when owner commit is removed', () => {
548             const commitSet = new IntermediateCommitSet(new CommitSet);
549             const commit = ownerCommit();
550
551             const fetchingPromise = commit.fetchOwnedCommits();
552             const requests = MockRemoteAPI.requests;
553             assert.equal(requests.length, 1);
554             assert.equal(requests[0].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
555             assert.equal(requests[0].method, 'GET');
556
557             requests[0].resolve({commits: [{
558                 id: 233,
559                 repository: MockModels.ownedRepository.id(),
560                 revision: '6f8b0dbbda95a440503b88db1dd03dad3a7b07fb',
561                 ownsCommits: true
562             }]});
563
564             return fetchingPromise.then(() => {
565                 commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
566                 commitSet.setCommitForRepository(MockModels.ownedRepository, commit.ownedCommits()[0]);
567                 commitSet.removeCommitForRepository(MockModels.ownerRepository);
568                 assert.deepEqual(commitSet.repositories(), []);
569             });
570         });
571
572         it('should not remove owner commits when owned commit is removed', () => {
573             const commitSet = new IntermediateCommitSet(new CommitSet);
574             const commit = ownerCommit();
575
576             const fetchingPromise = commit.fetchOwnedCommits();
577             const requests = MockRemoteAPI.requests;
578             assert.equal(requests.length, 1);
579             assert.equal(requests[0].url, '../api/commits/111/owned-commits?owner-revision=owner-commit-0');
580             assert.equal(requests[0].method, 'GET');
581
582             requests[0].resolve({commits: [{
583                 id: 233,
584                 repository: MockModels.ownedRepository.id(),
585                 revision: '6f8b0dbbda95a440503b88db1dd03dad3a7b07fb',
586                 time: +(new Date('2016-05-13T00:55:57.841344Z')),
587             }]});
588
589             return fetchingPromise.then(() => {
590                 commitSet.setCommitForRepository(MockModels.ownerRepository, commit);
591                 commitSet.setCommitForRepository(MockModels.ownedRepository, commit.ownedCommits()[0]);
592                 commitSet.removeCommitForRepository(MockModels.ownedRepository);
593                 assert.deepEqual(commitSet.repositories(), [MockModels.ownerRepository]);
594             });
595         });
596
597         it('should not update commit set for repository if removeCommitForRepository called before updateRevisionForOwnerRepository finishes', () => {
598             const commitSet = new IntermediateCommitSet(new CommitSet);
599             const commit = webkitCommit();
600             commitSet.setCommitForRepository(MockModels.webkit, commit);
601             const updatePromise = commitSet.updateRevisionForOwnerRepository(MockModels.webkit, 'webkit-commit-1');
602
603             commitSet.removeCommitForRepository(MockModels.webkit);
604
605             const requests = MockRemoteAPI.requests;
606             assert.equal(requests[0].url, '/api/commits/11/webkit-commit-1');
607             assert.equal(requests[0].method, 'GET');
608
609             requests[0].resolve({commits: [{
610                 id: 2018,
611                 repository: MockModels.webkit.id(),
612                 revision: 'webkit-commit-1',
613                 ownsCommits: false,
614                 time: 1456932774000,
615             }]});
616
617             return updatePromise.then(() => {
618                 assert.deepEqual(commitSet.repositories(), []);
619                 assert(!commitSet.commitForRepository(MockModels.webkit));
620             });
621         });
622
623     });
624
625 });
626
627 describe('CustomCommitSet', () => {
628     MockModels.inject();
629
630     describe('Test custom commit set without owned commit', () => {
631         it('should have right revision for a given repository', () => {
632             const commitSet = customCommitSetWithoutOwnedCommit();
633             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
634             assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
635         });
636
637         it('should have no patch for any repository', () => {
638             const commitSet = customCommitSetWithoutOwnedCommit();
639             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
640             assert.equal(commitSet.patchForRepository(MockModels.webkit), null);
641         });
642
643         it('should have no owner revision for a given repository', () => {
644             const commitSet = customCommitSetWithoutOwnedCommit();
645             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
646             assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
647         });
648
649         it('should return all repositories in it', () => {
650             const commitSet = customCommitSetWithoutOwnedCommit();
651             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit]);
652         });
653
654         it('should return only top level repositories', () => {
655             const commitSet = customCommitSetWithoutOwnedCommit();
656             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.webkit]);
657         });
658     });
659
660     describe('Test custom commit set with owned commit', () => {
661         it('should have right revision for a given repository', () => {
662             const commitSet = customCommitSetWithOwnedCommit();
663             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
664             assert.equal(commitSet.revisionForRepository(MockModels.ownerRepository), 'OwnerRepository-r0');
665             assert.equal(commitSet.revisionForRepository(MockModels.ownedRepository), 'OwnedRepository-r0');
666         });
667
668         it('should have no patch for any repository', () => {
669             const commitSet = customCommitSetWithOwnedCommit();
670             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
671             assert.equal(commitSet.patchForRepository(MockModels.ownerRepository), null);
672             assert.equal(commitSet.patchForRepository(MockModels.ownedRepository), null);
673         });
674
675         it('should have right owner revision for an owned repository', () => {
676             const commitSet = customCommitSetWithOwnedCommit();
677             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
678             assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownerRepository), null);
679             assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownedRepository), 'OwnerRepository-r0');
680         });
681
682         it('should return all repositories in it', () => {
683             const commitSet = customCommitSetWithOwnedCommit();
684             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.ownerRepository, MockModels.ownedRepository]);
685         });
686
687         it('should return only top level repositories', () => {
688             const commitSet = customCommitSetWithOwnedCommit();
689             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.ownerRepository]);
690         });
691     });
692
693     describe('Test custom commit set with patch', () => {
694         it('should have right revision for a given repository', () => {
695             const commitSet = customCommitSetWithPatch();
696             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
697             assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
698         });
699
700         it('should have a patch for a repository with patch specified', () => {
701             const commitSet = customCommitSetWithPatch();
702             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
703             assert.deepEqual(commitSet.patchForRepository(MockModels.webkit), createPatch());
704         });
705
706         it('should have no owner revision for a given repository', () => {
707             const commitSet = customCommitSetWithPatch();
708             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
709             assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
710         });
711
712         it('should return all repositories in it', () => {
713             const commitSet = customCommitSetWithPatch();
714             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit]);
715         });
716
717         it('should return only top level repositories', () => {
718             const commitSet = customCommitSetWithPatch();
719             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.webkit]);
720         });
721     });
722
723     describe('Test custom commit set with owned repository has same name as non-owned repository',  () => {
724         it('should have right revision for a given repository', () => {
725             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
726             assert.equal(commitSet.revisionForRepository(MockModels.osx), '10.11.4 15E65');
727             assert.equal(commitSet.revisionForRepository(MockModels.webkit), '200805');
728             assert.equal(commitSet.revisionForRepository(MockModels.ownedWebkit), 'owned-200805');
729         });
730
731         it('should have no patch for any repository', () => {
732             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
733             assert.equal(commitSet.patchForRepository(MockModels.osx), null);
734             assert.equal(commitSet.patchForRepository(MockModels.webkit), null);
735             assert.equal(commitSet.patchForRepository(MockModels.ownedWebkit), null);
736         });
737
738         it('should have right owner revision for an owned repository', () => {
739             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
740             assert.equal(commitSet.ownerRevisionForRepository(MockModels.osx), null);
741             assert.equal(commitSet.ownerRevisionForRepository(MockModels.webkit), null);
742             assert.equal(commitSet.ownerRevisionForRepository(MockModels.ownedWebkit), '10.11.4 15E65');
743         });
744
745         it('should return all repositories in it', () => {
746             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
747             assert.deepEqual(commitSet.repositories(), [MockModels.osx, MockModels.webkit, MockModels.ownedWebkit]);
748         });
749
750         it('should return only top level repositories', () => {
751             const commitSet = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
752             assert.deepEqual(commitSet.topLevelRepositories(), [MockModels.osx, MockModels.webkit]);
753         });
754     });
755
756     describe('Test custom commit set equality function', () => {
757         it('should be equal to same custom commit set', () => {
758             assert.deepEqual(customCommitSetWithoutOwnedCommit(), customCommitSetWithoutOwnedCommit());
759             assert.deepEqual(customCommitSetWithOwnedCommit(), customCommitSetWithOwnedCommit());
760             assert.deepEqual(customCommitSetWithPatch(), customCommitSetWithPatch());
761             assert.deepEqual(customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository(),
762                 customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository());
763         });
764
765         it('should not be equal even if non-owned revisions are the same', () => {
766             const commitSet0 = customCommitSetWithoutOwnedCommit();
767             const commitSet1 = customCommitSetWithOwnedRepositoryHasSameNameAsNotOwnedRepository();
768             assert.equal(commitSet0.equals(commitSet1), false);
769         });
770     });
771
772     describe('Test custom commit set custom root operations', () => {
773         it('should return empty custom roots if no custom root specified', () => {
774             assert.deepEqual(customCommitSetWithoutOwnedCommit().customRoots(), []);
775         });
776
777         it('should return root if root is added into commit set', () => {
778             const commitSet = customCommitSetWithoutOwnedCommit();
779             commitSet.addCustomRoot(createRoot());
780             assert.deepEqual(commitSet.customRoots(), [createRoot()]);
781         });
782     });
783 });