Merge pull request 'Alpha Release 0.2.0' (#109) from dev into main
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

Reviewed-on: #109
Reviewed-by: Philipp Dormann <philipp@philippdormann.de>
This commit is contained in:
Nicolai Ort 2021-01-20 17:05:12 +00:00
commit dd3d93edc7
38 changed files with 2824 additions and 1521 deletions

View File

@ -6,4 +6,4 @@ DB_USER=unused
DB_PASSWORD=bla
DB_NAME=./test.sqlite
NODE_ENV=dev
POSTALCODE_COUNTRYCODE=null
POSTALCODE_COUNTRYCODE=DE

View File

@ -6,4 +6,4 @@ DB_USER=bla
DB_PASSWORD=bla
DB_NAME=bla
NODE_ENV=production
POSTALCODE_COUNTRYCODE=null
POSTALCODE_COUNTRYCODE=DE

View File

@ -2,8 +2,67 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [v0.2.0](https://git.odit.services/lfk/backend/compare/v0.1.1...v0.2.0)
- 🧾New changelog file version [CI SKIP] [skip ci] [`8960aa5`](https://git.odit.services/lfk/backend/commit/8960aa5545ddeb57d4ef42c21c0ca6001dfeaea9)
- 🚀Bumped version to v0.2.0 [`ddafd90`](https://git.odit.services/lfk/backend/commit/ddafd90d3e41fb9ee37172a8306c30d8483dfe2c)
- Merge pull request 'Implemented group contacts feature/104-contacts' (#108) from feature/104-contacts into dev [`a0c2b5a`](https://git.odit.services/lfk/backend/commit/a0c2b5ade8d198ec16d33b39e47205e8b03a669f)
- Updated contact update tests [`c3d008e`](https://git.odit.services/lfk/backend/commit/c3d008ec0ff92f80addbdb93ffc1fa2b3278a8a6)
- Added contact delete tests [`dd7e5da`](https://git.odit.services/lfk/backend/commit/dd7e5dae368a8decd79357f658dda2164fa6f1e7)
- Added contact add valid tests [`e165f01`](https://git.odit.services/lfk/backend/commit/e165f019307e7745357493eacf3e2fa31538122b)
- Cleaned up var names [`a3c93f0`](https://git.odit.services/lfk/backend/commit/a3c93f0d394833f1a6f78d862b094ca751c85561)
- Added address update ivalid tests [`427dfaa`](https://git.odit.services/lfk/backend/commit/427dfaafabd243e94aba27c2dec2705fd8ed5d64)
- Added barebones contact controller from donor-controller [`3e7190e`](https://git.odit.services/lfk/backend/commit/3e7190e279181c5f99d890ca141489b24908b904)
- Added first address update tests [`4d40225`](https://git.odit.services/lfk/backend/commit/4d40225a4491e8eb3f41ef0fd558a599f63729be)
- Added a contact update class [`c172aa8`](https://git.odit.services/lfk/backend/commit/c172aa8bf8083500828743ed696955a1fe3caef2)
- Added address update valid tests [`230cdb0`](https://git.odit.services/lfk/backend/commit/230cdb0e37e2b7a21e7feb156f2b91a69ad200fd)
- Implemented deep address validation [`9dc9ce3`](https://git.odit.services/lfk/backend/commit/9dc9ce37d8fbfc92842e4e05bbde68398324a186)
- Added contact add invalid tests [`940d62c`](https://git.odit.services/lfk/backend/commit/940d62cde4cf7be7780904d681a5e4c9efaa2ba5)
- Added a contact response class [`1407fe3`](https://git.odit.services/lfk/backend/commit/1407fe36f3637d6c53024c48788b318d985f8960)
- Removed old create address class [`2a465f8`](https://git.odit.services/lfk/backend/commit/2a465f88c58c0b4be3ecd99d96a04c177a40b312)
- Switched the create classes over to the new address implementation [`2cd15d2`](https://git.odit.services/lfk/backend/commit/2cd15d25e934a5439bfea4de901f136e360e17f6)
- Added contact get tests [`b002cf2`](https://git.odit.services/lfk/backend/commit/b002cf2df1eafc722fbfb51b3bffb02bee002305)
- Test's now accept the new address format [`8dbee32`](https://git.odit.services/lfk/backend/commit/8dbee32eeec8ee3d013e4446e8f53544ee4cb577)
- Implemented the get endpoints [`ab70f7e`](https://git.odit.services/lfk/backend/commit/ab70f7e49893344dde8f5af93f571a5d67818e19)
- Implemented contact deletion [`0379786`](https://git.odit.services/lfk/backend/commit/0379786cbda057ad95d709fa135d34beb0db8de1)
- Removed the IAddressUser Interface entity [`e265172`](https://git.odit.services/lfk/backend/commit/e2651728c5abf2273bf51a7652c51d55d8fa0a2f)
- Implemented contact updateing [`28fb983`](https://git.odit.services/lfk/backend/commit/28fb9834e18bde012c5b51cc49a39585d20f7cc1)
- Fixed key null constraint [`de82437`](https://git.odit.services/lfk/backend/commit/de824375d3a1da6ee4d78ea39b7da66fc05f2a02)
- Implemented contact posting [`11af9c0`](https://git.odit.services/lfk/backend/commit/11af9c02d977dcd6919652256dbdb9fd5438cabd)
- Implemented contact group setting on creation [`3b06d1a`](https://git.odit.services/lfk/backend/commit/3b06d1a6ef3c95eb5bb7d485accddabba0a8e4f7)
- 🧾New changelog file version [CI SKIP] [skip ci] [`32e054e`](https://git.odit.services/lfk/backend/commit/32e054eb84c869210fd483583ae5a6d0e2249cf9)
- Switched Address to embedded entity [`7fbe649`](https://git.odit.services/lfk/backend/commit/7fbe649dc90f4bb9f240c5a80fed447048e5e105)
- Removed the address errors [`58ae9b5`](https://git.odit.services/lfk/backend/commit/58ae9b589aef3580f4b8558c3d5ddbd7171e7915)
- Switched the update classes over to the new address implementation [`d0df5dd`](https://git.odit.services/lfk/backend/commit/d0df5dd641ac17f1fd8ad6bd8b46afa9dd2745c3)
- Updated the contact errors [`a9a5eb6`](https://git.odit.services/lfk/backend/commit/a9a5eb673570bb3c0d1a55bb1292e208493663bd)
- Implemented adress deletion (through reset) [`57b9c2b`](https://git.odit.services/lfk/backend/commit/57b9c2babcd68d69d1cbb240a86c2897717ba758)
- Fixed donor address check [`4824547`](https://git.odit.services/lfk/backend/commit/4824547dde4d7f90e9e2377a26df34cabf082fdb)
- Updated contact delete tests [`8ae53f1`](https://git.odit.services/lfk/backend/commit/8ae53f1c4930e2fd72eb230a5314336f3a45a611)
- Added address to contact response [`09e429f`](https://git.odit.services/lfk/backend/commit/09e429fc676c7dd370bba0495b072f81867bd250)
- Updated comments [`a4e8311`](https://git.odit.services/lfk/backend/commit/a4e8311cbd22588ecb4dc2fdbe05397b07d336f8)
- Updated the responseclasses to use the new address implementation [`dafac06`](https://git.odit.services/lfk/backend/commit/dafac06bc84d1b237096a561b3adcd3ca5cb1dd8)
- Removed (now useless) relations [`673dea2`](https://git.odit.services/lfk/backend/commit/673dea2e5754e99ff77f7556d4fc03d4cca28a94)
- Added missing id property [`6b4b16c`](https://git.odit.services/lfk/backend/commit/6b4b16c13b0c2f55745ded3431cad2f4986be296)
- Added address validity check [`ae7c5ff`](https://git.odit.services/lfk/backend/commit/ae7c5ff0c387e9337d01a9dd819a4dddc208f6dd)
- 🧾New changelog file version [CI SKIP] [skip ci] [`f53894b`](https://git.odit.services/lfk/backend/commit/f53894b16ac1c06ecbeeb0b63a56ac438b2fbe1b)
- Updated comments [`8bc01d3`](https://git.odit.services/lfk/backend/commit/8bc01d3f2406ce8e58c2ab2963c858495c510dcf)
- Fixed contact cascading [`179c2a5`](https://git.odit.services/lfk/backend/commit/179c2a5157fca036acf8d0e6a51821d377860bc1)
- Added openapi description about non-deletion [`56c73c2`](https://git.odit.services/lfk/backend/commit/56c73c2555d4d12ffb088ec5550667022d3a8694)
- Added contact permission target [`d12801e`](https://git.odit.services/lfk/backend/commit/d12801e34d57cec0e867f69123e3be39ed2fe2f5)
- Adjusted env sample [`a1acd35`](https://git.odit.services/lfk/backend/commit/a1acd3519f66965202da0cd15df61a807230619c)
- Renamed controller to better fit the overall nameing scheme [`d743f7e`](https://git.odit.services/lfk/backend/commit/d743f7ee1277256ada8fe39f900349ff2643118a)
- Fixed column not getting resolved [`2b658ac`](https://git.odit.services/lfk/backend/commit/2b658ac381f318cf37fc2051ea3e83976e3c5773)
- Fixed column not getting resolved [`321d291`](https://git.odit.services/lfk/backend/commit/321d291b4bf983ff4930cadecf3a013430a97649)
- Set country code for the ci env to DE [`30b585c`](https://git.odit.services/lfk/backend/commit/30b585c0c12b3b9818778110d33d5b3ab84d4192)
- Implemented postal code validation for the validaton function [`f245840`](https://git.odit.services/lfk/backend/commit/f245840cde5726611197b00730aca72ea133c427)
- Fixed push undefined eror [`2eb26e4`](https://git.odit.services/lfk/backend/commit/2eb26e4e381a97fd829a294501fa42ac7b712b56)
- Merge pull request 'Fully implemented addresses feature/105-addresses' (#107) from feature/105-addresses into dev [`5e36855`](https://git.odit.services/lfk/backend/commit/5e368552ea810ea1d3963b1207ba98f7b46c4abc)
#### [v0.1.1](https://git.odit.services/lfk/backend/compare/v0.1.0...v0.1.1)
> 16 January 2021
- Merge pull request 'Alpha Release 0.1.1 - Hotfix release' (#106) from dev into main [`7533c34`](https://git.odit.services/lfk/backend/commit/7533c349ef98ed328151259fca68621b3eb5fd98)
- 🚀Bumped version to v0.1.1 [`9445c6f`](https://git.odit.services/lfk/backend/commit/9445c6f21e376329b9200664a44a94ba1f1dd463)
- 🧾New changelog file version [CI SKIP] [skip ci] [`1b9d296`](https://git.odit.services/lfk/backend/commit/1b9d2969ebdca4dca84898b1e8307be7b781b90b)
- Implemented the /me controller that allows a user to get and update themselves [`8ef5f90`](https://git.odit.services/lfk/backend/commit/8ef5f90abda97a73d5c5a7767a144ac3fb5288c1)
@ -14,12 +73,13 @@ All notable changes to this project will be documented in this file. Dates are d
- automaticly merge main into dev after building a latest image [`02efb9a`](https://git.odit.services/lfk/backend/commit/02efb9a8e55831ecce4109e17b2f07a56e491fd5)
- User deletion now requires confirmation [`6b7ecd3`](https://git.odit.services/lfk/backend/commit/6b7ecd3044c45b2eed46ee5010bed4dab4f02df9)
- 🧾New changelog file version [CI SKIP] [skip ci] [`3766899`](https://git.odit.services/lfk/backend/commit/3766899c8393545a89986a98dafd542edc4a1d39)
- 🧾New changelog file version [CI SKIP] [skip ci] [`6febb99`](https://git.odit.services/lfk/backend/commit/6febb994990b4cab7ee54b0368f74dd95664bfdf)
- 🧾New changelog file version [CI SKIP] [skip ci] [`de36a24`](https://git.odit.services/lfk/backend/commit/de36a24191a8cdc4ff6b23637ea9f91109b59bbb)
- Merge pull request 'User self-management feature/100-me_endpoints' (#103) from feature/100-me_endpoints into dev [`a6c7d54`](https://git.odit.services/lfk/backend/commit/a6c7d54fe72ffe23add926afa0be150a7a370099)
- Created barebones file for the userchecker [`e586a11`](https://git.odit.services/lfk/backend/commit/e586a11e2ad42af9c9bb5d2a47f48e3306fe49b2)
- 🧾New changelog file version [CI SKIP] [skip ci] [`6febb99`](https://git.odit.services/lfk/backend/commit/6febb994990b4cab7ee54b0368f74dd95664bfdf)
- Updated descriptions and responses [`fc7b8f4`](https://git.odit.services/lfk/backend/commit/fc7b8f4c16cef0e72b04f096d5a17d4144b5feb7)
- 🧾New changelog file version [CI SKIP] [skip ci] [`50b893f`](https://git.odit.services/lfk/backend/commit/50b893f5370902ccc40f8bb45ed160103400f529)
- 🧾New changelog file version [CI SKIP] [skip ci] [`de36a24`](https://git.odit.services/lfk/backend/commit/de36a24191a8cdc4ff6b23637ea9f91109b59bbb)
- 🧾New changelog file version [CI SKIP] [skip ci] [`91569ce`](https://git.odit.services/lfk/backend/commit/91569ced40402a63017a90a01efaf48578b5c806)
- Merge pull request 'User self-management feature/100-me_endpoints' (#103) from feature/100-me_endpoints into dev [`a6c7d54`](https://git.odit.services/lfk/backend/commit/a6c7d54fe72ffe23add926afa0be150a7a370099)
- Moved the me endpoints to /users/me [`f9834b5`](https://git.odit.services/lfk/backend/commit/f9834b5f4d80b11ee5f7773b339dd421341c6e7f)
- Moved optional param to being optional [`a334adf`](https://git.odit.services/lfk/backend/commit/a334adffc6d07c8ab340263123e00a96f21acecb)

View File

@ -1,6 +1,6 @@
{
"name": "@odit/lfk-backend",
"version": "0.1.1",
"version": "0.2.0",
"main": "src/app.ts",
"repository": "https://git.odit.services/lfk/backend",
"author": {

View File

@ -0,0 +1,107 @@
import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers';
import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi';
import { getConnection, getConnectionManager, Repository } from 'typeorm';
import { GroupContactIdsNotMatchingError, GroupContactNotFoundError } from '../errors/GroupContactErrors';
import { RunnerGroupNotFoundError } from '../errors/RunnerGroupErrors';
import { CreateGroupContact } from '../models/actions/create/CreateGroupContact';
import { UpdateGroupContact } from '../models/actions/update/UpdateGroupContact';
import { GroupContact } from '../models/entities/GroupContact';
import { RunnerGroup } from '../models/entities/RunnerGroup';
import { ResponseEmpty } from '../models/responses/ResponseEmpty';
import { ResponseGroupContact } from '../models/responses/ResponseGroupContact';
@JsonController('/contacts')
@OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] })
export class GroupContactController {
private contactRepository: Repository<GroupContact>;
/**
* Gets the repository of this controller's model/entity.
*/
constructor() {
this.contactRepository = getConnectionManager().get().getRepository(GroupContact);
}
@Get()
@Authorized("CONTACT:GET")
@ResponseSchema(ResponseGroupContact, { isArray: true })
@OpenAPI({ description: 'Lists all contacts. <br> This includes the contact\'s associated groups.' })
async getAll() {
let responseContacts: ResponseGroupContact[] = new Array<ResponseGroupContact>();
const contacts = await this.contactRepository.find({ relations: ['groups'] });
contacts.forEach(contact => {
responseContacts.push(contact.toResponse());
});
return responseContacts;
}
@Get('/:id')
@Authorized("CONTACT:GET")
@ResponseSchema(ResponseGroupContact)
@ResponseSchema(GroupContactNotFoundError, { statusCode: 404 })
@OnUndefined(GroupContactNotFoundError)
@OpenAPI({ description: 'Lists all information about the contact whose id got provided. <br> This includes the contact\'s associated groups.' })
async getOne(@Param('id') id: number) {
let contact = await this.contactRepository.findOne({ id: id }, { relations: ['groups'] })
if (!contact) { throw new GroupContactNotFoundError(); }
return contact.toResponse();
}
@Post()
@Authorized("CONTACT:CREATE")
@ResponseSchema(ResponseGroupContact)
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
@OpenAPI({ description: 'Create a new contact.' })
async post(@Body({ validate: true }) createContact: CreateGroupContact) {
let contact;
try {
contact = await createContact.toEntity();
} catch (error) {
throw error;
}
contact = await this.contactRepository.save(contact)
return (await this.contactRepository.findOne({ id: contact.id }, { relations: ['groups'] })).toResponse();
}
@Put('/:id')
@Authorized("CONTACT:UPDATE")
@ResponseSchema(ResponseGroupContact)
@ResponseSchema(GroupContactNotFoundError, { statusCode: 404 })
@ResponseSchema(GroupContactIdsNotMatchingError, { statusCode: 406 })
@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 })
@OpenAPI({ description: "Update the contact whose id you provided. <br> Please remember that ids can't be changed." })
async put(@Param('id') id: number, @Body({ validate: true }) contact: UpdateGroupContact) {
let oldContact = await this.contactRepository.findOne({ id: id });
if (!oldContact) {
throw new GroupContactNotFoundError();
}
if (oldContact.id != contact.id) {
throw new GroupContactIdsNotMatchingError();
}
await this.contactRepository.save(await contact.update(oldContact));
return (await this.contactRepository.findOne({ id: contact.id }, { relations: ['groups'] })).toResponse();
}
@Delete('/:id')
@Authorized("CONTACT:DELETE")
@ResponseSchema(ResponseGroupContact)
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
@OnUndefined(204)
@OpenAPI({ description: 'Delete the contact whose id you provided. <br> If no contact with this id exists it will just return 204(no content). <br> This won\'t delete any groups associated with the contact.' })
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let contact = await this.contactRepository.findOne({ id: id });
if (!contact) { return null; }
const responseContact = await this.contactRepository.findOne(contact, { relations: ['groups'] });
for (let group of responseContact.groups) {
group.contact = null;
await getConnection().getRepository(RunnerGroup).save(group);
}
await this.contactRepository.delete(contact);
return responseContact.toResponse();
}
}

View File

@ -29,7 +29,7 @@ export class RunnerOrganisationController {
@OpenAPI({ description: 'Lists all organisations. <br> This includes their address, contact and teams (if existing/associated).' })
async getAll() {
let responseTeams: ResponseRunnerOrganisation[] = new Array<ResponseRunnerOrganisation>();
const runners = await this.runnerOrganisationRepository.find({ relations: ['address', 'contact', 'teams'] });
const runners = await this.runnerOrganisationRepository.find({ relations: ['contact', 'teams'] });
runners.forEach(runner => {
responseTeams.push(new ResponseRunnerOrganisation(runner));
});
@ -43,7 +43,7 @@ export class RunnerOrganisationController {
@OnUndefined(RunnerOrganisationNotFoundError)
@OpenAPI({ description: 'Lists all information about the organisation whose id got provided.' })
async getOne(@Param('id') id: number) {
let runnerOrg = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['address', 'contact', 'teams'] });
let runnerOrg = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['contact', 'teams'] });
if (!runnerOrg) { throw new RunnerOrganisationNotFoundError(); }
return new ResponseRunnerOrganisation(runnerOrg);
}
@ -62,7 +62,7 @@ export class RunnerOrganisationController {
runnerOrganisation = await this.runnerOrganisationRepository.save(runnerOrganisation);
return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['address', 'contact', 'teams'] }));
return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['contact', 'teams'] }));
}
@Put('/:id')
@ -84,7 +84,7 @@ export class RunnerOrganisationController {
await this.runnerOrganisationRepository.save(await updateOrganisation.update(oldRunnerOrganisation));
return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(id, { relations: ['address', 'contact', 'teams'] }));
return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(id, { relations: ['contact', 'teams'] }));
}
@Delete('/:id')
@ -94,11 +94,11 @@ export class RunnerOrganisationController {
@ResponseSchema(RunnerOrganisationHasTeamsError, { statusCode: 406 })
@ResponseSchema(RunnerOrganisationHasRunnersError, { statusCode: 406 })
@OnUndefined(204)
@OpenAPI({ description: 'Delete the organsisation whose id you provided. <br> If the organisation still has runners and/or teams associated this will fail. <br> To delete the organisation with all associated runners and teams set the force QueryParam to true (cascading deletion might take a while). <br> If no organisation with this id exists it will just return 204(no content).' })
@OpenAPI({ description: 'Delete the organsisation whose id you provided. <br> If the organisation still has runners and/or teams associated this will fail. <br> To delete the organisation with all associated runners and teams set the force QueryParam to true (cascading deletion might take a while). <br> This won\'t delete the associated contact. <br> If no organisation with this id exists it will just return 204(no content).' })
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let organisation = await this.runnerOrganisationRepository.findOne({ id: id });
if (!organisation) { return null; }
let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['address', 'contact', 'runners', 'teams'] });
let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['contact', 'runners', 'teams'] });
if (!force) {
if (runnerOrganisation.teams.length != 0) {

View File

@ -93,7 +93,7 @@ export class RunnerTeamController {
@ResponseSchema(ResponseEmpty, { statusCode: 204 })
@ResponseSchema(RunnerTeamHasRunnersError, { statusCode: 406 })
@OnUndefined(204)
@OpenAPI({ description: 'Delete the team whose id you provided. <br> If the team still has runners associated this will fail. <br> To delete the team with all associated runners set the force QueryParam to true (cascading deletion might take a while). <br> If no team with this id exists it will just return 204(no content).' })
@OpenAPI({ description: 'Delete the team whose id you provided. <br> If the team still has runners associated this will fail. <br> To delete the team with all associated runners set the force QueryParam to true (cascading deletion might take a while). <br> This won\'t delete the associated contact.<br> If no team with this id exists it will just return 204(no content).' })
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let team = await this.runnerTeamRepository.findOne({ id: id });
if (!team) { return null; }

View File

@ -1,24 +1,57 @@
import { IsString } from 'class-validator';
import { NotAcceptableError, NotFoundError } from 'routing-controllers';
/**
* Error to throw, when to provided address doesn't belong to the accepted types.
*/
export class AddressWrongTypeError extends NotAcceptableError {
@IsString()
name = "AddressWrongTypeError"
@IsString()
message = "The address must be an existing address's id. \n You provided a object of another type."
}
/**
* Error to throw, when a non-existent address get's loaded.
*/
export class AddressNotFoundError extends NotFoundError {
@IsString()
name = "AddressNotFoundError"
@IsString()
message = "The address you provided couldn't be located in the system. \n Please check your request."
import { IsString } from 'class-validator';
import { BadRequestError } from 'routing-controllers';
/**
* Error to throw when an address's postal code fails validation.
*/
export class AddressPostalCodeInvalidError extends BadRequestError {
@IsString()
name = "AddressPostalCodeInvalidError"
@IsString()
message = "The postal code you provided is invalid. \n Please check if your postal code follows the postal code validation guidelines."
}
/**
* Error to throw when an non-empty address's first line isn't set.
*/
export class AddressFirstLineEmptyError extends BadRequestError {
@IsString()
name = "AddressFirstLineEmptyError"
@IsString()
message = "You provided a empty first address line. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country"
}
/**
* Error to throw when an non-empty address's postal code isn't set.
*/
export class AddressPostalCodeEmptyError extends BadRequestError {
@IsString()
name = "AddressPostalCodeEmptyError"
@IsString()
message = "You provided a empty postal code. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country"
}
/**
* Error to throw when an non-empty address's city isn't set.
*/
export class AddressCityEmptyError extends BadRequestError {
@IsString()
name = "AddressCityEmptyError"
@IsString()
message = "You provided a empty city. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country"
}
/**
* Error to throw when an non-empty address's country isn't set.
*/
export class AddressCountryEmptyError extends BadRequestError {
@IsString()
name = "AddressCountryEmptyError"
@IsString()
message = "You provided a empty country. \n If you want an empty address please set all propertys to null. \n For non-empty addresses the following fields have to be set: address1, postalcode, city, country"
}

View File

@ -2,18 +2,7 @@ import { IsString } from 'class-validator';
import { NotAcceptableError, NotFoundError } from 'routing-controllers';
/**
* Error to throw, when a provided groupContact doesn't belong to the accepted types.
*/
export class GroupContactWrongTypeError extends NotAcceptableError {
@IsString()
name = "GroupContactWrongTypeError"
@IsString()
message = "The groupContact must be an existing groupContact's id. \n You provided a object of another type."
}
/**
* Error to throw, when a non-existent groupContact get's loaded.
* Error to throw, when a non-existent contact get's requested.
*/
export class GroupContactNotFoundError extends NotFoundError {
@IsString()
@ -21,4 +10,16 @@ export class GroupContactNotFoundError extends NotFoundError {
@IsString()
message = "The groupContact you provided couldn't be located in the system. \n Please check your request."
}
}
/**
* Error to throw when two contacts' ids don't match.
* Usually occurs when a user tries to change a contact's id.
*/
export class GroupContactIdsNotMatchingError extends NotAcceptableError {
@IsString()
name = "GroupContactIdsNotMatchingError"
@IsString()
message = "The ids don't match! \n And if you wanted to change a contact's id: This isn't allowed!"
}

View File

@ -1,69 +0,0 @@
import { IsNotEmpty, IsOptional, IsPostalCode, IsString } from 'class-validator';
import { config } from '../../../config';
import { Address } from '../../entities/Address';
/**
* This classed is used to create a new Address entity from a json body (post request).
*/
export class CreateAddress {
/**
* The newaddress's description.
*/
@IsString()
@IsOptional()
description?: string;
/**
* The new address's first line.
* Containing the street and house number.
*/
@IsString()
@IsNotEmpty()
address1: string;
/**
* The new address's second line.
* Containing optional information.
*/
@IsString()
@IsOptional()
address2?: string;
/**
* The new address's postal code.
* This will get checked against the postal code syntax for the configured country.
*/
@IsString()
@IsNotEmpty()
@IsPostalCode(config.postalcode_validation_countrycode)
postalcode: string;
/**
* The new address's city.
*/
@IsString()
@IsNotEmpty()
city: string;
/**
* The new address's country.
*/
@IsString()
@IsNotEmpty()
country: string;
/**
* Creates a new Address entity from this.
*/
public async toEntity(): Promise<Address> {
let newAddress: Address = new Address();
newAddress.address1 = this.address1;
newAddress.address2 = this.address2;
newAddress.postalcode = this.postalcode;
newAddress.city = this.city;
newAddress.country = this.country;
return newAddress;
}
}

View File

@ -1,38 +1,39 @@
import { IsBoolean, IsOptional } from 'class-validator';
import { DonorReceiptAddressNeededError } from '../../../errors/DonorErrors';
import { Donor } from '../../entities/Donor';
import { CreateParticipant } from './CreateParticipant';
/**
* This classed is used to create a new Donor entity from a json body (post request).
*/
export class CreateDonor extends CreateParticipant {
/**
* Does this donor need a receipt?
*/
@IsBoolean()
@IsOptional()
receiptNeeded?: boolean = false;
/**
* Creates a new Donor entity from this.
*/
public async toEntity(): Promise<Donor> {
let newDonor: Donor = new Donor();
newDonor.firstname = this.firstname;
newDonor.middlename = this.middlename;
newDonor.lastname = this.lastname;
newDonor.phone = this.phone;
newDonor.email = this.email;
newDonor.address = await this.getAddress();
newDonor.receiptNeeded = this.receiptNeeded;
if (this.receiptNeeded == true && this.address == null) {
throw new DonorReceiptAddressNeededError()
}
return newDonor;
}
import { IsBoolean, IsOptional } from 'class-validator';
import { DonorReceiptAddressNeededError } from '../../../errors/DonorErrors';
import { Address } from '../../entities/Address';
import { Donor } from '../../entities/Donor';
import { CreateParticipant } from './CreateParticipant';
/**
* This classed is used to create a new Donor entity from a json body (post request).
*/
export class CreateDonor extends CreateParticipant {
/**
* Does this donor need a receipt?
*/
@IsBoolean()
@IsOptional()
receiptNeeded?: boolean = false;
/**
* Creates a new Donor entity from this.
*/
public async toEntity(): Promise<Donor> {
let newDonor: Donor = new Donor();
newDonor.firstname = this.firstname;
newDonor.middlename = this.middlename;
newDonor.lastname = this.lastname;
newDonor.phone = this.phone;
newDonor.email = this.email;
newDonor.receiptNeeded = this.receiptNeeded;
newDonor.address = this.address;
Address.validate(newDonor.address);
if (this.receiptNeeded == true && Address.isValidAddress(newDonor.address) == false) {
throw new DonorReceiptAddressNeededError()
}
return newDonor;
}
}

View File

@ -1,78 +1,97 @@
import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { config } from '../../../config';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address';
import { GroupContact } from '../../entities/GroupContact';
/**
* This classed is used to create a new Group entity from a json body (post request).
*/
export class CreateGroupContact {
/**
* The new contact's first name.
*/
@IsNotEmpty()
@IsString()
firstname: string;
/**
* The new contact's middle name.
*/
@IsOptional()
@IsString()
middlename?: string;
/**
* The new contact's last name.
*/
@IsNotEmpty()
@IsString()
lastname: string;
/**
* The new contact's address's id.
*/
@IsInt()
@IsOptional()
address?: number;
/**
* The contact's phone number.
* This will be validated against the configured country phone numer syntax (default: international).
*/
@IsOptional()
@IsPhoneNumber(config.phone_validation_countrycode)
phone?: string;
/**
* The contact's email address.
*/
@IsOptional()
@IsEmail()
email?: string;
/**
* Gets the new contact's address by it's id.
*/
public async getAddress(): Promise<Address> {
if (!this.address) { return null; }
let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
if (!address) { throw new AddressNotFoundError; }
return address;
}
/**
* Creates a new Address entity from this.
*/
public async toEntity(): Promise<GroupContact> {
let contact: GroupContact = new GroupContact();
contact.firstname = this.firstname;
contact.middlename = this.middlename;
contact.lastname = this.lastname;
contact.email = this.email;
contact.phone = this.phone;
contact.address = await this.getAddress();
return null;
}
import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { config } from '../../../config';
import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
import { Address } from '../../entities/Address';
import { GroupContact } from '../../entities/GroupContact';
import { RunnerGroup } from '../../entities/RunnerGroup';
/**
* This classed is used to create a new GroupContact entity from a json body (post request).
*/
export class CreateGroupContact {
/**
* The new contact's first name.
*/
@IsNotEmpty()
@IsString()
firstname: string;
/**
* The new contact's middle name.
*/
@IsOptional()
@IsString()
middlename?: string;
/**
* The new contact's last name.
*/
@IsNotEmpty()
@IsString()
lastname: string;
/**
* The new contact's address.
*/
@IsOptional()
@IsObject()
address?: Address;
/**
* The contact's phone number.
* This will be validated against the configured country phone numer syntax (default: international).
*/
@IsOptional()
@IsPhoneNumber(config.phone_validation_countrycode)
phone?: string;
/**
* The new contact's email address.
*/
@IsOptional()
@IsEmail()
email?: string;
/**
* The new contacts's groups' ids.
* You can provide either one groupId or an array of groupIDs.
*/
@IsOptional()
groups?: number[] | number
/**
* Get's all groups for this contact by their id's;
*/
public async getGroups(): Promise<RunnerGroup[]> {
if (!this.groups) { return null; }
let groups = new Array<RunnerGroup>();
if (!Array.isArray(this.groups)) {
this.groups = [this.groups]
}
for (let group of this.groups) {
let found = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: group });
if (!found) { throw new RunnerGroupNotFoundError(); }
groups.push(found);
}
return groups;
}
/**
* Creates a new GroupContact entity from this.
*/
public async toEntity(): Promise<GroupContact> {
let newContact: GroupContact = new GroupContact();
newContact.firstname = this.firstname;
newContact.middlename = this.middlename;
newContact.lastname = this.lastname;
newContact.email = this.email;
newContact.phone = this.phone;
newContact.address = this.address;
Address.validate(newContact.address);
newContact.groups = await this.getGroups();
return newContact;
}
}

View File

@ -1,65 +1,53 @@
import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { config } from '../../../config';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address';
/**
* This classed is used to create a new Participant entity from a json body (post request).
*/
export abstract class CreateParticipant {
/**
* The new participant's first name.
*/
@IsString()
@IsNotEmpty()
firstname: string;
/**
* The new participant's middle name.
*/
@IsString()
@IsOptional()
middlename?: string;
/**
* The new participant's last name.
*/
@IsString()
@IsNotEmpty()
lastname: string;
/**
* The new participant's phone number.
* This will be validated against the configured country phone numer syntax (default: international).
*/
@IsString()
@IsOptional()
@IsPhoneNumber(config.phone_validation_countrycode)
phone?: string;
/**
* The new participant's e-mail address.
*/
@IsString()
@IsOptional()
@IsEmail()
email?: string;
/**
* The new participant's address's id.
*/
@IsInt()
@IsOptional()
address?: number;
/**
* Gets the new participant's address by it's id.
*/
public async getAddress(): Promise<Address> {
if (!this.address) { return null; }
let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
if (!address) { throw new AddressNotFoundError; }
return address;
}
import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { config } from '../../../config';
import { Address } from '../../entities/Address';
/**
* This classed is used to create a new Participant entity from a json body (post request).
*/
export abstract class CreateParticipant {
/**
* The new participant's first name.
*/
@IsString()
@IsNotEmpty()
firstname: string;
/**
* The new participant's middle name.
*/
@IsString()
@IsOptional()
middlename?: string;
/**
* The new participant's last name.
*/
@IsString()
@IsNotEmpty()
lastname: string;
/**
* The new participant's phone number.
* This will be validated against the configured country phone numer syntax (default: international).
*/
@IsString()
@IsOptional()
@IsPhoneNumber(config.phone_validation_countrycode)
phone?: string;
/**
* The new participant's e-mail address.
*/
@IsString()
@IsOptional()
@IsEmail()
email?: string;
/**
* The new participant's address.
*/
@IsOptional()
@IsObject()
address?: Address;
}

View File

@ -1,53 +1,55 @@
import { IsInt } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
import { RunnerOrganisationWrongTypeError } from '../../../errors/RunnerOrganisationErrors';
import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
import { Runner } from '../../entities/Runner';
import { RunnerGroup } from '../../entities/RunnerGroup';
import { CreateParticipant } from './CreateParticipant';
/**
* This classed is used to create a new Runner entity from a json body (post request).
*/
export class CreateRunner extends CreateParticipant {
/**
* The new runner's group's id.
*/
@IsInt()
group: number;
/**
* Creates a new Runner entity from this.
*/
public async toEntity(): Promise<Runner> {
let newRunner: Runner = new Runner();
newRunner.firstname = this.firstname;
newRunner.middlename = this.middlename;
newRunner.lastname = this.lastname;
newRunner.phone = this.phone;
newRunner.email = this.email;
newRunner.group = await this.getGroup();
newRunner.address = await this.getAddress();
return newRunner;
}
/**
* Gets the new runner's group by it's id.
*/
public async getGroup(): Promise<RunnerGroup> {
if (this.group === undefined || this.group === null) {
throw new RunnerTeamNeedsParentError();
}
if (!isNaN(this.group)) {
let group = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: this.group });
if (!group) { throw new RunnerGroupNotFoundError; }
return group;
}
throw new RunnerOrganisationWrongTypeError;
}
import { IsInt } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
import { RunnerOrganisationWrongTypeError } from '../../../errors/RunnerOrganisationErrors';
import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
import { Address } from '../../entities/Address';
import { Runner } from '../../entities/Runner';
import { RunnerGroup } from '../../entities/RunnerGroup';
import { CreateParticipant } from './CreateParticipant';
/**
* This classed is used to create a new Runner entity from a json body (post request).
*/
export class CreateRunner extends CreateParticipant {
/**
* The new runner's group's id.
*/
@IsInt()
group: number;
/**
* Creates a new Runner entity from this.
*/
public async toEntity(): Promise<Runner> {
let newRunner: Runner = new Runner();
newRunner.firstname = this.firstname;
newRunner.middlename = this.middlename;
newRunner.lastname = this.lastname;
newRunner.phone = this.phone;
newRunner.email = this.email;
newRunner.group = await this.getGroup();
newRunner.address = this.address;
Address.validate(newRunner.address);
return newRunner;
}
/**
* Gets the new runner's group by it's id.
*/
public async getGroup(): Promise<RunnerGroup> {
if (this.group === undefined || this.group === null) {
throw new RunnerTeamNeedsParentError();
}
if (!isNaN(this.group)) {
let group = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: this.group });
if (!group) { throw new RunnerGroupNotFoundError; }
return group;
}
throw new RunnerOrganisationWrongTypeError;
}
}

View File

@ -1,41 +1,30 @@
import { IsInt, IsOptional } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address';
import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
import { CreateRunnerGroup } from './CreateRunnerGroup';
/**
* This classed is used to create a new RunnerOrganisation entity from a json body (post request).
*/
export class CreateRunnerOrganisation extends CreateRunnerGroup {
/**
* The new organisation's address's id.
*/
@IsInt()
@IsOptional()
address?: number;
/**
* Gets the org's address by it's id.
*/
public async getAddress(): Promise<Address> {
if (!this.address) { return null; }
let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
if (!address) { throw new AddressNotFoundError; }
return address;
}
/**
* Creates a new RunnerOrganisation entity from this.
*/
public async toEntity(): Promise<RunnerOrganisation> {
let newRunnerOrganisation: RunnerOrganisation = new RunnerOrganisation();
newRunnerOrganisation.name = this.name;
newRunnerOrganisation.contact = await this.getContact();
newRunnerOrganisation.address = await this.getAddress();
return newRunnerOrganisation;
}
import { IsObject, IsOptional } from 'class-validator';
import { Address } from '../../entities/Address';
import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
import { CreateRunnerGroup } from './CreateRunnerGroup';
/**
* This classed is used to create a new RunnerOrganisation entity from a json body (post request).
*/
export class CreateRunnerOrganisation extends CreateRunnerGroup {
/**
* The new organisation's address.
*/
@IsOptional()
@IsObject()
address?: Address;
/**
* Creates a new RunnerOrganisation entity from this.
*/
public async toEntity(): Promise<RunnerOrganisation> {
let newRunnerOrganisation: RunnerOrganisation = new RunnerOrganisation();
newRunnerOrganisation.name = this.name;
newRunnerOrganisation.contact = await this.getContact();
newRunnerOrganisation.address = this.address;
Address.validate(newRunnerOrganisation.address);
return newRunnerOrganisation;
}
}

View File

@ -1,44 +1,46 @@
import { IsBoolean, IsInt, IsOptional } from 'class-validator';
import { DonorReceiptAddressNeededError } from '../../../errors/DonorErrors';
import { Donor } from '../../entities/Donor';
import { CreateParticipant } from '../create/CreateParticipant';
/**
* This class is used to update a Donor entity (via put request).
*/
export class UpdateDonor extends CreateParticipant {
/**
* The updated donor'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;
/**
* Does the updated donor need a receipt?
*/
@IsBoolean()
@IsOptional()
receiptNeeded?: boolean;
/**
* Updates a provided Donor entity based on this.
*/
public async update(donor: Donor): Promise<Donor> {
donor.firstname = this.firstname;
donor.middlename = this.middlename;
donor.lastname = this.lastname;
donor.phone = this.phone;
donor.email = this.email;
donor.receiptNeeded = this.receiptNeeded;
donor.address = await this.getAddress();
if (this.receiptNeeded == true && this.address == null) {
throw new DonorReceiptAddressNeededError()
}
return donor;
}
import { IsBoolean, IsInt, IsOptional } from 'class-validator';
import { DonorReceiptAddressNeededError } from '../../../errors/DonorErrors';
import { Address } from '../../entities/Address';
import { Donor } from '../../entities/Donor';
import { CreateParticipant } from '../create/CreateParticipant';
/**
* This class is used to update a Donor entity (via put request).
*/
export class UpdateDonor extends CreateParticipant {
/**
* The updated donor'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;
/**
* Does the updated donor need a receipt?
*/
@IsBoolean()
@IsOptional()
receiptNeeded?: boolean;
/**
* Updates a provided Donor entity based on this.
*/
public async update(donor: Donor): Promise<Donor> {
donor.firstname = this.firstname;
donor.middlename = this.middlename;
donor.lastname = this.lastname;
donor.phone = this.phone;
donor.email = this.email;
donor.receiptNeeded = this.receiptNeeded;
if (!this.address) { donor.address.reset(); }
else { donor.address = this.address; }
Address.validate(donor.address);
if (this.receiptNeeded == true && Address.isValidAddress(donor.address) == false) {
throw new DonorReceiptAddressNeededError()
}
return donor;
}
}

View File

@ -0,0 +1,106 @@
import { IsEmail, IsInt, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { config } from '../../../config';
import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
import { Address } from '../../entities/Address';
import { GroupContact } from '../../entities/GroupContact';
import { RunnerGroup } from '../../entities/RunnerGroup';
/**
* This class is used to update a GroupContact entity (via put request).
*/
export class UpdateGroupContact {
/**
* The updated contact'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;
/**
* The updated contact's first name.
*/
@IsNotEmpty()
@IsString()
firstname: string;
/**
* The updated contact's middle name.
*/
@IsOptional()
@IsString()
middlename?: string;
/**
* The updated contact's last name.
*/
@IsNotEmpty()
@IsString()
lastname: string;
/**
* The updated contact's address.
*/
@IsOptional()
@IsObject()
address?: Address;
/**
* The updated contact's phone number.
* This will be validated against the configured country phone numer syntax (default: international).
*/
@IsOptional()
@IsPhoneNumber(config.phone_validation_countrycode)
phone?: string;
/**
* The updated contact's email address.
*/
@IsOptional()
@IsEmail()
email?: string;
/**
* The updated contacts's groups' ids.
* You can provide either one groupId or an array of groupIDs.
*/
@IsOptional()
groups?: number[] | number
/**
* Get's all groups for this contact by their id's;
*/
public async getGroups(): Promise<RunnerGroup[]> {
if (!this.groups) { return null; }
let groups = new Array<RunnerGroup>();
if (!Array.isArray(this.groups)) {
this.groups = [this.groups]
}
for (let group of this.groups) {
let found = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: group });
if (!found) { throw new RunnerGroupNotFoundError(); }
groups.push(found);
}
return groups;
}
/**
* Updates a provided Donor entity based on this.
* @param contact the contact you want to update.
*/
public async update(contact: GroupContact): Promise<GroupContact> {
contact.firstname = this.firstname; GroupContact
contact.middlename = this.middlename;
contact.lastname = this.lastname;
contact.phone = this.phone;
contact.email = this.email;
if (!this.address) { contact.address.reset(); }
else { contact.address = this.address; }
Address.validate(contact.address);
contact.groups = await this.getGroups();
return contact;
}
}

View File

@ -1,54 +1,57 @@
import { IsInt, IsPositive } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
import { Runner } from '../../entities/Runner';
import { RunnerGroup } from '../../entities/RunnerGroup';
import { CreateParticipant } from '../create/CreateParticipant';
/**
* This class is used to update a Runner entity (via put request).
*/
export class UpdateRunner extends CreateParticipant {
/**
* The updated runner'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;
/**
* The updated runner's group's id.
*/
@IsInt()
@IsPositive()
group: number;
/**
* Updates a provided Runner entity based on this.
*/
public async update(runner: Runner): Promise<Runner> {
runner.firstname = this.firstname;
runner.middlename = this.middlename;
runner.lastname = this.lastname;
runner.phone = this.phone;
runner.email = this.email;
runner.group = await this.getGroup();
runner.address = await this.getAddress();
return runner;
}
/**
* Loads the updated runner's group based on it's id.
*/
public async getGroup(): Promise<RunnerGroup> {
if (this.group === undefined || this.group === null) {
throw new RunnerTeamNeedsParentError();
}
let group = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: this.group });
if (!group) { throw new RunnerGroupNotFoundError; }
return group;
}
import { IsInt, IsPositive } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors';
import { RunnerTeamNeedsParentError } from '../../../errors/RunnerTeamErrors';
import { Address } from '../../entities/Address';
import { Runner } from '../../entities/Runner';
import { RunnerGroup } from '../../entities/RunnerGroup';
import { CreateParticipant } from '../create/CreateParticipant';
/**
* This class is used to update a Runner entity (via put request).
*/
export class UpdateRunner extends CreateParticipant {
/**
* The updated runner'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;
/**
* The updated runner's group's id.
*/
@IsInt()
@IsPositive()
group: number;
/**
* Updates a provided Runner entity based on this.
*/
public async update(runner: Runner): Promise<Runner> {
runner.firstname = this.firstname;
runner.middlename = this.middlename;
runner.lastname = this.lastname;
runner.phone = this.phone;
runner.email = this.email;
runner.group = await this.getGroup();
if (!this.address) { runner.address.reset(); }
else { runner.address = this.address; }
Address.validate(runner.address);
return runner;
}
/**
* Loads the updated runner's group based on it's id.
*/
public async getGroup(): Promise<RunnerGroup> {
if (this.group === undefined || this.group === null) {
throw new RunnerTeamNeedsParentError();
}
let group = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: this.group });
if (!group) { throw new RunnerGroupNotFoundError; }
return group;
}
}

View File

@ -1,48 +1,38 @@
import { IsInt, IsOptional } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address';
import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
import { CreateRunnerGroup } from '../create/CreateRunnerGroup';
/**
* This class is used to update a RunnerOrganisation entity (via put request).
*/
export class UpdateRunnerOrganisation extends CreateRunnerGroup {
/**
* The updated orgs'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;
/**
* The updated organisation's address's id.
*/
@IsInt()
@IsOptional()
address?: number;
/**
* Loads the organisation's address based on it's id.
*/
public async getAddress(): Promise<Address> {
if (!this.address) { return null; }
let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
if (!address) { throw new AddressNotFoundError; }
return address;
}
/**
* Updates a provided RunnerOrganisation entity based on this.
*/
public async update(organisation: RunnerOrganisation): Promise<RunnerOrganisation> {
organisation.name = this.name;
organisation.contact = await this.getContact();
organisation.address = await this.getAddress();
return organisation;
}
import { IsInt, IsObject, IsOptional } from 'class-validator';
import { Address } from '../../entities/Address';
import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
import { CreateRunnerGroup } from '../create/CreateRunnerGroup';
/**
* This class is used to update a RunnerOrganisation entity (via put request).
*/
export class UpdateRunnerOrganisation extends CreateRunnerGroup {
/**
* The updated orgs'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;
/**
* The updated organisation's address.
*/
@IsOptional()
@IsObject()
address?: Address;
/**
* Updates a provided RunnerOrganisation entity based on this.
*/
public async update(organisation: RunnerOrganisation): Promise<RunnerOrganisation> {
organisation.name = this.name;
organisation.contact = await this.getContact();
if (!this.address) { organisation.address.reset(); }
else { organisation.address = this.address; }
Address.validate(organisation.address);
return organisation;
}
}

View File

@ -1,90 +1,86 @@
import {
IsInt,
IsNotEmpty,
IsOptional,
IsPostalCode,
IsString
} from "class-validator";
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { config } from '../../config';
import { IAddressUser } from './IAddressUser';
/**
* Defines the Address entity.
* Implemented this way to prevent any formatting differences.
*/
@Entity()
export class Address {
/**
* Autogenerated unique id (primary key).
*/
@PrimaryGeneratedColumn()
@IsInt()
id: number;
/**
* The address's description.
* Optional and mostly for UX.
*/
@Column({ nullable: true })
@IsString()
@IsOptional()
description?: string;
/**
* The address's first line.
* Containing the street and house number.
*/
@Column()
@IsString()
@IsNotEmpty()
address1: string;
/**
* The address's second line.
* Containing optional information.
*/
@Column({ nullable: true })
@IsString()
@IsOptional()
address2?: string;
/**
* The address's postal code.
* This will get checked against the postal code syntax for the configured country.
*/
@Column()
@IsString()
@IsNotEmpty()
@IsPostalCode(config.postalcode_validation_countrycode)
postalcode: string;
/**
* The address's city.
*/
@Column()
@IsString()
@IsNotEmpty()
city: string;
/**
* The address's country.
*/
@Column()
@IsString()
@IsNotEmpty()
country: string;
/**
* Used to link the address to participants.
*/
@OneToMany(() => IAddressUser, addressUser => addressUser.address, { nullable: true })
addressUsers: IAddressUser[];
/**
* Turns this entity into it's response class.
*/
public toResponse() {
return new Error("NotImplemented");
}
}
import {
IsPostalCode,
IsString
} from "class-validator";
import { Column } from "typeorm";
import ValidatorJS from 'validator';
import { config } from '../../config';
import { AddressCityEmptyError, AddressCountryEmptyError, AddressFirstLineEmptyError, AddressPostalCodeEmptyError, AddressPostalCodeInvalidError } from '../../errors/AddressErrors';
/**
* Defines the Address class.
* Implemented this way to prevent any formatting differences.
*/
export class Address {
/**
* The address's first line.
* Containing the street and house number.
*/
@Column({ nullable: true })
@IsString()
address1?: string;
/**
* The address's second line.
* Containing optional information.
*/
@Column({ nullable: true })
@IsString()
address2?: string;
/**
* The address's postal code.
* This will get checked against the postal code syntax for the configured country.
*/
@Column({ nullable: true })
@IsString()
@IsPostalCode(config.postalcode_validation_countrycode)
postalcode: string;
/**
* The address's city.
*/
@Column({ nullable: true })
@IsString()
city: string;
/**
* The address's country.
*/
@Column({ nullable: true })
@IsString()
country: string;
public reset() {
this.address1 = null;
this.address2 = null;
this.city = null;
this.country = null;
this.postalcode = null;
}
/**
* Checks if this is a valid address
*/
public static isValidAddress(address: Address): Boolean {
if (address == null) { return false; }
if (address.address1 == null || address.city == null || address.country == null || address.postalcode == null) { return false; }
if (ValidatorJS.isPostalCode(address.postalcode, config.postalcode_validation_countrycode) == false) { return false; }
return true;
}
/**
* This function validates addresses.
* This is a workaround for non-existant class validation for embedded entities.
* @param address The address that shall get validated.
*/
public static validate(address: Address) {
if (address == null) { return; }
if (address.address1 == null && address.city == null && address.country == null && address.postalcode == null) { return; }
if (address.address1 == null) { throw new AddressFirstLineEmptyError(); }
if (address.postalcode == null) { throw new AddressPostalCodeEmptyError(); }
if (address.city == null) { throw new AddressCityEmptyError(); }
if (address.country == null) { throw new AddressCountryEmptyError(); }
if (ValidatorJS.isPostalCode(address.postalcode.toString(), config.postalcode_validation_countrycode) == false) { throw new AddressPostalCodeInvalidError(); }
}
}

View File

@ -7,10 +7,10 @@ import {
IsString
} from "class-validator";
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { config } from '../../config';
import { ResponseGroupContact } from '../responses/ResponseGroupContact';
import { Address } from "./Address";
import { IAddressUser } from './IAddressUser';
import { RunnerGroup } from "./RunnerGroup";
/**
@ -18,7 +18,7 @@ import { RunnerGroup } from "./RunnerGroup";
* Mainly it's own class to reduce duplicate code and enable contact's to be associated with multiple groups.
*/
@Entity()
export class GroupContact implements IAddressUser {
export class GroupContact {
/**
* Autogenerated unique id (primary key).
*/
@ -54,8 +54,7 @@ export class GroupContact implements IAddressUser {
* The contact's address.
* This is a address object to prevent any formatting differences.
*/
@IsOptional()
@ManyToOne(() => Address, address => address.addressUsers, { nullable: true })
@Column(type => Address)
address?: Address;
/**
@ -85,7 +84,7 @@ export class GroupContact implements IAddressUser {
/**
* Turns this entity into it's response class.
*/
public toResponse() {
return new Error("NotImplemented");
public toResponse(): ResponseGroupContact {
return new ResponseGroupContact(this);
}
}

View File

@ -1,20 +0,0 @@
import { Entity, ManyToOne, PrimaryColumn } from 'typeorm';
import { Address } from './Address';
/**
* The interface(tm) all entities using addresses have to implement.
* This is a abstract class, because apparently typeorm can't really work with interfaces :/
*/
@Entity()
export abstract class IAddressUser {
@PrimaryColumn()
id: number;
@ManyToOne(() => Address, address => address.addressUsers, { nullable: true })
address?: Address
/**
* Turns this entity into it's response class.
*/
public abstract toResponse();
}

View File

@ -7,11 +7,10 @@ import {
IsString
} from "class-validator";
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm";
import { Column, Entity, PrimaryGeneratedColumn, TableInheritance } from "typeorm";
import { config } from '../../config';
import { ResponseParticipant } from '../responses/ResponseParticipant';
import { Address } from "./Address";
import { IAddressUser } from './IAddressUser';
/**
* Defines the Participant entity.
@ -19,7 +18,7 @@ import { IAddressUser } from './IAddressUser';
*/
@Entity()
@TableInheritance({ column: { name: "type", type: "varchar" } })
export abstract class Participant implements IAddressUser {
export abstract class Participant {
/**
* Autogenerated unique id (primary key).
*/
@ -55,7 +54,7 @@ export abstract class Participant implements IAddressUser {
* The participant's address.
* This is a address object to prevent any formatting differences.
*/
@ManyToOne(() => Address, address => address.addressUsers, { nullable: true })
@Column(type => Address)
address?: Address;
/**

View File

@ -1,65 +1,64 @@
import { IsInt, IsOptional } from "class-validator";
import { ChildEntity, ManyToOne, OneToMany } from "typeorm";
import { ResponseRunnerOrganisation } from '../responses/ResponseRunnerOrganisation';
import { Address } from './Address';
import { IAddressUser } from './IAddressUser';
import { Runner } from './Runner';
import { RunnerGroup } from "./RunnerGroup";
import { RunnerTeam } from "./RunnerTeam";
/**
* Defines the RunnerOrganisation entity.
* This usually is a school, club or company.
*/
@ChildEntity()
export class RunnerOrganisation extends RunnerGroup implements IAddressUser {
/**
* The organisations's address.
*/
@IsOptional()
@ManyToOne(() => Address, address => address.addressUsers, { nullable: true })
address?: Address;
/**
* The organisation's teams.
* Used to link teams to a organisation.
*/
@OneToMany(() => RunnerTeam, team => team.parentGroup, { nullable: true })
teams: RunnerTeam[];
/**
* Returns all runners associated with this organisation (directly or indirectly via teams).
*/
public get allRunners(): Runner[] {
let returnRunners: Runner[] = new Array<Runner>();
returnRunners.push(...this.runners);
for (let team of this.teams) {
returnRunners.push(...team.runners)
}
return returnRunners;
}
/**
* Returns the total distance ran by this group's runners based on all their valid scans.
*/
@IsInt()
public get distance(): number {
return this.allRunners.reduce((sum, current) => sum + current.distance, 0);
}
/**
* Returns the total donations a runner has collected based on his linked donations and distance ran.
*/
@IsInt()
public get distanceDonationAmount(): number {
return this.allRunners.reduce((sum, current) => sum + current.distanceDonationAmount, 0);
}
/**
* Turns this entity into it's response class.
*/
public toResponse(): ResponseRunnerOrganisation {
return new ResponseRunnerOrganisation(this);
}
import { IsInt, IsOptional } from "class-validator";
import { ChildEntity, Column, OneToMany } from "typeorm";
import { ResponseRunnerOrganisation } from '../responses/ResponseRunnerOrganisation';
import { Address } from './Address';
import { Runner } from './Runner';
import { RunnerGroup } from "./RunnerGroup";
import { RunnerTeam } from "./RunnerTeam";
/**
* Defines the RunnerOrganisation entity.
* This usually is a school, club or company.
*/
@ChildEntity()
export class RunnerOrganisation extends RunnerGroup {
/**
* The organisations's address.
*/
@IsOptional()
@Column(type => Address)
address?: Address;
/**
* The organisation's teams.
* Used to link teams to a organisation.
*/
@OneToMany(() => RunnerTeam, team => team.parentGroup, { nullable: true })
teams: RunnerTeam[];
/**
* Returns all runners associated with this organisation (directly or indirectly via teams).
*/
public get allRunners(): Runner[] {
let returnRunners: Runner[] = new Array<Runner>();
returnRunners.push(...this.runners);
for (let team of this.teams) {
returnRunners.push(...team.runners)
}
return returnRunners;
}
/**
* Returns the total distance ran by this group's runners based on all their valid scans.
*/
@IsInt()
public get distance(): number {
return this.allRunners.reduce((sum, current) => sum + current.distance, 0);
}
/**
* Returns the total donations a runner has collected based on his linked donations and distance ran.
*/
@IsInt()
public get distanceDonationAmount(): number {
return this.allRunners.reduce((sum, current) => sum + current.distanceDonationAmount, 0);
}
/**
* Turns this entity into it's response class.
*/
public toResponse(): ResponseRunnerOrganisation {
return new ResponseRunnerOrganisation(this);
}
}

View File

@ -14,5 +14,6 @@ export enum PermissionTarget {
SCAN = 'SCAN',
STATION = 'STATION',
CARD = 'CARD',
DONATION = 'DONATION'
DONATION = 'DONATION',
CONTACT = 'CONTACT'
}

View File

@ -0,0 +1,76 @@
import { IsInt, IsObject, IsString } from "class-validator";
import { Address } from '../entities/Address';
import { GroupContact } from '../entities/GroupContact';
import { ResponseRunnerGroup } from './ResponseRunnerGroup';
/**
* Defines the group contact response.
*/
export class ResponseGroupContact {
/**
* The contact's id.
*/
@IsInt()
id: number;
/**
* The contact's first name.
*/
@IsString()
firstname: string;
/**
* The contact's middle name.
*/
@IsString()
middlename?: string;
/**
* The contact's last name.
*/
@IsString()
lastname: string;
/**
* The contact's phone number.
*/
@IsString()
phone?: string;
/**
* The contact's e-mail address.
*/
@IsString()
email?: string;
/**
* The contact's associated runner groups.
*/
@IsObject()
groups: ResponseRunnerGroup[];
/**
* The contact's address.
* This is a address object to prevent any formatting differences.
*/
@IsObject()
address?: Address;
/**
* Creates a ResponseGroupContact object from a contact.
* @param contact The contact the response shall be build for.
*/
public constructor(contact: GroupContact) {
this.id = contact.id;
this.firstname = contact.firstname;
this.middlename = contact.middlename;
this.lastname = contact.lastname;
this.phone = contact.phone;
this.email = contact.email;
this.address = contact.address;
this.groups = new Array<ResponseRunnerGroup>();
for (let group of contact.groups) {
this.groups.push(group.toResponse());
}
}
}

View File

@ -1,56 +1,65 @@
import { IsInt, IsString } from "class-validator";
import { Participant } from '../entities/Participant';
/**
* Defines the participant response.
*/
export abstract class ResponseParticipant {
/**
* The participant's id.
*/
@IsInt()
id: number;
/**
* The participant's first name.
*/
@IsString()
firstname: string;
/**
* The participant's middle name.
*/
@IsString()
middlename?: string;
/**
* The participant's last name.
*/
@IsString()
lastname: string;
/**
* The participant's phone number.
*/
@IsString()
phone?: string;
/**
* The participant's e-mail address.
*/
@IsString()
email?: string;
/**
* Creates a ResponseParticipant object from a participant.
* @param participant The participant the response shall be build for.
*/
public constructor(participant: Participant) {
this.id = participant.id;
this.firstname = participant.firstname;
this.middlename = participant.middlename;
this.lastname = participant.lastname;
this.phone = participant.phone;
this.email = participant.email;
}
}
import { IsInt, IsObject, IsOptional, IsString } from "class-validator";
import { Address } from '../entities/Address';
import { Participant } from '../entities/Participant';
/**
* Defines the participant response.
*/
export abstract class ResponseParticipant {
/**
* The participant's id.
*/
@IsInt()
id: number;
/**
* The participant's first name.
*/
@IsString()
firstname: string;
/**
* The participant's middle name.
*/
@IsString()
middlename?: string;
/**
* The participant's last name.
*/
@IsString()
lastname: string;
/**
* The participant's phone number.
*/
@IsString()
phone?: string;
/**
* The participant's e-mail address.
*/
@IsString()
email?: string;
/**
* The participant's address.
*/
@IsOptional()
@IsObject()
address?: Address;
/**
* Creates a ResponseParticipant object from a participant.
* @param participant The participant the response shall be build for.
*/
public constructor(participant: Participant) {
this.id = participant.id;
this.firstname = participant.firstname;
this.middlename = participant.middlename;
this.lastname = participant.lastname;
this.phone = participant.phone;
this.email = participant.email;
this.address = participant.address;
}
}

View File

@ -0,0 +1,216 @@
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/contacts with errors', () => {
it('creating a new contact without any parameters should return 400', async () => {
const res = await axios.post(base + '/api/contacts', null, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact without a last name should return 400', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"middlename": "middle"
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a invalid phone number should return 400', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"phone": "123"
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a invalid mail address should return 400', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "string",
"middlename": "string",
"lastname": "string",
"phone": null,
"email": "123",
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with an invalid address 400', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "string",
"middlename": "string",
"lastname": "string",
"address": {
"city": "Testcity"
}
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a invalid group should return 404', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "string",
"middlename": "string",
"lastname": "string",
"groups": 9999999999999
}, axios_config);
expect(res.status).toEqual(404);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('POST /api/contacts working (simple)', () => {
it('creating a new contact with only needed params should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last"
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with all non-relationship optional params should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"email": "testContact@lauf-fuer-kaya.de",
"phone": "+49017612345678",
"address": {
"address1": "test",
"address2": null,
"city": "herzogenaurach",
"country": "germany",
"postalcode": "91074",
}
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('POST /api/contacts working (with group)', () => {
let added_org;
let added_team;
let added_contact;
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
delete res.data.contact;
delete res.data.teams;
added_org = res.data
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new team with a parent org should return 200', async () => {
const res = await axios.post(base + '/api/teams', {
"name": "test_team",
"parentGroup": added_org.id
}, axios_config);
delete res.data.contact;
delete res.data.parentGroup;
added_team = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a valid org should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": added_org.id
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
delete res.data.id;
expect(res.data).toEqual({
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": [added_org]
});
});
it('creating a new contact with a valid team should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": added_team.id
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
delete res.data.id;
expect(res.data).toEqual({
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": [added_team]
});
});
it('creating a new contact with a valid org and team should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": [added_org.id, added_team.id]
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
added_contact = res.data
delete res.data.id;
expect(res.data).toEqual({
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": [added_org, added_team]
});
});
it('checking if the added team\'s contact is the new contact should return 200', async () => {
const res = await axios.get(base + '/api/teams/' + added_team.id, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
delete res.data.contact.groups;
delete res.data.contact.id;
delete added_contact.groups;
expect(res.data.contact).toEqual(added_contact);
});
});

View File

@ -0,0 +1,183 @@
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 + deletion (non-existant)', () => {
it('delete', async () => {
const res = await axios.delete(base + '/api/contacts/0', axios_config);
expect(res.status).toEqual(204);
});
});
// ---------------
describe('add+delete (simple)', () => {
let added_contact;
it('creating a new contact with only needed params should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_contact = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('delete contact', async () => {
const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
let deleted_contact = res.data
expect(deleted_contact).toEqual(added_contact);
});
it('check if contact really was deleted', async () => {
const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(404);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('add+delete (with org)', () => {
let added_org;
let added_contact;
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
delete res.data.contact;
delete res.data.teams;
added_org = res.data
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a valid org should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": added_org.id
}, axios_config);
added_contact = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
});
it('delete contact', async () => {
const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
delete res.data.groups[0].contact;
expect(res.data).toEqual(added_contact);
});
it('check if contact really was deleted', async () => {
const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(404);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('add+delete (with team)', () => {
let added_org;
let added_team;
let added_contact;
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
delete res.data.contact;
delete res.data.teams;
added_org = res.data
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new team with a parent org should return 200', async () => {
const res = await axios.post(base + '/api/teams', {
"name": "test_team",
"parentGroup": added_org.id
}, axios_config);
delete res.data.contact;
delete res.data.parentGroup;
added_team = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a valid team should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": added_team.id
}, axios_config);
added_contact = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
});
it('delete contact', async () => {
const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
delete res.data.groups[0].contact;
expect(res.data).toEqual(added_contact);
});
it('check if contact really was deleted', async () => {
const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(404);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('add+delete (with org&team)', () => {
let added_org;
let added_team;
let added_contact;
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
delete res.data.contact;
delete res.data.teams;
added_org = res.data
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new team with a parent org should return 200', async () => {
const res = await axios.post(base + '/api/teams', {
"name": "test_team",
"parentGroup": added_org.id
}, axios_config);
delete res.data.contact;
delete res.data.parentGroup;
added_team = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a valid org and team should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": [added_org.id, added_team.id]
}, axios_config);
added_contact = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
});
it('delete contact', async () => {
const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
delete res.data.groups[0].contact;
delete res.data.groups[1].contact;
expect(res.data).toEqual(added_contact);
});
it('check if contact really was deleted', async () => {
const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(404);
expect(res.headers['content-type']).toContain("application/json")
});
});

View File

@ -0,0 +1,57 @@
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/contacts', () => {
it('basic get should return 200', async () => {
const res = await axios.get(base + '/api/contacts', axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('GET /api/contacts/0', () => {
it('basic get should return 404', async () => {
const res = await axios.get(base + '/api/contacts/0', axios_config);
expect(res.status).toEqual(404);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('GET /api/contacts after adding', () => {
let added_contact;
it('creating a new donor with only needed params should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_contact = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('explicit get should return 200', async () => {
const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
let gotten_donor = res.data
expect(gotten_donor).toEqual(added_contact);
});
it('get from all runners should return 200', async () => {
const res = await axios.get(base + '/api/contacts/', axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
let gotten_donors = res.data
expect(gotten_donors).toContainEqual(added_contact);
});
});

View File

@ -0,0 +1,237 @@
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('Update contact name after adding', () => {
let added_contact;
it('creating a new contact with only needed params should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_contact = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('valid update should return 200', async () => {
let contact_copy = added_contact
contact_copy.firstname = "second"
const res = await axios.put(base + '/api/contacts/' + added_contact.id, contact_copy, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
expect(res.data).toEqual(contact_copy);
});
});
// ---------------
describe('Update contact id after adding(should fail)', () => {
let added_contact;
it('creating a new donor with only needed params should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_contact = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('invalid update should return 406', async () => {
added_contact.id++;
const res = await axios.put(base + '/api/contacts/' + (added_contact.id - 1), added_contact, axios_config);
expect(res.status).toEqual(406);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('Update contact group after adding (should work)', () => {
let added_org;
let added_team;
let added_contact;
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
delete res.data.contact;
delete res.data.teams;
added_org = res.data
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new team with a parent org should return 200', async () => {
const res = await axios.post(base + '/api/teams', {
"name": "test_team",
"parentGroup": added_org.id
}, axios_config);
delete res.data.contact;
delete res.data.parentGroup;
added_team = res.data;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a valid org should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": added_org.id
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
added_contact = res.data
expect(res.data).toEqual({
"id": res.data.id,
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": [added_org]
});
});
it('valid group update to single team should return 200', async () => {
const res = await axios.put(base + '/api/contacts/' + added_contact.id, {
"id": added_contact.id,
"firstname": "first",
"lastname": "last",
"groups": added_team.id
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": res.data.id,
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": [added_team]
});
});
it('valid group update to org and team should return 200', async () => {
const res = await axios.put(base + '/api/contacts/' + added_contact.id, {
"id": added_contact.id,
"firstname": "first",
"lastname": "last",
"groups": [added_org.id, added_team.id]
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": res.data.id,
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": [added_org, added_team]
});
});
it('valid group update to none should return 200', async () => {
const res = await axios.put(base + '/api/contacts/' + added_contact.id, {
"id": added_contact.id,
"firstname": "first",
"lastname": "last",
"groups": null
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": res.data.id,
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": []
});
});
});
// ---------------
describe('Update contact group invalid after adding (should fail)', () => {
let added_org;
let added_contact;
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
delete res.data.contact;
delete res.data.teams;
added_org = res.data
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new contact with a valid org should return 200', async () => {
const res = await axios.post(base + '/api/contacts', {
"firstname": "first",
"lastname": "last",
"groups": added_org.id
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
added_contact = res.data
expect(res.data).toEqual({
"id": res.data.id,
"firstname": "first",
"middlename": null,
"lastname": "last",
"phone": null,
"email": null,
"address": {
"address1": null,
"address2": null,
"postalcode": null,
"city": null,
"country": null
},
"groups": [added_org]
});
});
it('invalid group update to single team should return 404', async () => {
const res = await axios.put(base + '/api/contacts/' + added_contact.id, {
"id": added_contact.id,
"firstname": "first",
"lastname": "last",
"groups": 999999999999999
}, axios_config);
expect(res.status).toEqual(404);
expect(res.headers['content-type']).toContain("application/json");
});
});

View File

@ -1,94 +1,84 @@
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/donors with errors', () => {
it('creating a new donor without any parameters should return 400', async () => {
const res1 = await axios.post(base + '/api/donors', null, axios_config);
expect(res1.status).toEqual(400);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new donor without a last name should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle"
}, axios_config);
expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with a invalid address should return 404', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"address": 99999999999999999999999999
}, axios_config);
expect(res2.status).toEqual(404);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with a invalid phone number should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"phone": "123"
}, axios_config);
expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with a invalid mail address should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "string",
"middlename": "string",
"lastname": "string",
"phone": null,
"email": "123",
}, axios_config);
expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor without an address but with receiptNeeded=true 406', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "string",
"middlename": "string",
"lastname": "string",
"receiptNeeded": true
}, axios_config);
expect(res2.status).toEqual(406);
expect(res2.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('POST /api/donors working', () => {
it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "last"
}, axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with all non-relationship optional params should return 200', async () => {
const res3 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"receiptNeeded": false
}, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
});
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/donors with errors', () => {
it('creating a new donor without any parameters should return 400', async () => {
const res1 = await axios.post(base + '/api/donors', null, axios_config);
expect(res1.status).toEqual(400);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new donor without a last name should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle"
}, axios_config);
expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with a invalid phone number should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"phone": "123"
}, axios_config);
expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with a invalid mail address should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "string",
"middlename": "string",
"lastname": "string",
"phone": null,
"email": "123",
}, axios_config);
expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor without an address but with receiptNeeded=true 406', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "string",
"middlename": "string",
"lastname": "string",
"receiptNeeded": true
}, axios_config);
expect(res2.status).toEqual(406);
expect(res2.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('POST /api/donors working', () => {
it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "last"
}, axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with all non-relationship optional params should return 200', async () => {
const res3 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"receiptNeeded": false
}, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
});
});

View File

@ -1,75 +1,75 @@
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('Update donor name after adding', () => {
let added_donor;
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_donor = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('valid update should return 200', async () => {
let donor_copy = added_donor
donor_copy.firstname = "second"
const res3 = await axios.put(base + '/api/donors/' + added_donor.id, donor_copy, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
let updated_donor = res3.data
expect(updated_donor).toEqual(donor_copy);
});
});
// ---------------
describe('Update donor id after adding(should fail)', () => {
let added_donor;
it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_donor = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid update should return 406', async () => {
added_donor.id++;
const res3 = await axios.put(base + '/api/donors/' + (added_donor.id - 1), added_donor, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('Update donor without address but receiptNeeded=true should fail', () => {
let added_donor;
it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "last",
}, axios_config);
added_donor = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid update should return 406', async () => {
added_donor.receiptNeeded = true;
const res3 = await axios.put(base + '/api/donors/' + added_donor.id, added_donor, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
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('Update donor name after adding', () => {
let added_donor;
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_donor = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('valid update should return 200', async () => {
let donor_copy = added_donor
donor_copy.firstname = "second"
const res3 = await axios.put(base + '/api/donors/' + added_donor.id, donor_copy, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
let updated_donor = res3.data
expect(updated_donor).toEqual(donor_copy);
});
});
// ---------------
describe('Update donor id after adding(should fail)', () => {
let added_donor;
it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "last"
}, axios_config);
added_donor = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid update should return 406', async () => {
added_donor.id++;
const res3 = await axios.put(base + '/api/donors/' + (added_donor.id - 1), added_donor, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('Update donor without address but receiptNeeded=true should fail', () => {
let added_donor;
it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"lastname": "testtest",
}, axios_config);
added_donor = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid update should return 406', async () => {
added_donor.receiptNeeded = true;
const res3 = await axios.put(base + '/api/donors/' + added_donor.id, added_donor, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
});

View File

@ -1,90 +1,102 @@
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/organisations', () => {
it('basic get should return 200', async () => {
const res = await axios.get(base + '/api/organisations', axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('POST /api/organisations', () => {
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new org with without a name should return 400', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": null
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('adding + getting from all orgs', () => {
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('check if org was added', async () => {
const res = await axios.get(base + '/api/organisations', axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
let added_org = res.data[res.data.length - 1]
delete added_org.id
expect(added_org).toEqual({
"name": "test123",
"contact": null,
"address": null,
"teams": []
})
});
});
// ---------------
describe('adding + getting explicitly', () => {
let added_org_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
let added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('check if org was added', async () => {
const res2 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data
added_org_id = added_org2.id;
delete added_org2.id
expect(added_org2).toEqual({
"name": "test123",
"contact": null,
"address": null,
"teams": []
})
});
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/organisations', () => {
it('basic get should return 200', async () => {
const res = await axios.get(base + '/api/organisations', axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('POST /api/organisations', () => {
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('creating a new org with without a name should return 400', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": null
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('adding + getting from all orgs', () => {
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('check if org was added', async () => {
const res = await axios.get(base + '/api/organisations', axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
let added_org = res.data[res.data.length - 1]
delete added_org.id
expect(added_org).toEqual({
"name": "test123",
"contact": null,
"address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": []
})
});
});
// ---------------
describe('adding + getting explicitly', () => {
let added_org_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
let added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('check if org was added', async () => {
const res2 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data
added_org_id = added_org2.id;
delete added_org2.id
expect(added_org2).toEqual({
"name": "test123",
"contact": null,
"address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": []
})
});
});

View File

@ -1,132 +1,144 @@
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 + deletion (non-existant)', () => {
it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/0', axios_config);
expect(res2.status).toEqual(204);
});
});
// ---------------
describe('adding + deletion (successfull)', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id, axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data
added_org_id = added_org2.id;
delete added_org2.id
expect(added_org2).toEqual({
"name": "test123",
"contact": null,
"address": null,
"teams": []
});
});
it('check if org really was deleted', async () => {
const res3 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
expect(res3.status).toEqual(404);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('adding + deletion with teams still existing (without force)', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('delete org - this should fail with a 406', async () => {
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id, axios_config);
expect(res2.status).toEqual(406);
expect(res2.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('adding + deletion with teams still existing (with force)', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id + '?force=true', axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data
added_org_id = added_org2.id;
delete added_org2.id;
delete added_org2.teams;
expect(added_org2).toEqual({
"name": "test123",
"contact": null,
"address": null
});
});
it('check if org really was deleted', async () => {
const res3 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
expect(res3.status).toEqual(404);
expect(res3.headers['content-type']).toContain("application/json")
});
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 + deletion (non-existant)', () => {
it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/0', axios_config);
expect(res2.status).toEqual(204);
});
});
// ---------------
describe('adding + deletion (successfull)', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id, axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data
added_org_id = added_org2.id;
delete added_org2.id
expect(added_org2).toEqual({
"name": "test123",
"contact": null,
"address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": []
});
});
it('check if org really was deleted', async () => {
const res3 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
expect(res3.status).toEqual(404);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('adding + deletion with teams still existing (without force)', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('delete org - this should fail with a 406', async () => {
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id, axios_config);
expect(res2.status).toEqual(406);
expect(res2.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('adding + deletion with teams still existing (with force)', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id + '?force=true', axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data
added_org_id = added_org2.id;
delete added_org2.id;
delete added_org2.teams;
expect(added_org2).toEqual({
"name": "test123",
"contact": null,
"address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
});
});
it('check if org really was deleted', async () => {
const res3 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
expect(res3.status).toEqual(404);
expect(res3.headers['content-type']).toContain("application/json")
});
});

View File

@ -1,73 +1,383 @@
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 name', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('update org', async () => {
const res2 = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": null,
}, axios_config);
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data
added_org_id = added_org2.id;
delete added_org2.id
expect(added_org2).toEqual({
"name": "testlelele",
"contact": null,
"address": null,
"teams": []
})
});
});
// ---------------
describe('adding + try updating id (should return 406)', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('update org', async () => {
const res2 = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id + 1,
"name": "testlelele",
"contact": null,
"address": null,
}, axios_config);
expect(res2.status).toEqual(406);
expect(res2.headers['content-type']).toContain("application/json")
});
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 name', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res.data
added_org_id = added_org.id;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('update org', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": null,
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
let added_org2 = res.data
added_org_id = added_org2.id;
delete added_org2.id
expect(added_org2).toEqual({
"name": "testlelele",
"contact": null,
"address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": []
})
});
});
// ---------------
describe('adding + try updating id (should return 406)', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res.data
added_org_id = added_org.id;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('update org', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id + 1,
"name": "testlelele",
"contact": null,
"address": null,
}, axios_config);
expect(res.status).toEqual(406);
expect(res.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('adding + updateing address valid)', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res.data
added_org_id = added_org.id;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('adding address to org should return 200', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test1",
"address2": null,
"city": "Herzogenaurach",
"country": "Burkina Faso",
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test1",
"address2": null,
"city": "Herzogenaurach",
"country": "Burkina Faso",
"postalcode": "90174"
},
"teams": []
});
});
it('updateing address\'s first line should return 200', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": null,
"city": "TestCity",
"country": "Burkina Faso",
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": null,
"city": "TestCity",
"country": "Burkina Faso",
"postalcode": "90174"
},
"teams": []
});
});
it('updateing address\'s second line should return 200', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "TestCity",
"country": "Burkina Faso",
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "TestCity",
"country": "Burkina Faso",
"postalcode": "90174"
},
"teams": []
});
});
it('updateing address\'s city should return 200', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "Kaya",
"country": "Burkina Faso",
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "Kaya",
"country": "Burkina Faso",
"postalcode": "90174"
},
"teams": []
});
});
it('updateing address\'s country should return 200', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "Kaya",
"country": "Germany",
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "Kaya",
"country": "Germany",
"postalcode": "90174"
},
"teams": []
});
});
it('updateing address\'s postal code should return 200', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "Kaya",
"country": "Germany",
"postalcode": "91065"
}
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test2",
"address2": "Test3",
"city": "Kaya",
"country": "Germany",
"postalcode": "91065"
},
"teams": []
});
});
it('removing org\'s should return 200', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null
}, axios_config);
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json");
expect(res.data).toEqual({
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null
},
"teams": []
});
});
});
// ---------------
describe('adding + updateing address invalid)', () => {
let added_org_id
let added_org
it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res.data
added_org_id = added_org.id;
expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json")
});
it('adding address to org w/o address1 should return 400', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": null,
"address2": null,
"city": "TestCity",
"country": "Burkina Faso",
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json");
});
it('adding address to org w/o city should return 400', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test1",
"address2": null,
"city": null,
"country": "Burkina Faso",
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json");
});
it('adding address to org w/o country should return 400', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test1",
"address2": null,
"city": "TestCity",
"country": null,
"postalcode": "90174"
}
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json");
});
it('adding address to org w/o postal code should return 400', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test1",
"address2": null,
"city": "TestCity",
"country": "Burkina Faso",
"postalcode": null
}
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json");
});
it('adding address to org w/ invalid postal code should return 400', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id,
"name": "testlelele",
"contact": null,
"address": {
"address1": "Test1",
"address2": null,
"city": "TestCity",
"country": "Burkina Faso",
"postalcode": "-1"
}
}, axios_config);
expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json");
});
});

View File

@ -1,131 +1,130 @@
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 name', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('update name', async () => {
const res3 = await axios.put(base + '/api/teams/' + added_team_id, {
"id": added_team_id,
"name": "testlelele",
"contact": null,
"parentGroup": added_org.id
}, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
let updated_team = res3.data;
added_team.name = "testlelele";
expect(updated_team).toEqual(added_team)
});
});
// ---------------
describe('adding + try updating id (should return 406)', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('update team', async () => {
added_team.id = added_team.id + 1;
added_team.parentGroup = added_team.parentGroup.id;
const res3 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('add+update parent org (valid)', () => {
let added_org;
let added_org2;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org.id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new org with just a name should return 200', async () => {
const res3 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org2 = res3.data;
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
});
it('update team', async () => {
added_team.parentGroup = added_org2.id;
const res4 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config);
let updated_team = res4.data;
expect(res4.status).toEqual(200);
expect(res4.headers['content-type']).toContain("application/json")
delete added_org2.address;
delete added_org2.contact;
delete added_org2.teams;
expect(updated_team.parentGroup).toEqual(added_org2)
});
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 name', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('update name', async () => {
const res3 = await axios.put(base + '/api/teams/' + added_team_id, {
"id": added_team_id,
"name": "testlelele",
"contact": null,
"parentGroup": added_org.id
}, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
let updated_team = res3.data;
added_team.name = "testlelele";
expect(updated_team).toEqual(added_team)
});
});
// ---------------
describe('adding + try updating id (should return 406)', () => {
let added_org;
let added_org_id;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org_id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('update team', async () => {
added_team.id = added_team.id + 1;
added_team.parentGroup = added_team.parentGroup.id;
const res3 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('add+update parent org (valid)', () => {
let added_org;
let added_org2;
let added_team;
let added_team_id
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', {
"name": "test123",
"parentGroup": added_org.id
}, axios_config);
added_team = res2.data;
added_team_id = added_team.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new org with just a name should return 200', async () => {
const res3 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org2 = res3.data;
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
});
it('update team', async () => {
added_team.parentGroup = added_org2.id;
const res4 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config);
let updated_team = res4.data;
expect(res4.status).toEqual(200);
expect(res4.headers['content-type']).toContain("application/json")
delete added_org2.contact;
delete added_org2.teams;
expect(updated_team.parentGroup).toEqual(added_org2)
});
});

View File

@ -1,160 +1,156 @@
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('Update runner name after adding', () => {
let added_org;
let added_runner;
let updated_runner;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org.id
}, axios_config);
added_runner = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('valid update should return 200', async () => {
let runnercopy = added_runner
runnercopy.firstname = "second"
runnercopy.group = added_runner.group.id;
const res3 = await axios.put(base + '/api/runners/' + added_runner.id, runnercopy, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
updated_runner = res3.data;
delete added_org.address;
delete added_org.contact;
delete added_org.teams;
runnercopy.group = added_org;
expect(updated_runner).toEqual(runnercopy);
});
});
// ---------------
describe('Update runner group after adding', () => {
let added_org_id;
let added_org_2;
let added_runner;
let updated_runner;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
let added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org_id
}, axios_config);
added_runner = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new org with just a name should return 200', async () => {
const res3 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org_2 = res3.data
delete added_org_2.address;
delete added_org_2.contact;
delete added_org_2.teams;
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
});
it('valid group update should return 200', async () => {
added_runner.group = added_org_2.id;
const res3 = await axios.put(base + '/api/runners/' + added_runner.id, added_runner, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
updated_runner = res3.data
expect(updated_runner.group).toEqual(added_org_2);
});
});
// ---------------
describe('Update runner id after adding(should fail)', () => {
let added_org_id;
let added_runner;
let added_runner_id;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
let added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org_id
}, axios_config);
added_runner = res2.data;
added_runner_id = added_runner.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid update should return 406', async () => {
added_runner.id++;
added_runner.group = added_runner.group.id;
const res3 = await axios.put(base + '/api/runners/' + added_runner_id, added_runner, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('Update runner group with invalid group after adding', () => {
let added_org;
let added_runner;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org.id
}, axios_config);
added_runner = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid group update should return 404', async () => {
added_runner.group = 99999999999999999;
const res3 = await axios.put(base + '/api/runners/' + added_runner.id, added_runner, axios_config);
expect(res3.status).toEqual(404);
expect(res3.headers['content-type']).toContain("application/json")
});
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('Update runner name after adding', () => {
let added_org;
let added_runner;
let updated_runner;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org.id
}, axios_config);
added_runner = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('valid update should return 200', async () => {
let runnercopy = added_runner
runnercopy.firstname = "second"
runnercopy.group = added_runner.group.id;
const res3 = await axios.put(base + '/api/runners/' + added_runner.id, runnercopy, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
updated_runner = res3.data;
delete added_org.contact;
delete added_org.teams;
runnercopy.group = added_org;
expect(updated_runner).toEqual(runnercopy);
});
});
// ---------------
describe('Update runner group after adding', () => {
let added_org_id;
let added_org_2;
let added_runner;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
let added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org_id
}, axios_config);
added_runner = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new org with just a name should return 200', async () => {
const res3 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org_2 = res3.data
delete added_org_2.contact;
delete added_org_2.teams;
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
});
it('valid group update should return 200', async () => {
added_runner.group = added_org_2.id;
const res3 = await axios.put(base + '/api/runners/' + added_runner.id, added_runner, axios_config);
expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json")
expect(res3.data.group).toEqual(added_org_2);
});
});
// ---------------
describe('Update runner id after adding(should fail)', () => {
let added_org_id;
let added_runner;
let added_runner_id;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
let added_org = res1.data
added_org_id = added_org.id;
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org_id
}, axios_config);
added_runner = res2.data;
added_runner_id = added_runner.id;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid update should return 406', async () => {
added_runner.id++;
added_runner.group = added_runner.group.id;
const res3 = await axios.put(base + '/api/runners/' + added_runner_id, added_runner, axios_config);
expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json")
});
});
// ---------------
describe('Update runner group with invalid group after adding', () => {
let added_org;
let added_runner;
it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', {
"name": "test123"
}, axios_config);
added_org = res1.data
expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json")
});
it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/runners', {
"firstname": "first",
"lastname": "last",
"group": added_org.id
}, axios_config);
added_runner = res2.data;
expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json")
});
it('invalid group update should return 404', async () => {
added_runner.group = 99999999999999999;
const res3 = await axios.put(base + '/api/runners/' + added_runner.id, added_runner, axios_config);
expect(res3.status).toEqual(404);
expect(res3.headers['content-type']).toContain("application/json")
});
});