Compare commits

..

No commits in common. "5e368552ea810ea1d3963b1207ba98f7b46c4abc" and "f53894b16ac1c06ecbeeb0b63a56ac438b2fbe1b" have entirely different histories.

25 changed files with 1497 additions and 1734 deletions

View File

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

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).' }) @OpenAPI({ description: 'Lists all organisations. <br> This includes their address, contact and teams (if existing/associated).' })
async getAll() { async getAll() {
let responseTeams: ResponseRunnerOrganisation[] = new Array<ResponseRunnerOrganisation>(); let responseTeams: ResponseRunnerOrganisation[] = new Array<ResponseRunnerOrganisation>();
const runners = await this.runnerOrganisationRepository.find({ relations: ['contact', 'teams'] }); const runners = await this.runnerOrganisationRepository.find({ relations: ['address', 'contact', 'teams'] });
runners.forEach(runner => { runners.forEach(runner => {
responseTeams.push(new ResponseRunnerOrganisation(runner)); responseTeams.push(new ResponseRunnerOrganisation(runner));
}); });
@ -43,7 +43,7 @@ export class RunnerOrganisationController {
@OnUndefined(RunnerOrganisationNotFoundError) @OnUndefined(RunnerOrganisationNotFoundError)
@OpenAPI({ description: 'Lists all information about the organisation whose id got provided.' }) @OpenAPI({ description: 'Lists all information about the organisation whose id got provided.' })
async getOne(@Param('id') id: number) { async getOne(@Param('id') id: number) {
let runnerOrg = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['contact', 'teams'] }); let runnerOrg = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['address', 'contact', 'teams'] });
if (!runnerOrg) { throw new RunnerOrganisationNotFoundError(); } if (!runnerOrg) { throw new RunnerOrganisationNotFoundError(); }
return new ResponseRunnerOrganisation(runnerOrg); return new ResponseRunnerOrganisation(runnerOrg);
} }
@ -62,7 +62,7 @@ export class RunnerOrganisationController {
runnerOrganisation = await this.runnerOrganisationRepository.save(runnerOrganisation); runnerOrganisation = await this.runnerOrganisationRepository.save(runnerOrganisation);
return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['contact', 'teams'] })); return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['address', 'contact', 'teams'] }));
} }
@Put('/:id') @Put('/:id')
@ -84,7 +84,7 @@ export class RunnerOrganisationController {
await this.runnerOrganisationRepository.save(await updateOrganisation.update(oldRunnerOrganisation)); await this.runnerOrganisationRepository.save(await updateOrganisation.update(oldRunnerOrganisation));
return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(id, { relations: ['contact', 'teams'] })); return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(id, { relations: ['address', 'contact', 'teams'] }));
} }
@Delete('/:id') @Delete('/:id')
@ -98,7 +98,7 @@ export class RunnerOrganisationController {
async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { async remove(@Param("id") id: number, @QueryParam("force") force: boolean) {
let organisation = await this.runnerOrganisationRepository.findOne({ id: id }); let organisation = await this.runnerOrganisationRepository.findOne({ id: id });
if (!organisation) { return null; } if (!organisation) { return null; }
let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['contact', 'runners', 'teams'] }); let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['address', 'contact', 'runners', 'teams'] });
if (!force) { if (!force) {
if (runnerOrganisation.teams.length != 0) { if (runnerOrganisation.teams.length != 0) {

View File

@ -1,57 +1,24 @@
import { IsString } from 'class-validator'; import { IsString } from 'class-validator';
import { BadRequestError } from 'routing-controllers'; import { NotAcceptableError, NotFoundError } from 'routing-controllers';
/** /**
* Error to throw when an address's postal code fails validation. * Error to throw, when to provided address doesn't belong to the accepted types.
*/ */
export class AddressPostalCodeInvalidError extends BadRequestError { export class AddressWrongTypeError extends NotAcceptableError {
@IsString() @IsString()
name = "AddressPostalCodeInvalidError" name = "AddressWrongTypeError"
@IsString() @IsString()
message = "The postal code you provided is invalid. \n Please check if your postal code follows the postal code validation guidelines." message = "The address must be an existing address's id. \n You provided a object of another type."
} }
/** /**
* Error to throw when an non-empty address's first line isn't set. * Error to throw, when a non-existent address get's loaded.
*/ */
export class AddressFirstLineEmptyError extends BadRequestError { export class AddressNotFoundError extends NotFoundError {
@IsString() @IsString()
name = "AddressFirstLineEmptyError" name = "AddressNotFoundError"
@IsString() @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" message = "The address you provided couldn't be located in the system. \n Please check your request."
}
/**
* 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

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

View File

@ -1,68 +1,78 @@
import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { config } from '../../../config'; import { getConnectionManager } from 'typeorm';
import { Address } from '../../entities/Address'; import { config } from '../../../config';
import { GroupContact } from '../../entities/GroupContact'; 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 { * This classed is used to create a new Group entity from a json body (post request).
/** */
* The new contact's first name. export class CreateGroupContact {
*/ /**
@IsNotEmpty() * The new contact's first name.
@IsString() */
firstname: string; @IsNotEmpty()
@IsString()
/** firstname: string;
* The new contact's middle name.
*/ /**
@IsOptional() * The new contact's middle name.
@IsString() */
middlename?: string; @IsOptional()
@IsString()
/** middlename?: string;
* The new contact's last name.
*/ /**
@IsNotEmpty() * The new contact's last name.
@IsString() */
lastname: string; @IsNotEmpty()
@IsString()
/** lastname: string;
* The new contact's address.
*/ /**
@IsOptional() * The new contact's address's id.
@IsObject() */
address?: Address; @IsInt()
@IsOptional()
/** address?: number;
* The contact's phone number.
* This will be validated against the configured country phone numer syntax (default: international). /**
*/ * The contact's phone number.
@IsOptional() * This will be validated against the configured country phone numer syntax (default: international).
@IsPhoneNumber(config.phone_validation_countrycode) */
phone?: string; @IsOptional()
@IsPhoneNumber(config.phone_validation_countrycode)
/** phone?: string;
* The contact's email address.
*/ /**
@IsOptional() * The contact's email address.
@IsEmail() */
email?: string; @IsOptional()
@IsEmail()
email?: string;
/**
* Creates a new Address entity from this. /**
*/ * Gets the new contact's address by it's id.
public async toEntity(): Promise<GroupContact> { */
let contact: GroupContact = new GroupContact(); public async getAddress(): Promise<Address> {
contact.firstname = this.firstname; if (!this.address) { return null; }
contact.middlename = this.middlename; let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
contact.lastname = this.lastname; if (!address) { throw new AddressNotFoundError; }
contact.email = this.email; return address;
contact.phone = this.phone; }
contact.address = this.address;
Address.validate(contact.address); /**
return contact; * 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;
}
} }

View File

@ -1,53 +1,65 @@
import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { config } from '../../../config'; import { getConnectionManager } from 'typeorm';
import { Address } from '../../entities/Address'; 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 { * This classed is used to create a new Participant entity from a json body (post request).
/** */
* The new participant's first name. export abstract class CreateParticipant {
*/ /**
@IsString() * The new participant's first name.
@IsNotEmpty() */
firstname: string; @IsString()
@IsNotEmpty()
/** firstname: string;
* The new participant's middle name.
*/ /**
@IsString() * The new participant's middle name.
@IsOptional() */
middlename?: string; @IsString()
@IsOptional()
/** middlename?: string;
* The new participant's last name.
*/ /**
@IsString() * The new participant's last name.
@IsNotEmpty() */
lastname: string; @IsString()
@IsNotEmpty()
/** lastname: string;
* The new participant's phone number.
* This will be validated against the configured country phone numer syntax (default: international). /**
*/ * The new participant's phone number.
@IsString() * This will be validated against the configured country phone numer syntax (default: international).
@IsOptional() */
@IsPhoneNumber(config.phone_validation_countrycode) @IsString()
phone?: string; @IsOptional()
@IsPhoneNumber(config.phone_validation_countrycode)
/** phone?: string;
* The new participant's e-mail address.
*/ /**
@IsString() * The new participant's e-mail address.
@IsOptional() */
@IsEmail() @IsString()
email?: string; @IsOptional()
@IsEmail()
/** email?: string;
* The new participant's address.
*/ /**
@IsOptional() * The new participant's address's id.
@IsObject() */
address?: Address; @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;
}
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -1,38 +1,48 @@
import { IsInt, IsObject, IsOptional } from 'class-validator'; import { IsInt, IsOptional } from 'class-validator';
import { Address } from '../../entities/Address'; import { getConnectionManager } from 'typeorm';
import { RunnerOrganisation } from '../../entities/RunnerOrganisation'; import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { CreateRunnerGroup } from '../create/CreateRunnerGroup'; 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 { * 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). /**
*/ * The updated orgs's id.
@IsInt() * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to).
id: number; */
@IsInt()
/** id: number;
* The updated organisation's address.
*/ /**
@IsOptional() * The updated organisation's address's id.
@IsObject() */
address?: Address; @IsInt()
@IsOptional()
/** address?: number;
* Updates a provided RunnerOrganisation entity based on this.
*/ /**
public async update(organisation: RunnerOrganisation): Promise<RunnerOrganisation> { * Loads the organisation's address based on it's id.
*/
organisation.name = this.name; public async getAddress(): Promise<Address> {
organisation.contact = await this.getContact(); if (!this.address) { return null; }
if (!this.address) { organisation.address.reset(); } let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
else { organisation.address = this.address; } if (!address) { throw new AddressNotFoundError; }
Address.validate(organisation.address); return address;
}
return organisation;
} /**
* 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;
}
} }

View File

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

View File

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

View File

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

View File

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

@ -1,84 +1,94 @@
import axios from 'axios'; import axios from 'axios';
import { config } from '../../config'; import { config } from '../../config';
const base = "http://localhost:" + config.internal_port const base = "http://localhost:" + config.internal_port
let access_token; let access_token;
let axios_config; let axios_config;
beforeAll(async () => { beforeAll(async () => {
const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
access_token = res.data["access_token"]; access_token = res.data["access_token"];
axios_config = { axios_config = {
headers: { "authorization": "Bearer " + access_token }, headers: { "authorization": "Bearer " + access_token },
validateStatus: undefined validateStatus: undefined
}; };
}); });
// --------------- // ---------------
describe('POST /api/donors with errors', () => { describe('POST /api/donors with errors', () => {
it('creating a new donor without any parameters should return 400', async () => { it('creating a new donor without any parameters should return 400', async () => {
const res1 = await axios.post(base + '/api/donors', null, axios_config); const res1 = await axios.post(base + '/api/donors', null, axios_config);
expect(res1.status).toEqual(400); expect(res1.status).toEqual(400);
expect(res1.headers['content-type']).toContain("application/json") expect(res1.headers['content-type']).toContain("application/json")
}); });
it('creating a new donor without a last name should return 400', async () => { it('creating a new donor without a last name should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', { const res2 = await axios.post(base + '/api/donors', {
"firstname": "first", "firstname": "first",
"middlename": "middle" "middlename": "middle"
}, axios_config); }, axios_config);
expect(res2.status).toEqual(400); expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('creating a new donor with a invalid phone number should return 400', async () => { it('creating a new donor with a invalid address should return 404', async () => {
const res2 = await axios.post(base + '/api/donors', { const res2 = await axios.post(base + '/api/donors', {
"firstname": "first", "firstname": "first",
"middlename": "middle", "middlename": "middle",
"lastname": "last", "lastname": "last",
"phone": "123" "address": 99999999999999999999999999
}, axios_config); }, axios_config);
expect(res2.status).toEqual(400); expect(res2.status).toEqual(404);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('creating a new donor with a invalid mail address should return 400', async () => { it('creating a new donor with a invalid phone number should return 400', async () => {
const res2 = await axios.post(base + '/api/donors', { const res2 = await axios.post(base + '/api/donors', {
"firstname": "string", "firstname": "first",
"middlename": "string", "middlename": "middle",
"lastname": "string", "lastname": "last",
"phone": null, "phone": "123"
"email": "123", }, axios_config);
}, axios_config); expect(res2.status).toEqual(400);
expect(res2.status).toEqual(400); expect(res2.headers['content-type']).toContain("application/json")
expect(res2.headers['content-type']).toContain("application/json") });
}); it('creating a new donor with a invalid mail address should return 400', async () => {
it('creating a new donor without an address but with receiptNeeded=true 406', async () => { const res2 = await axios.post(base + '/api/donors', {
const res2 = await axios.post(base + '/api/donors', { "firstname": "string",
"firstname": "string", "middlename": "string",
"middlename": "string", "lastname": "string",
"lastname": "string", "phone": null,
"receiptNeeded": true "email": "123",
}, axios_config); }, axios_config);
expect(res2.status).toEqual(406); expect(res2.status).toEqual(400);
expect(res2.headers['content-type']).toContain("application/json") 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', {
describe('POST /api/donors working', () => { "firstname": "string",
it('creating a new donor with only needed params should return 200', async () => { "middlename": "string",
const res2 = await axios.post(base + '/api/donors', { "lastname": "string",
"firstname": "first", "receiptNeeded": true
"lastname": "last" }, axios_config);
}, axios_config); expect(res2.status).toEqual(406);
expect(res2.status).toEqual(200); expect(res2.headers['content-type']).toContain("application/json")
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', { describe('POST /api/donors working', () => {
"firstname": "first", it('creating a new donor with only needed params should return 200', async () => {
"middlename": "middle", const res2 = await axios.post(base + '/api/donors', {
"lastname": "last", "firstname": "first",
"receiptNeeded": false "lastname": "last"
}, axios_config); }, axios_config);
expect(res3.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json") 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 axios from 'axios';
import { config } from '../../config'; import { config } from '../../config';
const base = "http://localhost:" + config.internal_port const base = "http://localhost:" + config.internal_port
let access_token; let access_token;
let axios_config; let axios_config;
beforeAll(async () => { beforeAll(async () => {
const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
access_token = res.data["access_token"]; access_token = res.data["access_token"];
axios_config = { axios_config = {
headers: { "authorization": "Bearer " + access_token }, headers: { "authorization": "Bearer " + access_token },
validateStatus: undefined validateStatus: undefined
}; };
}); });
describe('Update donor name after adding', () => { describe('Update donor name after adding', () => {
let added_donor; let added_donor;
it('creating a new runner with only needed params should return 200', async () => { it('creating a new runner with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', { const res2 = await axios.post(base + '/api/donors', {
"firstname": "first", "firstname": "first",
"lastname": "last" "lastname": "last"
}, axios_config); }, axios_config);
added_donor = res2.data; added_donor = res2.data;
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('valid update should return 200', async () => { it('valid update should return 200', async () => {
let donor_copy = added_donor let donor_copy = added_donor
donor_copy.firstname = "second" donor_copy.firstname = "second"
const res3 = await axios.put(base + '/api/donors/' + added_donor.id, donor_copy, axios_config); const res3 = await axios.put(base + '/api/donors/' + added_donor.id, donor_copy, axios_config);
expect(res3.status).toEqual(200); expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json") expect(res3.headers['content-type']).toContain("application/json")
let updated_donor = res3.data let updated_donor = res3.data
expect(updated_donor).toEqual(donor_copy); expect(updated_donor).toEqual(donor_copy);
}); });
}); });
// --------------- // ---------------
describe('Update donor id after adding(should fail)', () => { describe('Update donor id after adding(should fail)', () => {
let added_donor; let added_donor;
it('creating a new donor with only needed params should return 200', async () => { it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', { const res2 = await axios.post(base + '/api/donors', {
"firstname": "first", "firstname": "first",
"lastname": "last" "lastname": "last"
}, axios_config); }, axios_config);
added_donor = res2.data; added_donor = res2.data;
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('invalid update should return 406', async () => { it('invalid update should return 406', async () => {
added_donor.id++; added_donor.id++;
const res3 = await axios.put(base + '/api/donors/' + (added_donor.id - 1), added_donor, axios_config); const res3 = await axios.put(base + '/api/donors/' + (added_donor.id - 1), added_donor, axios_config);
expect(res3.status).toEqual(406); expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json") expect(res3.headers['content-type']).toContain("application/json")
}); });
}); });
// --------------- // ---------------
describe('Update donor without address but receiptNeeded=true should fail', () => { describe('Update donor without address but receiptNeeded=true should fail', () => {
let added_donor; let added_donor;
it('creating a new donor with only needed params should return 200', async () => { it('creating a new donor with only needed params should return 200', async () => {
const res2 = await axios.post(base + '/api/donors', { const res2 = await axios.post(base + '/api/donors', {
"firstname": "first", "firstname": "first",
"lastname": "testtest", "lastname": "last",
}, axios_config); }, axios_config);
added_donor = res2.data; added_donor = res2.data;
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('invalid update should return 406', async () => { it('invalid update should return 406', async () => {
added_donor.receiptNeeded = true; added_donor.receiptNeeded = true;
const res3 = await axios.put(base + '/api/donors/' + added_donor.id, added_donor, axios_config); const res3 = await axios.put(base + '/api/donors/' + added_donor.id, added_donor, axios_config);
expect(res3.status).toEqual(406); expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json") expect(res3.headers['content-type']).toContain("application/json")
}); });
}); });

View File

@ -1,102 +1,90 @@
import axios from 'axios'; import axios from 'axios';
import { config } from '../../config'; import { config } from '../../config';
const base = "http://localhost:" + config.internal_port const base = "http://localhost:" + config.internal_port
let access_token; let access_token;
let axios_config; let axios_config;
beforeAll(async () => { beforeAll(async () => {
const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
access_token = res.data["access_token"]; access_token = res.data["access_token"];
axios_config = { axios_config = {
headers: { "authorization": "Bearer " + access_token }, headers: { "authorization": "Bearer " + access_token },
validateStatus: undefined validateStatus: undefined
}; };
}); });
describe('GET /api/organisations', () => { describe('GET /api/organisations', () => {
it('basic get should return 200', async () => { it('basic get should return 200', async () => {
const res = await axios.get(base + '/api/organisations', axios_config); const res = await axios.get(base + '/api/organisations', axios_config);
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
}); });
}); });
// --------------- // ---------------
describe('POST /api/organisations', () => { describe('POST /api/organisations', () => {
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', { const res = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
}); });
it('creating a new org with without a name should return 400', async () => { it('creating a new org with without a name should return 400', async () => {
const res = await axios.post(base + '/api/organisations', { const res = await axios.post(base + '/api/organisations', {
"name": null "name": null
}, axios_config); }, axios_config);
expect(res.status).toEqual(400); expect(res.status).toEqual(400);
expect(res.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
}); });
}); });
// --------------- // ---------------
describe('adding + getting from all orgs', () => { describe('adding + getting from all orgs', () => {
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', { const res = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
}); });
it('check if org was added', async () => { it('check if org was added', async () => {
const res = await axios.get(base + '/api/organisations', axios_config); const res = await axios.get(base + '/api/organisations', axios_config);
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
let added_org = res.data[res.data.length - 1] let added_org = res.data[res.data.length - 1]
delete added_org.id delete added_org.id
expect(added_org).toEqual({ expect(added_org).toEqual({
"name": "test123", "name": "test123",
"contact": null, "contact": null,
"address": { "address": null,
"address1": null, "teams": []
"address2": null, })
"city": null, });
"country": null, });
"postalcode": null, // ---------------
}, describe('adding + getting explicitly', () => {
"teams": [] 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);
describe('adding + getting explicitly', () => { let added_org = res1.data
let added_org_id added_org_id = added_org.id;
it('creating a new org with just a name should return 200', async () => { expect(res1.status).toEqual(200);
const res1 = await axios.post(base + '/api/organisations', { expect(res1.headers['content-type']).toContain("application/json")
"name": "test123" });
}, axios_config); it('check if org was added', async () => {
let added_org = res1.data const res2 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
added_org_id = added_org.id; expect(res2.status).toEqual(200);
expect(res1.status).toEqual(200); expect(res2.headers['content-type']).toContain("application/json")
expect(res1.headers['content-type']).toContain("application/json") let added_org2 = res2.data
}); added_org_id = added_org2.id;
it('check if org was added', async () => { delete added_org2.id
const res2 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config); expect(added_org2).toEqual({
expect(res2.status).toEqual(200); "name": "test123",
expect(res2.headers['content-type']).toContain("application/json") "contact": null,
let added_org2 = res2.data "address": null,
added_org_id = added_org2.id; "teams": []
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,144 +1,132 @@
import axios from 'axios'; import axios from 'axios';
import { config } from '../../config'; import { config } from '../../config';
const base = "http://localhost:" + config.internal_port const base = "http://localhost:" + config.internal_port
let access_token; let access_token;
let axios_config; let axios_config;
beforeAll(async () => { beforeAll(async () => {
const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
access_token = res.data["access_token"]; access_token = res.data["access_token"];
axios_config = { axios_config = {
headers: { "authorization": "Bearer " + access_token }, headers: { "authorization": "Bearer " + access_token },
validateStatus: undefined validateStatus: undefined
}; };
}); });
// --------------- // ---------------
describe('adding + deletion (non-existant)', () => { describe('adding + deletion (non-existant)', () => {
it('delete', async () => { it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/0', axios_config); const res2 = await axios.delete(base + '/api/organisations/0', axios_config);
expect(res2.status).toEqual(204); expect(res2.status).toEqual(204);
}); });
}); });
// --------------- // ---------------
describe('adding + deletion (successfull)', () => { describe('adding + deletion (successfull)', () => {
let added_org_id let added_org_id
let added_org let added_org
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', { const res1 = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org = res1.data added_org = res1.data
added_org_id = added_org.id; added_org_id = added_org.id;
expect(res1.status).toEqual(200); expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json") expect(res1.headers['content-type']).toContain("application/json")
}); });
it('delete', async () => { it('delete', async () => {
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id, axios_config); const res2 = await axios.delete(base + '/api/organisations/' + added_org_id, axios_config);
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res2.data let added_org2 = res2.data
added_org_id = added_org2.id; added_org_id = added_org2.id;
delete added_org2.id delete added_org2.id
expect(added_org2).toEqual({ expect(added_org2).toEqual({
"name": "test123", "name": "test123",
"contact": null, "contact": null,
"address": { "address": null,
"address1": null, "teams": []
"address2": null, });
"city": null, });
"country": null, it('check if org really was deleted', async () => {
"postalcode": null, const res3 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
}, expect(res3.status).toEqual(404);
"teams": [] expect(res3.headers['content-type']).toContain("application/json")
}); });
}); });
it('check if org really was deleted', async () => { // ---------------
const res3 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config); describe('adding + deletion with teams still existing (without force)', () => {
expect(res3.status).toEqual(404); let added_org;
expect(res3.headers['content-type']).toContain("application/json") let added_org_id;
}); let added_team;
}); let added_team_id
// --------------- it('creating a new org with just a name should return 200', async () => {
describe('adding + deletion with teams still existing (without force)', () => { const res1 = await axios.post(base + '/api/organisations', {
let added_org; "name": "test123"
let added_org_id; }, axios_config);
let added_team; added_org = res1.data;
let added_team_id added_org_id = added_org.id;
it('creating a new org with just a name should return 200', async () => { expect(res1.status).toEqual(200);
const res1 = await axios.post(base + '/api/organisations', { expect(res1.headers['content-type']).toContain("application/json")
"name": "test123" });
}, axios_config); it('creating a new team with a valid org should return 200', async () => {
added_org = res1.data; const res2 = await axios.post(base + '/api/teams', {
added_org_id = added_org.id; "name": "test123",
expect(res1.status).toEqual(200); "parentGroup": added_org_id
expect(res1.headers['content-type']).toContain("application/json") }, axios_config);
}); added_team = res2.data;
it('creating a new team with a valid org should return 200', async () => { added_team_id = added_team.id;
const res2 = await axios.post(base + '/api/teams', { expect(res2.status).toEqual(200);
"name": "test123", expect(res2.headers['content-type']).toContain("application/json")
"parentGroup": added_org_id });
}, axios_config); it('delete org - this should fail with a 406', async () => {
added_team = res2.data; const res2 = await axios.delete(base + '/api/organisations/' + added_org_id, axios_config);
added_team_id = added_team.id; expect(res2.status).toEqual(406);
expect(res2.status).toEqual(200); expect(res2.headers['content-type']).toContain("application/json")
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); describe('adding + deletion with teams still existing (with force)', () => {
expect(res2.status).toEqual(406); let added_org;
expect(res2.headers['content-type']).toContain("application/json") let added_org_id;
}); let added_team;
}); let added_team_id
// --------------- it('creating a new org with just a name should return 200', async () => {
describe('adding + deletion with teams still existing (with force)', () => { const res1 = await axios.post(base + '/api/organisations', {
let added_org; "name": "test123"
let added_org_id; }, axios_config);
let added_team; added_org = res1.data;
let added_team_id added_org_id = added_org.id;
it('creating a new org with just a name should return 200', async () => { expect(res1.status).toEqual(200);
const res1 = await axios.post(base + '/api/organisations', { expect(res1.headers['content-type']).toContain("application/json")
"name": "test123" });
}, axios_config); it('creating a new team with a valid org should return 200', async () => {
added_org = res1.data; const res2 = await axios.post(base + '/api/teams', {
added_org_id = added_org.id; "name": "test123",
expect(res1.status).toEqual(200); "parentGroup": added_org_id
expect(res1.headers['content-type']).toContain("application/json") }, axios_config);
}); added_team = res2.data;
it('creating a new team with a valid org should return 200', async () => { added_team_id = added_team.id;
const res2 = await axios.post(base + '/api/teams', { expect(res2.status).toEqual(200);
"name": "test123", expect(res2.headers['content-type']).toContain("application/json")
"parentGroup": added_org_id });
}, axios_config); it('delete', async () => {
added_team = res2.data; const res2 = await axios.delete(base + '/api/organisations/' + added_org_id + '?force=true', axios_config);
added_team_id = added_team.id; expect(res2.status).toEqual(200);
expect(res2.status).toEqual(200); expect(res2.headers['content-type']).toContain("application/json")
expect(res2.headers['content-type']).toContain("application/json") let added_org2 = res2.data
}); added_org_id = added_org2.id;
it('delete', async () => { delete added_org2.id;
const res2 = await axios.delete(base + '/api/organisations/' + added_org_id + '?force=true', axios_config); delete added_org2.teams;
expect(res2.status).toEqual(200); expect(added_org2).toEqual({
expect(res2.headers['content-type']).toContain("application/json") "name": "test123",
let added_org2 = res2.data "contact": null,
added_org_id = added_org2.id; "address": null
delete added_org2.id; });
delete added_org2.teams; });
expect(added_org2).toEqual({ it('check if org really was deleted', async () => {
"name": "test123", const res3 = await axios.get(base + '/api/organisations/' + added_org_id, axios_config);
"contact": null, expect(res3.status).toEqual(404);
"address": { expect(res3.headers['content-type']).toContain("application/json")
"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,383 +1,73 @@
import axios from 'axios'; import axios from 'axios';
import { config } from '../../config'; import { config } from '../../config';
const base = "http://localhost:" + config.internal_port const base = "http://localhost:" + config.internal_port
let access_token; let access_token;
let axios_config; let axios_config;
beforeAll(async () => { beforeAll(async () => {
const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
access_token = res.data["access_token"]; access_token = res.data["access_token"];
axios_config = { axios_config = {
headers: { "authorization": "Bearer " + access_token }, headers: { "authorization": "Bearer " + access_token },
validateStatus: undefined validateStatus: undefined
}; };
}); });
// --------------- // ---------------
describe('adding + updating name', () => { describe('adding + updating name', () => {
let added_org_id let added_org_id
let added_org let added_org
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res = await axios.post(base + '/api/organisations', { const res1 = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org = res.data added_org = res1.data
added_org_id = added_org.id; added_org_id = added_org.id;
expect(res.status).toEqual(200); expect(res1.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json") expect(res1.headers['content-type']).toContain("application/json")
}); });
it('update org', async () => { it('update org', async () => {
const res = await axios.put(base + '/api/organisations/' + added_org_id, { const res2 = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id, "id": added_org_id,
"name": "testlelele", "name": "testlelele",
"contact": null, "contact": null,
"address": null, "address": null,
}, axios_config); }, axios_config);
expect(res.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
let added_org2 = res.data let added_org2 = res2.data
added_org_id = added_org2.id; added_org_id = added_org2.id;
delete added_org2.id delete added_org2.id
expect(added_org2).toEqual({ expect(added_org2).toEqual({
"name": "testlelele", "name": "testlelele",
"contact": null, "contact": null,
"address": { "address": null,
"address1": null, "teams": []
"address2": null, })
"city": null, });
"country": null, });
"postalcode": null, // ---------------
}, describe('adding + try updating id (should return 406)', () => {
"teams": [] 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"
describe('adding + try updating id (should return 406)', () => { }, axios_config);
let added_org_id added_org = res1.data
let added_org added_org_id = added_org.id;
it('creating a new org with just a name should return 200', async () => { expect(res1.status).toEqual(200);
const res = await axios.post(base + '/api/organisations', { expect(res1.headers['content-type']).toContain("application/json")
"name": "test123" });
}, axios_config); it('update org', async () => {
added_org = res.data const res2 = await axios.put(base + '/api/organisations/' + added_org_id, {
added_org_id = added_org.id; "id": added_org_id + 1,
expect(res.status).toEqual(200); "name": "testlelele",
expect(res.headers['content-type']).toContain("application/json") "contact": null,
}); "address": null,
it('update org', async () => { }, axios_config);
const res = await axios.put(base + '/api/organisations/' + added_org_id, { expect(res2.status).toEqual(406);
"id": added_org_id + 1, expect(res2.headers['content-type']).toContain("application/json")
"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,130 +1,131 @@
import axios from 'axios'; import axios from 'axios';
import { config } from '../../config'; import { config } from '../../config';
const base = "http://localhost:" + config.internal_port const base = "http://localhost:" + config.internal_port
let access_token; let access_token;
let axios_config; let axios_config;
beforeAll(async () => { beforeAll(async () => {
const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" });
access_token = res.data["access_token"]; access_token = res.data["access_token"];
axios_config = { axios_config = {
headers: { "authorization": "Bearer " + access_token }, headers: { "authorization": "Bearer " + access_token },
validateStatus: undefined validateStatus: undefined
}; };
}); });
// --------------- // ---------------
describe('adding + updating name', () => { describe('adding + updating name', () => {
let added_org; let added_org;
let added_org_id; let added_org_id;
let added_team; let added_team;
let added_team_id let added_team_id
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', { const res1 = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org = res1.data; added_org = res1.data;
added_org_id = added_org.id; added_org_id = added_org.id;
expect(res1.status).toEqual(200); expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json") expect(res1.headers['content-type']).toContain("application/json")
}); });
it('creating a new team with a valid org should return 200', async () => { it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', { const res2 = await axios.post(base + '/api/teams', {
"name": "test123", "name": "test123",
"parentGroup": added_org_id "parentGroup": added_org_id
}, axios_config); }, axios_config);
added_team = res2.data; added_team = res2.data;
added_team_id = added_team.id; added_team_id = added_team.id;
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('update name', async () => { it('update name', async () => {
const res3 = await axios.put(base + '/api/teams/' + added_team_id, { const res3 = await axios.put(base + '/api/teams/' + added_team_id, {
"id": added_team_id, "id": added_team_id,
"name": "testlelele", "name": "testlelele",
"contact": null, "contact": null,
"parentGroup": added_org.id "parentGroup": added_org.id
}, axios_config); }, axios_config);
expect(res3.status).toEqual(200); expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json") expect(res3.headers['content-type']).toContain("application/json")
let updated_team = res3.data; let updated_team = res3.data;
added_team.name = "testlelele"; added_team.name = "testlelele";
expect(updated_team).toEqual(added_team) expect(updated_team).toEqual(added_team)
}); });
}); });
// --------------- // ---------------
describe('adding + try updating id (should return 406)', () => { describe('adding + try updating id (should return 406)', () => {
let added_org; let added_org;
let added_org_id; let added_org_id;
let added_team; let added_team;
let added_team_id let added_team_id
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', { const res1 = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org = res1.data; added_org = res1.data;
added_org_id = added_org.id; added_org_id = added_org.id;
expect(res1.status).toEqual(200); expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json") expect(res1.headers['content-type']).toContain("application/json")
}); });
it('creating a new team with a valid org should return 200', async () => { it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', { const res2 = await axios.post(base + '/api/teams', {
"name": "test123", "name": "test123",
"parentGroup": added_org_id "parentGroup": added_org_id
}, axios_config); }, axios_config);
added_team = res2.data; added_team = res2.data;
added_team_id = added_team.id; added_team_id = added_team.id;
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('update team', async () => { it('update team', async () => {
added_team.id = added_team.id + 1; added_team.id = added_team.id + 1;
added_team.parentGroup = added_team.parentGroup.id; added_team.parentGroup = added_team.parentGroup.id;
const res3 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config); const res3 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config);
expect(res3.status).toEqual(406); expect(res3.status).toEqual(406);
expect(res3.headers['content-type']).toContain("application/json") expect(res3.headers['content-type']).toContain("application/json")
}); });
}); });
// --------------- // ---------------
describe('add+update parent org (valid)', () => { describe('add+update parent org (valid)', () => {
let added_org; let added_org;
let added_org2; let added_org2;
let added_team; let added_team;
let added_team_id let added_team_id
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res1 = await axios.post(base + '/api/organisations', { const res1 = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org = res1.data; added_org = res1.data;
expect(res1.status).toEqual(200); expect(res1.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json") expect(res1.headers['content-type']).toContain("application/json")
}); });
it('creating a new team with a valid org should return 200', async () => { it('creating a new team with a valid org should return 200', async () => {
const res2 = await axios.post(base + '/api/teams', { const res2 = await axios.post(base + '/api/teams', {
"name": "test123", "name": "test123",
"parentGroup": added_org.id "parentGroup": added_org.id
}, axios_config); }, axios_config);
added_team = res2.data; added_team = res2.data;
added_team_id = added_team.id; added_team_id = added_team.id;
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res2.headers['content-type']).toContain("application/json")
}); });
it('creating a new org with just a name should return 200', async () => { it('creating a new org with just a name should return 200', async () => {
const res3 = await axios.post(base + '/api/organisations', { const res3 = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org2 = res3.data; added_org2 = res3.data;
expect(res3.status).toEqual(200); expect(res3.status).toEqual(200);
expect(res3.headers['content-type']).toContain("application/json") expect(res3.headers['content-type']).toContain("application/json")
}); });
it('update team', async () => { it('update team', async () => {
added_team.parentGroup = added_org2.id; added_team.parentGroup = added_org2.id;
const res4 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config); const res4 = await axios.put(base + '/api/teams/' + added_team_id, added_team, axios_config);
let updated_team = res4.data; let updated_team = res4.data;
expect(res4.status).toEqual(200); expect(res4.status).toEqual(200);
expect(res4.headers['content-type']).toContain("application/json") expect(res4.headers['content-type']).toContain("application/json")
delete added_org2.contact; delete added_org2.address;
delete added_org2.teams; delete added_org2.contact;
expect(updated_team.parentGroup).toEqual(added_org2) delete added_org2.teams;
}); expect(updated_team.parentGroup).toEqual(added_org2)
});
}); });

View File

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