Skip to content

Commit

Permalink
test: 100% coverage of generic-fields-form (#2455)
Browse files Browse the repository at this point in the history
* test: 100% coverage of generic-fields-form

* minor
  • Loading branch information
suyashpatil78 authored Sep 29, 2023
1 parent 853838d commit 019b303
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,111 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';

import { GenericFieldsFormComponent } from './generic-fields-form.component';
import { FormBuilder, FormControl } from '@angular/forms';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { dependentCustomProperties } from 'src/app/core/mock-data/custom-property.data';
import { AllowedPaymentModes } from 'src/app/core/models/allowed-payment-modes.enum';

xdescribe('GenericFieldsFormComponent', () => {
describe('GenericFieldsFormComponent', () => {
let component: GenericFieldsFormComponent;
let fixture: ComponentFixture<GenericFieldsFormComponent>;

beforeEach(
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [GenericFieldsFormComponent],
imports: [IonicModule.forRoot()],
}).compileComponents();
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [GenericFieldsFormComponent],
imports: [IonicModule.forRoot()],
providers: [FormBuilder],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();

fixture = TestBed.createComponent(GenericFieldsFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
})
);
fixture = TestBed.createComponent(GenericFieldsFormComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));

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

describe('ngOnInit():', () => {
it('should emit categoryChanged event if category option changes', () => {
spyOn(component.categoryChanged, 'emit');
component.ngOnInit();
component.genericFieldsFormGroup.controls.category.setValue(32108);
expect(component.categoryChanged.emit).toHaveBeenCalledOnceWith(32108);
});

it('should assign projectDependentFields to projectDependentFieldsMapping.projectId if project option changes', () => {
component.projectDependentFieldsMapping = {
3943: dependentCustomProperties,
};
component.ngOnInit();
expect(component.projectDependentFields).toEqual([]);
component.genericFieldsFormGroup.controls.project.setValue(3943);
expect(component.projectDependentFields).toEqual(dependentCustomProperties);
});

it('should assign costCenterDependentFields to costCenterDependentFieldsMapping.costCenterId if cost center option changes', () => {
component.costCenterDependentFieldsMapping = {
13795: dependentCustomProperties,
};
component.ngOnInit();
expect(component.costCenterDependentFields).toEqual([]);
component.genericFieldsFormGroup.controls.costCenter.setValue(13795);
expect(component.costCenterDependentFields).toEqual(dependentCustomProperties);
});

it('should emit paymentModeChanged event if payment mode option changes', () => {
spyOn(component.paymentModeChanged, 'emit');
component.ngOnInit();
component.genericFieldsFormGroup.controls.paymentMode.setValue(AllowedPaymentModes.PERSONAL_ACCOUNT);
expect(component.paymentModeChanged.emit).toHaveBeenCalledOnceWith(AllowedPaymentModes.PERSONAL_ACCOUNT);
});

it('should emit receiptChanged event if receipt option changes', () => {
spyOn(component.receiptChanged, 'emit');
component.ngOnInit();
component.genericFieldsFormGroup.controls.receipt_ids.setValue('txErhlkzewZF');
expect(component.receiptChanged.emit).toHaveBeenCalledOnceWith('txErhlkzewZF');
});

it('should emit fieldsTouched event if any field is touched', () => {
spyOn(component.fieldsTouched, 'emit');
spyOn(component, 'isFieldTouched').and.returnValues(true);
component.ngOnInit();
component.genericFieldsFormGroup.controls.amount.setValue(100);
expect(component.fieldsTouched.emit).toHaveBeenCalledOnceWith(['amount']);
});
});

it('ngOnDestroy(): should unsubscribe from onChangeSub', () => {
component.onChangeSub = jasmine.createSpyObj('onChangeSub', ['unsubscribe']);
component.ngOnDestroy();
expect(component.onChangeSub.unsubscribe).toHaveBeenCalledTimes(1);
});

it('writeValue(): should patch value to form control', () => {
component.genericFieldsFormGroup = new FormBuilder().group({
location_1: new FormControl(),
});
const newValue = new FormBuilder().group({
location_1: new FormControl(200),
});
spyOn(component.genericFieldsFormGroup, 'patchValue');
component.writeValue(newValue);
expect(component.genericFieldsFormGroup.patchValue).toHaveBeenCalledOnceWith(newValue);
});

it('registerOnChange(): should subscribe to value changes', () => {
const onChange = (): void => {};
spyOn(component.genericFieldsFormGroup.valueChanges, 'subscribe');
component.registerOnChange(onChange);
expect(component.genericFieldsFormGroup.valueChanges.subscribe).toHaveBeenCalledOnceWith(onChange);
});

it('registerOnTouched(): should set onTouched', () => {
const onTouched = (): void => {};
component.registerOnTouched(onTouched);
expect(component.onTouched).toEqual(onTouched);
});
});
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
import { Component, EventEmitter, Injector, Input, OnDestroy, OnInit, Output, TemplateRef } from '@angular/core';
import { Subscription } from 'rxjs';
import { Subscription, noop } from 'rxjs';
import { filter } from 'rxjs/operators';
import { CorporateCardExpense } from 'src/app/core/models/v2/corporate-card-expense.model';
import {
FormControl,
FormGroup,
ControlValueAccessor,
NG_VALUE_ACCESSOR,
FormBuilder,
Validators,
} from '@angular/forms';
import { FormGroup, ControlValueAccessor, NG_VALUE_ACCESSOR, FormBuilder, Validators } from '@angular/forms';
import { FileObject } from 'src/app/core/models/file-obj.model';
import { CustomProperty } from 'src/app/core/models/custom-properties.model';
import { AllowedPaymentModes } from 'src/app/core/models/allowed-payment-modes.enum';

