Commit should order by 'commit_order' as secondary key.
[WebKit.git] / Websites / perf.webkit.org / server-tests / api-commits.js
1 'use strict';
2
3 const assert = require('assert');
4
5 const TestServer = require('./resources/test-server.js');
6 const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
7 const connectToDatabaseInEveryTest = require('./resources/common-operations.js').connectToDatabaseInEveryTest;
8
9 describe("/api/commits/", () => {
10     TestServer.inject();
11     connectToDatabaseInEveryTest();
12
13     const subversionCommits = {
14         "slaveName": "someSlave",
15         "slavePassword": "somePassword",
16         "commits": [
17             {
18                 "repository": "WebKit",
19                 "revision": "210948",
20                 "time": "2017-01-20T02:52:34.577Z",
21                 "author": {"name": "Zalan Bujtas", "account": "zalan@apple.com"},
22                 "message": "a message",
23             },
24             {
25                 "repository": "WebKit",
26                 "revision": "210949",
27                 "time": "2017-01-20T03:23:50.645Z",
28                 "author": {"name": "Chris Dumez", "account": "cdumez@apple.com"},
29                 "message": "some message",
30             },
31             {
32                 "repository": "WebKit",
33                 "previousCommit": "210949",
34                 "revision": "210950",
35                 "time": "2017-01-20T03:49:37.887Z",
36                 "author": {"name": "Commit Queue", "account": "commit-queue@webkit.org"},
37                 "message": "another message",
38             }
39         ]
40     }
41
42     const systemVersionCommits = {
43         "slaveName": "someSlave",
44         "slavePassword": "somePassword",
45         "commits": [
46             {
47                 "repository": "OSX",
48                 "revision": "16D32",
49                 "order": 6
50             },
51             {
52                 "repository": "OSX",
53                 "revision": "16C68",
54                 "order": 5
55             },
56             {
57                 "repository": "OSX",
58                 "revision": "16C67",
59                 "order": 4
60             },
61             {
62                 "repository": "OSX",
63                 "revision": "16B2657",
64                 "order": 3
65             },
66             {
67                 "repository": "OSX",
68                 "revision": "16B2555",
69                 "order": 2
70             },
71             {
72                 "repository": "OSX",
73                 "revision": "16A323",
74                 "order": 1
75             }
76         ]
77     }
78
79     const notYetReportedCommit = {
80         revision: '210951',
81         time: '2017-01-20T03:56:20.045Z'
82     }
83
84     function assertCommitIsSameAsOneSubmitted(commit, submitted)
85     {
86         assert.equal(commit['revision'], submitted['revision']);
87         assert.equal(new Date(commit['time']).toISOString(), submitted['time']);
88         assert.equal(commit['message'], submitted['message']);
89         assert.equal(commit['authorName'], submitted['author']['name']);
90         assert.equal(commit['authorEmail'], submitted['author']['account']);
91         if(submitted['previousCommit']) {
92             assert.ok(commit['previousCommit']);
93         } else {
94             assert.equal(commit['previousCommit'], null);
95         }
96     }
97
98     describe('/api/commits/<repository>/', () => {
99         it("should return RepositoryNotFound when there are no matching repository", () => {
100             return TestServer.remoteAPI().getJSON('/api/commits/WebKit').then((response) => {
101                 assert.equal(response['status'], 'RepositoryNotFound');
102             });
103         });
104
105         it("should return an empty result when there are no reported commits", () => {
106             const db = TestServer.database();
107             return Promise.all([
108                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
109                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
110             ]).then(() => {
111                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit');
112             }).then((response) => {
113                 assert.equal(response['status'], 'OK');
114                 assert.deepEqual(response['commits'], []);
115             });
116         });
117
118         it("should return the list of all commits for a given repository", () => {
119             return addSlaveForReport(subversionCommits).then(() => {
120                 return TestServer.remoteAPI().postJSON('/api/report-commits/', subversionCommits);
121             }).then(function (response) {
122                 assert.equal(response['status'], 'OK');
123                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/');
124             }).then(function (result) {
125                 assert.equal(result['status'], 'OK');
126
127                 const commits = result['commits'];
128                 assert.equal(commits.length, 3);
129                 const submittedCommits = subversionCommits['commits'];
130                 assertCommitIsSameAsOneSubmitted(commits[0], submittedCommits[0]);
131                 assertCommitIsSameAsOneSubmitted(commits[1], submittedCommits[1]);
132                 assertCommitIsSameAsOneSubmitted(commits[2], submittedCommits[2]);
133                 assert.equal(commits[2]['previousCommit'], commits[1]['id']);
134             });
135         });
136
137         it("should return the list of ordered commits for a given repository", () => {
138             return addSlaveForReport(subversionCommits).then(() => {
139                 return TestServer.remoteAPI().postJSON('/api/report-commits/', systemVersionCommits);
140             }).then(function (response) {
141                 assert.equal(response['status'], 'OK');
142                 return TestServer.remoteAPI().getJSON('/api/commits/OSX/');
143             }).then(function (result) {
144                 assert.equal(result['status'], 'OK');
145                 const commits = result['commits'];
146                 const submittedCommits = systemVersionCommits['commits'];
147                 assert.equal(commits.length, submittedCommits.length);
148                 assert.equal(commits[0]['revision'], submittedCommits[5]['revision']);
149                 assert.equal(commits[1]['revision'], submittedCommits[4]['revision']);
150                 assert.equal(commits[2]['revision'], submittedCommits[3]['revision']);
151                 assert.equal(commits[3]['revision'], submittedCommits[2]['revision']);
152                 assert.equal(commits[4]['revision'], submittedCommits[1]['revision']);
153                 assert.equal(commits[5]['revision'], submittedCommits[0]['revision']);
154             });
155         });
156     });
157
158     describe('/api/commits/<repository>/oldest', () => {
159         it("should return RepositoryNotFound when there are no matching repository", () => {
160             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/oldest').then((response) => {
161                 assert.equal(response['status'], 'RepositoryNotFound');
162             });
163         });
164
165         it("should return an empty results when there are no commits", () => {
166             return TestServer.database().insert('repositories', {'id': 1, 'name': 'WebKit'}).then(() => {
167                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/oldest');
168             }).then((response) => {
169                 assert.equal(response['status'], 'OK');
170                 assert.deepEqual(response['commits'], []);
171             });
172         });
173
174         it("should return the oldest commit", () => {
175             const remote = TestServer.remoteAPI();
176             return addSlaveForReport(subversionCommits).then(() => {
177                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
178             }).then(() => {
179                 return remote.getJSON('/api/commits/WebKit/oldest');
180             }).then(function (result) {
181                 assert.equal(result['status'], 'OK');
182                 assert.equal(result['commits'].length, 1);
183                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'][0]);
184             });
185         });
186
187         it("should return the oldest commit based on 'commit_order' when 'commit_time' is missing", () => {
188             const remote = TestServer.remoteAPI();
189             return addSlaveForReport(systemVersionCommits).then(() => {
190                 return remote.postJSONWithStatus('/api/report-commits/', systemVersionCommits);
191             }).then(() => {
192                 return remote.getJSON('/api/commits/OSX/oldest');
193             }).then(function (result) {
194                 assert.equal(result['status'], 'OK');
195                 assert.equal(result['commits'].length, 1);
196                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][5]['revision']);
197             });
198         });
199     });
200
201     describe('/api/commits/<repository>/latest', () => {
202         it("should return RepositoryNotFound when there are no matching repository", () => {
203             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/latest').then((response) => {
204                 assert.equal(response['status'], 'RepositoryNotFound');
205             });
206         });
207
208         it("should return an empty results when there are no commits", () => {
209             return TestServer.database().insert('repositories', {'id': 1, 'name': 'WebKit'}).then(() => {
210                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/latest');
211             }).then((response) => {
212                 assert.equal(response['status'], 'OK');
213                 assert.deepEqual(response['commits'], []);
214             });
215         });
216
217         it("should return the oldest commit", () => {
218             const remote = TestServer.remoteAPI();
219             return addSlaveForReport(subversionCommits).then(() => {
220                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
221             }).then(() => {
222                 return remote.getJSON('/api/commits/WebKit/latest');
223             }).then(function (result) {
224                 assert.equal(result['status'], 'OK');
225                 assert.equal(result['commits'].length, 1);
226                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'].slice().pop());
227             });
228         });
229
230         it("should return the latest commit based on 'commit_order' when 'commit_time' is missing", () => {
231             const remote = TestServer.remoteAPI();
232             return addSlaveForReport(systemVersionCommits).then(() => {
233                 return remote.postJSONWithStatus('/api/report-commits/', systemVersionCommits);
234             }).then(() => {
235                 return remote.getJSON('/api/commits/OSX/latest');
236             }).then(function (result) {
237                 assert.equal(result['status'], 'OK');
238                 assert.equal(result['commits'].length, 1);
239                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][0]['revision']);
240             });
241         });
242     });
243
244     describe('/api/commits/<repository>/last-reported', () => {
245         it("should return RepositoryNotFound when there are no matching repository", () => {
246             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/last-reported').then((response) => {
247                 assert.equal(response['status'], 'RepositoryNotFound');
248             });
249         });
250
251         it("should return an empty result when there are no reported commits", () => {
252             const db = TestServer.database();
253             return Promise.all([
254                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
255                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
256             ]).then(() => {
257                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/last-reported');
258             }).then((response) => {
259                 assert.equal(response['status'], 'OK');
260                 assert.deepEqual(response['commits'], []);
261             });
262         });
263
264         it("should return an empty results when there are no reported commits", () => {
265             return TestServer.database().insert('repositories', {'id': 1, 'name': 'WebKit'}).then(() => {
266                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/last-reported');
267             }).then((response) => {
268                 assert.equal(response['status'], 'OK');
269                 assert.deepEqual(response['commits'], []);
270             });
271         });
272
273         it("should return the oldest reported commit", () => {
274             const db = TestServer.database();
275             const remote = TestServer.remoteAPI();
276             return Promise.all([
277                 addSlaveForReport(subversionCommits),
278                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
279                 db.insert('commits', {'repository': 1, 'revision': notYetReportedCommit.revision, 'time': notYetReportedCommit.time}),
280             ]).then(() => {
281                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
282             }).then(() => {
283                 return remote.getJSON('/api/commits/WebKit/last-reported');
284             }).then(function (result) {
285                 assert.equal(result['status'], 'OK');
286                 assert.equal(result['commits'].length, 1);
287                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'].slice().pop());
288             });
289         });
290
291         it("should return the last reported commit based on 'commit_order' when 'commit_time' is missing", () => {
292             const remote = TestServer.remoteAPI();
293             return addSlaveForReport(systemVersionCommits).then(() => {
294                 return remote.postJSONWithStatus('/api/report-commits/', systemVersionCommits);
295             }).then(() => {
296                 return remote.getJSON('/api/commits/OSX/last-reported');
297             }).then(function (result) {
298                 assert.equal(result['status'], 'OK');
299                 assert.equal(result['commits'].length, 1);
300                 assert.equal(result['commits'][0]['revision'], systemVersionCommits['commits'][0]['revision']);
301             });
302         });
303     });
304
305     describe('/api/commits/<repository>/<commit>', () => {
306         it("should return RepositoryNotFound when there are no matching repository", () => {
307             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/210949').then((response) => {
308                 assert.equal(response['status'], 'RepositoryNotFound');
309             });
310         });
311
312         it("should return UnknownCommit when one of the specified commit does not exist in the database", () => {
313             const db = TestServer.database();
314             return Promise.all([
315                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
316                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
317             ]).then(() => {
318                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/210949');
319             }).then((response) => {
320                 assert.equal(response['status'], 'UnknownCommit');
321             });
322         });
323
324         it("should return the commit even if it had not been reported", () => {
325             const db = TestServer.database();
326             return Promise.all([
327                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
328                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
329             ]).then(() => {
330                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/210950');
331             }).then((result) => {
332                 assert.equal(result['status'], 'OK');
333                 assert.equal(result['commits'].length, 1);
334                 assertCommitIsSameAsOneSubmitted(result['commits'][0], {
335                     previousCommit: null,
336                     revision: '210950',
337                     time: '2017-01-20T03:49:37.887Z',
338                     author: {name: null, account: null},
339                     message: null,
340                 });
341             });
342         });
343
344         it("should return the full result for a reported commit", () => {
345             const remote = TestServer.remoteAPI();
346             return addSlaveForReport(subversionCommits).then(() => {
347                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
348             }).then(() => {
349                 return remote.getJSON('/api/commits/WebKit/210949');
350             }).then((result) => {
351                 assert.equal(result['status'], 'OK');
352                 assert.deepEqual(result['commits'].length, 1);
353                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'][1]);
354             });
355         });
356
357     });
358
359     describe('/api/commits/<repository>/?from=<commit-1>&to=<commit-2>', () => {
360         it("should return RepositoryNotFound when there are no matching repository", () => {
361             return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210900&to=211000').then((response) => {
362                 assert.equal(response['status'], 'RepositoryNotFound');
363             });
364         });
365
366         it("should return UnknownCommit when one of the specified commit does not exist in the database", () => {
367             const db = TestServer.database();
368             return Promise.all([
369                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
370                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'})
371             ]).then(() => {
372                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210900&to=211000');
373             }).then((response) => {
374                 assert.equal(response['status'], 'UnknownCommit');
375             });
376         });
377
378         it("should return an empty result when commits in the specified range have not reported", () => {
379             const db = TestServer.database();
380             return Promise.all([
381                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
382                 db.insert('commits', {'repository': 1, 'revision': '210949', 'time': '2017-01-20T03:23:50.645Z'}),
383                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z'}),
384             ]).then(() => {
385                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210949&to=210950');
386             }).then((response) => {
387                 assert.equal(response['status'], 'OK');
388                 assert.deepEqual(response['commits'], []);
389             });
390         });
391
392         it("should return reported commits in the specified range", () => {
393             const db = TestServer.database();
394             return Promise.all([
395                 db.insert('repositories', {'id': 1, 'name': 'WebKit'}),
396                 db.insert('commits', {'repository': 1, 'revision': '210949', 'time': '2017-01-20T03:23:50.645Z', 'reported': true}),
397                 db.insert('commits', {'repository': 1, 'revision': '210950', 'time': '2017-01-20T03:49:37.887Z', 'reported': true}),
398             ]).then(() => {
399                 return TestServer.remoteAPI().getJSON('/api/commits/WebKit/?from=210949&to=210950');
400             }).then((result) => {
401                 assert.equal(result['status'], 'OK');
402                 assert.deepEqual(result['commits'].length, 2);
403                 assertCommitIsSameAsOneSubmitted(result['commits'][0], {
404                     previousCommit: null,
405                     revision: '210949',
406                     time: '2017-01-20T03:23:50.645Z',
407                     author: {name: null, account: null},
408                     message: null,
409                 });
410                 assertCommitIsSameAsOneSubmitted(result['commits'][1], {
411                     previousCommit: null,
412                     revision: '210950',
413                     time: '2017-01-20T03:49:37.887Z',
414                     author: {name: null, account: null},
415                     message: null,
416                 });
417             });
418         });
419
420         it("should not include a revision not within the specified range", () => {
421             const remote = TestServer.remoteAPI();
422             return addSlaveForReport(subversionCommits).then(() => {
423                 return remote.postJSONWithStatus('/api/report-commits/', subversionCommits);
424             }).then(() => {
425                 return remote.getJSON('/api/commits/WebKit/?from=210948&to=210949');
426             }).then((result) => {
427                 assert.equal(result['status'], 'OK');
428                 assert.deepEqual(result['commits'].length, 2);
429                 assertCommitIsSameAsOneSubmitted(result['commits'][0], subversionCommits['commits'][0]);
430                 assertCommitIsSameAsOneSubmitted(result['commits'][1], subversionCommits['commits'][1]);
431             });
432         });
433
434     });
435
436 });