diff --git a/src/app/fyle/dashboard/tasks/dismiss-dialog/dismiss-dialog.component.spec.ts b/src/app/fyle/dashboard/tasks/dismiss-dialog/dismiss-dialog.component.spec.ts index a32c0fa0f3..92786dd0f3 100644 --- a/src/app/fyle/dashboard/tasks/dismiss-dialog/dismiss-dialog.component.spec.ts +++ b/src/app/fyle/dashboard/tasks/dismiss-dialog/dismiss-dialog.component.spec.ts @@ -1,24 +1,100 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { IonicModule } from '@ionic/angular'; +import { IonicModule, PopoverController } from '@ionic/angular'; import { DismissDialogComponent } from './dismiss-dialog.component'; +import { FormButtonValidationDirective } from 'src/app/shared/directive/form-button-validation.directive'; +import { MatIconModule } from '@angular/material/icon'; +import { MatIconTestingModule } from '@angular/material/icon/testing'; +import { FormsModule } from '@angular/forms'; +import { of, throwError } from 'rxjs'; +import { click, getElementBySelector, getTextContent } from 'src/app/core/dom-helpers'; describe('DismissDialogComponent', () => { let component: DismissDialogComponent; let fixture: ComponentFixture; + let popoverController: jasmine.SpyObj; + + const dismissMethod = () => of(true); + const errMethod = () => throwError(() => new Error('error')); beforeEach(waitForAsync(() => { + const popoverControllerSpy = jasmine.createSpyObj('PopoverController', ['dismiss']); TestBed.configureTestingModule({ - declarations: [DismissDialogComponent], - imports: [IonicModule.forRoot()], + declarations: [DismissDialogComponent, FormButtonValidationDirective], + imports: [IonicModule.forRoot(), FormsModule, MatIconTestingModule, MatIconModule], + providers: [ + { + provide: PopoverController, + useValue: popoverControllerSpy, + }, + ], }).compileComponents(); fixture = TestBed.createComponent(DismissDialogComponent); component = fixture.componentInstance; + popoverController = TestBed.inject(PopoverController) as jasmine.SpyObj; fixture.detectChanges(); })); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should display header and CTA text correctly', () => { + fixture.detectChanges(); + + expect(getTextContent(getElementBySelector(fixture, '.dismiss-dialog--header'))).toEqual( + 'Dismiss duplicate expenses' + ); + expect(getTextContent(getElementBySelector(fixture, '.dismiss-dialog--dismiss'))).toEqual('Yes, Dismiss'); + }); + + it('cancel(): should cancel the CTA', () => { + popoverController.dismiss.and.callThrough(); + component.dismissCallInProgress = false; + fixture.detectChanges(); + + component.cancel(); + expect(popoverController.dismiss).toHaveBeenCalledTimes(1); + }); + + describe('dismiss():', () => { + it('should dismiss expense', (done) => { + popoverController.dismiss.and.callThrough(); + component.dismissCallInProgress = false; + component.dismissMethod = dismissMethod; + fixture.detectChanges(); + + component.dismiss(); + expect(popoverController.dismiss).toHaveBeenCalledWith({ status: 'success' }); + done(); + }); + + it('should not dismiss expenses if dismiss method throws error', (done) => { + popoverController.dismiss.and.callThrough(); + component.dismissCallInProgress = false; + component.dismissMethod = errMethod; + fixture.detectChanges(); + + component.dismiss(); + expect(popoverController.dismiss).toHaveBeenCalledWith({ status: 'error' }); + done(); + }); + }); + + it('should call cancel() if button is clicked', () => { + const cancelFn = spyOn(component, 'cancel'); + + const cancelButton = getElementBySelector(fixture, '.dismiss-dialog--cancel') as HTMLElement; + click(cancelButton); + expect(cancelFn).toHaveBeenCalledTimes(1); + }); + + it('should call dismiss() if card is clicked', () => { + const dismissFn = spyOn(component, 'dismiss'); + + const dismissCard = getElementBySelector(fixture, '.dismiss-dialog--dismiss') as HTMLElement; + click(dismissCard); + expect(dismissFn).toHaveBeenCalledTimes(1); + }); }); diff --git a/src/app/fyle/potential-duplicates/potential-duplicates.page.spec.ts b/src/app/fyle/potential-duplicates/potential-duplicates.page.spec.ts index ad7212040e..173675953c 100644 --- a/src/app/fyle/potential-duplicates/potential-duplicates.page.spec.ts +++ b/src/app/fyle/potential-duplicates/potential-duplicates.page.spec.ts @@ -14,6 +14,8 @@ import { ExpensesService } from 'src/app/core/services/platform/v1/spender/expen import { cloneDeep } from 'lodash'; import { OrgSettingsService } from 'src/app/core/services/org-settings.service'; import { expenseDuplicateSet } from 'src/app/core/mock-data/platform/v1/expense-duplicate-sets.data'; +import { PopoverController } from '@ionic/angular'; +import { DismissDialogComponent } from '../dashboard/tasks/dismiss-dialog/dismiss-dialog.component'; describe('PotentialDuplicatesPage', () => { let component: PotentialDuplicatesPage; @@ -23,6 +25,7 @@ describe('PotentialDuplicatesPage', () => { let matSnackBar: jasmine.SpyObj; let trackingService: jasmine.SpyObj; let expensesService: jasmine.SpyObj; + let popoverController: jasmine.SpyObj; beforeEach(waitForAsync(() => { const routerSpy = jasmine.createSpyObj('Router', ['navigate']); @@ -39,6 +42,7 @@ describe('PotentialDuplicatesPage', () => { 'dismissDuplicates', ]); const orgSettingsServiceSpy = jasmine.createSpyObj('OrgSettingsService', ['get']); + const popoverControllerSpy = jasmine.createSpyObj('PopoverController', ['create']); TestBed.configureTestingModule({ declarations: [PotentialDuplicatesPage], @@ -68,6 +72,10 @@ describe('PotentialDuplicatesPage', () => { provide: OrgSettingsService, useValue: orgSettingsServiceSpy, }, + { + provide: PopoverController, + useValue: popoverControllerSpy, + }, ], schemas: [CUSTOM_ELEMENTS_SCHEMA], }).compileComponents(); @@ -81,6 +89,7 @@ describe('PotentialDuplicatesPage', () => { matSnackBar = TestBed.inject(MatSnackBar) as jasmine.SpyObj; trackingService = TestBed.inject(TrackingService) as jasmine.SpyObj; expensesService = TestBed.inject(ExpensesService) as jasmine.SpyObj; + popoverController = TestBed.inject(PopoverController) as jasmine.SpyObj; component.loadData$ = new BehaviorSubject(null); component.duplicateSets$ = of([]); @@ -166,38 +175,125 @@ describe('PotentialDuplicatesPage', () => { expensesService.dismissDuplicates.and.returnValue(of(null)); }); - it('should dismiss a duplicate expense', () => { - component.dismiss(apiExpenses1[0]); + it('should dismiss a duplicate expense and show the dialog', async () => { + const popoverResponse = { data: { status: 'success' } }; + const popoverSpy = jasmine.createSpyObj('Popover', ['present', 'onDidDismiss']); + popoverSpy.onDidDismiss.and.resolveTo(popoverResponse); + popoverController.create.and.resolveTo(popoverSpy); + + await component.dismiss(apiExpenses1[0]); + + expect(popoverController.create).toHaveBeenCalledWith({ + component: DismissDialogComponent, + cssClass: 'dismiss-dialog', + backdropDismiss: false, + componentProps: { + dismissMethod: jasmine.any(Function), + }, + }); + + expect(popoverSpy.present).toHaveBeenCalledTimes(1); + expect(popoverSpy.onDidDismiss).toHaveBeenCalledTimes(1); + + if (popoverResponse.data?.status === 'success') { + expect(component.duplicateExpenses[0].length).toEqual(1); + expect(component.showDismissedSuccessToast).toHaveBeenCalledTimes(1); + } + }); + + it('should not dismiss a duplicate expense if popover is dismissed without success status', async () => { + const popoverResponse = { data: { status: 'error' } }; + const popoverSpy = jasmine.createSpyObj('Popover', ['present', 'onDidDismiss']); + popoverSpy.onDidDismiss.and.resolveTo(popoverResponse); + popoverController.create.and.resolveTo(popoverSpy); + + await component.dismiss(apiExpenses1[0]); + + expect(popoverController.create).toHaveBeenCalledWith({ + component: DismissDialogComponent, + cssClass: 'dismiss-dialog', + backdropDismiss: false, + componentProps: { + dismissMethod: jasmine.any(Function), + }, + }); - expect(component.duplicateExpenses[0].length).toEqual(1); - expect(expensesService.dismissDuplicates).toHaveBeenCalledOnceWith( - ['txcSFe6efB6R', 'txDDLtRaflUW'], - ['txDDLtRaflUW'] - ); - expect(component.showDismissedSuccessToast).toHaveBeenCalledTimes(1); + expect(popoverSpy.present).toHaveBeenCalledTimes(1); + expect(popoverSpy.onDidDismiss).toHaveBeenCalledTimes(1); + expect(component.duplicateExpenses[0].length).toEqual(2); + expect(component.showDismissedSuccessToast).not.toHaveBeenCalled(); }); }); describe('dismissAll(): ', () => { - it('should dismiss all transactions', () => { + it('should dismiss all transactions and show the dialog', async () => { component.duplicateSetData = [['tx5fBcPBAxLv'], ['tx5fBcPBAxLv', 'tx3nHShG60zq']]; component.selectedSet = 1; + const popoverResponse = { data: { status: 'success' } }; + expensesService.dismissDuplicates.and.returnValue(of(null)); spyOn(component, 'showDismissedSuccessToast'); spyOn(component.loadData$, 'next'); expensesService.getExpenses.and.returnValue(of([apiExpenses1[0], expenseData])); component.duplicateSets$ = of([[apiExpenses1[0]], [expenseData]]); - component.dismissAll(); + const popoverSpy = jasmine.createSpyObj('Popover', ['present', 'onDidDismiss']); + popoverSpy.onDidDismiss.and.resolveTo(popoverResponse); + popoverController.create.and.resolveTo(popoverSpy); + + await component.dismissAll(); + + expect(popoverController.create).toHaveBeenCalledWith({ + component: DismissDialogComponent, + cssClass: 'dismiss-dialog', + backdropDismiss: false, + componentProps: { + dismissMethod: jasmine.any(Function), + }, + }); + + expect(popoverSpy.present).toHaveBeenCalledTimes(1); + expect(popoverSpy.onDidDismiss).toHaveBeenCalledTimes(1); + + if (popoverResponse.data?.status === 'success') { + expect(component.selectedSet).toEqual(0); + expect(trackingService.dismissedDuplicateSet).toHaveBeenCalledTimes(1); + expect(component.showDismissedSuccessToast).toHaveBeenCalledTimes(1); + expect(component.loadData$.next).toHaveBeenCalledTimes(1); + } + }); + + it('should not perform actions if popover is dismissed without success status', async () => { + component.duplicateSetData = [['tx5fBcPBAxLv'], ['tx5fBcPBAxLv', 'tx3nHShG60zq']]; + component.selectedSet = 1; + const popoverResponse = { data: { status: 'error' } }; + + spyOn(component, 'showDismissedSuccessToast'); + spyOn(component.loadData$, 'next'); + expensesService.getExpenses.and.returnValue(of([apiExpenses1[0], expenseData])); + component.duplicateSets$ = of([[apiExpenses1[0]], [expenseData]]); + + const popoverSpy = jasmine.createSpyObj('Popover', ['present', 'onDidDismiss']); + popoverSpy.onDidDismiss.and.resolveTo(popoverResponse); + popoverController.create.and.resolveTo(popoverSpy); + + await component.dismissAll(); + + expect(popoverController.create).toHaveBeenCalledWith({ + component: DismissDialogComponent, + cssClass: 'dismiss-dialog', + backdropDismiss: false, + componentProps: { + dismissMethod: jasmine.any(Function), + }, + }); - expect(expensesService.dismissDuplicates).toHaveBeenCalledOnceWith( - ['tx5fBcPBAxLv', 'tx3nHShG60zq'], - ['tx5fBcPBAxLv', 'tx3nHShG60zq'] - ); - expect(component.selectedSet).toEqual(0); - expect(trackingService.dismissedDuplicateSet).toHaveBeenCalledTimes(1); - expect(component.showDismissedSuccessToast).toHaveBeenCalledTimes(1); - expect(component.loadData$.next).toHaveBeenCalledTimes(1); + expect(popoverSpy.present).toHaveBeenCalledTimes(1); + expect(popoverSpy.onDidDismiss).toHaveBeenCalledTimes(1); + expect(component.selectedSet).toEqual(1); + expect(trackingService.dismissedDuplicateSet).not.toHaveBeenCalled(); + expect(component.showDismissedSuccessToast).not.toHaveBeenCalled(); + expect(component.loadData$.next).not.toHaveBeenCalled(); }); });