Skip to content
This repository has been archived by the owner on Oct 26, 2022. It is now read-only.

feat(agent): Creates payload and request to create/update translations for agents #321

Merged
merged 6 commits into from
Apr 29, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
IAgentDTO,
IAgentRequest,
AgentTranslation,
IAgentTranslationRequest,
} from '@models/agent';
import { AgentService } from '@core/services/api/agent.service';
import { Constants } from '@utils/constants';
Expand Down Expand Up @@ -242,7 +243,28 @@ export class AgentDetailSmartComponent implements OnInit {
}

private setTranslation(): void {
const requestPayload = this.buildPayload();
// TODO: send request to update/create the translation records in the database
const requestPayload = this.buildPayload(),
translationForLanguage = this.agent.hasTranslationList.find(
(language) => language.code === this.languageCode,
),
translationPayload: IAgentTranslationRequest = {
dynamicContent: requestPayload.dynamicContent,
};

translationForLanguage.hasTranslation
? this.updateTranslation(translationPayload)
: this.createTranslation(translationPayload);
Comment on lines +254 to +256
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we trigger setTranslation and it actually goes not contain any changes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delayed response. Do you mean the form values don't change? The client will send a request to the server regardless of whether or not the payload value changes.

}

private createTranslation(payload: IAgentTranslationRequest): void {
this.agentService
.createTranslation(payload, this.agent.id)
.subscribe(() => this.router.navigateByUrl('/content/agent-list'));
}

private updateTranslation(payload: IAgentTranslationRequest): void {
this.agentService
.updateTranslation(payload, this.agent.id)
.subscribe(() => this.router.navigateByUrl('/content/agent-list'));
}
}
190 changes: 186 additions & 4 deletions src/app/infrastructure/core/services/api/agent.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ import {
AgentRequest,
IAgentDTO,
IAgentRequest,
IAgentTranslationRequest,
AgentTranslationRequest,
IAgentTranslation,
IAgentTranslationList,
AgentTranslation,
} from '@models/agent';
import { getTranslocoModule } from '@utils/test/transloco-testing-module';
import { Logger } from '@utils/logger';
Expand All @@ -24,10 +29,12 @@ import { ToastrTestingModule } from '@utils/test/toastr-testing-module';
? Logger.log('Unit skipped')
: describe('[Unit] AgentService', () => {
pratimasakinala marked this conversation as resolved.
Show resolved Hide resolved
const route = `${environment.apiRoute}/agents`;
let testAgent: IAgentDTO;
let service: AgentService;
let anotherTestAgent: IAgentDTO;
let apiService: ApiService;
let httpTestingController: HttpTestingController;
let service: AgentService;
let testAgent: IAgentDTO;
let testAgentSetTranslation: IAgentDTO;

beforeEach(() => {
TestBed.configureTestingModule({
Expand Down Expand Up @@ -62,7 +69,34 @@ import { ToastrTestingModule } from '@utils/test/toastr-testing-module';
zipCode: '93721',
},
});
anotherTestAgent = new AgentDTO({
id: 2,
name: 'Test Tester Testing',
email: '[email protected]',
dynamicContent: {
'en-US': {
description: 'This is a test',
},
},
phoneNumber: '5595555555',
address: {
address1: '123 Main St.',
address2: '',
city: 'Fresno',
state: 'CA',
zipCode: '93721',
},
});
testAgentSetTranslation = {
...testAgent,
dynamicContent: {
'es-MX': {
description: 'Esto es una prueba',
},
},
};
pratimasakinala marked this conversation as resolved.
Show resolved Hide resolved
});

it('should be created', () => {
expect(service).toBeTruthy();
});
Expand Down Expand Up @@ -90,8 +124,8 @@ import { ToastrTestingModule } from '@utils/test/toastr-testing-module';

describe('createAgent()', () => {
it('should use POST as the request method', () => {
const newUser: IAgentRequest = new AgentRequest();
service.createAgent(newUser).subscribe();
const newAgent: IAgentRequest = new AgentRequest();
service.createAgent(newAgent).subscribe();
pratimasakinala marked this conversation as resolved.
Show resolved Hide resolved
const req = httpTestingController.expectOne(route);

expect(req.request.method).toBe('POST');
Expand Down Expand Up @@ -182,4 +216,152 @@ import { ToastrTestingModule } from '@utils/test/toastr-testing-module';
expect(response).toEqual(expectedValue);
});
});

describe('unpackAgentTranslationList', () => {
it('should return empty translated content when language code requested does not exist on the agent data', () => {
const agent: IAgentDTO = { ...testAgent };
const content: IAgentTranslationList = agent.dynamicContent;
const expectedValue: IAgentTranslation = {
description: '',
};
const value: IAgentTranslation = service.unpackAgentTranslationList(
content,
'es-MX',
);

expect({ ...value }).toEqual({ ...expectedValue });
});

it('should return the translated content for the requested agent', () => {
const agent: IAgentDTO = { ...testAgent };
const content: IAgentTranslationList = agent.dynamicContent;
const expectedValue: IAgentTranslation = {
description: 'This is a test',
};
const value: IAgentTranslation = service.unpackAgentTranslationList(
content,
'en-US',
);

expect({ ...value }).toEqual({ ...expectedValue });
});
});

describe('getTranslatedAgent()', () => {
it('should return the equivalent to the entire JSON value of the requested agent when the language requested does not exist on the agent data', () => {
const agent: IAgentDTO = new AgentDTO({ ...testAgent });
const expectedValue: IAgentDTO = { ...testAgent };
const value: IAgentDTO = service.getTranslatedAgent(agent, 'es-MX');

expect({ ...value }).toEqual({ ...expectedValue });
pratimasakinala marked this conversation as resolved.
Show resolved Hide resolved
});

it('should return the requested agent with the requested translated content', () => {
const translatedContent = new AgentTranslation({
description: 'This is a test',
});
const agent: IAgentDTO = new AgentDTO({ ...testAgent });
const expectedValue: IAgentDTO = {
...testAgent,
translatedContentForDisplay: translatedContent,
};
const value: IAgentDTO = service.getTranslatedAgent(agent, 'en-US');

expect({ ...value }).toEqual({ ...expectedValue });
});
});

describe('getTranslatedAgentList()', () => {
it('should return the agents in the list with translated content unpacked', () => {
const translatedContent = new AgentTranslation({
description: 'This is a test',
});
const agentList: IAgentDTO[] = new Array<IAgentDTO>(
{ ...testAgent },
{ ...anotherTestAgent },
);
const expectedValue: IAgentDTO[] = [
{
...testAgent,
translatedContentForDisplay: translatedContent,
},
{
...anotherTestAgent,
translatedContentForDisplay: translatedContent,
},
];
const value: IAgentDTO[] = service.getTranslatedAgentList(
agentList,
'en-US',
);

expect(value).toEqual(expectedValue);
});
});

describe('createTranslation()', () => {
it('should use POST as the request method', () => {
const newTranslation: IAgentTranslationRequest = new AgentTranslationRequest();
service.createTranslation(newTranslation, 1).subscribe();
const translationRoute = `${route}/1/translations`;
const req = httpTestingController.expectOne(translationRoute);

expect(req.request.method).toBe('POST');
});

it('should return the requested agent on creation', () => {
const newAgentTranslation: IAgentTranslationRequest = new AgentTranslationRequest(
{
dynamicContent: {
'es-MX': {
description: 'Esto es una prueba',
},
},
},
);
const expectedValue: IAgentDTO = { ...testAgentSetTranslation };
let response: IAgentDTO;
spyOn(apiService, 'post').and.returnValue(
observableOf(expectedValue),
);

service.createTranslation(newAgentTranslation, 1).subscribe((res) => {
response = res;
});

expect(response).toEqual(expectedValue);
});
});

describe('updateTranslation()', () => {
it('should use PUT as the request method', () => {
const agentTranslation: IAgentTranslationRequest = new AgentTranslationRequest();
service.updateTranslation(agentTranslation, 1).subscribe();
const translationRoute = `${route}/1/translations`;
const req = httpTestingController.expectOne(translationRoute);

expect(req.request.method).toBe('PUT');
});

it('should return the requested agent on successful update', () => {
const agentTranslation: IAgentTranslationRequest = new AgentTranslationRequest(
{
dynamicContent: {
'es-MX': {
description: 'Esto es una prueba',
},
},
},
);
const expectedValue: IAgentDTO = { ...testAgentSetTranslation };
let response: IAgentDTO;
spyOn(apiService, 'put').and.returnValue(observableOf(expectedValue));

service.updateTranslation(agentTranslation, 1).subscribe((res) => {
response = res;
});

expect(response).toEqual(expectedValue);
});
});
});
39 changes: 39 additions & 0 deletions src/app/infrastructure/core/services/api/agent.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
IAgentRequest,
IAgentTranslation,
IAgentTranslationList,
IAgentTranslationRequest,
} from '@models/agent';
import { environment } from '@env/environment';
import { Message } from '@models/message';
Expand Down Expand Up @@ -130,4 +131,42 @@ export class AgentService {

return agentList;
}

