From 71cb97e1120e97c43705c2c9c68e5e6ab9acc051 Mon Sep 17 00:00:00 2001 From: Sasha Dresden Date: Wed, 21 Aug 2024 10:40:37 -0400 Subject: [PATCH 1/3] Add ability to unamend an unmodified amendment --- .../report-list/report-list.component.spec.ts | 26 +++++++++++++++++++ .../report-list/report-list.component.ts | 23 ++++++++++++++++ .../src/app/shared/models/report.model.ts | 1 + .../shared/services/report.service.spec.ts | 13 ++++++++++ .../src/app/shared/services/report.service.ts | 4 +++ 5 files changed, 67 insertions(+) diff --git a/front-end/src/app/reports/report-list/report-list.component.spec.ts b/front-end/src/app/reports/report-list/report-list.component.spec.ts index 0929aaa7f3..7a03a43b5c 100644 --- a/front-end/src/app/reports/report-list/report-list.component.spec.ts +++ b/front-end/src/app/reports/report-list/report-list.component.spec.ts @@ -60,6 +60,19 @@ describe('ReportListComponent', () => { expect(component).toBeTruthy(); }); + describe('rowActions', () => { + it('should have "Unamend" if report can_unamend', () => { + const report = testActiveReport; + report.can_unamend = false; + const action = component.rowActions.find((action) => action.label === 'Unamend'); + if (action) { + expect(action.isAvailable(report)).toBeFalse(); + report.can_unamend = true; + expect(action.isAvailable(report)).toBeTrue(); + } + }); + }); + it('#getEmptyItem should return a new Report instance', () => { const item = component['getEmptyItem'](); expect(item.id).toBe(undefined); @@ -85,6 +98,19 @@ describe('ReportListComponent', () => { expect(amendSpy).toHaveBeenCalled(); }); + describe('unamend', () => { + it('should call confirm', () => { + const confirmSpy = spyOn(component.confirmationService, 'confirm'); + component.confirmUnamend(testActiveReport); + expect(confirmSpy).toHaveBeenCalledTimes(1); + }); + + it('should hit service', () => { + const unamendSpy = spyOn(reportService, 'startUnamendment').and.returnValue(of('')); + component.unamendReport({ id: '999' } as Report); + expect(unamendSpy).toHaveBeenCalled(); + }); + }); it('#onActionClick should route properly', () => { const navigateSpy = spyOn(router, 'navigateByUrl'); component.onRowActionClick(new TableAction('', component.editItem.bind(component)), { diff --git a/front-end/src/app/reports/report-list/report-list.component.ts b/front-end/src/app/reports/report-list/report-list.component.ts index af738b8c4b..eac17d18a7 100644 --- a/front-end/src/app/reports/report-list/report-list.component.ts +++ b/front-end/src/app/reports/report-list/report-list.component.ts @@ -33,6 +33,7 @@ export class ReportListComponent extends TableListBaseComponent implemen (report: Report) => report.report_status !== ReportStatus.IN_PROGRESS, ), new TableAction('Delete', this.confirmDelete.bind(this), (report: Report) => report.can_delete), + new TableAction('Unamend', this.confirmUnamend.bind(this), (report: Report) => report.can_unamend), new TableAction('Download as .fec', this.download.bind(this)), ]; @@ -107,6 +108,28 @@ export class ReportListComponent extends TableListBaseComponent implemen }); } + public confirmUnamend(report: Report): void { + this.confirmationService.confirm({ + message: 'Are you sure you want to unamend this amendent? This action cannot be undone.', + header: 'Hang on...', + rejectLabel: 'Cancel', + rejectIcon: 'none', + rejectButtonStyleClass: 'p-button-secondary', + acceptLabel: 'Confirm', + acceptIcon: 'none', + accept: async () => this.unamendReport(report), + }); + } + + async unamendReport(report: Report) { + this.itemService + .startUnamendment(report) + .pipe(take(1), takeUntil(this.destroy$)) + .subscribe(() => { + this.loadTableItems({}); + }); + } + public confirmDelete(report: Report): void { this.confirmationService.confirm({ message: 'Are you sure you want to delete this report? This action cannot be undone.', diff --git a/front-end/src/app/shared/models/report.model.ts b/front-end/src/app/shared/models/report.model.ts index 061bb3ab4a..60c50db609 100644 --- a/front-end/src/app/shared/models/report.model.ts +++ b/front-end/src/app/shared/models/report.model.ts @@ -38,6 +38,7 @@ export abstract class Report extends BaseModel { @Transform(BaseModel.dateTransform) updated: Date | undefined; can_delete = false; + can_unamend = false; version_label?: string; report_code?: string; report_code_label?: string; diff --git a/front-end/src/app/shared/services/report.service.spec.ts b/front-end/src/app/shared/services/report.service.spec.ts index 99f4c60402..6849bf6e24 100644 --- a/front-end/src/app/shared/services/report.service.spec.ts +++ b/front-end/src/app/shared/services/report.service.spec.ts @@ -82,4 +82,17 @@ describe('ReportService', () => { req.flush('amended 1'); httpTestingController.verify(); }); + + it('#startUnamendment() should call unamend', () => { + const report: Form3X = Form3X.fromJSON({ id: 1 }); + + service.startUnamendment(report).subscribe((response: string) => { + expect(response).toEqual('unamended 1'); + }); + + const req = httpTestingController.expectOne(`${environment.apiUrl}/reports/1/unamend/`); + expect(req.request.method).toEqual('POST'); + req.flush('unamended 1'); + httpTestingController.verify(); + }); }); diff --git a/front-end/src/app/shared/services/report.service.ts b/front-end/src/app/shared/services/report.service.ts index ef04d36ee9..221d11efec 100644 --- a/front-end/src/app/shared/services/report.service.ts +++ b/front-end/src/app/shared/services/report.service.ts @@ -104,6 +104,10 @@ export class ReportService implements TableListService { return this.apiService.post(`${this.apiEndpoint}/${report.id}/amend/`, {}); } + public startUnamendment(report: Report): Observable { + return this.apiService.post(`${this.apiEndpoint}/${report.id}/unamend/`, {}); + } + preparePayload(item: Report): Record { const payload = item.toJson(); delete payload['schema']; From 76b74efbab13d4d9e2b266271e303903cd776611 Mon Sep 17 00:00:00 2001 From: Sasha Dresden Date: Fri, 23 Aug 2024 13:21:08 -0400 Subject: [PATCH 2/3] Remove confirm unamend --- .../report-list/report-list.component.spec.ts | 6 ------ .../report-list/report-list.component.ts | 21 +++++++------------ 2 files changed, 7 insertions(+), 20 deletions(-) diff --git a/front-end/src/app/reports/report-list/report-list.component.spec.ts b/front-end/src/app/reports/report-list/report-list.component.spec.ts index 7a03a43b5c..d4adf56eec 100644 --- a/front-end/src/app/reports/report-list/report-list.component.spec.ts +++ b/front-end/src/app/reports/report-list/report-list.component.spec.ts @@ -99,12 +99,6 @@ describe('ReportListComponent', () => { }); describe('unamend', () => { - it('should call confirm', () => { - const confirmSpy = spyOn(component.confirmationService, 'confirm'); - component.confirmUnamend(testActiveReport); - expect(confirmSpy).toHaveBeenCalledTimes(1); - }); - it('should hit service', () => { const unamendSpy = spyOn(reportService, 'startUnamendment').and.returnValue(of('')); component.unamendReport({ id: '999' } as Report); diff --git a/front-end/src/app/reports/report-list/report-list.component.ts b/front-end/src/app/reports/report-list/report-list.component.ts index eac17d18a7..cc3bdb66fd 100644 --- a/front-end/src/app/reports/report-list/report-list.component.ts +++ b/front-end/src/app/reports/report-list/report-list.component.ts @@ -33,7 +33,7 @@ export class ReportListComponent extends TableListBaseComponent implemen (report: Report) => report.report_status !== ReportStatus.IN_PROGRESS, ), new TableAction('Delete', this.confirmDelete.bind(this), (report: Report) => report.can_delete), - new TableAction('Unamend', this.confirmUnamend.bind(this), (report: Report) => report.can_unamend), + new TableAction('Unamend', this.unamendReport.bind(this), (report: Report) => report.can_unamend), new TableAction('Download as .fec', this.download.bind(this)), ]; @@ -108,25 +108,18 @@ export class ReportListComponent extends TableListBaseComponent implemen }); } - public confirmUnamend(report: Report): void { - this.confirmationService.confirm({ - message: 'Are you sure you want to unamend this amendent? This action cannot be undone.', - header: 'Hang on...', - rejectLabel: 'Cancel', - rejectIcon: 'none', - rejectButtonStyleClass: 'p-button-secondary', - acceptLabel: 'Confirm', - acceptIcon: 'none', - accept: async () => this.unamendReport(report), - }); - } - async unamendReport(report: Report) { this.itemService .startUnamendment(report) .pipe(take(1), takeUntil(this.destroy$)) .subscribe(() => { this.loadTableItems({}); + this.messageService.add({ + severity: 'success', + summary: 'Successful', + detail: 'Report Unamended', + life: 3000, + }); }); } From 57842d9de445ef3770e5abb283cfd9204976cab8 Mon Sep 17 00:00:00 2001 From: Sasha Dresden Date: Fri, 23 Aug 2024 13:45:56 -0400 Subject: [PATCH 3/3] Convert amend/unamend to promise for ea sier processing --- .../report-list/report-list.component.spec.ts | 16 +++++----- .../report-list/report-list.component.ts | 32 +++++++------------ .../shared/services/report.service.spec.ts | 14 ++++---- .../src/app/shared/services/report.service.ts | 8 ++--- 4 files changed, 31 insertions(+), 39 deletions(-) diff --git a/front-end/src/app/reports/report-list/report-list.component.spec.ts b/front-end/src/app/reports/report-list/report-list.component.spec.ts index d4adf56eec..f51ab00fde 100644 --- a/front-end/src/app/reports/report-list/report-list.component.spec.ts +++ b/front-end/src/app/reports/report-list/report-list.component.spec.ts @@ -92,18 +92,18 @@ describe('ReportListComponent', () => { expect(navigateSpy).toHaveBeenCalledWith('/reports/f3x/submit/status/777'); }); - it('#amend should hit service', () => { - const amendSpy = spyOn(reportService, 'startAmendment').and.returnValue(of('')); - component.amendReport({ id: '999' } as Report); + it('#amend should hit service', fakeAsync(async () => { + const amendSpy = spyOn(reportService, 'startAmendment').and.returnValue(Promise.resolve('')); + await component.amendReport({ id: '999' } as Report); expect(amendSpy).toHaveBeenCalled(); - }); + })); describe('unamend', () => { - it('should hit service', () => { - const unamendSpy = spyOn(reportService, 'startUnamendment').and.returnValue(of('')); - component.unamendReport({ id: '999' } as Report); + it('should hit service', fakeAsync(async () => { + const unamendSpy = spyOn(reportService, 'startUnamendment').and.returnValue(Promise.resolve('')); + await component.unamendReport({ id: '999' } as Report); expect(unamendSpy).toHaveBeenCalled(); - }); + })); }); it('#onActionClick should route properly', () => { const navigateSpy = spyOn(router, 'navigateByUrl'); diff --git a/front-end/src/app/reports/report-list/report-list.component.ts b/front-end/src/app/reports/report-list/report-list.component.ts index cc3bdb66fd..53ec5e8d2f 100644 --- a/front-end/src/app/reports/report-list/report-list.component.ts +++ b/front-end/src/app/reports/report-list/report-list.component.ts @@ -1,5 +1,5 @@ import { Component, ElementRef, OnDestroy, OnInit } from '@angular/core'; -import { firstValueFrom, lastValueFrom, take, takeUntil } from 'rxjs'; +import { firstValueFrom, lastValueFrom } from 'rxjs'; import { ConfirmationService, MessageService } from 'primeng/api'; import { TableAction, TableListBaseComponent } from '../../shared/components/table-list-base/table-list-base.component'; import { Report, ReportStatus, ReportTypes } from '../../shared/models/report.model'; @@ -99,28 +99,20 @@ export class ReportListComponent extends TableListBaseComponent implemen } } - public amendReport(report: Report): void { - this.itemService - .startAmendment(report) - .pipe(take(1), takeUntil(this.destroy$)) - .subscribe(() => { - this.loadTableItems({}); - }); + async amendReport(report: Report) { + await this.itemService.startAmendment(report); + this.loadTableItems({}); } async unamendReport(report: Report) { - this.itemService - .startUnamendment(report) - .pipe(take(1), takeUntil(this.destroy$)) - .subscribe(() => { - this.loadTableItems({}); - this.messageService.add({ - severity: 'success', - summary: 'Successful', - detail: 'Report Unamended', - life: 3000, - }); - }); + await this.itemService.startUnamendment(report); + this.loadTableItems({}); + this.messageService.add({ + severity: 'success', + summary: 'Successful', + detail: 'Report Unamended', + life: 3000, + }); } public confirmDelete(report: Report): void { diff --git a/front-end/src/app/shared/services/report.service.spec.ts b/front-end/src/app/shared/services/report.service.spec.ts index 6849bf6e24..2b554ecde2 100644 --- a/front-end/src/app/shared/services/report.service.spec.ts +++ b/front-end/src/app/shared/services/report.service.spec.ts @@ -1,4 +1,4 @@ -import { TestBed } from '@angular/core/testing'; +import { fakeAsync, TestBed } from '@angular/core/testing'; import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { provideMockStore } from '@ngrx/store/testing'; import { testMockStore } from '../utils/unit-test.utils'; @@ -70,10 +70,10 @@ describe('ReportService', () => { httpTestingController.verify(); }); - it('#startAmendment() should call amend', () => { + it('#startAmendment() should call amend', fakeAsync(async () => { const report: Form3X = Form3X.fromJSON({ id: 1 }); - service.startAmendment(report).subscribe((response: string) => { + service.startAmendment(report).then((response) => { expect(response).toEqual('amended 1'); }); @@ -81,12 +81,12 @@ describe('ReportService', () => { expect(req.request.method).toEqual('POST'); req.flush('amended 1'); httpTestingController.verify(); - }); + })); - it('#startUnamendment() should call unamend', () => { + it('#startUnamendment() should call unamend', fakeAsync(async () => { const report: Form3X = Form3X.fromJSON({ id: 1 }); - service.startUnamendment(report).subscribe((response: string) => { + service.startUnamendment(report).then((response) => { expect(response).toEqual('unamended 1'); }); @@ -94,5 +94,5 @@ describe('ReportService', () => { expect(req.request.method).toEqual('POST'); req.flush('unamended 1'); httpTestingController.verify(); - }); + })); }); diff --git a/front-end/src/app/shared/services/report.service.ts b/front-end/src/app/shared/services/report.service.ts index 221d11efec..3b4095634d 100644 --- a/front-end/src/app/shared/services/report.service.ts +++ b/front-end/src/app/shared/services/report.service.ts @@ -100,12 +100,12 @@ export class ReportService implements TableListService { return !uploadSubmission || fecStatus == 'REJECTED' || fecfileTaskState == 'FAILED'; } - public startAmendment(report: Report): Observable { - return this.apiService.post(`${this.apiEndpoint}/${report.id}/amend/`, {}); + public startAmendment(report: Report): Promise { + return firstValueFrom(this.apiService.post(`${this.apiEndpoint}/${report.id}/amend/`, {})); } - public startUnamendment(report: Report): Observable { - return this.apiService.post(`${this.apiEndpoint}/${report.id}/unamend/`, {}); + public startUnamendment(report: Report): Promise { + return firstValueFrom(this.apiService.post(`${this.apiEndpoint}/${report.id}/unamend/`, {})); } preparePayload(item: Report): Record {