Skip to content

Commit 3ddaafc

Browse files
committed
test: add tests for project endpoint
1 parent f5d1208 commit 3ddaafc

File tree

3 files changed

+341
-18
lines changed

3 files changed

+341
-18
lines changed

test/e2e/ProjectScenario.spec.ts

Lines changed: 312 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
import app from '../../src/server';
2+
import DB from '../../src/models';
3+
import express = require('express');
4+
import { Router } from 'express';
5+
import * as utils from '../utils/utils';
6+
7+
8+
const chai = require('chai');
9+
const chaiHttp = require('chai-http');
10+
11+
chai.use(chaiHttp);
12+
const {expect} = chai;
13+
14+
const APIKEY = '7718330d2794406c980bdbded6c9dc1d';
15+
16+
17+
function delay(ms: number) {
18+
return new Promise( resolve => setTimeout(resolve, ms) );
19+
}
20+
21+
describe('POST api/project', () => {
22+
before(async () => {
23+
await DB.apikeys.create({
24+
id: 1,
25+
key: APIKEY,
26+
whitelist_domains: ['*'],
27+
whitelist_ips: ['*']
28+
});
29+
await DB.langs.create({
30+
lang_slug: 'node',
31+
lang_name: 'NodeJS',
32+
lang_version: '10'
33+
});
34+
await utils.setupMockQueue();
35+
36+
});
37+
after(utils.truncateTables);
38+
39+
it('should throw 403 error if API Key is absent', async () => {
40+
const res = await chai.request(app).post(`/api/project`);
41+
42+
expect(res.status).to.equal(403);
43+
expect(res.body.message).to.equal('No API Key in request');
44+
});
45+
46+
it('should throw 404 error if GET request is made', async () => {
47+
const res = await chai.request(app).get(`/api/project`).set({
48+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
49+
Accept: 'application/json'
50+
});
51+
52+
expect(res.status).to.equal(404);
53+
});
54+
55+
it('should throw 400 error if correct params are not sent along with the POST request', async () => {
56+
const res = await chai.request(app).post(`/api/project`).set({
57+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
58+
Accept: 'application/json'
59+
}).send({});
60+
61+
expect(res.status).to.equal(400);
62+
expect(res.body.err.message).to.equal('"lang" is required');
63+
});
64+
65+
it('should throw 400 error for incorrect language', async () => {
66+
const params = {
67+
lang: 'abcd',
68+
problem: 'https://minio.cb.lk/public/input',
69+
submission: 'https://minio.cb.lk/public/input',
70+
submissionDirs: 'src',
71+
mode: 'sync',
72+
timelimit: 1
73+
};
74+
75+
const res = await chai.request(app).post(`/api/project`).set({
76+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
77+
Accept: 'application/json'
78+
}).send(params);
79+
80+
expect(res.status).to.equal(400);
81+
});
82+
83+
it('should throw 400 error for problem missing', async () => {
84+
const params = {
85+
lang: 'node',
86+
submission: 'https://minio.cb.lk/public/input',
87+
submissionDirs: 'src',
88+
mode: 'sync',
89+
timelimit: 1
90+
};
91+
92+
const res = await chai.request(app).post(`/api/project`).set({
93+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
94+
Accept: 'application/json'
95+
}).send(params);
96+
97+
expect(res.status).to.equal(400);
98+
expect(res.body.err.message).to.equal('"problem" is required');
99+
});
100+
101+
it('should throw 400 error when problem is not an url', async () => {
102+
const params = {
103+
lang: 'node',
104+
problem: 'not-a-url',
105+
submission: 'https://minio.cb.lk/public/input',
106+
submissionDirs: 'src',
107+
mode: 'sync',
108+
timelimit: 1
109+
};
110+
111+
const res = await chai.request(app).post(`/api/project`).set({
112+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
113+
Accept: 'application/json'
114+
}).send(params);
115+
116+
expect(res.status).to.equal(400);
117+
expect(res.body.err.message).to.equal('"problem" must be a valid uri');
118+
});
119+
120+
it('should throw 400 error for submission missing', async () => {
121+
const params = {
122+
lang: 'node',
123+
problem: 'https://minio.cb.lk/public/input',
124+
submissionDirs: 'src',
125+
mode: 'sync',
126+
timelimit: 1
127+
};
128+
129+
const res = await chai.request(app).post(`/api/project`).set({
130+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
131+
Accept: 'application/json'
132+
}).send(params);
133+
134+
expect(res.status).to.equal(400);
135+
expect(res.body.err.message).to.equal('"submission" is required');
136+
});
137+
138+
it('should throw 400 error when submission is not an url', async () => {
139+
const params = {
140+
lang: 'node',
141+
problem: 'https://minio.cb.lk/public/input',
142+
submission: 'not-a-url',
143+
submissionDirs: 'src',
144+
mode: 'sync',
145+
timelimit: 1
146+
};
147+
148+
const res = await chai.request(app).post(`/api/project`).set({
149+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
150+
Accept: 'application/json'
151+
}).send(params);
152+
153+
expect(res.status).to.equal(400);
154+
expect(res.body.err.message).to.equal('"submission" must be a valid uri');
155+
});
156+
157+
it('should throw 400 error for submissionDirs missing', async () => {
158+
const params = {
159+
lang: 'node',
160+
problem: 'https://minio.cb.lk/public/input',
161+
submission: 'https://minio.cb.lk/public/input',
162+
mode: 'sync',
163+
timelimit: 1
164+
};
165+
166+
const res = await chai.request(app).post(`/api/project`).set({
167+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
168+
Accept: 'application/json'
169+
}).send(params);
170+
171+
expect(res.status).to.equal(400);
172+
expect(res.body.err.message).to.equal('"submissionDirs" is required');
173+
});
174+
175+
it('should throw 400 error when submissionDirs is not a string', async () => {
176+
const params = {
177+
lang: 'node',
178+
problem: 'https://minio.cb.lk/public/input',
179+
submission: 'https://minio.cb.lk/public/input',
180+
submissionDirs: 123,
181+
mode: 'sync',
182+
timelimit: 1
183+
};
184+
185+
const res = await chai.request(app).post(`/api/project`).set({
186+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
187+
Accept: 'application/json'
188+
}).send(params);
189+
190+
expect(res.status).to.equal(400);
191+
expect(res.body.err.message).to.equal('"submissionDirs" must be a string');
192+
});
193+
194+
it('should throw 400 error for incorrect mode ', async () => {
195+
const params = {
196+
lang: 'node',
197+
problem: 'https://minio.cb.lk/public/input',
198+
submission: 'https://minio.cb.lk/public/input',
199+
submissionDirs: 'src',
200+
mode: 'abc',
201+
timelimit: 1
202+
};
203+
204+
const res = await chai.request(app).post(`/api/project`).set({
205+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
206+
Accept: 'application/json'
207+
}).send(params);
208+
209+
expect(res.status).to.equal(400);
210+
expect(res.body.err.message).to.equal('"mode" must be one of [sync, callback, poll]');
211+
});
212+
213+
it('should throw 400 if mode is callback but callback is not present', async () => {
214+
const params = {
215+
lang: 'node',
216+
problem: 'https://minio.cb.lk/public/input',
217+
submission: 'https://minio.cb.lk/public/input',
218+
submissionDirs: 'src',
219+
mode: 'callback',
220+
timelimit: 1
221+
};
222+
223+
const res = await chai.request(app).post(`/api/project`).set({
224+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
225+
Accept: 'application/json'
226+
}).send(params);
227+
228+
expect(res.status).to.equal(400);
229+
expect(res.body.err.message).to.equal('"callback" is required');
230+
});
231+
232+
it('should return correct result in sync mode ', async () => {
233+
const params = {
234+
lang: 'node',
235+
problem: 'https://minio.cb.lk/public/input',
236+
submission: 'https://minio.cb.lk/public/input',
237+
submissionDirs: 'src',
238+
mode: 'sync',
239+
timelimit: 1
240+
};
241+
242+
const res = await chai.request(app).post(`/api/project`).set({
243+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
244+
Accept: 'application/json'
245+
}).send(params);
246+
247+
expect(res.body.score).to.equal(100);
248+
expect(res.status).to.equal(200);
249+
});
250+
251+
252+
it('should return correct submission.id in poll mode', async () => {
253+
const params = {
254+
lang: 'node',
255+
problem: 'https://minio.cb.lk/public/input',
256+
submission: 'https://minio.cb.lk/public/input',
257+
submissionDirs: 'src',
258+
mode: 'poll',
259+
timelimit: 1
260+
};
261+
262+
const res = await chai.request(app).post(`/api/project`).set({
263+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
264+
Accept: 'application/json'
265+
}).send(params);
266+
267+
268+
// there is a delay of 1000 for onSuccess, so setting 2000ms delay here.
269+
await delay(2000);
270+
const submission = await DB.submissions.findById(res.body.id);
271+
272+
expect(res.body.id).to.exist;
273+
expect(res.status).to.equal(200);
274+
expect(submission.results.score).to.equal(100);
275+
});
276+
277+
it('should return id and send result to callback url in callback mode', async () => {
278+
const params = {
279+
lang: 'node',
280+
problem: 'https://minio.cb.lk/public/input',
281+
submission: 'https://minio.cb.lk/public/input',
282+
submissionDirs: 'src',
283+
mode: 'callback',
284+
callback: 'http://localhost:2404',
285+
timelimit: 1
286+
};
287+
288+
const res = await chai.request(app).post(`/api/project`).set({
289+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
290+
Accept: 'application/json'
291+
}).send(params);
292+
293+
let resultFromCallBack;
294+
295+
// Mock server for callback
296+
const app2 = express();
297+
app2.use(express.json());
298+
const router = Router();
299+
app2.listen(2404, () => {
300+
router.post('/', (req, res) => {
301+
resultFromCallBack = req.body;
302+
});
303+
app2.use('/', router);
304+
});
305+
306+
await delay(2000);
307+
308+
expect(res.body.id).to.exist;
309+
expect(res.status).to.equal(200);
310+
expect(resultFromCallBack.score).to.equal(100);
311+
});
312+
});

