From 5ffc710d90c98728b839302312b7771733618ff0 Mon Sep 17 00:00:00 2001 From: romarionijim Date: Thu, 6 Feb 2025 19:20:45 +0200 Subject: [PATCH 1/3] refactor: update gender-related API calls in UsersApiTests --- tests/api_tests/users/UsersApiTests.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/api_tests/users/UsersApiTests.spec.ts b/tests/api_tests/users/UsersApiTests.spec.ts index 3ae9122..1063397 100644 --- a/tests/api_tests/users/UsersApiTests.spec.ts +++ b/tests/api_tests/users/UsersApiTests.spec.ts @@ -22,8 +22,8 @@ test.describe('Api tests for GoRestApi endpoints', async () => { test('gender equality - [POST] /users', { tag: [TestTags.Users] }, async ({ usersApi }) => { await test.step('make an api request to make both male and female genders equal', async () => { await usersApi.makeBothGendersEven(); - let maleGender = await usersApi.getGender('male') - let femaleGender = await usersApi.getGender('female') + let maleGender = await usersApi.getGenderCount('male') + let femaleGender = await usersApi.getGenderCount('female') expect(maleGender).toEqual(femaleGender) }) }) @@ -44,7 +44,7 @@ test.describe('Api tests for GoRestApi endpoints', async () => { await test.step('make a request to delete all users that have an inactive status', async () => { let response = await usersApi.deleteInactiveUsers() expect(response?.status()).toBe(StatusCode.UNAUTHORIZED) - let actualInactiveUsers = await usersApi.getInActiveUsers() + let actualInactiveUsers = await usersApi.getInactiveUsers() let expectedInactiveUsersLength = actualInactiveUsers.length expect(expectedInactiveUsersLength).toBe(0) }) From 50133d135df8182649666c0bb55f3303b3f9b309 Mon Sep 17 00:00:00 2001 From: romarionijim Date: Thu, 6 Feb 2025 19:22:18 +0200 Subject: [PATCH 2/3] refactor: refine access modifiers and function placement --- infra/api/entities/petStore/PetStore.ts | 18 +++-- infra/api/entities/pokemon/PokemonApi.ts | 4 +- infra/api/entities/users-api/Users.ts | 86 +++++++++++++----------- infra/api/helpers/types/api-types.ts | 1 - 4 files changed, 61 insertions(+), 48 deletions(-) diff --git a/infra/api/entities/petStore/PetStore.ts b/infra/api/entities/petStore/PetStore.ts index 74bfa0b..0cd5e28 100644 --- a/infra/api/entities/petStore/PetStore.ts +++ b/infra/api/entities/petStore/PetStore.ts @@ -9,12 +9,12 @@ export class PetStoreApi extends ApiClient { private petStorePetEndpoint = `${ApplicationUrl.PET_STORE_URL}/${ApiEndpoints.PET}` - public async getPet(petId: number): Promise { + async getPet(petId: number): Promise { let response = await this.get(`${this.petStorePetEndpoint}/${petId}`) return response; } - public async createNewPet(petData: { [key: string]: T }) { + async createNewPet(petData: { [key: string]: T }) { let response = await this.post(this.petStorePetEndpoint, { requestData: petData }) return response; } @@ -22,7 +22,7 @@ export class PetStoreApi extends ApiClient { /** * @description this function uploads a pet image via reading a file and uploading it as a buffer file using the playwright multipart photo upload */ - public async uploadPetImage(petId: number, fileName: string) { + async uploadPetImage(petId: number, fileName: string) { const rootDir = '.' const file = path.resolve(rootDir, fileName); const image = fs.readFileSync(file); @@ -33,16 +33,22 @@ export class PetStoreApi extends ApiClient { buffer: image, }, } - let response = await this.post(`${this.petStorePetEndpoint}/${petId}/${ApiEndpoints.UPLOAD_IMAGE}`, { isMultiPart: true, multiPartData }) + let response = await this.post( + `${this.petStorePetEndpoint}/${petId}/${ApiEndpoints.UPLOAD_IMAGE}`, + { + isMultiPart: true, + multiPartData + } + ) return response; } - public async updatePet(updatedData: { [key: string]: T }) { + async updatePet(updatedData: { [key: string]: T }) { let response = await this.put(this.petStorePetEndpoint, { requestData: updatedData }) return response; } - public async deletePet(petId: number) { + async deletePet(petId: number) { let response = await this.delete(`${this.petStorePetEndpoint}/${petId}`) return response; } diff --git a/infra/api/entities/pokemon/PokemonApi.ts b/infra/api/entities/pokemon/PokemonApi.ts index b720628..56dc951 100644 --- a/infra/api/entities/pokemon/PokemonApi.ts +++ b/infra/api/entities/pokemon/PokemonApi.ts @@ -7,7 +7,7 @@ export class PokemonApi extends ApiClient { private POKEMON_BASE_URL = ApplicationUrl.POKEMON_URL; private POKEMON_ENDPOINT = `${this.POKEMON_BASE_URL}/${ApiEndpoints.POKEMON}`; - public async getPokemon() { + async getPokemon() { let response = await this.get(this.POKEMON_ENDPOINT) return response; } @@ -15,7 +15,7 @@ export class PokemonApi extends ApiClient { /** * @description get all pokemon recourses by using pagination - you can choose via page or limit and offset pagination mechanism */ - public async getAllPokemonRecourses(limit: number, offset: number) { + async getAllPokemonRecourses(limit: number, offset: number) { let responses = await this.paginateRequest( RequestMethod.GET, this.POKEMON_ENDPOINT, diff --git a/infra/api/entities/users-api/Users.ts b/infra/api/entities/users-api/Users.ts index c2a4abe..e312d3b 100644 --- a/infra/api/entities/users-api/Users.ts +++ b/infra/api/entities/users-api/Users.ts @@ -6,15 +6,15 @@ import { ApiEndpoints } from "@api-endpoints"; export class Users extends ApiClient { private usersEndpoint = `${ApplicationUrl.GO_REST_API}/${ApiEndpoints.USERS_ENDPOINT}` - public async getUsers() { + async getUsers() { let response = await this.get(this.usersEndpoint) return response; } - public async getGender(gender: string) { + async getGenderCount(gender: string) { let response = await this.get(this.usersEndpoint) let responseObject = await response?.json() - let genderFilter = responseObject.filter((el: any) => el.gender === gender).length + let genderFilter = responseObject.filter((el: { gender: string; }) => el.gender === gender).length return genderFilter } @@ -22,21 +22,21 @@ export class Users extends ApiClient { * @description make both genders even for the first default 10 records without pagination * @returns */ - public async makeBothGendersEven() { + async makeBothGendersEven() { let response: APIResponse | undefined - let maleUsers = await this.getGender('male'); - let femaleUsers = await this.getGender('female'); + let maleUsers = await this.getGenderCount('male'); + let femaleUsers = await this.getGenderCount('female'); try { let difference = Math.abs(maleUsers - femaleUsers) if (maleUsers === femaleUsers) { return; } else if (maleUsers > femaleUsers) { for (let i = 0; i < difference; i++) { - response = await this.post(this.usersEndpoint, { requestData: payloads.femaleData, isAuthorizationRequired: true }) + response = await this.post(this.usersEndpoint, { requestData: payloads.femaleData }) } } else { for (let i = 0; i < difference; i++) { - response = await this.post(this.usersEndpoint, { requestData: payloads.maleData, isAuthorizationRequired: true }) + response = await this.post(this.usersEndpoint, { requestData: payloads.maleData }) } } return response; @@ -45,23 +45,16 @@ export class Users extends ApiClient { } } - private async getUserStatus(status: string) { - let users = await this.get(this.usersEndpoint) - let usersJsonObject = await users?.json() - let inactiveUsers = usersJsonObject.filter((user: { status: string; }) => user.status === status) - return inactiveUsers - } - - public async getInActiveUsers() { - let res = await this.getUserStatus('inactive') - return res + async getInactiveUsers() { + let response = await this.getUserStatus('inactive') + return response } - public async deleteInactiveUsers() { + async deleteInactiveUsers() { let response: APIResponse | undefined - let inActiveUsers = await this.getInActiveUsers() + let inActiveUsers = await this.getInactiveUsers() for (let user of inActiveUsers) { - response = await this.delete(`${this.usersEndpoint}/${user.id}`, { isAuthorizationRequired: true }) + response = await this.delete(`${this.usersEndpoint}/${user.id}`) } return response; } @@ -70,7 +63,7 @@ export class Users extends ApiClient { * @description get all of the users using page pagination * @returns */ - public async getAllUsers(page: number) { + async getAllUsers(page: number) { let response = await this.paginateRequest( RequestMethod.GET, this.usersEndpoint, @@ -82,26 +75,23 @@ export class Users extends ApiClient { return response; } - public async getTypeOfUserProperties() { - let users = await this.getUsers(); - let userObject = await users?.json() - let types: any = []; - for (let user of userObject) { - types.push([typeof user.id, typeof user.name, typeof user.email, typeof user.gender, typeof user.status]); - } - return types; + async getTypeOfUserProperties() { + const usersResponse = await this.getUsers(); + const users = await usersResponse?.json(); + return users.map((user: any) => [ + typeof user.id, + typeof user.name, + typeof user.email, + typeof user.gender, + typeof user.status + ]); } - private async extractEmailExtension(email: string) { - let domain = email.split('@').pop() - let extension = domain?.split('.').pop() - return extension - } /** * @description replaces each email with .co.il extension - */ - public async replaceEmailExtensionForUsers() { + */ + async replaceEmailExtensionForUsers() { let users = await this.getUsers() let usersObject = await users?.json() let response: APIResponse | undefined @@ -112,7 +102,12 @@ export class Users extends ApiClient { if (emailExtension && emailExtension !== 'co.il') { let newEmail = await email.replace(emailExtension, 'co.il'); let newEmailProperty = { email: newEmail } - response = await this.patch(`${this.usersEndpoint}/${user.id}`, { requestData: newEmailProperty, isAuthorizationRequired: true }) + response = await this.patch( + `${this.usersEndpoint}/${user.id}`, + { + requestData: newEmailProperty + } + ) } } return response @@ -121,7 +116,7 @@ export class Users extends ApiClient { } } - public async getCurrentUserEmailExtension() { + async getCurrentUserEmailExtension() { let extensions: string[] = [] let users = await this.getUsers() let usersJsonObject = await users?.json() @@ -132,4 +127,17 @@ export class Users extends ApiClient { } return extensions } + + private async getUserStatus(status: string) { + let users = await this.get(this.usersEndpoint) + let usersJsonObject = await users?.json() + let inactiveUsers = usersJsonObject.filter((user: { status: string; }) => user.status === status) + return inactiveUsers + } + + private async extractEmailExtension(email: string) { + let domain = email.split('@').pop() + let extension = domain?.split('.').pop() + return extension + } } \ No newline at end of file diff --git a/infra/api/helpers/types/api-types.ts b/infra/api/helpers/types/api-types.ts index 27444f4..5887990 100644 --- a/infra/api/helpers/types/api-types.ts +++ b/infra/api/helpers/types/api-types.ts @@ -41,7 +41,6 @@ export interface IPagination { export interface IRequestOptions { queryParams?: { [key: string]: any }, requestData?: { [key: string]: T }, - isAuthorizationRequired?: boolean, isMultiPart?: boolean, multiPartData?: { [key: string]: any }, } From 2e965a208ec223c0e67967784704e593a5d9c94a Mon Sep 17 00:00:00 2001 From: romarionijim Date: Thu, 6 Feb 2025 19:25:41 +0200 Subject: [PATCH 3/3] refactor: remove public access modifier from API methods for consistency --- infra/api/entities/petStore/PetStore.ts | 18 ++++--- infra/api/entities/pokemon/PokemonApi.ts | 4 +- infra/api/entities/users-api/Users.ts | 60 +++++++++------------ tests/api_tests/users/UsersApiTests.spec.ts | 6 +-- 4 files changed, 42 insertions(+), 46 deletions(-) diff --git a/infra/api/entities/petStore/PetStore.ts b/infra/api/entities/petStore/PetStore.ts index 74bfa0b..0cd5e28 100644 --- a/infra/api/entities/petStore/PetStore.ts +++ b/infra/api/entities/petStore/PetStore.ts @@ -9,12 +9,12 @@ export class PetStoreApi extends ApiClient { private petStorePetEndpoint = `${ApplicationUrl.PET_STORE_URL}/${ApiEndpoints.PET}` - public async getPet(petId: number): Promise { + async getPet(petId: number): Promise { let response = await this.get(`${this.petStorePetEndpoint}/${petId}`) return response; } - public async createNewPet(petData: { [key: string]: T }) { + async createNewPet(petData: { [key: string]: T }) { let response = await this.post(this.petStorePetEndpoint, { requestData: petData }) return response; } @@ -22,7 +22,7 @@ export class PetStoreApi extends ApiClient { /** * @description this function uploads a pet image via reading a file and uploading it as a buffer file using the playwright multipart photo upload */ - public async uploadPetImage(petId: number, fileName: string) { + async uploadPetImage(petId: number, fileName: string) { const rootDir = '.' const file = path.resolve(rootDir, fileName); const image = fs.readFileSync(file); @@ -33,16 +33,22 @@ export class PetStoreApi extends ApiClient { buffer: image, }, } - let response = await this.post(`${this.petStorePetEndpoint}/${petId}/${ApiEndpoints.UPLOAD_IMAGE}`, { isMultiPart: true, multiPartData }) + let response = await this.post( + `${this.petStorePetEndpoint}/${petId}/${ApiEndpoints.UPLOAD_IMAGE}`, + { + isMultiPart: true, + multiPartData + } + ) return response; } - public async updatePet(updatedData: { [key: string]: T }) { + async updatePet(updatedData: { [key: string]: T }) { let response = await this.put(this.petStorePetEndpoint, { requestData: updatedData }) return response; } - public async deletePet(petId: number) { + async deletePet(petId: number) { let response = await this.delete(`${this.petStorePetEndpoint}/${petId}`) return response; } diff --git a/infra/api/entities/pokemon/PokemonApi.ts b/infra/api/entities/pokemon/PokemonApi.ts index b720628..56dc951 100644 --- a/infra/api/entities/pokemon/PokemonApi.ts +++ b/infra/api/entities/pokemon/PokemonApi.ts @@ -7,7 +7,7 @@ export class PokemonApi extends ApiClient { private POKEMON_BASE_URL = ApplicationUrl.POKEMON_URL; private POKEMON_ENDPOINT = `${this.POKEMON_BASE_URL}/${ApiEndpoints.POKEMON}`; - public async getPokemon() { + async getPokemon() { let response = await this.get(this.POKEMON_ENDPOINT) return response; } @@ -15,7 +15,7 @@ export class PokemonApi extends ApiClient { /** * @description get all pokemon recourses by using pagination - you can choose via page or limit and offset pagination mechanism */ - public async getAllPokemonRecourses(limit: number, offset: number) { + async getAllPokemonRecourses(limit: number, offset: number) { let responses = await this.paginateRequest( RequestMethod.GET, this.POKEMON_ENDPOINT, diff --git a/infra/api/entities/users-api/Users.ts b/infra/api/entities/users-api/Users.ts index c2a4abe..52b45f0 100644 --- a/infra/api/entities/users-api/Users.ts +++ b/infra/api/entities/users-api/Users.ts @@ -6,15 +6,15 @@ import { ApiEndpoints } from "@api-endpoints"; export class Users extends ApiClient { private usersEndpoint = `${ApplicationUrl.GO_REST_API}/${ApiEndpoints.USERS_ENDPOINT}` - public async getUsers() { + async getUsers() { let response = await this.get(this.usersEndpoint) return response; } - public async getGender(gender: string) { + async getGenderCount(gender: string) { let response = await this.get(this.usersEndpoint) let responseObject = await response?.json() - let genderFilter = responseObject.filter((el: any) => el.gender === gender).length + let genderFilter = responseObject.filter((el: { gender: string; }) => el.gender === gender).length return genderFilter } @@ -22,10 +22,10 @@ export class Users extends ApiClient { * @description make both genders even for the first default 10 records without pagination * @returns */ - public async makeBothGendersEven() { + async makeBothGendersEven() { let response: APIResponse | undefined - let maleUsers = await this.getGender('male'); - let femaleUsers = await this.getGender('female'); + let maleUsers = await this.getGenderCount('male'); + let femaleUsers = await this.getGenderCount('female'); try { let difference = Math.abs(maleUsers - femaleUsers) if (maleUsers === femaleUsers) { @@ -45,21 +45,14 @@ export class Users extends ApiClient { } } - private async getUserStatus(status: string) { - let users = await this.get(this.usersEndpoint) - let usersJsonObject = await users?.json() - let inactiveUsers = usersJsonObject.filter((user: { status: string; }) => user.status === status) - return inactiveUsers - } - - public async getInActiveUsers() { - let res = await this.getUserStatus('inactive') - return res + async getInactiveUsers() { + let response = await this.getUserStatus('inactive') + return response } - public async deleteInactiveUsers() { + async deleteInactiveUsers() { let response: APIResponse | undefined - let inActiveUsers = await this.getInActiveUsers() + let inActiveUsers = await this.getInactiveUsers() for (let user of inActiveUsers) { response = await this.delete(`${this.usersEndpoint}/${user.id}`, { isAuthorizationRequired: true }) } @@ -70,7 +63,7 @@ export class Users extends ApiClient { * @description get all of the users using page pagination * @returns */ - public async getAllUsers(page: number) { + async getAllUsers(page: number) { let response = await this.paginateRequest( RequestMethod.GET, this.usersEndpoint, @@ -82,26 +75,23 @@ export class Users extends ApiClient { return response; } - public async getTypeOfUserProperties() { - let users = await this.getUsers(); - let userObject = await users?.json() - let types: any = []; - for (let user of userObject) { - types.push([typeof user.id, typeof user.name, typeof user.email, typeof user.gender, typeof user.status]); - } - return types; + async getTypeOfUserProperties() { + const usersResponse = await this.getUsers(); + const users = await usersResponse?.json(); + return users.map((user: any) => [ + typeof user.id, + typeof user.name, + typeof user.email, + typeof user.gender, + typeof user.status + ]); } - private async extractEmailExtension(email: string) { - let domain = email.split('@').pop() - let extension = domain?.split('.').pop() - return extension - } /** * @description replaces each email with .co.il extension - */ - public async replaceEmailExtensionForUsers() { + */ + async replaceEmailExtensionForUsers() { let users = await this.getUsers() let usersObject = await users?.json() let response: APIResponse | undefined @@ -121,7 +111,7 @@ export class Users extends ApiClient { } } - public async getCurrentUserEmailExtension() { + async getCurrentUserEmailExtension() { let extensions: string[] = [] let users = await this.getUsers() let usersJsonObject = await users?.json() diff --git a/tests/api_tests/users/UsersApiTests.spec.ts b/tests/api_tests/users/UsersApiTests.spec.ts index 3ae9122..1063397 100644 --- a/tests/api_tests/users/UsersApiTests.spec.ts +++ b/tests/api_tests/users/UsersApiTests.spec.ts @@ -22,8 +22,8 @@ test.describe('Api tests for GoRestApi endpoints', async () => { test('gender equality - [POST] /users', { tag: [TestTags.Users] }, async ({ usersApi }) => { await test.step('make an api request to make both male and female genders equal', async () => { await usersApi.makeBothGendersEven(); - let maleGender = await usersApi.getGender('male') - let femaleGender = await usersApi.getGender('female') + let maleGender = await usersApi.getGenderCount('male') + let femaleGender = await usersApi.getGenderCount('female') expect(maleGender).toEqual(femaleGender) }) }) @@ -44,7 +44,7 @@ test.describe('Api tests for GoRestApi endpoints', async () => { await test.step('make a request to delete all users that have an inactive status', async () => { let response = await usersApi.deleteInactiveUsers() expect(response?.status()).toBe(StatusCode.UNAUTHORIZED) - let actualInactiveUsers = await usersApi.getInActiveUsers() + let actualInactiveUsers = await usersApi.getInactiveUsers() let expectedInactiveUsersLength = actualInactiveUsers.length expect(expectedInactiveUsersLength).toBe(0) })