Merge pull request 'Minimum lap times for tracks feature/71-track_times' (#72) from feature/71-track_times into dev
Reviewed-on: #72 closes #71
This commit is contained in:
		| @@ -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(); | ||||
|   | ||||
| @@ -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, TrackNotFoundError } from "../errors/TrackErrors"; | ||||
| 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'; | ||||
| @@ -48,6 +48,7 @@ export class TrackController { | ||||
| 	@Post() | ||||
| 	@Authorized("TRACK:CREATE") | ||||
| 	@ResponseSchema(ResponseTrack) | ||||
| 	@ResponseSchema(TrackLapTimeCantBeNegativeError, { statusCode: 406 }) | ||||
| 	@OpenAPI({ description: "Create a new track. <br> Please remember that the track\'s distance must be greater than 0." }) | ||||
| 	async post( | ||||
| 		@Body({ validate: true }) | ||||
| @@ -61,20 +62,21 @@ 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. <br> 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') | ||||
|   | ||||
| @@ -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." | ||||
| } | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { IsInt, IsNotEmpty, IsPositive, IsString } from 'class-validator'; | ||||
| import { IsInt, IsNotEmpty, IsOptional, IsPositive, IsString } from 'class-validator'; | ||||
| import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors'; | ||||
| import { Track } from '../entities/Track'; | ||||
|  | ||||
| /** | ||||
| @@ -19,6 +20,14 @@ export class CreateTrack { | ||||
|     @IsPositive() | ||||
|     distance: number; | ||||
|  | ||||
|     /** | ||||
|      * The minimum time a runner should take to run a lap on this track (in seconds). | ||||
|      * Will be used for fraud detection. | ||||
|      */ | ||||
|     @IsInt() | ||||
|     @IsOptional() | ||||
|     minimumLapTime: number; | ||||
|  | ||||
|     /** | ||||
|      * Creates a new Track entity from this. | ||||
|      */ | ||||
| @@ -27,6 +36,10 @@ export class CreateTrack { | ||||
|  | ||||
|         newTrack.name = this.name; | ||||
|         newTrack.distance = this.distance; | ||||
|         newTrack.minimumLapTime = this.minimumLapTime; | ||||
|         if (this.minimumLapTime < 0) { | ||||
|             throw new TrackLapTimeCantBeNegativeError(); | ||||
|         } | ||||
|  | ||||
|         return newTrack; | ||||
|     } | ||||
|   | ||||
							
								
								
									
										50
									
								
								src/models/actions/UpdateTrack.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/models/actions/UpdateTrack.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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 (in seconds). | ||||
|      * 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; | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,7 @@ | ||||
| import { | ||||
|   IsInt, | ||||
|   IsNotEmpty, | ||||
|   IsOptional, | ||||
|   IsPositive, | ||||
|   IsString | ||||
| } from "class-validator"; | ||||
| @@ -18,7 +19,7 @@ export class Track { | ||||
|    */ | ||||
|   @PrimaryGeneratedColumn() | ||||
|   @IsInt() | ||||
|   id: number;; | ||||
|   id: number; | ||||
|  | ||||
|   /** | ||||
|    * The track's name. | ||||
| @@ -38,6 +39,15 @@ export class Track { | ||||
|   @IsPositive() | ||||
|   distance: number; | ||||
|  | ||||
|   /** | ||||
|    * 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 }) | ||||
|   @IsInt() | ||||
|   @IsOptional() | ||||
|   minimumLapTime?: number; | ||||
|  | ||||
|   /** | ||||
|    * Used to link scan stations to a certain track. | ||||
|    * This makes the configuration of the scan stations easier. | ||||
|   | ||||
| @@ -1,4 +1,5 @@ | ||||
| import { IsInt, IsString } from "class-validator"; | ||||
| import { IsInt, IsOptional, IsString } from "class-validator"; | ||||
| import { TrackLapTimeCantBeNegativeError } from '../../errors/TrackErrors'; | ||||
| import { Track } from '../entities/Track'; | ||||
|  | ||||
| /** | ||||
| @@ -23,6 +24,14 @@ export class ResponseTrack { | ||||
|     @IsInt() | ||||
|     distance: number; | ||||
|  | ||||
|     /** | ||||
|      * The minimum time a runner should take to run a lap on this track (in seconds). | ||||
|      * 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 +40,9 @@ export class ResponseTrack { | ||||
|         this.id = track.id; | ||||
|         this.name = track.name; | ||||
|         this.distance = track.distance; | ||||
|         this.minimumLapTime = track.minimumLapTime; | ||||
|         if (this.minimumLapTime < 0) { | ||||
|             throw new TrackLapTimeCantBeNegativeError(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -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 | ||||
| 		}) | ||||
| 	}); | ||||
| }); | ||||
							
								
								
									
										90
									
								
								src/tests/tracks/track_add.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								src/tests/tracks/track_add.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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": "testtrack", | ||||
| 			"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": "testtrack", | ||||
| 			"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": "testtrack", | ||||
| 			"distance": 200, | ||||
| 			"minimumLapTime": 123 | ||||
| 		}) | ||||
| 	}); | ||||
| }); | ||||
							
								
								
									
										53
									
								
								src/tests/tracks/track_delete.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								src/tests/tracks/track_delete.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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); | ||||
| 	}); | ||||
| }); | ||||
							
								
								
									
										98
									
								
								src/tests/tracks/track_update.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								src/tests/tracks/track_update.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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") | ||||
| 	}); | ||||
| }); | ||||
							
								
								
									
										49
									
								
								src/tests/tracks/tracks_get.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/tests/tracks/tracks_get.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -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"); | ||||
| 	}); | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user