Merge pull request 'Release 0.10.2' (#192) from dev into main
Reviewed-on: #192 Reviewed-by: Philipp Dormann <philipp@philippdormann.de>
This commit is contained in:
commit
1d82f65b0d
15
.drone.yml
15
.drone.yml
|
@ -19,10 +19,17 @@ get:
|
|||
path: odit-git-bot
|
||||
name: sshkey
|
||||
|
||||
---
|
||||
kind: secret
|
||||
name: ci_token
|
||||
get:
|
||||
path: odit-ci-bot
|
||||
name: apikey
|
||||
|
||||
---
|
||||
kind: pipeline
|
||||
type: kubernetes
|
||||
name: tests:node_latest
|
||||
name: tests:node_14.15.1-alpine3.12
|
||||
clone:
|
||||
disable: true
|
||||
steps:
|
||||
|
@ -32,7 +39,7 @@ steps:
|
|||
- git clone $DRONE_REMOTE_URL .
|
||||
- git checkout $DRONE_SOURCE_BRANCH
|
||||
- name: run tests
|
||||
image: node:latest
|
||||
image: node:14.15.1-alpine3.12
|
||||
commands:
|
||||
- yarn
|
||||
- yarn test:ci
|
||||
|
@ -176,13 +183,13 @@ steps:
|
|||
settings:
|
||||
urls: https://ci.odit.services/api/repos/lfk/lfk-client-node/builds?SOURCE_TAG=${DRONE_TAG}
|
||||
bearer:
|
||||
from_secret: BOT_DRONE_KEY
|
||||
from_secret: ci_token
|
||||
- name: trigger js lib build
|
||||
image: idcooldi/drone-webhook
|
||||
settings:
|
||||
urls: https://ci.odit.services/api/repos/lfk/lfk-client-js/builds?SOURCE_TAG=${DRONE_TAG}
|
||||
bearer:
|
||||
from_secret: BOT_DRONE_KEY
|
||||
from_secret: ci_token
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
48
CHANGELOG.md
48
CHANGELOG.md
|
@ -2,17 +2,61 @@
|
|||
|
||||
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
|
||||
|
||||
#### [v0.10.2](https://git.odit.services/lfk/backend/compare/v0.10.1...v0.10.2)
|
||||
|
||||
- Added first selfservice test [`057ae0d`](https://git.odit.services/lfk/backend/commit/057ae0d79758cd627d6d128406a0d201b6b7ad9b)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`b7ad5d3`](https://git.odit.services/lfk/backend/commit/b7ad5d3a31b8b4f5960852d3ac38af133719ebcd)
|
||||
- First try of the laptime sort [`4471e57`](https://git.odit.services/lfk/backend/commit/4471e57438582d55ff846fd69c2cfcc26b40df2a)
|
||||
- Potential fix for all remaining errors [`377d5da`](https://git.odit.services/lfk/backend/commit/377d5dadb2a14cb2d70e0b2dc77026f51b3fb51c)
|
||||
- At least one fewer test should fail now [`87f444c`](https://git.odit.services/lfk/backend/commit/87f444c30d69d65a9f918c63631a859a389eeee3)
|
||||
- Tried workaround for no availdable stats [`8f0f795`](https://git.odit.services/lfk/backend/commit/8f0f795a709db216396998b68b8bbd64ff4d44ff)
|
||||
- Reverted temp bugfix [`4603a84`](https://git.odit.services/lfk/backend/commit/4603a84f16fb53a14d1792447100f5b470969dd0)
|
||||
- Fixed sorting algo [`988f17a`](https://git.odit.services/lfk/backend/commit/988f17a795bb2d867e9d1d8e78051dff1a14ec30)
|
||||
- Added runners stats tests [`7111068`](https://git.odit.services/lfk/backend/commit/7111068361e00cc1308664a3ae650a56e28c015c)
|
||||
- Added basic laptime endpoint [`cb71fcd`](https://git.odit.services/lfk/backend/commit/cb71fcd13bc61e6214e2fd7b70e72094749463d3)
|
||||
- Added orgs by donations stats tests [`d4a02e7`](https://git.odit.services/lfk/backend/commit/d4a02e7db2ff4976be21605e31aac2f3c82a49c0)
|
||||
- Added teams stats endpoint tests [`b9a7dc8`](https://git.odit.services/lfk/backend/commit/b9a7dc84f05441445453193974b2a793b5197fa5)
|
||||
- Now resolving all missing relations [`257f320`](https://git.odit.services/lfk/backend/commit/257f320ee3bf6429c4314c64023520366f9f730b)
|
||||
- Added min laptime to StatsRunner [`51daf96`](https://git.odit.services/lfk/backend/commit/51daf969cf74792b2c2f2f16ce4359d9fca47bc8)
|
||||
- Fixed sorting [`7b15c2d`](https://git.odit.services/lfk/backend/commit/7b15c2d88b14e7279aad97b0c950202ddb5acaaa)
|
||||
- Fixed top-ten bein top 9 [`a6a526d`](https://git.odit.services/lfk/backend/commit/a6a526dc5d8b1613ea34e82e477081349e764aec)
|
||||
- added new ci secret [`5633e85`](https://git.odit.services/lfk/backend/commit/5633e85f41cb69b10fd8a86f57f1bd2f50848f7b)
|
||||
- Added temp console log for test [`22cae39`](https://git.odit.services/lfk/backend/commit/22cae39bd351ca285880e50187ea0d46a7a26437)
|
||||
- Added temp console log for ci debugging [`4a73eab`](https://git.odit.services/lfk/backend/commit/4a73eab134c3a9f58771be996bc8811b62cf378e)
|
||||
- Temp disabled runners by donations test [`0b07a53`](https://git.odit.services/lfk/backend/commit/0b07a53ed209c6193ead3c4d199545e22333ab32)
|
||||
- Updated default docker-compose [`f8baca5`](https://git.odit.services/lfk/backend/commit/f8baca5ab2c56b906751bc7edd71477456ad91f3)
|
||||
- Removed all useless console.logs [`95e1eec`](https://git.odit.services/lfk/backend/commit/95e1eec313a79458dd75307a9d0f8319af0d0904)
|
||||
- Resolved missing parentgroup relation [`23bd432`](https://git.odit.services/lfk/backend/commit/23bd432c5f33a0863217120d97e2e4ea52a08baf)
|
||||
- Removed console logs for now working tests [`71b33ab`](https://git.odit.services/lfk/backend/commit/71b33ab05b53b62c8b271bd2995c94b2fc212dfd)
|
||||
- Fixed typo in test [`cbcb829`](https://git.odit.services/lfk/backend/commit/cbcb829fbde3a4a5e7f94de5dcf24d854c5fc257)
|
||||
- Ptotential fix for stats failing [`dcdbdd1`](https://git.odit.services/lfk/backend/commit/dcdbdd15acfe6eef4220b7ed66db60d78107d1f9)
|
||||
- 🚀Bumped version to v0.10.2 [`6e236ed`](https://git.odit.services/lfk/backend/commit/6e236ede145e164ee84543fb62404b4776550973)
|
||||
- Merge pull request 'stats/runners/laptime feature/190-runners_laptime' (#191) from feature/190-runners_laptime into dev [`a694ad2`](https://git.odit.services/lfk/backend/commit/a694ad225c68fa23152402acba871c857433cc70)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`dd6d799`](https://git.odit.services/lfk/backend/commit/dd6d799c847fc96aec1be8f2667ad371890076fb)
|
||||
- Pinned testing container tag to prod container tag [`10221b9`](https://git.odit.services/lfk/backend/commit/10221b9f2e4493080f3ff095d9772bcfd0ac50eb)
|
||||
- Now resolving all relations for orgs by distance [`4a294b1`](https://git.odit.services/lfk/backend/commit/4a294b1e17c44294274b06748ec8141812c2d217)
|
||||
- Added temp console log [`720774f`](https://git.odit.services/lfk/backend/commit/720774fcf47c38601ab88d5d74cfcd0e47b21acf)
|
||||
- Removed console log for passing tests [`132b48c`](https://git.odit.services/lfk/backend/commit/132b48cf2a9e990a5e830c744ed8244bd25e8b3a)
|
||||
- Removed console log [`1d8c8c8`](https://git.odit.services/lfk/backend/commit/1d8c8c8e9cefa58449f7abb2481d9396fe37ba20)
|
||||
- Temp test logging workaround [`bf686e8`](https://git.odit.services/lfk/backend/commit/bf686e89e02998ccc80c838ef890c736c252634c)
|
||||
- Temp test logging workaround [`6163f0a`](https://git.odit.services/lfk/backend/commit/6163f0a90b3721d3a1488f89cbb39ddff7152241)
|
||||
- Removed test for content type [`63964fb`](https://git.odit.services/lfk/backend/commit/63964fbf2c41d9b90f995f056e9db65ab07d54a8)
|
||||
|
||||
#### [v0.10.1](https://git.odit.services/lfk/backend/compare/v0.10.0...v0.10.1)
|
||||
|
||||
> 3 April 2021
|
||||
|
||||
- Merge pull request 'Release 0.10.1' (#189) from dev into main [`e89e07d`](https://git.odit.services/lfk/backend/commit/e89e07d0fc99f14148b01204fb8ed39e2da77e38)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`69afd4d`](https://git.odit.services/lfk/backend/commit/69afd4d5877401eb46df430f43a7feb273abda1e)
|
||||
- 🚀Bumped version to v0.10.1 [`24d152f`](https://git.odit.services/lfk/backend/commit/24d152fdc8fe17fffa2f2a718d7145ba8a91d79c)
|
||||
- New class: ResponseSelfServiceDonor [`d70c5b1`](https://git.odit.services/lfk/backend/commit/d70c5b1bbc9f02782f8755b6929e2d3458e10221)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`4279e43`](https://git.odit.services/lfk/backend/commit/4279e4374304887e8db40eab77763b20bbce91a1)
|
||||
- Removed duplicate openapi statement [`4834a66`](https://git.odit.services/lfk/backend/commit/4834a6698b0958602421c1478a95fec7edda910b)
|
||||
- Merge pull request 'Selfservice donations reformatting feature/187-selfservice_donation' (#188) from feature/187-selfservice_donation into dev [`d837654`](https://git.odit.services/lfk/backend/commit/d837654617f7de5d055ffb06c65e2cd52f65c604)
|
||||
- New class: ResponseSelfServiceDonor [`d70c5b1`](https://git.odit.services/lfk/backend/commit/d70c5b1bbc9f02782f8755b6929e2d3458e10221)
|
||||
- Switched selfservice donation.donor from string to object [`0767943`](https://git.odit.services/lfk/backend/commit/0767943721b6964d542f580c541e744f86444ac6)
|
||||
- Adjusted runner property names [`ca87774`](https://git.odit.services/lfk/backend/commit/ca87774767807a2c4bc869b0de95cc73832a8405)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`71e3d0e`](https://git.odit.services/lfk/backend/commit/71e3d0efe2cbde47aea0f26cb5a8b5cd3312707d)
|
||||
- 🧾New changelog file version [CI SKIP] [skip ci] [`c28843c`](https://git.odit.services/lfk/backend/commit/c28843c405dc4fd06a10f0fb85814acede15a769)
|
||||
- Merge pull request 'Selfservice donations reformatting feature/187-selfservice_donation' (#188) from feature/187-selfservice_donation into dev [`d837654`](https://git.odit.services/lfk/backend/commit/d837654617f7de5d055ffb06c65e2cd52f65c604)
|
||||
- Added new responsetype for new class [`f693f2c`](https://git.odit.services/lfk/backend/commit/f693f2cde9a04147155aea4de5d52e1d19d722ca)
|
||||
|
||||
#### [v0.10.0](https://git.odit.services/lfk/backend/compare/v0.9.2...v0.10.0)
|
||||
|
|
|
@ -11,8 +11,12 @@ services:
|
|||
DB_PORT: bla
|
||||
DB_USER: bla
|
||||
DB_PASSWORD: bla
|
||||
DB_NAME: dev.sqlite
|
||||
DB_NAME: ./db.sqlite
|
||||
NODE_ENV: production
|
||||
POSTALCODE_COUNTRYCODE: DE
|
||||
SEED_TEST_DATA: "false"
|
||||
MAILER_URL: https://dev.lauf-fuer-kaya.de/mailer
|
||||
MAILER_KEY: asdasd
|
||||
# APP_PORT: 4010
|
||||
# DB_TYPE: postgres
|
||||
# DB_HOST: backend_db
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@odit/lfk-backend",
|
||||
"version": "0.10.1",
|
||||
"version": "0.10.2",
|
||||
"main": "src/app.ts",
|
||||
"repository": "https://git.odit.services/lfk/backend",
|
||||
"author": {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Get, JsonController, UseBefore } from 'routing-controllers';
|
||||
import { Get, JsonController, QueryParam, UseBefore } from 'routing-controllers';
|
||||
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
|
||||
import { getConnection } from 'typeorm';
|
||||
import StatsAuth from '../middlewares/StatsAuth';
|
||||
|
@ -7,6 +7,7 @@ import { Runner } from '../models/entities/Runner';
|
|||
import { RunnerOrganization } from '../models/entities/RunnerOrganization';
|
||||
import { RunnerTeam } from '../models/entities/RunnerTeam';
|
||||
import { Scan } from '../models/entities/Scan';
|
||||
import { TrackScan } from '../models/entities/TrackScan';
|
||||
import { User } from '../models/entities/User';
|
||||
import { ResponseStats } from '../models/responses/ResponseStats';
|
||||
import { ResponseStatsOrgnisation } from '../models/responses/ResponseStatsOrganization';
|
||||
|
@ -36,7 +37,10 @@ export class StatsController {
|
|||
@OpenAPI({ description: "Returns the top ten runners by distance.", security: [{ "StatsApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async getTopRunnersByDistance() {
|
||||
let runners = await getConnection().getRepository(Runner).find({ relations: ['scans', 'group', 'distanceDonations', 'scans.track'] });
|
||||
let topRunners = runners.sort((runner1, runner2) => runner1.distance - runner2.distance).slice(0, 9);
|
||||
if (!runners || runners.length == 0) {
|
||||
return [];
|
||||
}
|
||||
let topRunners = runners.sort((runner1, runner2) => runner2.distance - runner1.distance).slice(0, 10);
|
||||
let responseRunners: ResponseStatsRunner[] = new Array<ResponseStatsRunner>();
|
||||
topRunners.forEach(runner => {
|
||||
responseRunners.push(new ResponseStatsRunner(runner));
|
||||
|
@ -49,8 +53,11 @@ export class StatsController {
|
|||
@ResponseSchema(ResponseStatsRunner, { isArray: true })
|
||||
@OpenAPI({ description: "Returns the top ten runners by donations.", security: [{ "StatsApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async getTopRunnersByDonations() {
|
||||
let runners = await getConnection().getRepository(Runner).find({ relations: ['scans', 'group', 'distanceDonations', 'scans.track'] });
|
||||
let topRunners = runners.sort((runner1, runner2) => runner1.distanceDonationAmount - runner2.distanceDonationAmount).slice(0, 9);
|
||||
let runners = await getConnection().getRepository(Runner).find({ relations: ['group', 'distanceDonations', 'distanceDonations.runner', 'distanceDonations.runner.scans', 'distanceDonations.runner.scans.track'] });
|
||||
if (!runners || runners.length == 0) {
|
||||
return [];
|
||||
}
|
||||
let topRunners = runners.sort((runner1, runner2) => runner2.distanceDonationAmount - runner1.distanceDonationAmount).slice(0, 10);
|
||||
let responseRunners: ResponseStatsRunner[] = new Array<ResponseStatsRunner>();
|
||||
topRunners.forEach(runner => {
|
||||
responseRunners.push(new ResponseStatsRunner(runner));
|
||||
|
@ -58,6 +65,34 @@ export class StatsController {
|
|||
return responseRunners;
|
||||
}
|
||||
|
||||
@Get("/runners/laptime")
|
||||
@UseBefore(StatsAuth)
|
||||
@ResponseSchema(ResponseStatsRunner, { isArray: true })
|
||||
@OpenAPI({ description: "Returns the top ten runners by fastest laptime on your selected track (track by id).", security: [{ "StatsApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async getTopRunnersByLaptime(@QueryParam("track") track: number) {
|
||||
let scans = await getConnection().getRepository(TrackScan).find({ relations: ['track', 'runner', 'runner.group', 'runner.scans', 'runner.scans.track', 'runner.distanceDonations'] });
|
||||
if (!scans || scans.length == 0) {
|
||||
return [];
|
||||
}
|
||||
scans = scans.filter((s) => { return s.track.id == track && s.valid == true && s.lapTime != 0 }).sort((scan1, scan2) => scan1.lapTime - scan2.lapTime);
|
||||
|
||||
let topScans = new Array<TrackScan>();
|
||||
let knownRunners = new Array<number>();
|
||||
for (let i = 0; i < scans.length && topScans.length < 10; i++) {
|
||||
const element = scans[i];
|
||||
if (!knownRunners.includes(element.runner.id)) {
|
||||
topScans.push(element);
|
||||
knownRunners.push(element.runner.id);
|
||||
}
|
||||
}
|
||||
|
||||
let responseRunners: ResponseStatsRunner[] = new Array<ResponseStatsRunner>();
|
||||
topScans.forEach(scan => {
|
||||
responseRunners.push(new ResponseStatsRunner(scan.runner, scan.lapTime));
|
||||
});
|
||||
return responseRunners;
|
||||
}
|
||||
|
||||
@Get("/scans")
|
||||
@UseBefore(StatsAuth)
|
||||
@ResponseSchema(ResponseStatsRunner, { isArray: true })
|
||||
|
@ -71,8 +106,11 @@ export class StatsController {
|
|||
@ResponseSchema(ResponseStatsTeam, { isArray: true })
|
||||
@OpenAPI({ description: "Returns the top ten teams by distance.", security: [{ "StatsApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async getTopTeamsByDistance() {
|
||||
let teams = await getConnection().getRepository(RunnerTeam).find({ relations: ['runners', 'runners.scans', 'runners.distanceDonations', 'runners.scans.track'] });
|
||||
let topTeams = teams.sort((team1, team2) => team1.distance - team2.distance).slice(0, 9);
|
||||
let teams = await getConnection().getRepository(RunnerTeam).find({ relations: ['parentGroup', 'runners', 'runners.scans', 'runners.scans.track'] });
|
||||
if (!teams || teams.length == 0) {
|
||||
return [];
|
||||
}
|
||||
let topTeams = teams.sort((team1, team2) => team2.distance - team1.distance).slice(0, 10);
|
||||
let responseTeams: ResponseStatsTeam[] = new Array<ResponseStatsTeam>();
|
||||
topTeams.forEach(team => {
|
||||
responseTeams.push(new ResponseStatsTeam(team));
|
||||
|
@ -85,8 +123,11 @@ export class StatsController {
|
|||
@ResponseSchema(ResponseStatsTeam, { isArray: true })
|
||||
@OpenAPI({ description: "Returns the top ten teams by donations.", security: [{ "StatsApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async getTopTeamsByDonations() {
|
||||
let teams = await getConnection().getRepository(RunnerTeam).find({ relations: ['runners', 'runners.scans', 'runners.distanceDonations', 'runners.scans.track'] });
|
||||
let topTeams = teams.sort((team1, team2) => team1.distanceDonationAmount - team2.distanceDonationAmount).slice(0, 9);
|
||||
let teams = await getConnection().getRepository(RunnerTeam).find({ relations: ['parentGroup', 'runners', 'runners.scans', 'runners.distanceDonations', 'runners.scans.track'] });
|
||||
if (!teams || teams.length == 0) {
|
||||
return [];
|
||||
}
|
||||
let topTeams = teams.sort((team1, team2) => team2.distanceDonationAmount - team1.distanceDonationAmount).slice(0, 10);
|
||||
let responseTeams: ResponseStatsTeam[] = new Array<ResponseStatsTeam>();
|
||||
topTeams.forEach(team => {
|
||||
responseTeams.push(new ResponseStatsTeam(team));
|
||||
|
@ -100,7 +141,10 @@ export class StatsController {
|
|||
@OpenAPI({ description: "Returns the top ten organizations by distance.", security: [{ "StatsApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async getTopOrgsByDistance() {
|
||||
let orgs = await getConnection().getRepository(RunnerOrganization).find({ relations: ['runners', 'runners.scans', 'runners.distanceDonations', 'runners.scans.track', 'teams', 'teams.runners', 'teams.runners.scans', 'teams.runners.distanceDonations', 'teams.runners.scans.track'] });
|
||||
let topOrgs = orgs.sort((org1, org2) => org1.distance - org2.distance).slice(0, 9);
|
||||
if (!orgs || orgs.length == 0) {
|
||||
return [];
|
||||
}
|
||||
let topOrgs = orgs.sort((org1, org2) => org2.distance - org1.distance).slice(0, 10);
|
||||
let responseOrgs: ResponseStatsOrgnisation[] = new Array<ResponseStatsOrgnisation>();
|
||||
topOrgs.forEach(org => {
|
||||
responseOrgs.push(new ResponseStatsOrgnisation(org));
|
||||
|
@ -113,8 +157,11 @@ export class StatsController {
|
|||
@ResponseSchema(ResponseStatsOrgnisation, { isArray: true })
|
||||
@OpenAPI({ description: "Returns the top ten organizations by donations.", security: [{ "StatsApiToken": [] }, { "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
|
||||
async getTopOrgsByDonations() {
|
||||
let orgs = await getConnection().getRepository(RunnerOrganization).find({ relations: ['runners', 'runners.scans', 'runners.distanceDonations', 'runners.scans.track', 'teams', 'teams.runners', 'teams.runners.scans', 'teams.runners.distanceDonations', 'teams.runners.scans.track'] });
|
||||
let topOrgs = orgs.sort((org1, org2) => org1.distanceDonationAmount - org2.distanceDonationAmount).slice(0, 9);
|
||||
let orgs = await getConnection().getRepository(RunnerOrganization).find({ relations: ['runners', 'runners.distanceDonations', 'runners.distanceDonations.runner', 'runners.distanceDonations.runner.scans', 'runners.distanceDonations.runner.scans.track', 'teams', 'teams.runners', 'teams.runners.distanceDonations', 'teams.runners.distanceDonations.runner', 'teams.runners.distanceDonations.runner.scans', 'teams.runners.distanceDonations.runner.scans.track'] });
|
||||
if (!orgs || orgs.length == 0) {
|
||||
return [];
|
||||
}
|
||||
let topOrgs = orgs.sort((org1, org2) => org2.distanceDonationAmount - org1.distanceDonationAmount).slice(0, 10);
|
||||
let responseOrgs: ResponseStatsOrgnisation[] = new Array<ResponseStatsOrgnisation>();
|
||||
topOrgs.forEach(org => {
|
||||
responseOrgs.push(new ResponseStatsOrgnisation(org));
|
||||
|
|
|
@ -51,6 +51,9 @@ export abstract class RunnerGroup {
|
|||
*/
|
||||
@IsInt()
|
||||
public get distance(): number {
|
||||
if (!this.runners || this.runners.length == 0) {
|
||||
return 0;
|
||||
}
|
||||
return this.runners.reduce((sum, current) => sum + current.distance, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,15 @@ export class ResponseStatsOrgnisation implements IResponse {
|
|||
public constructor(org: RunnerOrganization) {
|
||||
this.name = org.name;
|
||||
this.id = org.id;
|
||||
this.distance = org.distance;
|
||||
this.donationAmount = org.distanceDonationAmount;
|
||||
try {
|
||||
this.distance = org.distance;
|
||||
} catch {
|
||||
this.distance = -1;
|
||||
}
|
||||
try {
|
||||
this.donationAmount = org.distanceDonationAmount;
|
||||
} catch {
|
||||
this.donationAmount = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
IsInt,
|
||||
IsObject,
|
||||
IsOptional,
|
||||
IsString
|
||||
} from "class-validator";
|
||||
import { Runner } from '../entities/Runner';
|
||||
|
@ -55,6 +56,13 @@ export class ResponseStatsRunner implements IResponse {
|
|||
@IsInt()
|
||||
donationAmount: number;
|
||||
|
||||
/**
|
||||
* The runner's fastest laptime in seconds.
|
||||
*/
|
||||
@IsInt()
|
||||
@IsOptional()
|
||||
minLaptime?: number;
|
||||
|
||||
/**
|
||||
* The runner's group.
|
||||
*/
|
||||
|
@ -65,13 +73,28 @@ export class ResponseStatsRunner implements IResponse {
|
|||
* Creates a new runner stats response from a runner
|
||||
* @param runner The runner whoes response shall be generated - the following relations have to be resolved: scans, group, distanceDonations, scans.track
|
||||
*/
|
||||
public constructor(runner: Runner) {
|
||||
public constructor(runner: Runner, laptime?: number) {
|
||||
this.id = runner.id;
|
||||
this.firstname = runner.firstname;
|
||||
this.middlename = runner.middlename;
|
||||
if (runner.firstname) {
|
||||
this.middlename = runner.middlename;
|
||||
}
|
||||
this.lastname = runner.lastname;
|
||||
this.distance = runner.distance;
|
||||
this.donationAmount = runner.distanceDonationAmount;
|
||||
try {
|
||||
this.distance = runner.distance;
|
||||
}
|
||||
catch {
|
||||
this.distance = -1;
|
||||
}
|
||||
try {
|
||||
this.donationAmount = runner.distanceDonationAmount;
|
||||
}
|
||||
catch {
|
||||
this.donationAmount = -1;
|
||||
}
|
||||
if (laptime) {
|
||||
this.minLaptime = laptime;
|
||||
}
|
||||
this.group = runner.group.toResponse();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,15 @@ export class ResponseStatsTeam implements IResponse {
|
|||
this.name = team.name;
|
||||
this.id = team.id;
|
||||
this.parent = team.parentGroup.toResponse();
|
||||
this.distance = team.distance;
|
||||
this.donationAmount = team.distanceDonationAmount;
|
||||
try {
|
||||
this.distance = team.distance;
|
||||
} catch {
|
||||
this.distance = -1;
|
||||
}
|
||||
try {
|
||||
this.donationAmount = team.distanceDonationAmount;
|
||||
} catch {
|
||||
this.donationAmount = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
import axios from 'axios';
|
||||
import { config } from '../../config';
|
||||
const base = "http://localhost:" + config.internal_port
|
||||
|
||||
let axios_config_full;
|
||||
let axios_config_stats;
|
||||
|
||||
beforeAll(async () => {
|
||||
jest.setTimeout(20000);
|
||||
const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
|
||||
let access_token = res.data["access_token"];
|
||||
axios_config_full = {
|
||||
headers: { "authorization": "Bearer " + access_token },
|
||||
validateStatus: undefined
|
||||
};
|
||||
const res2 = await axios.post(base + '/api/statsclients', { username: "demo", password: "demo" }, axios_config_full);
|
||||
access_token = res2.data["key"];
|
||||
axios_config_stats = {
|
||||
headers: { "authorization": "Bearer " + access_token },
|
||||
validateStatus: undefined
|
||||
};
|
||||
});
|
||||
|
||||
describe('GET /api/stats/runners/distance w/o auth should return 200', () => {
|
||||
it('get with invalid token should return 401', async () => {
|
||||
const res = await axios.get(base + '/api/stats/runners/distance', {
|
||||
headers: { "authorization": "Bearer 123123123123123123" },
|
||||
validateStatus: undefined
|
||||
});
|
||||
expect(res.status).toEqual(401);
|
||||
});
|
||||
});
|
||||
// ---------------
|
||||
describe('GET /api/stats should return 200', () => {
|
||||
it('get w/o auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats', { validateStatus: undefined });
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
it('get w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
});
|
||||
// ---------------
|
||||
describe('GET /api/stats/runners/* should return 200', () => {
|
||||
it('get by distance w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats/runners/distance', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
it('get by donations w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats/runners/donations', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
it('get by laptime w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats/runners/laptime', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
});
|
||||
// ---------------
|
||||
describe('GET /api/stats/teams/* should return 200', () => {
|
||||
it('get by distance w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats/teams/distance', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
it('get by donations w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats/teams/donations', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
});
|
||||
// ---------------
|
||||
describe('GET /api/stats/organizations/* should return 200', () => {
|
||||
it('get by distance w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats/organizations/distance', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
it('get by donations w/ auth should return 200', async () => {
|
||||
const res = await axios.get(base + '/api/stats/organizations/donations', axios_config_stats);
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.headers['content-type']).toContain("application/json");
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue