Merge branch 'dev' into feature/104-contacts

This commit is contained in:
Nicolai Ort 2021-01-19 16:44:34 +01:00
commit 703b4f89a6
26 changed files with 1761 additions and 1497 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=null POSTALCODE_COUNTRYCODE=DE

View File

@ -2,8 +2,35 @@
All notable changes to this project will be documented in this file. Dates are displayed in UTC. All notable changes to this project will be documented in this file. Dates are displayed in UTC.
#### [v0.1.1](https://git.odit.services/lfk/backend/compare/v0.1.1...v0.1.1)
- Merge pull request 'Fully implemented addresses feature/105-addresses' (#107) from feature/105-addresses into dev [`5e36855`](https://git.odit.services/lfk/backend/commit/5e368552ea810ea1d3963b1207ba98f7b46c4abc)
- Cleaned up var names [`a3c93f0`](https://git.odit.services/lfk/backend/commit/a3c93f0d394833f1a6f78d862b094ca751c85561)
- Added address update ivalid tests [`427dfaa`](https://git.odit.services/lfk/backend/commit/427dfaafabd243e94aba27c2dec2705fd8ed5d64)
- Added first address update tests [`4d40225`](https://git.odit.services/lfk/backend/commit/4d40225a4491e8eb3f41ef0fd558a599f63729be)
- Added address update valid tests [`230cdb0`](https://git.odit.services/lfk/backend/commit/230cdb0e37e2b7a21e7feb156f2b91a69ad200fd)
- Implemented deep address validation [`9dc9ce3`](https://git.odit.services/lfk/backend/commit/9dc9ce37d8fbfc92842e4e05bbde68398324a186)
- Removed old create address class [`2a465f8`](https://git.odit.services/lfk/backend/commit/2a465f88c58c0b4be3ecd99d96a04c177a40b312)
- Switched the create classes over to the new address implementation [`2cd15d2`](https://git.odit.services/lfk/backend/commit/2cd15d25e934a5439bfea4de901f136e360e17f6)
- Test's now accept the new address format [`8dbee32`](https://git.odit.services/lfk/backend/commit/8dbee32eeec8ee3d013e4446e8f53544ee4cb577)
- Removed the IAddressUser Interface entity [`e265172`](https://git.odit.services/lfk/backend/commit/e2651728c5abf2273bf51a7652c51d55d8fa0a2f)
- Switched Address to embedded entity [`7fbe649`](https://git.odit.services/lfk/backend/commit/7fbe649dc90f4bb9f240c5a80fed447048e5e105)
- Removed the address errors [`58ae9b5`](https://git.odit.services/lfk/backend/commit/58ae9b589aef3580f4b8558c3d5ddbd7171e7915)
- Switched the update classes over to the new address implementation [`d0df5dd`](https://git.odit.services/lfk/backend/commit/d0df5dd641ac17f1fd8ad6bd8b46afa9dd2745c3)
- Implemented adress deletion (through reset) [`57b9c2b`](https://git.odit.services/lfk/backend/commit/57b9c2babcd68d69d1cbb240a86c2897717ba758)
- Fixed donor address check [`4824547`](https://git.odit.services/lfk/backend/commit/4824547dde4d7f90e9e2377a26df34cabf082fdb)
- Updated the responseclasses to use the new address implementation [`dafac06`](https://git.odit.services/lfk/backend/commit/dafac06bc84d1b237096a561b3adcd3ca5cb1dd8)
- Removed (now useless) relations [`673dea2`](https://git.odit.services/lfk/backend/commit/673dea2e5754e99ff77f7556d4fc03d4cca28a94)
- Added address validity check [`ae7c5ff`](https://git.odit.services/lfk/backend/commit/ae7c5ff0c387e9337d01a9dd819a4dddc208f6dd)
- 🧾New changelog file version [CI SKIP] [skip ci] [`f53894b`](https://git.odit.services/lfk/backend/commit/f53894b16ac1c06ecbeeb0b63a56ac438b2fbe1b)
- Updated comments [`8bc01d3`](https://git.odit.services/lfk/backend/commit/8bc01d3f2406ce8e58c2ab2963c858495c510dcf)
- Set country code for the ci env to DE [`30b585c`](https://git.odit.services/lfk/backend/commit/30b585c0c12b3b9818778110d33d5b3ab84d4192)
- Implemented postal code validation for the validaton function [`f245840`](https://git.odit.services/lfk/backend/commit/f245840cde5726611197b00730aca72ea133c427)
#### [v0.1.1](https://git.odit.services/lfk/backend/compare/v0.1.0...v0.1.1) #### [v0.1.1](https://git.odit.services/lfk/backend/compare/v0.1.0...v0.1.1)
> 16 January 2021
- Merge pull request 'Alpha Release 0.1.1 - Hotfix release' (#106) from dev into main [`7533c34`](https://git.odit.services/lfk/backend/commit/7533c349ef98ed328151259fca68621b3eb5fd98) - Merge pull request 'Alpha Release 0.1.1 - Hotfix release' (#106) from dev into main [`7533c34`](https://git.odit.services/lfk/backend/commit/7533c349ef98ed328151259fca68621b3eb5fd98)
- 🚀Bumped version to v0.1.1 [`9445c6f`](https://git.odit.services/lfk/backend/commit/9445c6f21e376329b9200664a44a94ba1f1dd463) - 🚀Bumped version to v0.1.1 [`9445c6f`](https://git.odit.services/lfk/backend/commit/9445c6f21e376329b9200664a44a94ba1f1dd463)
- 🧾New changelog file version [CI SKIP] [skip ci] [`1b9d296`](https://git.odit.services/lfk/backend/commit/1b9d2969ebdca4dca84898b1e8307be7b781b90b) - 🧾New changelog file version [CI SKIP] [skip ci] [`1b9d296`](https://git.odit.services/lfk/backend/commit/1b9d2969ebdca4dca84898b1e8307be7b781b90b)

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: ['address', 'contact', 'teams'] }); const runners = await this.runnerOrganisationRepository.find({ relations: ['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: ['address', 'contact', 'teams'] }); let runnerOrg = await this.runnerOrganisationRepository.findOne({ id: id }, { relations: ['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: ['address', 'contact', 'teams'] })); return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(runnerOrganisation, { relations: ['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: ['address', 'contact', 'teams'] })); return new ResponseRunnerOrganisation(await this.runnerOrganisationRepository.findOne(id, { relations: ['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: ['address', 'contact', 'runners', 'teams'] }); let runnerOrganisation = await this.runnerOrganisationRepository.findOne(organisation, { relations: ['contact', 'runners', 'teams'] });
if (!force) { if (!force) {
if (runnerOrganisation.teams.length != 0) { if (runnerOrganisation.teams.length != 0) {

View File

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

View File

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

View File

@ -1,5 +1,6 @@
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';
@ -26,10 +27,10 @@ export class CreateDonor extends CreateParticipant {
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;
if (this.receiptNeeded == true && this.address == null) { Address.validate(newDonor.address);
if (this.receiptNeeded == true && Address.isValidAddress(newDonor.address) == false) {
throw new DonorReceiptAddressNeededError() throw new DonorReceiptAddressNeededError()
} }

View File

@ -1,7 +1,5 @@
import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { config } from '../../../config'; import { config } from '../../../config';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address'; import { Address } from '../../entities/Address';
import { GroupContact } from '../../entities/GroupContact'; import { GroupContact } from '../../entities/GroupContact';
@ -31,11 +29,11 @@ export class CreateGroupContact {
lastname: string; lastname: string;
/** /**
* The new contact's address's id. * The new contact's address.
*/ */
@IsInt()
@IsOptional() @IsOptional()
address?: number; @IsObject()
address?: Address;
/** /**
* The contact's phone number. * The contact's phone number.
@ -52,15 +50,6 @@ export class CreateGroupContact {
@IsEmail() @IsEmail()
email?: string; email?: string;
/**
* Gets the new contact's address by it's id.
*/
public async getAddress(): Promise<Address> {
if (!this.address) { return null; }
let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
if (!address) { throw new AddressNotFoundError; }
return address;
}
/** /**
* Creates a new Address entity from this. * Creates a new Address entity from this.
@ -72,7 +61,8 @@ export class CreateGroupContact {
contact.lastname = this.lastname; contact.lastname = this.lastname;
contact.email = this.email; contact.email = this.email;
contact.phone = this.phone; contact.phone = this.phone;
contact.address = await this.getAddress(); contact.address = this.address;
return null; Address.validate(contact.address);
return contact;
} }
} }

View File

@ -1,7 +1,5 @@
import { IsEmail, IsInt, IsNotEmpty, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { config } from '../../../config'; import { config } from '../../../config';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address'; import { Address } from '../../entities/Address';
/** /**
@ -47,19 +45,9 @@ export abstract class CreateParticipant {
email?: string; email?: string;
/** /**
* The new participant's address's id. * The new participant's address.
*/ */
@IsInt()
@IsOptional() @IsOptional()
address?: number; @IsObject()
address?: Address;
/**
* 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

@ -3,6 +3,7 @@ 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';
@ -30,7 +31,8 @@ export class CreateRunner extends CreateParticipant {
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;
} }

View File

@ -1,6 +1,4 @@
import { IsInt, IsOptional } from 'class-validator'; import { IsObject, IsOptional } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address'; import { Address } from '../../entities/Address';
import { RunnerOrganisation } from '../../entities/RunnerOrganisation'; import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
import { CreateRunnerGroup } from './CreateRunnerGroup'; import { CreateRunnerGroup } from './CreateRunnerGroup';
@ -10,21 +8,11 @@ import { CreateRunnerGroup } from './CreateRunnerGroup';
*/ */
export class CreateRunnerOrganisation extends CreateRunnerGroup { export class CreateRunnerOrganisation extends CreateRunnerGroup {
/** /**
* The new organisation's address's id. * The new organisation's address.
*/ */
@IsInt()
@IsOptional() @IsOptional()
address?: number; @IsObject()
address?: Address;
/**
* Gets the org's address by it's id.
*/
public async getAddress(): Promise<Address> {
if (!this.address) { return null; }
let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
if (!address) { throw new AddressNotFoundError; }
return address;
}
/** /**
* Creates a new RunnerOrganisation entity from this. * Creates a new RunnerOrganisation entity from this.
@ -34,7 +22,8 @@ export class CreateRunnerOrganisation extends CreateRunnerGroup {
newRunnerOrganisation.name = this.name; newRunnerOrganisation.name = this.name;
newRunnerOrganisation.contact = await this.getContact(); newRunnerOrganisation.contact = await this.getContact();
newRunnerOrganisation.address = await this.getAddress(); newRunnerOrganisation.address = this.address;
Address.validate(newRunnerOrganisation.address);
return newRunnerOrganisation; return newRunnerOrganisation;
} }

View File

@ -1,5 +1,6 @@
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';
@ -33,9 +34,10 @@ export class UpdateDonor extends CreateParticipant {
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);
if (this.receiptNeeded == true && Address.isValidAddress(donor.address) == false) {
throw new DonorReceiptAddressNeededError() throw new DonorReceiptAddressNeededError()
} }

View File

@ -2,6 +2,7 @@ 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';
@ -35,7 +36,9 @@ export class UpdateRunner extends CreateParticipant {
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; }
Address.validate(runner.address);
return runner; return runner;
} }

View File

@ -1,6 +1,4 @@
import { IsInt, IsOptional } from 'class-validator'; import { IsInt, IsObject, IsOptional } from 'class-validator';
import { getConnectionManager } from 'typeorm';
import { AddressNotFoundError } from '../../../errors/AddressErrors';
import { Address } from '../../entities/Address'; import { Address } from '../../entities/Address';
import { RunnerOrganisation } from '../../entities/RunnerOrganisation'; import { RunnerOrganisation } from '../../entities/RunnerOrganisation';
import { CreateRunnerGroup } from '../create/CreateRunnerGroup'; import { CreateRunnerGroup } from '../create/CreateRunnerGroup';
@ -18,21 +16,11 @@ export class UpdateRunnerOrganisation extends CreateRunnerGroup {
id: number; id: number;
/** /**
* The updated organisation's address's id. * The updated organisation's address.
*/ */
@IsInt()
@IsOptional() @IsOptional()
address?: number; @IsObject()
address?: Address;
/**
* Loads the organisation's address based on it's id.
*/
public async getAddress(): Promise<Address> {
if (!this.address) { return null; }
let address = await getConnectionManager().get().getRepository(Address).findOne({ id: this.address });
if (!address) { throw new AddressNotFoundError; }
return address;
}
/** /**
* Updates a provided RunnerOrganisation entity based on this. * Updates a provided RunnerOrganisation entity based on this.
@ -41,7 +29,9 @@ export class UpdateRunnerOrganisation extends CreateRunnerGroup {
organisation.name = this.name; organisation.name = this.name;
organisation.contact = await this.getContact(); organisation.contact = await this.getContact();
organisation.address = await this.getAddress(); if (!this.address) { organisation.address.reset(); }
else { organisation.address = this.address; }
Address.validate(organisation.address);
return organisation; return organisation;
} }

View File

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

View File

@ -7,11 +7,10 @@ import {
IsString IsString
} from "class-validator"; } from "class-validator";
import { Column, Entity, ManyToOne, OneToMany, PrimaryGeneratedColumn } from "typeorm"; import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm";
import { config } from '../../config'; import { config } from '../../config';
import { ResponseGroupContact } from '../responses/ResponseGroupContact'; import { ResponseGroupContact } from '../responses/ResponseGroupContact';
import { Address } from "./Address"; import { Address } from "./Address";
import { IAddressUser } from './IAddressUser';
import { RunnerGroup } from "./RunnerGroup"; import { RunnerGroup } from "./RunnerGroup";
/** /**
@ -19,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 implements IAddressUser { export class GroupContact {
/** /**
* Autogenerated unique id (primary key). * Autogenerated unique id (primary key).
*/ */
@ -56,7 +55,7 @@ export class GroupContact implements IAddressUser {
* This is a address object to prevent any formatting differences. * This is a address object to prevent any formatting differences.
*/ */
@IsOptional() @IsOptional()
@ManyToOne(() => Address, address => address.addressUsers, { nullable: true }) @Column(type => Address)
address?: Address; address?: Address;
/** /**

View File

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

View File

@ -7,11 +7,10 @@ import {
IsString IsString
} from "class-validator"; } from "class-validator";
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn, TableInheritance } from "typeorm"; import { Column, Entity, 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.
@ -19,7 +18,7 @@ import { IAddressUser } from './IAddressUser';
*/ */
@Entity() @Entity()
@TableInheritance({ column: { name: "type", type: "varchar" } }) @TableInheritance({ column: { name: "type", type: "varchar" } })
export abstract class Participant implements IAddressUser { export abstract class Participant {
/** /**
* Autogenerated unique id (primary key). * Autogenerated unique id (primary key).
*/ */
@ -55,7 +54,7 @@ export abstract class Participant implements IAddressUser {
* 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.
*/ */
@ManyToOne(() => Address, address => address.addressUsers, { nullable: true }) @Column(type => Address)
address?: Address; address?: Address;
/** /**

View File

@ -1,8 +1,7 @@
import { IsInt, IsOptional } from "class-validator"; import { IsInt, IsOptional } from "class-validator";
import { ChildEntity, ManyToOne, OneToMany } from "typeorm"; import { ChildEntity, Column, OneToMany } from "typeorm";
import { ResponseRunnerOrganisation } from '../responses/ResponseRunnerOrganisation'; import { ResponseRunnerOrganisation } from '../responses/ResponseRunnerOrganisation';
import { Address } from './Address'; import { Address } from './Address';
import { IAddressUser } from './IAddressUser';
import { Runner } from './Runner'; import { Runner } from './Runner';
import { RunnerGroup } from "./RunnerGroup"; import { RunnerGroup } from "./RunnerGroup";
import { RunnerTeam } from "./RunnerTeam"; import { RunnerTeam } from "./RunnerTeam";
@ -12,13 +11,13 @@ import { RunnerTeam } from "./RunnerTeam";
* This usually is a school, club or company. * This usually is a school, club or company.
*/ */
@ChildEntity() @ChildEntity()
export class RunnerOrganisation extends RunnerGroup implements IAddressUser { export class RunnerOrganisation extends RunnerGroup {
/** /**
* The organisations's address. * The organisations's address.
*/ */
@IsOptional() @IsOptional()
@ManyToOne(() => Address, address => address.addressUsers, { nullable: true }) @Column(type => Address)
address?: Address; address?: Address;
/** /**

View File

@ -1,4 +1,5 @@
import { IsInt, IsString } from "class-validator"; import { IsInt, IsObject, IsOptional, IsString } from "class-validator";
import { Address } from '../entities/Address';
import { Participant } from '../entities/Participant'; import { Participant } from '../entities/Participant';
/** /**
@ -41,6 +42,13 @@ export abstract class ResponseParticipant {
@IsString() @IsString()
email?: string; email?: string;
/**
* The participant's address.
*/
@IsOptional()
@IsObject()
address?: Address;
/** /**
* Creates a ResponseParticipant object from a participant. * Creates a ResponseParticipant object from a participant.
* @param participant The participant the response shall be build for. * @param participant The participant the response shall be build for.
@ -52,5 +60,6 @@ export abstract class ResponseParticipant {
this.lastname = participant.lastname; this.lastname = participant.lastname;
this.phone = participant.phone; this.phone = participant.phone;
this.email = participant.email; this.email = participant.email;
this.address = participant.address;
} }
} }

View File

@ -29,16 +29,6 @@ describe('POST /api/donors with errors', () => {
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 address should return 404', async () => {
const res2 = await axios.post(base + '/api/donors', {
"firstname": "first",
"middlename": "middle",
"lastname": "last",
"address": 99999999999999999999999999
}, axios_config);
expect(res2.status).toEqual(404);
expect(res2.headers['content-type']).toContain("application/json")
});
it('creating a new donor with a invalid phone number should return 400', async () => { 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": "first", "firstname": "first",

View File

@ -60,7 +60,7 @@ describe('Update donor without address but receiptNeeded=true should fail', () =
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": "testtest",
}, axios_config); }, axios_config);
added_donor = res2.data; added_donor = res2.data;
expect(res2.status).toEqual(200); expect(res2.status).toEqual(200);

View File

@ -56,7 +56,13 @@ describe('adding + getting from all orgs', () => {
expect(added_org).toEqual({ expect(added_org).toEqual({
"name": "test123", "name": "test123",
"contact": null, "contact": null,
"address": null, "address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": [] "teams": []
}) })
}); });
@ -83,7 +89,13 @@ describe('adding + getting explicitly', () => {
expect(added_org2).toEqual({ expect(added_org2).toEqual({
"name": "test123", "name": "test123",
"contact": null, "contact": null,
"address": null, "address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": [] "teams": []
}) })
}); });

View File

@ -44,7 +44,13 @@ describe('adding + deletion (successfull)', () => {
expect(added_org2).toEqual({ expect(added_org2).toEqual({
"name": "test123", "name": "test123",
"contact": null, "contact": null,
"address": null, "address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": [] "teams": []
}); });
}); });
@ -121,7 +127,13 @@ describe('adding + deletion with teams still existing (with force)', () => {
expect(added_org2).toEqual({ expect(added_org2).toEqual({
"name": "test123", "name": "test123",
"contact": null, "contact": null,
"address": null "address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
}); });
}); });
it('check if org really was deleted', async () => { it('check if org really was deleted', async () => {

View File

@ -19,30 +19,36 @@ 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 res1 = await axios.post(base + '/api/organisations', { const res = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org = res1.data added_org = res.data
added_org_id = added_org.id; added_org_id = added_org.id;
expect(res1.status).toEqual(200); expect(res.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
}); });
it('update org', async () => { it('update org', async () => {
const res2 = await axios.put(base + '/api/organisations/' + added_org_id, { const res = 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(res2.status).toEqual(200); expect(res.status).toEqual(200);
expect(res2.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
let added_org2 = res2.data let added_org2 = res.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": null, "address": {
"address1": null,
"address2": null,
"city": null,
"country": null,
"postalcode": null,
},
"teams": [] "teams": []
}) })
}); });
@ -52,22 +58,326 @@ describe('adding + try updating id (should return 406)', () => {
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 res = await axios.post(base + '/api/organisations', {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org = res1.data added_org = res.data
added_org_id = added_org.id; added_org_id = added_org.id;
expect(res1.status).toEqual(200); expect(res.status).toEqual(200);
expect(res1.headers['content-type']).toContain("application/json") expect(res.headers['content-type']).toContain("application/json")
}); });
it('update org', async () => { it('update org', async () => {
const res2 = await axios.put(base + '/api/organisations/' + added_org_id, { const res = await axios.put(base + '/api/organisations/' + added_org_id, {
"id": added_org_id + 1, "id": added_org_id + 1,
"name": "testlelele", "name": "testlelele",
"contact": null, "contact": null,
"address": null, "address": null,
}, axios_config); }, axios_config);
expect(res2.status).toEqual(406); expect(res.status).toEqual(406);
expect(res2.headers['content-type']).toContain("application/json") 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

@ -123,7 +123,6 @@ describe('add+update parent org (valid)', () => {
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.address;
delete added_org2.contact; delete added_org2.contact;
delete added_org2.teams; delete added_org2.teams;
expect(updated_team.parentGroup).toEqual(added_org2) expect(updated_team.parentGroup).toEqual(added_org2)

View File

@ -44,7 +44,6 @@ describe('Update runner name after adding', () => {
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.address;
delete added_org.contact; delete added_org.contact;
delete added_org.teams; delete added_org.teams;
runnercopy.group = added_org; runnercopy.group = added_org;
@ -56,7 +55,6 @@ describe('Update runner group after adding', () => {
let added_org_id; let added_org_id;
let added_org_2; let added_org_2;
let added_runner; let added_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"
@ -81,7 +79,6 @@ describe('Update runner group after adding', () => {
"name": "test123" "name": "test123"
}, axios_config); }, axios_config);
added_org_2 = res3.data added_org_2 = res3.data
delete added_org_2.address;
delete added_org_2.contact; delete added_org_2.contact;
delete added_org_2.teams; delete added_org_2.teams;
expect(res3.status).toEqual(200); expect(res3.status).toEqual(200);
@ -92,8 +89,7 @@ describe('Update runner group after adding', () => {
const res3 = await axios.put(base + '/api/runners/' + added_runner.id, added_runner, axios_config); const res3 = await axios.put(base + '/api/runners/' + added_runner.id, added_runner, 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 expect(res3.data.group).toEqual(added_org_2);
expect(updated_runner.group).toEqual(added_org_2);
}); });
}); });
// --------------- // ---------------