type Option = Partial<{
label: string;
value: any;
value: string;
}>;

type OptionsData = Partial<{
options: Option[];
areSameValues: boolean;
name: string;
value: any;
value: string;
}>;

@Component({
Expand Down Expand Up @@ -58,7 +52,7 @@ export class GenericFieldsFormComponent implements OnInit, ControlValueAccessor,

@Input() purposeOptionsData: OptionsData;

@Input() categoryDependentTemplate: TemplateRef<any>;
@Input() categoryDependentTemplate: TemplateRef<string[]>;

@Input() CCCTxns: CorporateCardExpense[];

Expand All @@ -70,11 +64,11 @@ export class GenericFieldsFormComponent implements OnInit, ControlValueAccessor,

@Output() fieldsTouched = new EventEmitter<string[]>();

@Output() categoryChanged = new EventEmitter<void>();
@Output() categoryChanged = new EventEmitter<number>();

@Output() receiptChanged = new EventEmitter<void>();
@Output() receiptChanged = new EventEmitter<string>();

@Output() paymentModeChanged = new EventEmitter<void>();
@Output() paymentModeChanged = new EventEmitter<AllowedPaymentModes>();

genericFieldsFormGroup: FormGroup;

Expand All @@ -84,9 +78,13 @@ export class GenericFieldsFormComponent implements OnInit, ControlValueAccessor,

costCenterDependentFields: CustomProperty<string>[] = [];

onTouched: () => void = noop;

constructor(private formBuilder: FormBuilder, private injector: Injector) {}

ngOnInit() {
isFieldTouched = (fieldName: string): boolean => this.genericFieldsFormGroup.get(fieldName).touched;

ngOnInit(): void {
this.genericFieldsFormGroup = this.formBuilder.group({
amount: [, Validators.required],
receipt_ids: [],
Expand All @@ -102,58 +100,56 @@ export class GenericFieldsFormComponent implements OnInit, ControlValueAccessor,
purpose: [],
});

this.genericFieldsFormGroup.controls.category.valueChanges.subscribe((categoryId) => {
this.genericFieldsFormGroup.controls.category.valueChanges.subscribe((categoryId: number) => {
this.categoryChanged.emit(categoryId);
});

this.genericFieldsFormGroup.controls.project.valueChanges
.pipe(filter((projectId) => !!projectId))
.subscribe((projectId) => {
.subscribe((projectId: number) => {
this.projectDependentFields = this.projectDependentFieldsMapping[projectId];
});

this.genericFieldsFormGroup.controls.costCenter.valueChanges
.pipe(filter((costCenterId) => !!costCenterId))
.subscribe((costCenterId) => {
.subscribe((costCenterId: number) => {
this.costCenterDependentFields = this.costCenterDependentFieldsMapping[costCenterId];
});

this.genericFieldsFormGroup.controls.paymentMode.valueChanges.subscribe((paymentMode) => {
this.genericFieldsFormGroup.controls.paymentMode.valueChanges.subscribe((paymentMode: AllowedPaymentModes) => {
this.paymentModeChanged.emit(paymentMode);
});

this.genericFieldsFormGroup.controls.receipt_ids.valueChanges.subscribe((receiptIds) => {
this.genericFieldsFormGroup.controls.receipt_ids.valueChanges.subscribe((receiptIds: string) => {
this.receiptChanged.emit(receiptIds);
});

this.genericFieldsFormGroup.valueChanges.subscribe((formControlNames) => {
const touchedItems = [];
this.genericFieldsFormGroup.valueChanges.subscribe((formControlNames: FormGroup) => {
const touchedItems: string[] = [];
Object.keys(formControlNames).forEach((key) => {
if (this.genericFieldsFormGroup.get(key).touched) {
if (this.isFieldTouched(key)) {
touchedItems.push(key);
}
});
this.fieldsTouched.emit(touchedItems);
});
}

onTouched = () => {};

ngOnDestroy(): void {
this.onChangeSub.unsubscribe();
this.onChangeSub?.unsubscribe();
}

writeValue(value: any) {
writeValue(value: FormGroup): void {
if (value) {
this.genericFieldsFormGroup.patchValue(value);
}
}

registerOnChange(onChange): void {
registerOnChange(onChange: () => void): void {
this.onChangeSub = this.genericFieldsFormGroup.valueChanges.subscribe(onChange);
}

registerOnTouched(onTouched): void {
registerOnTouched(onTouched: () => void): void {
this.onTouched = onTouched;
}
}

0 comments on commit 019b303

Please sign in to comment.