From 63b1ca9b56d3c729a441390ca4b4dd1134ae0a37 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 16:51:36 +0100 Subject: [PATCH 01/14] Added the minimum lap time to the track entity ref #71 --- src/models/entities/Track.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/models/entities/Track.ts b/src/models/entities/Track.ts index 22544d0..0636606 100644 --- a/src/models/entities/Track.ts +++ b/src/models/entities/Track.ts @@ -1,6 +1,7 @@ import { IsInt, IsNotEmpty, + IsOptional, IsPositive, IsString } from "class-validator"; @@ -38,6 +39,16 @@ export class Track { @IsPositive() distance: number; + /** + * The minimum time a runner should take to run a lap on this track. + * Will be used for fraud detection. + */ + @Column() + @IsInt() + @IsOptional() + @IsPositive() + minimumLapTime: number; + /** * Used to link scan stations to a certain track. * This makes the configuration of the scan stations easier. From 02f7ddbb37efe28cc682cda2666d442770f56e8c Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:04:09 +0100 Subject: [PATCH 02/14] Marked property as optional ref #71 --- src/models/actions/CreateTrack.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/models/actions/CreateTrack.ts b/src/models/actions/CreateTrack.ts index f04e55b..c4dde39 100644 --- a/src/models/actions/CreateTrack.ts +++ b/src/models/actions/CreateTrack.ts @@ -1,4 +1,4 @@ -import { IsInt, IsNotEmpty, IsPositive, IsString } from 'class-validator'; +import { IsInt, IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator'; import { Track } from '../entities/Track'; /** @@ -19,6 +19,15 @@ export class CreateTrack { @IsPositive() distance: number; + /** + * The minimum time a runner should take to run a lap on this track. + * Will be used for fraud detection. + */ + @IsInt() + @IsOptional() + @IsPositive() + minimumLapTime?: number; + /** * Creates a new Track entity from this. */ @@ -27,6 +36,7 @@ export class CreateTrack { newTrack.name = this.name; newTrack.distance = this.distance; + newTrack.minimumLapTime = this.minimumLapTime; return newTrack; } From 907259bf737f4ad5bcc5d65f152c3f54ce2f6408 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:05:43 +0100 Subject: [PATCH 03/14] Added the laptime to createtrack ref #71 --- src/models/entities/Track.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/models/entities/Track.ts b/src/models/entities/Track.ts index 0636606..19a08fa 100644 --- a/src/models/entities/Track.ts +++ b/src/models/entities/Track.ts @@ -19,7 +19,7 @@ export class Track { */ @PrimaryGeneratedColumn() @IsInt() - id: number;; + id: number; /** * The track's name. @@ -47,7 +47,7 @@ export class Track { @IsInt() @IsOptional() @IsPositive() - minimumLapTime: number; + minimumLapTime?: number; /** * Used to link scan stations to a certain track. From dcb791c9a2418900a9f07730fd9d650593606f72 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:06:57 +0100 Subject: [PATCH 04/14] Added the laptime to the track response ref #71 --- src/models/responses/ResponseTrack.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/models/responses/ResponseTrack.ts b/src/models/responses/ResponseTrack.ts index 83da863..17c128c 100644 --- a/src/models/responses/ResponseTrack.ts +++ b/src/models/responses/ResponseTrack.ts @@ -1,4 +1,4 @@ -import { IsInt, IsString } from "class-validator"; +import { IsInt, IsOptional, IsString } from "class-validator"; import { Track } from '../entities/Track'; /** @@ -23,6 +23,14 @@ export class ResponseTrack { @IsInt() distance: number; + /** + * The minimum time a runner should take to run a lap on this track. + * Will be used for fraud detection. + */ + @IsInt() + @IsOptional() + minimumLapTime?: number; + /** * Creates a ResponseTrack object from a track. * @param track The track the response shall be build for. @@ -31,5 +39,6 @@ export class ResponseTrack { this.id = track.id; this.name = track.name; this.distance = track.distance; + this.minimumLapTime = track.minimumLapTime; } } From 28c1b6d31dddab082a31aeaedff6dd9339dbfc0c Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:21:53 +0100 Subject: [PATCH 05/14] Improved error handling for negative lap times ref #71 --- src/controllers/TrackController.ts | 4 +++- src/errors/TrackErrors.ts | 11 +++++++++++ src/models/actions/CreateTrack.ts | 7 +++++-- src/models/entities/Track.ts | 3 +-- src/models/responses/ResponseTrack.ts | 4 ++++ 5 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/controllers/TrackController.ts b/src/controllers/TrackController.ts index 1f74193..d2d7e74 100644 --- a/src/controllers/TrackController.ts +++ b/src/controllers/TrackController.ts @@ -2,7 +2,7 @@ import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; -import { TrackIdsNotMatchingError, TrackNotFoundError } from "../errors/TrackErrors"; +import { TrackIdsNotMatchingError, TrackLapTimeCantBeNegativeError, TrackNotFoundError } from "../errors/TrackErrors"; import { CreateTrack } from '../models/actions/CreateTrack'; import { Track } from '../models/entities/Track'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; @@ -48,6 +48,7 @@ export class TrackController { @Post() @Authorized("TRACK:CREATE") @ResponseSchema(ResponseTrack) + @ResponseSchema(TrackLapTimeCantBeNegativeError, { statusCode: 406 }) @OpenAPI({ description: "Create a new track.
Please remember that the track\'s distance must be greater than 0." }) async post( @Body({ validate: true }) @@ -61,6 +62,7 @@ export class TrackController { @ResponseSchema(ResponseTrack) @ResponseSchema(TrackNotFoundError, { statusCode: 404 }) @ResponseSchema(TrackIdsNotMatchingError, { statusCode: 406 }) + @ResponseSchema(TrackLapTimeCantBeNegativeError, { statusCode: 406 }) @OpenAPI({ description: "Update the track whose id you provided.
Please remember that ids can't be changed." }) async put(@Param('id') id: number, @EntityFromBody() track: Track) { let oldTrack = await this.trackRepository.findOne({ id: id }); diff --git a/src/errors/TrackErrors.ts b/src/errors/TrackErrors.ts index 7d4cfa9..e3d1902 100644 --- a/src/errors/TrackErrors.ts +++ b/src/errors/TrackErrors.ts @@ -22,4 +22,15 @@ export class TrackIdsNotMatchingError extends NotAcceptableError { @IsString() message = "The ids don't match! \n And if you wanted to change a track's id: This isn't allowed" +} + +/** + * Error to throw when a track's lap time is set to a negative value. + */ +export class TrackLapTimeCantBeNegativeError extends NotAcceptableError { + @IsString() + name = "TrackLapTimeCantBeNegativeError" + + @IsString() + message = "The minimum lap time you provided is negative - That isn't possible. \n If you wanted to disable it: Just set it to 0/null." } \ No newline at end of file diff --git a/src/models/actions/CreateTrack.ts b/src/models/actions/CreateTrack.ts index c4dde39..0130ad8 100644 --- a/src/models/actions/CreateTrack.ts +++ b/src/models/actions/CreateTrack.ts @@ -1,4 +1,5 @@ import { IsInt, IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator'; +import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors'; import { Track } from '../entities/Track'; /** @@ -25,8 +26,7 @@ export class CreateTrack { */ @IsInt() @IsOptional() - @IsPositive() - minimumLapTime?: number; + minimumLapTime: number; /** * Creates a new Track entity from this. @@ -37,6 +37,9 @@ export class CreateTrack { newTrack.name = this.name; newTrack.distance = this.distance; newTrack.minimumLapTime = this.minimumLapTime; + if (this.minimumLapTime < 0) { + throw new TrackLapTimeCantBeNegativeError(); + } return newTrack; } diff --git a/src/models/entities/Track.ts b/src/models/entities/Track.ts index 19a08fa..3f05262 100644 --- a/src/models/entities/Track.ts +++ b/src/models/entities/Track.ts @@ -43,10 +43,9 @@ export class Track { * The minimum time a runner should take to run a lap on this track. * Will be used for fraud detection. */ - @Column() + @Column({ nullable: true }) @IsInt() @IsOptional() - @IsPositive() minimumLapTime?: number; /** diff --git a/src/models/responses/ResponseTrack.ts b/src/models/responses/ResponseTrack.ts index 17c128c..2ae34ff 100644 --- a/src/models/responses/ResponseTrack.ts +++ b/src/models/responses/ResponseTrack.ts @@ -1,4 +1,5 @@ import { IsInt, IsOptional, IsString } from "class-validator"; +import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors'; import { Track } from '../entities/Track'; /** @@ -40,5 +41,8 @@ export class ResponseTrack { this.name = track.name; this.distance = track.distance; this.minimumLapTime = track.minimumLapTime; + if (this.minimumLapTime < 0) { + throw new TrackLapTimeCantBeNegativeError(); + } } } From 59cb72a11d6a12a1733a3bd8d8c082252a408bfd Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:30:17 +0100 Subject: [PATCH 06/14] Implemented track upodates using the "new" method ref #71 --- src/controllers/TrackController.ts | 10 +++--- src/models/actions/UpdateTrack.ts | 50 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 src/models/actions/UpdateTrack.ts diff --git a/src/controllers/TrackController.ts b/src/controllers/TrackController.ts index d2d7e74..f03718f 100644 --- a/src/controllers/TrackController.ts +++ b/src/controllers/TrackController.ts @@ -1,9 +1,9 @@ import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put } from 'routing-controllers'; import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; import { getConnectionManager, Repository } from 'typeorm'; -import { EntityFromBody } from 'typeorm-routing-controllers-extensions'; import { TrackIdsNotMatchingError, TrackLapTimeCantBeNegativeError, TrackNotFoundError } from "../errors/TrackErrors"; import { CreateTrack } from '../models/actions/CreateTrack'; +import { UpdateTrack } from '../models/actions/UpdateTrack'; import { Track } from '../models/entities/Track'; import { ResponseEmpty } from '../models/responses/ResponseEmpty'; import { ResponseTrack } from '../models/responses/ResponseTrack'; @@ -64,19 +64,19 @@ export class TrackController { @ResponseSchema(TrackIdsNotMatchingError, { statusCode: 406 }) @ResponseSchema(TrackLapTimeCantBeNegativeError, { statusCode: 406 }) @OpenAPI({ description: "Update the track whose id you provided.
Please remember that ids can't be changed." }) - async put(@Param('id') id: number, @EntityFromBody() track: Track) { + async put(@Param('id') id: number, @Body({ validate: true }) updateTrack: UpdateTrack) { let oldTrack = await this.trackRepository.findOne({ id: id }); if (!oldTrack) { throw new TrackNotFoundError(); } - if (oldTrack.id != track.id) { + if (oldTrack.id != updateTrack.id) { throw new TrackIdsNotMatchingError(); } + await this.trackRepository.save(await updateTrack.updateTrack(oldTrack)); - await this.trackRepository.save(track); - return new ResponseTrack(track); + return new ResponseTrack(await this.trackRepository.findOne({ id: id })); } @Delete('/:id') diff --git a/src/models/actions/UpdateTrack.ts b/src/models/actions/UpdateTrack.ts new file mode 100644 index 0000000..6c1aec3 --- /dev/null +++ b/src/models/actions/UpdateTrack.ts @@ -0,0 +1,50 @@ +import { IsInt, IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator'; +import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors'; +import { Track } from '../entities/Track'; + +/** + * This class is used to update a Track entity (via put request). + */ +export class UpdateTrack { + /** + * The updated track's id. + * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to). + */ + @IsInt() + id: number; + + @IsString() + @IsNotEmpty() + name: string; + + /** + * The updated track's distance in meters (must be greater than 0). + */ + @IsInt() + @IsPositive() + distance: number; + + /** + * The minimum time a runner should take to run a lap on this track. + * Will be used for fraud detection. + */ + @IsInt() + @IsOptional() + minimumLapTime: number; + + + /** + * Update a Track entity based on this. + * @param track The track that shall be updated. + */ + public updateTrack(track: Track): Track { + track.name = this.name; + track.distance = this.distance; + track.minimumLapTime = this.minimumLapTime; + if (this.minimumLapTime < 0) { + throw new TrackLapTimeCantBeNegativeError(); + } + + return track; + } +} \ No newline at end of file From daa899a1ef4ccc7bff950cca887d8ba85c937df3 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:49:44 +0100 Subject: [PATCH 07/14] Removed the old basic test class ref #71 --- src/tests/tracks.spec.ts | 112 --------------------------------------- 1 file changed, 112 deletions(-) delete mode 100644 src/tests/tracks.spec.ts diff --git a/src/tests/tracks.spec.ts b/src/tests/tracks.spec.ts deleted file mode 100644 index 81e4850..0000000 --- a/src/tests/tracks.spec.ts +++ /dev/null @@ -1,112 +0,0 @@ -import axios from 'axios'; -import { config } from '../config'; -const base = "http://localhost:" + config.internal_port - -let access_token; -let axios_config; - -beforeAll(async () => { - const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); - access_token = res.data["access_token"]; - axios_config = { - headers: { "authorization": "Bearer " + access_token }, - validateStatus: undefined - }; -}); - -describe('GET /api/tracks', () => { - it('basic get should return 200', async () => { - const res = await axios.get(base + '/api/tracks', axios_config); - expect(res.status).toEqual(200); - expect(res.headers['content-type']).toContain("application/json") - }); - it('correct distance input should return 200', async () => { - const res = await axios.post(base + '/api/tracks', { - "name": "string", - "distance": 400 - }, axios_config); - expect(res.status).toEqual(200); - expect(res.headers['content-type']).toContain("application/json") - }); -}); -// --------------- -describe('POST /api/tracks', () => { - it('illegal distance input should return 400', async () => { - const res = await axios.post(base + '/api/tracks', { - "name": "string", - "distance": -1 - }, axios_config); - expect(res.status).toEqual(400); - expect(res.headers['content-type']).toContain("application/json") - }); - it('correct distance input should return 200', async () => { - const res = await axios.post(base + '/api/tracks', { - "name": "string", - "distance": 400 - }, axios_config); - expect(res.status).toEqual(200); - expect(res.headers['content-type']).toContain("application/json") - }); -}); -// --------------- -describe('adding + getting tracks', () => { - it('correct distance input should return 200', async () => { - const res = await axios.post(base + '/api/tracks', { - "name": "string", - "distance": 1000 - }, axios_config); - expect(res.status).toEqual(200); - expect(res.headers['content-type']).toContain("application/json") - }); - it('check if track was added', async () => { - const res = await axios.get(base + '/api/tracks', axios_config); - expect(res.status).toEqual(200); - expect(res.headers['content-type']).toContain("application/json") - let added_track = res.data[res.data.length - 1] - delete added_track.id - expect(added_track).toEqual({ - "name": "string", - "distance": 1000 - }) - }); -}); -// --------------- -describe('adding + getting + updating', () => { - let added_track; - it('correct distance input should return 200', async () => { - const res = await axios.post(base + '/api/tracks', { - "name": "string", - "distance": 1500 - }, axios_config); - expect(res.status).toEqual(200); - expect(res.headers['content-type']).toContain("application/json"); - added_track = res.data; - }); - it('get should return 200', async () => { - const res1 = await axios.get(base + '/api/tracks/' + added_track.id, axios_config); - expect(res1.status).toEqual(200); - expect(res1.headers['content-type']).toContain("application/json") - const compareTrack = res1.data; - expect(compareTrack).toEqual(added_track) - }) - it('get should return 200', async () => { - const res2 = await axios.put(base + '/api/tracks/' + added_track.id, { - "id": added_track.id, - "name": "apitrack", - "distance": 5100 - }, axios_config); - expect(res2.status).toEqual(200); - expect(res2.headers['content-type']).toContain("application/json") - }) - it('get should return 200', async () => { - const res3 = await axios.get(base + '/api/tracks/' + added_track.id, axios_config); - expect(res3.status).toEqual(200); - expect(res3.headers['content-type']).toContain("application/json") - let added_track2 = res3.data; - delete added_track2.id - expect(added_track2).toEqual({ - "name": "apitrack", - "distance": 5100 - }) - }); -}); From 9f103d8df1242b95fdea4a461975b05e4b0c2c6b Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:49:55 +0100 Subject: [PATCH 08/14] Added track get tests ref #71 --- src/tests/tracks/tracks_get.spec.ts | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/tests/tracks/tracks_get.spec.ts diff --git a/src/tests/tracks/tracks_get.spec.ts b/src/tests/tracks/tracks_get.spec.ts new file mode 100644 index 0000000..1057034 --- /dev/null +++ b/src/tests/tracks/tracks_get.spec.ts @@ -0,0 +1,49 @@ +import axios from 'axios'; +import { config } from '../../config'; +const base = "http://localhost:" + config.internal_port + +let access_token; +let axios_config; + +beforeAll(async () => { + const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); + access_token = res.data["access_token"]; + axios_config = { + headers: { "authorization": "Bearer " + access_token }, + validateStatus: undefined + }; +}); + +describe('GET /api/tracks sucessfully', () => { + it('basic get should return 200', async () => { + const res = await axios.get(base + '/api/tracks', axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json") + }); +}); +// --------------- +describe('GET /api/tracks illegally', () => { + it('get for non-existant track should return 404', async () => { + const res = await axios.get(base + '/api/tracks/-1', axios_config); + expect(res.status).toEqual(404); + expect(res.headers['content-type']).toContain("application/json") + }); +}); +// --------------- +describe('adding + getting tracks', () => { + let added_track; + it('correct distance input should return 200', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "string", + "distance": 1000 + }, axios_config); + added_track = res.data; + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json") + }); + it('check if track was added (no parameter validation)', async () => { + const res = await axios.get(base + '/api/tracks/' + added_track.id, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + }); +}); \ No newline at end of file From 1a0573e0d055488bbb2c8474c8d60f7ff5f32c02 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:52:16 +0100 Subject: [PATCH 09/14] Added track add tests ref #71 --- src/tests/tracks/track_add.spec.ts | 90 ++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/tests/tracks/track_add.spec.ts diff --git a/src/tests/tracks/track_add.spec.ts b/src/tests/tracks/track_add.spec.ts new file mode 100644 index 0000000..3a40d6f --- /dev/null +++ b/src/tests/tracks/track_add.spec.ts @@ -0,0 +1,90 @@ +import axios from 'axios'; +import { config } from '../../config'; +const base = "http://localhost:" + config.internal_port + +let access_token; +let axios_config; + +beforeAll(async () => { + const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); + access_token = res.data["access_token"]; + axios_config = { + headers: { "authorization": "Bearer " + access_token }, + validateStatus: undefined + }; +}); + + +describe('POST /api/tracks illegally', () => { + it('no distance input should return 400', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "string", + }, axios_config); + expect(res.status).toEqual(400); + expect(res.headers['content-type']).toContain("application/json") + }); + it('illegal distance input should return 400', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "string", + "distance": -1 + }, axios_config); + expect(res.status).toEqual(400); + expect(res.headers['content-type']).toContain("application/json") + }); + it('negative minimum lap time input should return 406', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "string", + "distance": 200, + "minimumLapTime": -1 + }, axios_config); + expect(res.status).toEqual(406); + expect(res.headers['content-type']).toContain("application/json") + }); +}); +// --------------- +describe('POST /api/tracks successfully', () => { + it('creating a track with the minimum amount of parameters should return 200', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "testtrack", + "distance": 200, + }, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + delete res.data.id; + expect(res.data).toEqual({ + "name": "string", + "distance": 200, + "minimumLapTime": null + }) + }); + it('creating a track with all parameters (optional set to null) should return 200', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "testtrack", + "distance": 200, + "minimumLapTime": null + }, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + delete res.data.id; + expect(res.data).toEqual({ + "name": "string", + "distance": 200, + "minimumLapTime": null + }) + }); + it('creating a track with all parameters should return 200', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "testtrack", + "distance": 200, + "minimumLapTime": 123 + }, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + delete res.data.id; + expect(res.data).toEqual({ + "name": "string", + "distance": 200, + "minimumLapTime": 123 + }) + }); +}); From f378b0651add4142ce02a288c7712ab8d4fdedfa Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 17:52:36 +0100 Subject: [PATCH 10/14] Added helpful comment about the tracktime's unit ref #71 --- src/models/actions/CreateTrack.ts | 2 +- src/models/actions/UpdateTrack.ts | 2 +- src/models/entities/Track.ts | 2 +- src/models/responses/ResponseTrack.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/models/actions/CreateTrack.ts b/src/models/actions/CreateTrack.ts index 0130ad8..fdeae71 100644 --- a/src/models/actions/CreateTrack.ts +++ b/src/models/actions/CreateTrack.ts @@ -21,7 +21,7 @@ export class CreateTrack { distance: number; /** - * The minimum time a runner should take to run a lap on this track. + * The minimum time a runner should take to run a lap on this track (in seconds). * Will be used for fraud detection. */ @IsInt() diff --git a/src/models/actions/UpdateTrack.ts b/src/models/actions/UpdateTrack.ts index 6c1aec3..bc64d54 100644 --- a/src/models/actions/UpdateTrack.ts +++ b/src/models/actions/UpdateTrack.ts @@ -25,7 +25,7 @@ export class UpdateTrack { distance: number; /** - * The minimum time a runner should take to run a lap on this track. + * The minimum time a runner should take to run a lap on this track (in seconds). * Will be used for fraud detection. */ @IsInt() diff --git a/src/models/entities/Track.ts b/src/models/entities/Track.ts index 3f05262..df18762 100644 --- a/src/models/entities/Track.ts +++ b/src/models/entities/Track.ts @@ -40,7 +40,7 @@ export class Track { distance: number; /** - * The minimum time a runner should take to run a lap on this track. + * The minimum time a runner should take to run a lap on this track (in seconds). * Will be used for fraud detection. */ @Column({ nullable: true }) diff --git a/src/models/responses/ResponseTrack.ts b/src/models/responses/ResponseTrack.ts index 2ae34ff..27ef813 100644 --- a/src/models/responses/ResponseTrack.ts +++ b/src/models/responses/ResponseTrack.ts @@ -25,7 +25,7 @@ export class ResponseTrack { distance: number; /** - * The minimum time a runner should take to run a lap on this track. + * The minimum time a runner should take to run a lap on this track (in seconds). * Will be used for fraud detection. */ @IsInt() From b6ea5e6549ef5dd347428f8d2fddc564abb7abdc Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 18:01:21 +0100 Subject: [PATCH 11/14] Fixed copy-paste mistake ref #71 --- src/tests/tracks/track_add.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tests/tracks/track_add.spec.ts b/src/tests/tracks/track_add.spec.ts index 3a40d6f..7f39f8d 100644 --- a/src/tests/tracks/track_add.spec.ts +++ b/src/tests/tracks/track_add.spec.ts @@ -52,7 +52,7 @@ describe('POST /api/tracks successfully', () => { expect(res.headers['content-type']).toContain("application/json"); delete res.data.id; expect(res.data).toEqual({ - "name": "string", + "name": "testtrack", "distance": 200, "minimumLapTime": null }) @@ -67,7 +67,7 @@ describe('POST /api/tracks successfully', () => { expect(res.headers['content-type']).toContain("application/json"); delete res.data.id; expect(res.data).toEqual({ - "name": "string", + "name": "testtrack", "distance": 200, "minimumLapTime": null }) @@ -82,7 +82,7 @@ describe('POST /api/tracks successfully', () => { expect(res.headers['content-type']).toContain("application/json"); delete res.data.id; expect(res.data).toEqual({ - "name": "string", + "name": "testtrack", "distance": 200, "minimumLapTime": 123 }) From 15d2d029dc251751ec46511d3e770392a96ba622 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 18:07:33 +0100 Subject: [PATCH 12/14] Added track delete tests ref #71 --- src/tests/tracks/track_delete.spec.ts | 53 +++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/tests/tracks/track_delete.spec.ts diff --git a/src/tests/tracks/track_delete.spec.ts b/src/tests/tracks/track_delete.spec.ts new file mode 100644 index 0000000..cb7ae89 --- /dev/null +++ b/src/tests/tracks/track_delete.spec.ts @@ -0,0 +1,53 @@ +import axios from 'axios'; +import { config } from '../../config'; +const base = "http://localhost:" + config.internal_port + +let access_token; +let axios_config; + +beforeAll(async () => { + const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); + access_token = res.data["access_token"]; + axios_config = { + headers: { "authorization": "Bearer " + access_token }, + validateStatus: undefined + }; +}); + +// --------------- +describe('DETELE track', () => { + let added_track + it('creating a track with the minimum amount of parameters should return 200', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "testtrack", + "distance": 200, + }, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + added_track = res.data + }); + it('delete track', async () => { + const res2 = await axios.delete(base + '/api/tracks/' + added_track.id, axios_config); + expect(res2.status).toEqual(200); + expect(res2.headers['content-type']).toContain("application/json") + let deleted_track = res2.data + delete deleted_track.id; + expect(res2.data).toEqual({ + "name": "testtrack", + "distance": 200, + "minimumLapTime": null + }); + }); + it('check if track really was deleted', async () => { + const res3 = await axios.get(base + '/api/tracks/' + added_track.id, axios_config); + expect(res3.status).toEqual(404); + expect(res3.headers['content-type']).toContain("application/json") + }); +}); +// --------------- +describe('DELETE track (non-existant)', () => { + it('delete', async () => { + const res2 = await axios.delete(base + '/api/tracks/0', axios_config); + expect(res2.status).toEqual(204); + }); +}); From d67be313e6c683a2494790af43fc4ab5300c5dfa Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 18:08:04 +0100 Subject: [PATCH 13/14] Added track update tests ref #71 --- src/tests/tracks/track_update.spec.ts | 98 +++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/tests/tracks/track_update.spec.ts diff --git a/src/tests/tracks/track_update.spec.ts b/src/tests/tracks/track_update.spec.ts new file mode 100644 index 0000000..ab2b707 --- /dev/null +++ b/src/tests/tracks/track_update.spec.ts @@ -0,0 +1,98 @@ +import axios from 'axios'; +import { config } from '../../config'; +const base = "http://localhost:" + config.internal_port + +let access_token; +let axios_config; + +beforeAll(async () => { + const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); + access_token = res.data["access_token"]; + axios_config = { + headers: { "authorization": "Bearer " + access_token }, + validateStatus: undefined + }; +}); + +describe('adding + updating illegally', () => { + let added_track; + it('correct distance input should return 200', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "apitrack", + "distance": 1500 + }, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + added_track = res.data; + }); + it('update with negative distance should return 400', async () => { + const res2 = await axios.put(base + '/api/tracks/' + added_track.id, { + "id": added_track.id, + "name": "apitrack", + "distance": -1 + }, axios_config); + expect(res2.status).toEqual(400); + expect(res2.headers['content-type']).toContain("application/json") + }); + it('update with negative laptime should return 406', async () => { + const res2 = await axios.put(base + '/api/tracks/' + added_track.id, { + "id": added_track.id, + "name": "apitrack", + "distance": 2, + "minimumLapTime": -1 + }, axios_config); + expect(res2.status).toEqual(406); + expect(res2.headers['content-type']).toContain("application/json") + }); +}); +// --------------- +describe('adding + updating successfilly', () => { + let added_track; + it('correct distance input should return 200', async () => { + const res = await axios.post(base + '/api/tracks', { + "name": "apitrack2", + "distance": 1500 + }, axios_config); + expect(res.status).toEqual(200); + expect(res.headers['content-type']).toContain("application/json"); + added_track = res.data; + }); + it('valid name change should return 200', async () => { + const res2 = await axios.put(base + '/api/tracks/' + added_track.id, { + "id": added_track.id, + "name": "apitrackk", + "distance": 1500 + }, axios_config); + expect(res2.status).toEqual(200); + expect(res2.headers['content-type']).toContain("application/json") + }); + it('valid distance change should return 200', async () => { + const res2 = await axios.put(base + '/api/tracks/' + added_track.id, { + "id": added_track.id, + "name": "apitrack2", + "distance": 5100 + }, axios_config); + expect(res2.status).toEqual(200); + expect(res2.headers['content-type']).toContain("application/json") + }); + it('valid laptime change (to a set number) should return 200', async () => { + const res2 = await axios.put(base + '/api/tracks/' + added_track.id, { + "id": added_track.id, + "name": "apitrack2", + "distance": 5100, + "minimumLapTime": 3 + }, axios_config); + expect(res2.status).toEqual(200); + expect(res2.headers['content-type']).toContain("application/json") + }); + it('valid laptime change (to a set null) should return 200', async () => { + const res2 = await axios.put(base + '/api/tracks/' + added_track.id, { + "id": added_track.id, + "name": "apitrack2", + "distance": 5100, + "minimumLapTime": null + }, axios_config); + expect(res2.status).toEqual(200); + expect(res2.headers['content-type']).toContain("application/json") + }); +}); From a5d70ce4b5ea758a535958752d65d0ab23c727c3 Mon Sep 17 00:00:00 2001 From: Nicolai Ort Date: Sun, 3 Jan 2021 18:13:53 +0100 Subject: [PATCH 14/14] Removed useless console.log --- src/controllers/AuthController.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/controllers/AuthController.ts b/src/controllers/AuthController.ts index cddb677..9672de5 100644 --- a/src/controllers/AuthController.ts +++ b/src/controllers/AuthController.ts @@ -70,7 +70,6 @@ export class AuthController { if (refresh_token && refresh_token.length != 0 && refreshAuth.token == undefined) { refreshAuth.token = refresh_token; } - console.log(req.headers) let auth; try { auth = await refreshAuth.toAuth();