Merge pull request 'Implemented group contacts feature/104-contacts' (#108) from feature/104-contacts into dev
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build is failing
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	continuous-integration/drone/push Build is failing
				
			Reviewed-on: #108
This commit is contained in:
		| @@ -6,4 +6,4 @@ DB_USER=bla | ||||
| DB_PASSWORD=bla | ||||
| DB_NAME=bla | ||||
| NODE_ENV=production | ||||
| POSTALCODE_COUNTRYCODE=null | ||||
| POSTALCODE_COUNTRYCODE=DE | ||||
							
								
								
									
										107
									
								
								src/controllers/GroupContactController.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/controllers/GroupContactController.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| import { Authorized, Body, Delete, Get, JsonController, OnUndefined, Param, Post, Put, QueryParam } from 'routing-controllers'; | ||||
| import { OpenAPI, ResponseSchema } from 'routing-controllers-openapi'; | ||||
| import { getConnection, getConnectionManager, Repository } from 'typeorm'; | ||||
| import { GroupContactIdsNotMatchingError, GroupContactNotFoundError } from '../errors/GroupContactErrors'; | ||||
| import { RunnerGroupNotFoundError } from '../errors/RunnerGroupErrors'; | ||||
| import { CreateGroupContact } from '../models/actions/create/CreateGroupContact'; | ||||
| import { UpdateGroupContact } from '../models/actions/update/UpdateGroupContact'; | ||||
| import { GroupContact } from '../models/entities/GroupContact'; | ||||
| import { RunnerGroup } from '../models/entities/RunnerGroup'; | ||||
| import { ResponseEmpty } from '../models/responses/ResponseEmpty'; | ||||
| import { ResponseGroupContact } from '../models/responses/ResponseGroupContact'; | ||||
|  | ||||
| @JsonController('/contacts') | ||||
| @OpenAPI({ security: [{ "AuthToken": [] }, { "RefreshTokenCookie": [] }] }) | ||||
| export class GroupContactController { | ||||
| 	private contactRepository: Repository<GroupContact>; | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets the repository of this controller's model/entity. | ||||
| 	 */ | ||||
| 	constructor() { | ||||
| 		this.contactRepository = getConnectionManager().get().getRepository(GroupContact); | ||||
| 	} | ||||
|  | ||||
| 	@Get() | ||||
| 	@Authorized("CONTACT:GET") | ||||
| 	@ResponseSchema(ResponseGroupContact, { isArray: true }) | ||||
| 	@OpenAPI({ description: 'Lists all contacts. <br> This includes the contact\'s associated groups.' }) | ||||
| 	async getAll() { | ||||
| 		let responseContacts: ResponseGroupContact[] = new Array<ResponseGroupContact>(); | ||||
| 		const contacts = await this.contactRepository.find({ relations: ['groups'] }); | ||||
| 		contacts.forEach(contact => { | ||||
| 			responseContacts.push(contact.toResponse()); | ||||
| 		}); | ||||
| 		return responseContacts; | ||||
| 	} | ||||
|  | ||||
| 	@Get('/:id') | ||||
| 	@Authorized("CONTACT:GET") | ||||
| 	@ResponseSchema(ResponseGroupContact) | ||||
| 	@ResponseSchema(GroupContactNotFoundError, { statusCode: 404 }) | ||||
| 	@OnUndefined(GroupContactNotFoundError) | ||||
| 	@OpenAPI({ description: 'Lists all information about the contact whose id got provided. <br> This includes the contact\'s associated groups.' }) | ||||
| 	async getOne(@Param('id') id: number) { | ||||
| 		let contact = await this.contactRepository.findOne({ id: id }, { relations: ['groups'] }) | ||||
| 		if (!contact) { throw new GroupContactNotFoundError(); } | ||||
| 		return contact.toResponse(); | ||||
| 	} | ||||
|  | ||||
| 	@Post() | ||||
| 	@Authorized("CONTACT:CREATE") | ||||
| 	@ResponseSchema(ResponseGroupContact) | ||||
| 	@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 }) | ||||
| 	@OpenAPI({ description: 'Create a new contact.' }) | ||||
| 	async post(@Body({ validate: true }) createContact: CreateGroupContact) { | ||||
| 		let contact; | ||||
| 		try { | ||||
| 			contact = await createContact.toEntity(); | ||||
| 		} catch (error) { | ||||
| 			throw error; | ||||
| 		} | ||||
|  | ||||
| 		contact = await this.contactRepository.save(contact) | ||||
| 		return (await this.contactRepository.findOne({ id: contact.id }, { relations: ['groups'] })).toResponse(); | ||||
| 	} | ||||
|  | ||||
| 	@Put('/:id') | ||||
| 	@Authorized("CONTACT:UPDATE") | ||||
| 	@ResponseSchema(ResponseGroupContact) | ||||
| 	@ResponseSchema(GroupContactNotFoundError, { statusCode: 404 }) | ||||
| 	@ResponseSchema(GroupContactIdsNotMatchingError, { statusCode: 406 }) | ||||
| 	@ResponseSchema(RunnerGroupNotFoundError, { statusCode: 404 }) | ||||
| 	@OpenAPI({ description: "Update the contact whose id you provided. <br> Please remember that ids can't be changed." }) | ||||
| 	async put(@Param('id') id: number, @Body({ validate: true }) contact: UpdateGroupContact) { | ||||
| 		let oldContact = await this.contactRepository.findOne({ id: id }); | ||||
|  | ||||
| 		if (!oldContact) { | ||||
| 			throw new GroupContactNotFoundError(); | ||||
| 		} | ||||
|  | ||||
| 		if (oldContact.id != contact.id) { | ||||
| 			throw new GroupContactIdsNotMatchingError(); | ||||
| 		} | ||||
|  | ||||
| 		await this.contactRepository.save(await contact.update(oldContact)); | ||||
| 		return (await this.contactRepository.findOne({ id: contact.id }, { relations: ['groups'] })).toResponse(); | ||||
| 	} | ||||
|  | ||||
| 	@Delete('/:id') | ||||
| 	@Authorized("CONTACT:DELETE") | ||||
| 	@ResponseSchema(ResponseGroupContact) | ||||
| 	@ResponseSchema(ResponseEmpty, { statusCode: 204 }) | ||||
| 	@OnUndefined(204) | ||||
| 	@OpenAPI({ description: 'Delete the contact whose id you provided. <br> If no contact with this id exists it will just return 204(no content). <br> This won\'t delete any groups associated with the contact.' }) | ||||
| 	async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { | ||||
| 		let contact = await this.contactRepository.findOne({ id: id }); | ||||
| 		if (!contact) { return null; } | ||||
| 		const responseContact = await this.contactRepository.findOne(contact, { relations: ['groups'] }); | ||||
| 		for (let group of responseContact.groups) { | ||||
| 			group.contact = null; | ||||
| 			await getConnection().getRepository(RunnerGroup).save(group); | ||||
| 		} | ||||
|  | ||||
| 		await this.contactRepository.delete(contact); | ||||
| 		return responseContact.toResponse(); | ||||
| 	} | ||||
| } | ||||
| @@ -94,7 +94,7 @@ export class RunnerOrganisationController { | ||||
| 	@ResponseSchema(RunnerOrganisationHasTeamsError, { statusCode: 406 }) | ||||
| 	@ResponseSchema(RunnerOrganisationHasRunnersError, { statusCode: 406 }) | ||||
| 	@OnUndefined(204) | ||||
| 	@OpenAPI({ description: 'Delete the organsisation whose id you provided. <br> If the organisation still has runners and/or teams associated this will fail. <br> To delete the organisation with all associated runners and teams set the force QueryParam to true (cascading deletion might take a while). <br> If no organisation with this id exists it will just return 204(no content).' }) | ||||
| 	@OpenAPI({ description: 'Delete the organsisation whose id you provided. <br> If the organisation still has runners and/or teams associated this will fail. <br> To delete the organisation with all associated runners and teams set the force QueryParam to true (cascading deletion might take a while). <br> This won\'t delete the associated contact. <br> If no organisation with this id exists it will just return 204(no content).' }) | ||||
| 	async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { | ||||
| 		let organisation = await this.runnerOrganisationRepository.findOne({ id: id }); | ||||
| 		if (!organisation) { return null; } | ||||
|   | ||||
| @@ -93,7 +93,7 @@ export class RunnerTeamController { | ||||
| 	@ResponseSchema(ResponseEmpty, { statusCode: 204 }) | ||||
| 	@ResponseSchema(RunnerTeamHasRunnersError, { statusCode: 406 }) | ||||
| 	@OnUndefined(204) | ||||
| 	@OpenAPI({ description: 'Delete the team whose id you provided. <br> If the team still has runners associated this will fail. <br> To delete the team with all associated runners set the force QueryParam to true (cascading deletion might take a while). <br> If no team with this id exists it will just return 204(no content).' }) | ||||
| 	@OpenAPI({ description: 'Delete the team whose id you provided. <br> If the team still has runners associated this will fail. <br> To delete the team with all associated runners set the force QueryParam to true (cascading deletion might take a while). <br> This won\'t delete the associated contact.<br> If no team with this id exists it will just return 204(no content).' }) | ||||
| 	async remove(@Param("id") id: number, @QueryParam("force") force: boolean) { | ||||
| 		let team = await this.runnerTeamRepository.findOne({ id: id }); | ||||
| 		if (!team) { return null; } | ||||
|   | ||||
| @@ -2,18 +2,7 @@ import { IsString } from 'class-validator'; | ||||
| import { NotAcceptableError, NotFoundError } from 'routing-controllers'; | ||||
|  | ||||
| /** | ||||
|  * Error to throw, when a provided groupContact doesn't belong to the accepted types. | ||||
|  */ | ||||
| export class GroupContactWrongTypeError extends NotAcceptableError { | ||||
| 	@IsString() | ||||
| 	name = "GroupContactWrongTypeError" | ||||
|  | ||||
| 	@IsString() | ||||
| 	message = "The groupContact must be an existing groupContact's id. \n You provided a object of another type." | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Error to throw, when a non-existent groupContact get's loaded. | ||||
|  * Error to throw, when a non-existent contact get's requested. | ||||
|  */ | ||||
| export class GroupContactNotFoundError extends NotFoundError { | ||||
| 	@IsString() | ||||
| @@ -21,4 +10,16 @@ export class GroupContactNotFoundError extends NotFoundError { | ||||
|  | ||||
| 	@IsString() | ||||
| 	message = "The groupContact you provided couldn't be located in the system. \n Please check your request." | ||||
| } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Error to throw when two contacts' ids don't match. | ||||
|  * Usually occurs when a user tries to change a contact's id. | ||||
|  */ | ||||
| export class GroupContactIdsNotMatchingError extends NotAcceptableError { | ||||
| 	@IsString() | ||||
| 	name = "GroupContactIdsNotMatchingError" | ||||
|  | ||||
| 	@IsString() | ||||
| 	message = "The ids don't match! \n And if you wanted to change a contact's id: This isn't allowed!" | ||||
| } | ||||
|   | ||||
| @@ -1,10 +1,13 @@ | ||||
| import { IsEmail, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; | ||||
| import { getConnectionManager } from 'typeorm'; | ||||
| import { config } from '../../../config'; | ||||
| import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors'; | ||||
| import { Address } from '../../entities/Address'; | ||||
| import { GroupContact } from '../../entities/GroupContact'; | ||||
| import { RunnerGroup } from '../../entities/RunnerGroup'; | ||||
|  | ||||
| /** | ||||
|  * This classed is used to create a new Group entity from a json body (post request). | ||||
|  * This classed is used to create a new GroupContact entity from a json body (post request). | ||||
|  */ | ||||
| export class CreateGroupContact { | ||||
|     /** | ||||
| @@ -44,25 +47,51 @@ export class CreateGroupContact { | ||||
|     phone?: string; | ||||
|  | ||||
|     /** | ||||
|      * The contact's email address. | ||||
|      * The new contact's email address. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsEmail() | ||||
|     email?: string; | ||||
|  | ||||
|     /** | ||||
|      * The new contacts's groups' ids. | ||||
|      * You can provide either one groupId or an array of groupIDs. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     groups?: number[] | number | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Creates a new Address entity from this. | ||||
|      * Get's all groups for this contact by their id's; | ||||
|      */ | ||||
|     public async getGroups(): Promise<RunnerGroup[]> { | ||||
|         if (!this.groups) { return null; } | ||||
|         let groups = new Array<RunnerGroup>(); | ||||
|         if (!Array.isArray(this.groups)) { | ||||
|             this.groups = [this.groups] | ||||
|         } | ||||
|         for (let group of this.groups) { | ||||
|             let found = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: group }); | ||||
|             if (!found) { throw new RunnerGroupNotFoundError(); } | ||||
|             groups.push(found); | ||||
|         } | ||||
|         return groups; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Creates a new GroupContact entity from this. | ||||
|      */ | ||||
|     public async toEntity(): Promise<GroupContact> { | ||||
|         let 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 = this.address; | ||||
|         Address.validate(contact.address); | ||||
|         return contact; | ||||
|         let newContact: GroupContact = new GroupContact(); | ||||
|         newContact.firstname = this.firstname; | ||||
|         newContact.middlename = this.middlename; | ||||
|         newContact.lastname = this.lastname; | ||||
|         newContact.email = this.email; | ||||
|         newContact.phone = this.phone; | ||||
|         newContact.address = this.address; | ||||
|         Address.validate(newContact.address); | ||||
|         newContact.groups = await this.getGroups(); | ||||
|  | ||||
|         return newContact; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										106
									
								
								src/models/actions/update/UpdateGroupContact.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								src/models/actions/update/UpdateGroupContact.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,106 @@ | ||||
| import { IsEmail, IsInt, IsNotEmpty, IsObject, IsOptional, IsPhoneNumber, IsString } from 'class-validator'; | ||||
| import { getConnectionManager } from 'typeorm'; | ||||
| import { config } from '../../../config'; | ||||
| import { RunnerGroupNotFoundError } from '../../../errors/RunnerGroupErrors'; | ||||
| import { Address } from '../../entities/Address'; | ||||
| import { GroupContact } from '../../entities/GroupContact'; | ||||
| import { RunnerGroup } from '../../entities/RunnerGroup'; | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * This class is used to update a GroupContact entity (via put request). | ||||
|  */ | ||||
| export class UpdateGroupContact { | ||||
|     /** | ||||
|      * The updated contact's id. | ||||
|      * This shouldn't have changed but it is here in case anyone ever wants to enable id changes (whyever they would want to). | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
|  | ||||
|     /** | ||||
|      * The updated contact's first name. | ||||
|      */ | ||||
|     @IsNotEmpty() | ||||
|     @IsString() | ||||
|     firstname: string; | ||||
|  | ||||
|     /** | ||||
|      * The updated contact's middle name. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsString() | ||||
|     middlename?: string; | ||||
|  | ||||
|     /** | ||||
|      * The updated contact's last name. | ||||
|      */ | ||||
|     @IsNotEmpty() | ||||
|     @IsString() | ||||
|     lastname: string; | ||||
|  | ||||
|     /** | ||||
|      * The updated contact's address. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsObject() | ||||
|     address?: Address; | ||||
|  | ||||
|     /** | ||||
|      * The updated contact's phone number. | ||||
|      * This will be validated against the configured country phone numer syntax (default: international). | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsPhoneNumber(config.phone_validation_countrycode) | ||||
|     phone?: string; | ||||
|  | ||||
|     /** | ||||
|      * The updated contact's email address. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     @IsEmail() | ||||
|     email?: string; | ||||
|  | ||||
|     /** | ||||
|      * The updated contacts's groups' ids. | ||||
|      * You can provide either one groupId or an array of groupIDs. | ||||
|      */ | ||||
|     @IsOptional() | ||||
|     groups?: number[] | number | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Get's all groups for this contact by their id's; | ||||
|      */ | ||||
|     public async getGroups(): Promise<RunnerGroup[]> { | ||||
|         if (!this.groups) { return null; } | ||||
|         let groups = new Array<RunnerGroup>(); | ||||
|         if (!Array.isArray(this.groups)) { | ||||
|             this.groups = [this.groups] | ||||
|         } | ||||
|         for (let group of this.groups) { | ||||
|             let found = await getConnectionManager().get().getRepository(RunnerGroup).findOne({ id: group }); | ||||
|             if (!found) { throw new RunnerGroupNotFoundError(); } | ||||
|             groups.push(found); | ||||
|         } | ||||
|         return groups; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Updates a provided Donor entity based on this. | ||||
|      * @param contact the contact you want to update. | ||||
|      */ | ||||
|     public async update(contact: GroupContact): Promise<GroupContact> { | ||||
|         contact.firstname = this.firstname; GroupContact | ||||
|         contact.middlename = this.middlename; | ||||
|         contact.lastname = this.lastname; | ||||
|         contact.phone = this.phone; | ||||
|         contact.email = this.email; | ||||
|         if (!this.address) { contact.address.reset(); } | ||||
|         else { contact.address = this.address; } | ||||
|         Address.validate(contact.address); | ||||
|         contact.groups = await this.getGroups(); | ||||
|  | ||||
|         return contact; | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,4 @@ | ||||
| import { | ||||
|   IsNotEmpty, | ||||
|   IsOptional, | ||||
|   IsPostalCode, | ||||
|   IsString | ||||
| } from "class-validator"; | ||||
| @@ -18,10 +16,9 @@ export class Address { | ||||
|    * The address's first line. | ||||
|    * Containing the street and house number. | ||||
|    */ | ||||
|   @Column() | ||||
|   @Column({ nullable: true }) | ||||
|   @IsString() | ||||
|   @IsNotEmpty() | ||||
|   address1: string; | ||||
|   address1?: string; | ||||
|  | ||||
|   /** | ||||
|    * The address's second line. | ||||
| @@ -29,33 +26,29 @@ export class Address { | ||||
|    */ | ||||
|   @Column({ nullable: true }) | ||||
|   @IsString() | ||||
|   @IsOptional() | ||||
|   address2?: string; | ||||
|  | ||||
|   /** | ||||
|    * The address's postal code. | ||||
|    * This will get checked against the postal code syntax for the configured country. | ||||
|    */ | ||||
|   @Column() | ||||
|   @Column({ nullable: true }) | ||||
|   @IsString() | ||||
|   @IsNotEmpty() | ||||
|   @IsPostalCode(config.postalcode_validation_countrycode) | ||||
|   postalcode: string; | ||||
|  | ||||
|   /** | ||||
|    * The address's city. | ||||
|    */ | ||||
|   @Column() | ||||
|   @Column({ nullable: true }) | ||||
|   @IsString() | ||||
|   @IsNotEmpty() | ||||
|   city: string; | ||||
|  | ||||
|   /** | ||||
|    * The address's country. | ||||
|    */ | ||||
|   @Column() | ||||
|   @Column({ nullable: true }) | ||||
|   @IsString() | ||||
|   @IsNotEmpty() | ||||
|   country: string; | ||||
|  | ||||
|   public reset() { | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import { | ||||
| } from "class-validator"; | ||||
| import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; | ||||
| import { config } from '../../config'; | ||||
| import { ResponseGroupContact } from '../responses/ResponseGroupContact'; | ||||
| import { Address } from "./Address"; | ||||
| import { RunnerGroup } from "./RunnerGroup"; | ||||
|  | ||||
| @@ -53,7 +54,6 @@ export class GroupContact { | ||||
|    * The contact's address. | ||||
|    * This is a address object to prevent any formatting differences. | ||||
|    */ | ||||
|   @IsOptional() | ||||
|   @Column(type => Address) | ||||
|   address?: Address; | ||||
|  | ||||
| @@ -84,7 +84,7 @@ export class GroupContact { | ||||
|   /** | ||||
|    * Turns this entity into it's response class. | ||||
|    */ | ||||
|   public toResponse() { | ||||
|     return new Error("NotImplemented"); | ||||
|   public toResponse(): ResponseGroupContact { | ||||
|     return new ResponseGroupContact(this); | ||||
|   } | ||||
| } | ||||
| @@ -14,5 +14,6 @@ export enum PermissionTarget { | ||||
|     SCAN = 'SCAN', | ||||
|     STATION = 'STATION', | ||||
|     CARD = 'CARD', | ||||
|     DONATION = 'DONATION' | ||||
|     DONATION = 'DONATION', | ||||
|     CONTACT = 'CONTACT' | ||||
| } | ||||
							
								
								
									
										76
									
								
								src/models/responses/ResponseGroupContact.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								src/models/responses/ResponseGroupContact.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| import { IsInt, IsObject, IsString } from "class-validator"; | ||||
| import { Address } from '../entities/Address'; | ||||
| import { GroupContact } from '../entities/GroupContact'; | ||||
| import { ResponseRunnerGroup } from './ResponseRunnerGroup'; | ||||
|  | ||||
| /** | ||||
|  * Defines the group contact response. | ||||
| */ | ||||
| export class ResponseGroupContact { | ||||
|     /** | ||||
|      * The contact's id. | ||||
|      */ | ||||
|     @IsInt() | ||||
|     id: number; | ||||
|  | ||||
|     /** | ||||
|      * The contact's first name. | ||||
|      */ | ||||
|     @IsString() | ||||
|     firstname: string; | ||||
|  | ||||
|     /** | ||||
|      * The contact's middle name. | ||||
|      */ | ||||
|     @IsString() | ||||
|     middlename?: string; | ||||
|  | ||||
|     /** | ||||
|      * The contact's last name. | ||||
|      */ | ||||
|     @IsString() | ||||
|     lastname: string; | ||||
|  | ||||
|     /** | ||||
|      * The contact's phone number. | ||||
|      */ | ||||
|     @IsString() | ||||
|     phone?: string; | ||||
|  | ||||
|     /** | ||||
|      * The contact's e-mail address. | ||||
|      */ | ||||
|     @IsString() | ||||
|     email?: string; | ||||
|  | ||||
|     /** | ||||
|      * The contact's associated runner groups. | ||||
|      */ | ||||
|     @IsObject() | ||||
|     groups: ResponseRunnerGroup[]; | ||||
|  | ||||
|     /** | ||||
|      * The contact's address. | ||||
|      * This is a address object to prevent any formatting differences. | ||||
|      */ | ||||
|     @IsObject() | ||||
|     address?: Address; | ||||
|  | ||||
|     /** | ||||
|      * Creates a ResponseGroupContact object from a contact. | ||||
|      * @param contact The contact the response shall be build for. | ||||
|      */ | ||||
|     public constructor(contact: GroupContact) { | ||||
|         this.id = contact.id; | ||||
|         this.firstname = contact.firstname; | ||||
|         this.middlename = contact.middlename; | ||||
|         this.lastname = contact.lastname; | ||||
|         this.phone = contact.phone; | ||||
|         this.email = contact.email; | ||||
|         this.address = contact.address; | ||||
|         this.groups = new Array<ResponseRunnerGroup>(); | ||||
|         for (let group of contact.groups) { | ||||
|             this.groups.push(group.toResponse()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										216
									
								
								src/tests/contacts/contact_add.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										216
									
								
								src/tests/contacts/contact_add.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,216 @@ | ||||
| import axios from 'axios'; | ||||
| import { config } from '../../config'; | ||||
| const base = "http://localhost:" + config.internal_port | ||||
|  | ||||
| let access_token; | ||||
| let axios_config; | ||||
|  | ||||
| beforeAll(async () => { | ||||
|     const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); | ||||
|     access_token = res.data["access_token"]; | ||||
|     axios_config = { | ||||
|         headers: { "authorization": "Bearer " + access_token }, | ||||
|         validateStatus: undefined | ||||
|     }; | ||||
| }); | ||||
|  | ||||
| // --------------- | ||||
| describe('POST /api/contacts with errors', () => { | ||||
|     it('creating a new contact without any parameters should return 400', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', null, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact without a last name should return 400', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "middlename": "middle" | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a invalid phone number should return 400', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "middlename": "middle", | ||||
|             "lastname": "last", | ||||
|             "phone": "123" | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a invalid mail address should return 400', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "phone": null, | ||||
|             "email": "123", | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with an invalid address 400', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "address": { | ||||
|                 "city": "Testcity" | ||||
|             } | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(400); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a invalid group should return 404', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "string", | ||||
|             "middlename": "string", | ||||
|             "lastname": "string", | ||||
|             "groups": 9999999999999 | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('POST /api/contacts working (simple)', () => { | ||||
|     it('creating a new contact with only needed params should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last" | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with all non-relationship optional params should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "middlename": "middle", | ||||
|             "lastname": "last", | ||||
|             "email": "testContact@lauf-fuer-kaya.de", | ||||
|             "phone": "+49017612345678", | ||||
|             "address": { | ||||
|                 "address1": "test", | ||||
|                 "address2": null, | ||||
|                 "city": "herzogenaurach", | ||||
|                 "country": "germany", | ||||
|                 "postalcode": "91074", | ||||
|             } | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('POST /api/contacts working (with group)', () => { | ||||
|     let added_org; | ||||
|     let added_team; | ||||
|     let added_contact; | ||||
|     it('creating a new org with just a name should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/organisations', { | ||||
|             "name": "test123" | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.teams; | ||||
|         added_org = res.data | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new team with a parent org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/teams', { | ||||
|             "name": "test_team", | ||||
|             "parentGroup": added_org.id | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.parentGroup; | ||||
|         added_team = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a valid org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": added_org.id | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         delete res.data.id; | ||||
|         expect(res.data).toEqual({ | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [added_org] | ||||
|         }); | ||||
|     }); | ||||
|     it('creating a new contact with a valid team should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": added_team.id | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         delete res.data.id; | ||||
|         expect(res.data).toEqual({ | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [added_team] | ||||
|         }); | ||||
|     }); | ||||
|     it('creating a new contact with a valid org and team should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": [added_org.id, added_team.id] | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         added_contact = res.data | ||||
|         delete res.data.id; | ||||
|         expect(res.data).toEqual({ | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [added_org, added_team] | ||||
|         }); | ||||
|     }); | ||||
|     it('checking if the added team\'s contact is the new contact should return 200', async () => { | ||||
|         const res = await axios.get(base + '/api/teams/' + added_team.id, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         delete res.data.contact.groups; | ||||
|         delete res.data.contact.id; | ||||
|         delete added_contact.groups; | ||||
|         expect(res.data.contact).toEqual(added_contact); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										183
									
								
								src/tests/contacts/contact_delete.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								src/tests/contacts/contact_delete.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | ||||
| import axios from 'axios'; | ||||
| import { config } from '../../config'; | ||||
| const base = "http://localhost:" + config.internal_port | ||||
|  | ||||
| let access_token; | ||||
| let axios_config; | ||||
|  | ||||
| beforeAll(async () => { | ||||
|     const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); | ||||
|     access_token = res.data["access_token"]; | ||||
|     axios_config = { | ||||
|         headers: { "authorization": "Bearer " + access_token }, | ||||
|         validateStatus: undefined | ||||
|     }; | ||||
| }); | ||||
|  | ||||
| describe('adding + deletion (non-existant)', () => { | ||||
|     it('delete', async () => { | ||||
|         const res = await axios.delete(base + '/api/contacts/0', axios_config); | ||||
|         expect(res.status).toEqual(204); | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('add+delete (simple)', () => { | ||||
|     let added_contact; | ||||
|     it('creating a new contact with only needed params should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last" | ||||
|         }, axios_config); | ||||
|         added_contact = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('delete contact', async () => { | ||||
|         const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|         let deleted_contact = res.data | ||||
|         expect(deleted_contact).toEqual(added_contact); | ||||
|     }); | ||||
|     it('check if contact really was deleted', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('add+delete (with org)', () => { | ||||
|     let added_org; | ||||
|     let added_contact; | ||||
|     it('creating a new org with just a name should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/organisations', { | ||||
|             "name": "test123" | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.teams; | ||||
|         added_org = res.data | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a valid org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": added_org.id | ||||
|         }, axios_config); | ||||
|         added_contact = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
|     it('delete contact', async () => { | ||||
|         const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|         delete res.data.groups[0].contact; | ||||
|         expect(res.data).toEqual(added_contact); | ||||
|     }); | ||||
|     it('check if contact really was deleted', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('add+delete (with team)', () => { | ||||
|     let added_org; | ||||
|     let added_team; | ||||
|     let added_contact; | ||||
|     it('creating a new org with just a name should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/organisations', { | ||||
|             "name": "test123" | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.teams; | ||||
|         added_org = res.data | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new team with a parent org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/teams', { | ||||
|             "name": "test_team", | ||||
|             "parentGroup": added_org.id | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.parentGroup; | ||||
|         added_team = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a valid team should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": added_team.id | ||||
|         }, axios_config); | ||||
|         added_contact = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
|     it('delete contact', async () => { | ||||
|         const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|         delete res.data.groups[0].contact; | ||||
|         expect(res.data).toEqual(added_contact); | ||||
|     }); | ||||
|     it('check if contact really was deleted', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('add+delete (with org&team)', () => { | ||||
|     let added_org; | ||||
|     let added_team; | ||||
|     let added_contact; | ||||
|     it('creating a new org with just a name should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/organisations', { | ||||
|             "name": "test123" | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.teams; | ||||
|         added_org = res.data | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new team with a parent org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/teams', { | ||||
|             "name": "test_team", | ||||
|             "parentGroup": added_org.id | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.parentGroup; | ||||
|         added_team = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a valid org and team should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": [added_org.id, added_team.id] | ||||
|         }, axios_config); | ||||
|         added_contact = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
|     it('delete contact', async () => { | ||||
|         const res = await axios.delete(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|         delete res.data.groups[0].contact; | ||||
|         delete res.data.groups[1].contact; | ||||
|         expect(res.data).toEqual(added_contact); | ||||
|     }); | ||||
|     it('check if contact really was deleted', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										57
									
								
								src/tests/contacts/contact_get.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/tests/contacts/contact_get.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| import axios from 'axios'; | ||||
| import { config } from '../../config'; | ||||
| const base = "http://localhost:" + config.internal_port | ||||
| let access_token; | ||||
| let axios_config; | ||||
|  | ||||
| beforeAll(async () => { | ||||
|     const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); | ||||
|     access_token = res.data["access_token"]; | ||||
|     axios_config = { | ||||
|         headers: { "authorization": "Bearer " + access_token }, | ||||
|         validateStatus: undefined | ||||
|     }; | ||||
| }); | ||||
|  | ||||
| describe('GET /api/contacts', () => { | ||||
|     it('basic get should return 200', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts', axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('GET /api/contacts/0', () => { | ||||
|     it('basic get should return 404', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts/0', axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('GET /api/contacts after adding', () => { | ||||
|     let added_contact; | ||||
|     it('creating a new donor with only needed params should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last" | ||||
|         }, axios_config); | ||||
|         added_contact = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('explicit get should return 200', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts/' + added_contact.id, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|         let gotten_donor = res.data | ||||
|         expect(gotten_donor).toEqual(added_contact); | ||||
|     }); | ||||
|     it('get from all runners should return 200', async () => { | ||||
|         const res = await axios.get(base + '/api/contacts/', axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|         let gotten_donors = res.data | ||||
|         expect(gotten_donors).toContainEqual(added_contact); | ||||
|     }); | ||||
| }); | ||||
							
								
								
									
										237
									
								
								src/tests/contacts/contact_update.spec.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										237
									
								
								src/tests/contacts/contact_update.spec.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,237 @@ | ||||
| import axios from 'axios'; | ||||
| import { config } from '../../config'; | ||||
| const base = "http://localhost:" + config.internal_port | ||||
|  | ||||
| let access_token; | ||||
| let axios_config; | ||||
|  | ||||
| beforeAll(async () => { | ||||
|     const res = await axios.post(base + '/api/auth/login', { username: "demo", password: "demo" }); | ||||
|     access_token = res.data["access_token"]; | ||||
|     axios_config = { | ||||
|         headers: { "authorization": "Bearer " + access_token }, | ||||
|         validateStatus: undefined | ||||
|     }; | ||||
| }); | ||||
|  | ||||
| describe('Update contact name after adding', () => { | ||||
|     let added_contact; | ||||
|     it('creating a new contact with only needed params should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last" | ||||
|         }, axios_config); | ||||
|         added_contact = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('valid update should return 200', async () => { | ||||
|         let contact_copy = added_contact | ||||
|         contact_copy.firstname = "second" | ||||
|         const res = await axios.put(base + '/api/contacts/' + added_contact.id, contact_copy, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|         expect(res.data).toEqual(contact_copy); | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('Update contact id after adding(should fail)', () => { | ||||
|     let added_contact; | ||||
|     it('creating a new donor with only needed params should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last" | ||||
|         }, axios_config); | ||||
|         added_contact = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('invalid update should return 406', async () => { | ||||
|         added_contact.id++; | ||||
|         const res = await axios.put(base + '/api/contacts/' + (added_contact.id - 1), added_contact, axios_config); | ||||
|         expect(res.status).toEqual(406); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('Update contact group after adding (should work)', () => { | ||||
|     let added_org; | ||||
|     let added_team; | ||||
|     let added_contact; | ||||
|     it('creating a new org with just a name should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/organisations', { | ||||
|             "name": "test123" | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.teams; | ||||
|         added_org = res.data | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new team with a parent org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/teams', { | ||||
|             "name": "test_team", | ||||
|             "parentGroup": added_org.id | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.parentGroup; | ||||
|         added_team = res.data; | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a valid org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": added_org.id | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         added_contact = res.data | ||||
|         expect(res.data).toEqual({ | ||||
|             "id": res.data.id, | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [added_org] | ||||
|         }); | ||||
|     }); | ||||
|     it('valid group update to single team should return 200', async () => { | ||||
|         const res = await axios.put(base + '/api/contacts/' + added_contact.id, { | ||||
|             "id": added_contact.id, | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": added_team.id | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         expect(res.data).toEqual({ | ||||
|             "id": res.data.id, | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [added_team] | ||||
|         }); | ||||
|     }); | ||||
|     it('valid group update to org and team should return 200', async () => { | ||||
|         const res = await axios.put(base + '/api/contacts/' + added_contact.id, { | ||||
|             "id": added_contact.id, | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": [added_org.id, added_team.id] | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         expect(res.data).toEqual({ | ||||
|             "id": res.data.id, | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [added_org, added_team] | ||||
|         }); | ||||
|     }); | ||||
|     it('valid group update to none should return 200', async () => { | ||||
|         const res = await axios.put(base + '/api/contacts/' + added_contact.id, { | ||||
|             "id": added_contact.id, | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": null | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         expect(res.data).toEqual({ | ||||
|             "id": res.data.id, | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [] | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| // --------------- | ||||
| describe('Update contact group invalid after adding (should fail)', () => { | ||||
|     let added_org; | ||||
|     let added_contact; | ||||
|     it('creating a new org with just a name should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/organisations', { | ||||
|             "name": "test123" | ||||
|         }, axios_config); | ||||
|         delete res.data.contact; | ||||
|         delete res.data.teams; | ||||
|         added_org = res.data | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json") | ||||
|     }); | ||||
|     it('creating a new contact with a valid org should return 200', async () => { | ||||
|         const res = await axios.post(base + '/api/contacts', { | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": added_org.id | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(200); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|         added_contact = res.data | ||||
|         expect(res.data).toEqual({ | ||||
|             "id": res.data.id, | ||||
|             "firstname": "first", | ||||
|             "middlename": null, | ||||
|             "lastname": "last", | ||||
|             "phone": null, | ||||
|             "email": null, | ||||
|             "address": { | ||||
|                 "address1": null, | ||||
|                 "address2": null, | ||||
|                 "postalcode": null, | ||||
|                 "city": null, | ||||
|                 "country": null | ||||
|             }, | ||||
|             "groups": [added_org] | ||||
|         }); | ||||
|     }); | ||||
|     it('invalid group update to single team should return 404', async () => { | ||||
|         const res = await axios.put(base + '/api/contacts/' + added_contact.id, { | ||||
|             "id": added_contact.id, | ||||
|             "firstname": "first", | ||||
|             "lastname": "last", | ||||
|             "groups": 999999999999999 | ||||
|         }, axios_config); | ||||
|         expect(res.status).toEqual(404); | ||||
|         expect(res.headers['content-type']).toContain("application/json"); | ||||
|     }); | ||||
| }); | ||||
		Reference in New Issue
	
	Block a user