Created
July 31, 2022 08:55
-
-
Save jamal-abbasi/4b144ade6598a9e2fd3080fb86ba6d61 to your computer and use it in GitHub Desktop.
Unit Testing GraphQL resolver in nest.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Resolver, Query, Args, Mutation } from '@nestjs/graphql'; | |
import { KeyValInput } from '@common/inputs/key-val.input'; | |
import { CurrentUser, Fields } from '@common/decorators'; | |
import { ICurrentUser } from '@common/interfaces'; | |
import { AccountTypeService } from '@app/v1/account-type/account-type.service'; | |
import { AccountType, AccountTypeWithPagination } from '@app/v1/account-type/account-type.model'; | |
import { AccountTypeFilterParams, AccountTypeUpdateDto, ApproveAccountTypeInput } from './account-type.dto'; | |
import { PaginationParams, SortingParam } from '@rubix/common'; | |
@Resolver(AccountType) | |
export class AccountTypeResolver { | |
constructor(private readonly accountService: AccountTypeService) {} | |
@Query(() => [AccountType]) | |
async accountTypes( | |
@Fields() output: string[], | |
@CurrentUser() currentUser: ICurrentUser, | |
): Promise<AccountType[]> { | |
return this.accountService.list(currentUser, output); | |
} | |
@Mutation(() => [AccountType]) | |
async updateMultipleAccountTypes( | |
@Args('input', { description: 'Create Service Request' }) | |
input: AccountTypeUpdateDto, | |
@Fields() output: string[], | |
): Promise<AccountType[]> { | |
return this.accountService.updateMany(input, output); | |
} | |
@Query(() => AccountType, { nullable: true }) | |
async findById( | |
@Args('id', { description: 'Account Type Id (UUID)' }) id: string, | |
@Fields() output: string[], | |
@CurrentUser() currentUser: ICurrentUser, | |
): Promise<AccountType> { | |
return this.accountService.findById(currentUser, id, output); | |
} | |
@Query(() => [AccountType], { nullable: true }) | |
async findAccountTypesByCodes( | |
@Args('input', { type: () => [String], description: 'Account Type Codes' }) input: string[], | |
@Fields() output: string[], | |
@CurrentUser() currentUser: ICurrentUser, | |
): Promise<AccountType[]> { | |
return this.accountService.findByCodes(currentUser, input, output); | |
} | |
@Query(() => [AccountType]) | |
async findAccountTypeBy( | |
@Args('checks', { | |
type: () => [KeyValInput], | |
description: 'Checks to find a customers', | |
}) | |
checks: KeyValInput[], | |
@Fields() columns: string[], | |
): Promise<AccountType[]> { | |
return this.accountService.findByProperty(checks, columns); | |
} | |
@Mutation(() => [AccountType]) | |
async updateAccountTypes( | |
@Args('input', { description: 'Update account types authorization' }) | |
input: ApproveAccountTypeInput, | |
@Fields() output: string[], | |
@CurrentUser() current_user: ICurrentUser, | |
): Promise<AccountType[]> { | |
return this.accountService.update(current_user, input, output); | |
} | |
@Query(() => AccountTypeWithPagination) | |
async accountTypeList( | |
@Fields() output: string[], | |
@Args('pagination', { | |
nullable: true, | |
description: 'Pagination option (page no & limit)', | |
}) | |
paginationParams: PaginationParams, | |
@Args('filters', { | |
nullable: true, | |
description: 'Custom filter options based on fields', | |
}) | |
filteringParams: AccountTypeFilterParams, | |
@Args('sort_by', { | |
nullable: true, | |
description: 'Sort by (asc/desc) based on field', | |
}) | |
sortingParams: SortingParam, | |
@CurrentUser() currentUser: ICurrentUser, | |
): Promise<AccountTypeWithPagination> { | |
return this.accountService.findAll( | |
currentUser, | |
paginationParams, | |
filteringParams, | |
sortingParams, | |
output, | |
); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Test, TestingModule } from '@nestjs/testing'; | |
import { | |
CONDITION_OPERATORS, | |
ICurrentUser, | |
MAKER_CHECKER_MAIN_STATUS, | |
PaginationParams, | |
SortingParam, | |
} from '@rubix/common'; | |
import { | |
AccountTypeRepository, | |
SRCRequestRepository, | |
} from '@rubix/core/repository'; | |
import { AccountTypeResolver } from './account-type.resolver'; | |
import { AccountType } from './account-type.model'; | |
import { AccountTypeModule } from './account-type.module'; | |
import { SRCRequestService } from '../src-request/src-request.service'; | |
import { SRCRequestModule } from '../src-request/src-request.module'; | |
import { | |
AccountTypeUpdateDto, | |
AccountTypeFilterParams, | |
} from './account-type.dto'; | |
let accountType: AccountType = null; | |
const currentUser: ICurrentUser = { | |
id: 'F4477F0C-2538-4F27-AAB8-13F532605246', | |
tenant_id: process.env.ENV_RBX_TENANT_ID, | |
entity_id: '', | |
}; | |
const mockPaginationParams: PaginationParams = { | |
page: 1, | |
limit: 10, | |
}; | |
const mockSortingParams: SortingParam = { | |
sort_by: 'created_on', | |
sort_order: 'desc', | |
}; | |
const mockFilteringParams: AccountTypeFilterParams = { | |
account_status: MAKER_CHECKER_MAIN_STATUS.ACTIVE, | |
created_by: 'SYSTEM', | |
}; | |
const accountTypeOutput: string[] = [ | |
'id', | |
'tenant_id', | |
'name', | |
'name_ar', | |
'code', | |
'status', | |
'is_login_allowed', | |
'created_on', | |
'created_by', | |
'updated_on', | |
'updated_by', | |
'deleted_on', | |
'deleted_by', | |
]; | |
const srcRequestOutput: string[] = [ | |
'id', | |
'tenant_id', | |
'main_ref_id', | |
'request_type', | |
'request_details', | |
'application_status', | |
'process_status', | |
'created_on', | |
'created_by', | |
'updated_on', | |
'updated_by', | |
]; | |
describe('AccountTypeResolver initialization', () => { | |
let accountTypeResolver: AccountTypeResolver; | |
let srcRequestService: SRCRequestService; | |
let accountTypeRepository: AccountTypeRepository; | |
let srcRequestRepository: SRCRequestRepository; | |
beforeAll(async () => { | |
const module: TestingModule = await Test.createTestingModule({ | |
imports: [AccountTypeModule, SRCRequestModule], | |
}).compile(); | |
accountTypeResolver = module.get<AccountTypeResolver>(AccountTypeResolver); | |
srcRequestService = module.get<SRCRequestService>(SRCRequestService); | |
accountTypeRepository = module.get<AccountTypeRepository>( | |
AccountTypeRepository, | |
); | |
srcRequestRepository = | |
module.get<SRCRequestRepository>(SRCRequestRepository); | |
}, 30000); | |
/************* list of account types without pagination **************** */ | |
describe('accountTypes', () => { | |
it('list of account types without pagination success', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'accountTypes'); | |
const result = await accountTypeResolver.accountTypes( | |
accountTypeOutput, | |
currentUser, | |
); | |
accountType = result[0]; | |
expect(spy).toHaveBeenCalledTimes(1); | |
expect(result).toBeTruthy(); | |
expect(result.length).toBeGreaterThan(0); | |
}); | |
it('list of account types without pagination failed', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'accountTypes'); | |
const user = { ...currentUser }; | |
user.tenant_id = '80A6F9C5-2100-4F03-B76F-1FF80FAAC067'; | |
const result = await accountTypeResolver.accountTypes( | |
accountTypeOutput, | |
user, | |
); | |
expect(spy).toHaveBeenCalledTimes(2); | |
expect(result).toBeTruthy(); | |
expect(result.length).toBe(0); | |
}); | |
}); | |
/************* find account type **************** */ | |
describe('findById', () => { | |
it('find account type success', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'findById'); | |
const result = await accountTypeResolver.findById( | |
accountType.id, | |
accountTypeOutput, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(1); | |
expect(result).toBeTruthy(); | |
expect(result).toStrictEqual(accountType); | |
}); | |
it('find account type failed', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'findById'); | |
const result = await accountTypeResolver.findById( | |
'80A6F9C5-2100-4F03-B76F-1FF80FAAC067', | |
accountTypeOutput, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(2); | |
expect(result).not.toBeTruthy(); | |
}); | |
}); | |
/************* find account type by property **************** */ | |
describe('findAccountTypeBy', () => { | |
it('find account type by property success', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'findAccountTypeBy'); | |
const result = await accountTypeResolver.findAccountTypeBy( | |
[ | |
{ | |
record_key: 'name', | |
record_value: accountType.name, | |
record_operator: CONDITION_OPERATORS.AND, | |
}, | |
], | |
accountTypeOutput, | |
); | |
expect(spy).toHaveBeenCalledTimes(1); | |
expect(result).toBeTruthy(); | |
expect(result.length).toBeGreaterThan(0); | |
}); | |
it('find account type by property failed', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'findAccountTypeBy'); | |
const result = await accountTypeResolver.findAccountTypeBy( | |
[ | |
{ | |
record_key: 'name', | |
record_value: '', | |
record_operator: CONDITION_OPERATORS.AND, | |
}, | |
], | |
accountTypeOutput, | |
); | |
expect(spy).toHaveBeenCalledTimes(2); | |
expect(result.length).not.toBeTruthy(); | |
}); | |
}); | |
/************* update many account types **************** */ | |
describe('updateMultipleAccountTypes', () => { | |
it('update many account types success', async () => { | |
const accountTypeUpdateInput: AccountTypeUpdateDto = { | |
account_types: [ | |
{ | |
id: accountType.id, | |
status: MAKER_CHECKER_MAIN_STATUS.INACTIVE, | |
}, | |
], | |
}; | |
const spy = jest.spyOn(accountTypeResolver, 'updateMultipleAccountTypes'); | |
const result = await accountTypeResolver.updateMultipleAccountTypes( | |
accountTypeUpdateInput, | |
accountTypeOutput, | |
); | |
expect(spy).toHaveBeenCalledTimes(1); | |
expect(result[0]).toBeTruthy(); | |
expect(result[0].status).toBe( | |
accountTypeUpdateInput.account_types[0].status, | |
); | |
}); | |
it('update many account types failed', async () => { | |
const accountTypeUpdateInput: AccountTypeUpdateDto = { | |
account_types: [ | |
{ | |
id: '80A6F9C5-2100-4F03-B76F-1FF80FAAC067', | |
status: MAKER_CHECKER_MAIN_STATUS.ACTIVE, | |
}, | |
], | |
}; | |
const spy = jest.spyOn(accountTypeResolver, 'updateMultipleAccountTypes'); | |
const result = await accountTypeResolver.updateMultipleAccountTypes( | |
accountTypeUpdateInput, | |
accountTypeOutput, | |
); | |
expect(spy).toHaveBeenCalledTimes(2); | |
expect(result.length).not.toBeTruthy(); | |
await accountTypeResolver.updateMultipleAccountTypes( | |
{ | |
account_types: [{ id: accountType.id, status: accountType.status }], | |
}, | |
accountTypeOutput, | |
); | |
}); | |
}); | |
/************* update account type **************** */ | |
describe('updateAccountTypes', () => { | |
it('update account type success', async () => { | |
const request_details: any = { | |
current: [ | |
{ | |
account_code: accountType.code, | |
account_type: accountType.name, | |
access_status: accountType.is_login_allowed, | |
}, | |
], | |
new: [ | |
{ | |
account_code: accountType.code, | |
account_type: accountType.name, | |
current_access_status: accountType.is_login_allowed, | |
new_access_status: false, | |
}, | |
], | |
}; | |
const serviceRequest = { | |
main_ref_id: null, | |
request_type: 'ACT_TYPE_ACCESS', | |
request_details: request_details, | |
}; | |
const srcRequest = await srcRequestService.create( | |
currentUser, | |
serviceRequest, | |
srcRequestOutput, | |
); | |
const spy = jest.spyOn(accountTypeResolver, 'updateAccountTypes'); | |
const result = await accountTypeResolver.updateAccountTypes( | |
{ | |
id: srcRequest.id, | |
application_status: 'APPROVED', | |
process_status: 'MODIFICATION_COMPLETED', | |
}, | |
accountTypeOutput, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(1); | |
expect(result).toBeTruthy(); | |
expect(result[0].is_login_allowed).toBe(false); | |
await srcRequestRepository.delete({ | |
id: srcRequest.id, | |
}); | |
}); | |
it('update account type failed', async () => { | |
try { | |
const spy = jest.spyOn(accountTypeResolver, 'updateAccountTypes'); | |
await accountTypeResolver.updateAccountTypes( | |
{ | |
id: '80A6F9C5-2100-4F03-B76F-1FF80FAAC067', | |
application_status: 'APPROVED', | |
process_status: 'ACTIVATION_COMPLETED', | |
}, | |
accountTypeOutput, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(2); | |
} catch (error) { | |
expect(error).toBeTruthy(); | |
expect(error.status).toBe(404); | |
await accountTypeRepository.update( | |
{ id: accountType.id }, | |
{ is_login_allowed: accountType.is_login_allowed }, | |
accountTypeOutput, | |
); | |
} | |
}); | |
}); | |
/************* find all account types with pagination **************** */ | |
describe('accountTypeList', () => { | |
it('find all account types with pagination success', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'accountTypeList'); | |
const result = await accountTypeResolver.accountTypeList( | |
accountTypeOutput, | |
mockPaginationParams, | |
mockFilteringParams, | |
mockSortingParams, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(1); | |
expect(result).toBeTruthy(); | |
expect(result.data.length).toBeGreaterThan(0); | |
}); | |
it('find all account types with pagination failed', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'accountTypeList'); | |
const filterParams = { ...mockFilteringParams }; | |
filterParams.created_by = '80A6F9C5-2100-4F03-B76F-1FF80FAAC067'; | |
const result = await accountTypeResolver.accountTypeList( | |
accountTypeOutput, | |
mockPaginationParams, | |
filterParams, | |
mockSortingParams, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(2); | |
expect(result).toBeTruthy(); | |
expect(result.data.length).toBe(0); | |
}); | |
}); | |
/************* find account types by codes **************** */ | |
describe('findAccountTypesByCodes', () => { | |
it('find account types by codes success', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'findAccountTypesByCodes'); | |
const result = await accountTypeResolver.findAccountTypesByCodes( | |
[accountType.code], | |
accountTypeOutput, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(1); | |
expect(result).toBeTruthy(); | |
expect(result.length).toBeGreaterThan(0); | |
}); | |
it('find account types by codes failed', async () => { | |
const spy = jest.spyOn(accountTypeResolver, 'findAccountTypesByCodes'); | |
const result = await accountTypeResolver.findAccountTypesByCodes( | |
['666'], | |
accountTypeOutput, | |
currentUser, | |
); | |
expect(spy).toHaveBeenCalledTimes(2); | |
expect(result).toBeTruthy(); | |
expect(result.length).toBe(0); | |
}); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment