Skip to content

Commit

Permalink
test: 100% coverage of virtual-select component (#2500)
Browse files Browse the repository at this point in the history
* test: 100% coverage of virtual-select component

* pr comments
  • Loading branch information
suyashpatil78 authored Oct 13, 2023
1 parent 72f744b commit 8dd2965
Show file tree
Hide file tree
Showing 2 changed files with 270 additions and 0 deletions.
29 changes: 29 additions & 0 deletions src/app/core/mock-data/modal-controller.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { FyViewAttachmentComponent } from 'src/app/shared/components/fy-view-att
import { advanceRequestFileUrlData2, fileObject4 } from './file-object.data';
import { ViewCommentComponent } from 'src/app/shared/components/comments-history/view-comment/view-comment.component';
import { FyPopoverComponent } from 'src/app/shared/components/fy-popover/fy-popover.component';
import { VirtualSelectModalComponent } from 'src/app/shared/components/virtual-select/virtual-select-modal/virtual-select-modal.component';

export const modalControllerParams = {
component: FyFiltersComponent,
Expand Down Expand Up @@ -554,3 +555,31 @@ export const modalControllerParams9 = {
breakpoints: [0, 1],
handle: false,
};

export const virtualSelectModalControllerParams = {
component: VirtualSelectModalComponent,
componentProps: {
options: [],
currentSelection: undefined,
selectionElement: undefined,
nullOption: true,
cacheName: '',
subheader: 'All',
enableSearch: true,
selectModalHeader: 'Select Item',
placeholder: undefined,
showSaveButton: false,
defaultLabelProp: undefined,
recentlyUsed: undefined,
label: '',
},
mode: 'ios' as Mode,
cssClass: 'fy-modal',
showBackdrop: true,
canDismiss: true,
backdropDismiss: true,
animated: true,
initialBreakpoint: 1,
breakpoints: [0, 1],
handle: false,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import { ComponentFixture, TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { IonicModule, ModalController } from '@ionic/angular';

import { Injector, NO_ERRORS_SCHEMA } from '@angular/core';
import { VirtualSelectComponent } from './virtual-select.component';
import { ModalPropertiesService } from 'src/app/core/services/modal-properties.service';
import { FormControl, NG_VALUE_ACCESSOR, NgControl } from '@angular/forms';
import { properties } from 'src/app/core/mock-data/modal-properties.data';
import { virtualSelectModalControllerParams } from 'src/app/core/mock-data/modal-controller.data';

describe('VirtualSelectModalComponent', () => {
let component: VirtualSelectComponent;
let fixture: ComponentFixture<VirtualSelectComponent>;
let modalController: jasmine.SpyObj<ModalController>;
let modalProperties: jasmine.SpyObj<ModalPropertiesService>;

beforeEach(waitForAsync(() => {
const modalControllerSpy = jasmine.createSpyObj('ModalController', ['create']);
const modalPropertiesServiceSpy = jasmine.createSpyObj('ModalPropertiesService', ['getModalDefaultProperties']);
const injectorSpy = jasmine.createSpyObj('Injector', ['get']);

TestBed.configureTestingModule({
declarations: [VirtualSelectComponent],
imports: [IonicModule.forRoot()],
providers: [
{
provide: ModalController,
useValue: modalControllerSpy,
},
{
provide: ModalPropertiesService,
useValue: modalPropertiesServiceSpy,
},
{
provide: Injector,
useValue: injectorSpy,
},
{
provide: NgControl,
useValue: {
control: new FormControl(),
},
},
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();

fixture = TestBed.createComponent(VirtualSelectComponent);
component = fixture.componentInstance;
modalController = TestBed.inject(ModalController) as jasmine.SpyObj<ModalController>;
modalProperties = TestBed.inject(ModalPropertiesService) as jasmine.SpyObj<ModalPropertiesService>;
component.enableSearch = true;
fixture.debugElement.injector.get(NG_VALUE_ACCESSOR);
fixture.detectChanges();
}));

it('should create', () => {
expect(component).toBeTruthy();
});

describe('openModal():', () => {
let selectionModalSpy: jasmine.SpyObj<HTMLIonModalElement>;
beforeEach(() => {
selectionModalSpy = jasmine.createSpyObj('selectionModal', ['present', 'onWillDismiss']);
selectionModalSpy.onWillDismiss.and.resolveTo({
data: {
value: 'value',
},
});
modalProperties.getModalDefaultProperties.and.returnValue(properties);
modalController.create.and.resolveTo(selectionModalSpy);
});

it('should open select modal and set value equals to value returned by modal', fakeAsync(() => {
component.openModal();
tick(100);

expect(modalController.create).toHaveBeenCalledOnceWith(virtualSelectModalControllerParams);
expect(modalProperties.getModalDefaultProperties).toHaveBeenCalledOnceWith('virtual-modal');
expect(selectionModalSpy.present).toHaveBeenCalledTimes(1);
expect(selectionModalSpy.onWillDismiss).toHaveBeenCalledTimes(1);
}));

it('should open select modal and set value equals to value returned by modal if label is Payment Mode', fakeAsync(() => {
component.label = 'Payment Mode';
component.openModal();
tick(100);

expect(modalController.create).toHaveBeenCalledOnceWith({
...virtualSelectModalControllerParams,
componentProps: { ...virtualSelectModalControllerParams.componentProps, label: 'Payment Mode' },
});
expect(modalProperties.getModalDefaultProperties).toHaveBeenCalledOnceWith('payment-mode-modal');
expect(selectionModalSpy.present).toHaveBeenCalledTimes(1);
expect(selectionModalSpy.onWillDismiss).toHaveBeenCalledTimes(1);
}));
});

describe('get valid():', () => {
beforeEach(() => {
//@ts-ignore
component.ngControl.touched = true;
//@ts-ignore
component.ngControl.valid = true;
});

it('should return true if control is touched and valid', () => {
expect(component.valid).toBeTrue();
});

it('should return false if control is touched and invalid', () => {
//@ts-ignore
component.ngControl.valid = false;
expect(component.valid).toBeFalse();
});

it('should return true if control is untouched', () => {
//@ts-ignore
component.ngControl.touched = false;
//@ts-ignore
component.ngControl.valid = false;
expect(component.valid).toBeTrue();
});
});

describe('set value():', () => {
beforeEach(() => {
//@ts-ignore
component.innerValue = 'ECONOMY';
component.options = [
{ label: 'Business', value: 'BUSINESS' },
{ label: 'Economy', value: 'ECONOMY' },
{ label: 'First Class', value: 'FIRST_CLASS' },
];
//@ts-ignore
spyOn(component, 'onChangeCallback');
});

it('should set the value and update the displayValue if any "option.value" is equal to innerValue', () => {
component.value = 'BUSINESS';
//@ts-ignore
expect(component.innerValue).toEqual('BUSINESS');
expect(component.displayValue).toEqual('Business');
//@ts-ignore
expect(component.onChangeCallback).toHaveBeenCalledOnceWith('BUSINESS');
});

it('should set the value and update the displayValue if type of innerValue is string', () => {
component.value = '';
//@ts-ignore
expect(component.innerValue).toEqual('');
expect(component.displayValue).toEqual('');
//@ts-ignore
expect(component.onChangeCallback).toHaveBeenCalledOnceWith('');
});

it('should set the value and update the displayValue if innerValue and defaultLabelProps is defined', () => {
component.defaultLabelProp = 'vendor';
component.value = { travelClass: 'BUSINESS', vendor: 'vendor1' };
//@ts-ignore
expect(component.innerValue).toEqual({ travelClass: 'BUSINESS', vendor: 'vendor1' });
expect(component.displayValue).toEqual('vendor1');
//@ts-ignore
expect(component.onChangeCallback).toHaveBeenCalledOnceWith({ travelClass: 'BUSINESS', vendor: 'vendor1' });
});

it('should set the value and update the displayValue if none of the conditions holds true', () => {
component.defaultLabelProp = '';
component.value = { travelClass: 'BUSINESS', vendor: 'vendor1' };
//@ts-ignore
expect(component.innerValue).toEqual({ travelClass: 'BUSINESS', vendor: 'vendor1' });
expect(component.displayValue).toEqual('');
//@ts-ignore
expect(component.onChangeCallback).toHaveBeenCalledOnceWith({ travelClass: 'BUSINESS', vendor: 'vendor1' });
});
});

it('onBlur(): should call onTouchedCallback once', () => {
//@ts-ignore
spyOn(component, 'onTouchedCallback');
component.onBlur();
//@ts-ignore
expect(component.onTouchedCallback).toHaveBeenCalledTimes(1);
});

describe('writeValue(): ', () => {
beforeEach(() => {
//@ts-ignore
component.innerValue = 'ECONOMY';
component.options = [
{ label: 'Business', value: 'BUSINESS' },
{ label: 'Economy', value: 'ECONOMY' },
{ label: 'First Class', value: 'FIRST_CLASS' },
];
});

it('should set the value and update the displayValue if any "option.value" is equal to innerValue', () => {
component.writeValue('BUSINESS');
//@ts-ignore
expect(component.innerValue).toEqual('BUSINESS');
expect(component.displayValue).toEqual('Business');
});

it('should set the value and update the displayValue if type of innerValue is string', () => {
component.writeValue('');
//@ts-ignore
expect(component.innerValue).toEqual('');
expect(component.displayValue).toEqual('');
});

it('should set the value and update the displayValue if innerValue and defaultLabelProps is defined', () => {
component.defaultLabelProp = 'vendor';
component.writeValue({ travelClass: 'BUSINESS', vendor: 'vendor1' });
//@ts-ignore
expect(component.innerValue).toEqual({ travelClass: 'BUSINESS', vendor: 'vendor1' });
expect(component.displayValue).toEqual('vendor1');
});

it('should set the value and update the displayValue if none of the conditions holds true', () => {
component.defaultLabelProp = '';
component.writeValue({ travelClass: 'BUSINESS', vendor: 'vendor1' });
//@ts-ignore
expect(component.innerValue).toEqual({ travelClass: 'BUSINESS', vendor: 'vendor1' });
expect(component.displayValue).toEqual('');
});
});

it('registerOnChange(): should set onChangeCallback', () => {
const onChange = (): void => {};
component.registerOnChange(onChange);
//@ts-ignore
expect(component.onChangeCallback).toEqual(onChange);
});

it('registerOnTouched(): should set onTouchedCallback', () => {
const onTouched = (): void => {};
component.registerOnTouched(onTouched);
//@ts-ignore
expect(component.onTouchedCallback).toEqual(onTouched);
});
});

0 comments on commit 8dd2965

Please sign in to comment.