diff --git a/src/routes/api/index.ts b/src/routes/api/index.ts index 4f93a40..2d6d7bb 100644 --- a/src/routes/api/index.ts +++ b/src/routes/api/index.ts @@ -1,6 +1,7 @@ import { NextFunction, Request, Response, Router } from 'express' import run from './run' import submit from './submit' +import result from './result' import { route as langs } from './langs' import { checkValidApiKey } from '../../validators/ApiKeyValidators' import * as debug from 'debug' @@ -26,6 +27,7 @@ route.use((req: Request, res: Response, next: NextFunction) => { }) route.use('/runs', run) +route.use('/result', result) route.use('/submissions', submit) route.use('/langs', langs) diff --git a/src/routes/api/result/controller.ts b/src/routes/api/result/controller.ts new file mode 100644 index 0000000..789509e --- /dev/null +++ b/src/routes/api/result/controller.ts @@ -0,0 +1,18 @@ +import {Request, Response} from 'express'; +import DB from 'models' + +export default { + async sendResult(req: Request, res: Response) { + const submissionId = req.params.id ? parseInt(req.params.id) : null + if (!submissionId) { + res.status(400).json({err: 'SubmissionId not found'}) + } else { + DB.submissions.findByPk(submissionId) + .then((submission) => { + res.status(200).json(submission.results) + }).catch((err) => { + res.status(404).json({err: 'Submission not found'}) + }) + } + } +} \ No newline at end of file diff --git a/src/routes/api/result/index.ts b/src/routes/api/result/index.ts new file mode 100644 index 0000000..1298bec --- /dev/null +++ b/src/routes/api/result/index.ts @@ -0,0 +1,8 @@ +import { Router } from 'express' +import Controller from './controller' + +const router: Router = Router() + +router.get('/:id', Controller.sendResult) + +export default router diff --git a/test/e2e/ResultScenario.spec.ts b/test/e2e/ResultScenario.spec.ts new file mode 100644 index 0000000..b1e3fb8 --- /dev/null +++ b/test/e2e/ResultScenario.spec.ts @@ -0,0 +1,80 @@ +import app from '../../src/server'; +import DB from '../../src/models'; +import * as utils from "../utils/utils"; + +const chai = require('chai'); +const chaiHttp = require('chai-http'); + +chai.use(chaiHttp); +const {expect} = chai; + +const APIKEY = '7718330d2794406c980bdbded6c9dc1d'; + +describe('GET api/result/:id', () => { + before(async () => { + await DB.apikeys.create({ + id: 1, + key: APIKEY, + whitelist_domains: ['*'], + whitelist_ips: ['*'] + }); + }); + after(utils.truncateTables); + + + it('should throw 403 error API key is absent in the request', async () => { + const res = await chai.request(app).get(`/api/result/1`); + expect(res.status).to.equal(403); + expect(res.body.message).to.equal('No API Key in request'); + }); + + it('should throw error if incorrect API key is present', async () => { + const res = await chai.request(app).get('/api/result/1').set({ + 'Authorization': 'Bearer incorrectAPI-KEY', + Accept: 'application/json' + }); + expect(res.status).to.equal(403); + expect(res.body.message).to.equal('Invalid API Key'); + }); + + it('should throw 404 error if POST request is made', async () => { + const res = await chai.request(app).post('/api/result/1').set({ + Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d', + Accept: 'application/json' + }); + expect(res.status).to.equal(404); + }); + + it('should throw 404 error resultId is not present', async () => { + const res = await chai.request(app).get('/api/result').set({ + Authorization: `Bearer ${APIKEY}`, + Accept: 'application/json' + }); + + expect(res.status).to.equal(404); + }); + + it('should throw 404 error if result is not found ', async () => { + const res = await chai.request(app).get('/api/result/12').set({ + Authorization: `Bearer ${APIKEY}`, + Accept: 'application/json' + }); + + expect(res.status).to.equal(404); + }); + + it('should return correct result if everything is correct', async () => { + const submission = await DB.submissions.create({ + lang: 'cpp', + mode: 'poll', + results: {stdout: 'SUCCESS'} + }); + const res = await chai.request(app).get(`/api/result/${submission.id}`).set({ + Authorization: `Bearer ${APIKEY}`, + Accept: 'application/json' + }); + + expect(res.status).to.equal(200); + expect(res.body).to.deep.equal(submission.results); + }); +}); \ No newline at end of file diff --git a/test/e2e/RunScenario.spec.ts b/test/e2e/RunScenario.spec.ts index a07336d..fb80c48 100644 --- a/test/e2e/RunScenario.spec.ts +++ b/test/e2e/RunScenario.spec.ts @@ -23,11 +23,6 @@ const source = ` const stdin = 'Success'; const expectedOutput = 'Success'; - -function delay(ms: number) { - return new Promise( resolve => setTimeout(resolve, ms) ); -} - describe('POST api/runs', () => { before(async () => { await DB.apikeys.create({ @@ -171,12 +166,15 @@ describe('POST api/runs', () => { expect(res.status).to.equal(200); // there is a delay of 1000 for onSuccess, so setting 2000ms delay here. - await delay(2000); - const submission = await DB.submissions.findById(res.body.id); + await utils.delay(2000); + const resultResponse = await chai.request(app).get(`/api/result/${res.body.id}`).set({ + Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d', + Accept: 'application/json' + }).send(params); expect(res.body.id).to.exist; expect(res.status).to.equal(200); - expect(submission.results.stdout).to.equal(expectedOutput); + expect(resultResponse.body.stdout).to.equal(expectedOutput); }); it('should return id and send result to callback url in callback mode', async () => { @@ -206,7 +204,7 @@ describe('POST api/runs', () => { app2.use('/', router); }); - await delay(2000); + await utils.delay(2000); expect(res.body.id).to.exist; expect(res.status).to.equal(200); diff --git a/test/e2e/SubmitScenario.spec.ts b/test/e2e/SubmitScenario.spec.ts index 1a45f1d..39105c5 100644 --- a/test/e2e/SubmitScenario.spec.ts +++ b/test/e2e/SubmitScenario.spec.ts @@ -35,11 +35,6 @@ const testcases = [ ]; const expectedResult = 'Success'; - -function delay(ms: number) { - return new Promise( resolve => setTimeout(resolve, ms) ); -} - describe('POST api/submissions', () => { before(async () => { await DB.apikeys.create({ @@ -171,12 +166,15 @@ describe('POST api/submissions', () => { // there is a delay of 1000 for onSuccess, so setting 2000ms delay here. - await delay(2000); - const submission = await DB.submissions.findById(res.body.id); + await utils.delay(2000); + const resultResponse = await chai.request(app).get(`/api/result/${res.body.id}`).set({ + Authorization: 'Bearer 7718330d2794406c980bdbded6c9dc1d', + Accept: 'application/json' + }).send(params); expect(res.body.id).to.exist; expect(res.status).to.equal(200); - expect(submission.results.result).to.equal(expectedResult); + expect(resultResponse.body.result).to.equal(expectedResult); }); it('should return id and send result to callback url in callback mode', async () => { @@ -207,7 +205,7 @@ describe('POST api/submissions', () => { app2.use('/', router); }); - await delay(2000); + await utils.delay(2000); expect(res.body.id).to.exist; expect(res.status).to.equal(200); diff --git a/test/utils/utils.ts b/test/utils/utils.ts index 34eb868..393e662 100644 --- a/test/utils/utils.ts +++ b/test/utils/utils.ts @@ -48,4 +48,8 @@ export async function truncateTables() { await DB.apikeys.destroy({truncate: true}); await DB.langs.destroy({truncate: true}); await DB.submissions.destroy({truncate: true}); +} + +export function delay(ms: number) { + return new Promise( resolve => setTimeout(resolve, ms) ); } \ No newline at end of file