public createTranslation(
payload: IAgentTranslationRequest,
agentId: number,
): Observable<IAgentDTO> {
const endpoint = `${this.url}/${agentId}/translations`;

return this.apiService
.post<IAgentDTO, IAgentTranslationRequest>(endpoint, payload)
.pipe(
tap(() => {
const notificationTranslationKeys: INotificationTranslationKey = new NotificationTranslationKey();
const message: Message = new Message({
message: notificationTranslationKeys.translationCreated,
});
return this.notificationService.showSuccess([message]);
}),
);
}

public updateTranslation(
payload: IAgentTranslationRequest,
agentId: number,
): Observable<IAgentDTO> {
const endpoint = `${this.url}/${agentId}/translations`;

return this.apiService
.put<IAgentDTO, IAgentTranslationRequest>(endpoint, payload)
.pipe(
tap(() => {
const notificationTranslationKeys: INotificationTranslationKey = new NotificationTranslationKey();
const message: Message = new Message({
message: notificationTranslationKeys.translationUpdated,
});
return this.notificationService.showSuccess([message]);
}),
);
}
}
14 changes: 14 additions & 0 deletions src/app/infrastructure/models/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,17 @@ export class AgentRequest implements IAgentRequest {
}
}
}

export interface IAgentTranslationRequest {
dynamicContent: IAgentTranslationList;
}

export class AgentTranslationRequest implements IAgentTranslationRequest {
dynamicContent: IAgentTranslationList = new AgentTranslationList();

constructor(configOverride?: Partial<IAgentTranslationRequest>) {
if (configOverride) {
Object.assign(this, configOverride);
}
}
}
4 changes: 4 additions & 0 deletions src/app/infrastructure/models/translation/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export interface INotificationTranslationKey {
returningToDashboard: string;
returningToUserList: string;
serverError: string;
translationCreated: string;
translationUpdated: string;
unableToCompleteRequest: string;
unableToLoadAgencies: string;
unableToLoadAgency: string;
Expand Down Expand Up @@ -64,6 +66,8 @@ export class NotificationTranslationKey implements INotificationTranslationKey {
returningToDashboard: string = 'notification.returningToDashboard';
returningToUserList: string = 'notification.returningToUserList';
serverError: string = 'notification.serverError';
translationCreated: string = 'notification.translationCreated';
translationUpdated: string = 'notification.translationUpdated';
unableToCompleteRequest: string = 'notification.unableToCompleteRequest';
unableToLoadAgencies: string = 'notification.unableToLoadAgencies';
unableToLoadAgency: string = 'notification.unableToLoadAgency';
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@
"returningToDashboard": "Returning to the dashboard.",
"returningToUserList": "Returning to user list.",
"serverError": "Server Error.",
"translationCreated": "Translation {{ notification.created }}.",
"translationUpdated": "Translation {{ notification.updated }}.",
"unableToCompleteRequest": "Unable to complete request.",
"unableToLoadAgencies": "Unable to load agencies. {{ notification.returningToUserList }}",
"unableToLoadAgency": "Unable to load agency. Returning to agency list.",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/es-MX.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@
"returningToDashboard": "Volviendo al tablero.",
"returningToUserList": "Volviendo a la lista de usuarios.",
"serverError": "Error del Servidor.",
"translationCreated": "Traducción {{ notification.created }}.",
"translationUpdated": "Traducción {{ notification.updated }}.",
"unableToCompleteRequest": "No se pudo completar la solicitud.",
"unableToLoadAgencies": "No se pueden cargar agencias. {{ notification.returningToUserList }}",
"unableToLoadAgency": "No se pudo cargar la agencia. Volviendo a la lista de agencias.",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/tl.json
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@
"returningToDashboard": "Bumabalik sa dashboard.",
"returningToUserList": "Bumabalik sa listahan ng gumagamit.",
"serverError": "Error sa Server.",
"translationCreated": "Nilikha ang pagsasalin.",
"translationUpdated": "Na-update ang pagsasalin.",
"unableToCompleteRequest": "Hindi makumpleto ang kahilingan.",
"unableToLoadAgencies": "Hindi mai-load ang mga ahensya. {{ notification.returningToUserList }}",
"unableToLoadAgency": "Hindi mai-load ang ahensya. Bumabalik sa listahan ng ahensya.",
Expand Down
2 changes: 2 additions & 0 deletions src/assets/i18n/vi-VN.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@
"returningToDashboard": "Quay lại trang tổng quan.",
"returningToUserList": "Quay lại danh sách người dùng.",
"serverError": "Lỗi máy chủ.",
"translationCreated": "Bản dịch đã tạo.",
"translationUpdated": "Đã cập nhật bản dịch.",
"unableToCompleteRequest": "Không thể hoàn thành yêu cầu.",
"unableToLoadAgencies": "Không thể tải đại lý. {{ notification.returningToUserList }}",
"unableToLoadAgency": "Không thể tải đại lý. Quay lại danh sách đại lý.",
Expand Down