test/e2e/SubmitScenario.spec.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,24 @@ describe('POST api/submissions', () => {
136136
expect(res.body.err.message).to.equal('"mode" must be one of [sync, callback, poll]');
137137
});
138138

139+
it('should throw 400 error for incorrect testcases ', async () => {
140+
const params = {
141+
source: (new Buffer(source).toString('base64')),
142+
lang: 'cpp',
143+
mode: 'poll',
144+
timelimit: 1,
145+
testcases: []
146+
};
147+
148+
const res = await chai.request(app).post(`/api/submissions`).set({
149+
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
150+
Accept: 'application/json'
151+
}).send(params);
152+
153+
expect(res.status).to.equal(400);
154+
expect(res.body.err.message).to.equal('"testcases" must contain at least 1 items');
155+
});
156+
139157
it('should return correct result in sync mode ', async () => {
140158
const params = {
141159
source: (new Buffer(source).toString('base64')),
@@ -213,22 +231,4 @@ describe('POST api/submissions', () => {
213231
expect(res.status).to.equal(200);
214232
expect(resultFromCallBack.result).to.equal(expectedResult);
215233
});
216-
217-
it('should throw 400 error for incorrect testcases ', async () => {
218-
const params = {
219-
source: (new Buffer(source).toString('base64')),
220-
lang: 'cpp',
221-
mode: 'poll',
222-
timelimit: 1,
223-
testcases: []
224-
};
225-
226-
const res = await chai.request(app).post(`/api/submissions`).set({
227-
Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d',
228-
Accept: 'application/json'
229-
}).send(params);
230-
231-
expect(res.status).to.equal(400);
232-
expect(res.body.err.message).to.equal('"testcases" must contain at least 1 items');
233-
});
234234
});

test/utils/utils.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ export async function setupMockQueue(){
2727
testcases: []
2828
}
2929
}
30+
else if(job.submissionDirs) {
31+
// project_result
32+
payload = {
33+
id: job.id,
34+
stdout: 'stdout',
35+
stderr: 'stderr',
36+
time: 1,
37+
code: 100,
38+
score: 100
39+
}
40+
}
3041
else {
3142
// run_result
3243
payload = {

0 commit comments

Comments
 (0)