Skip to content

Commit

Permalink
NAS-133118 / 25.04 / Addes tests for glossary and form-section compon…
Browse files Browse the repository at this point in the history
…ents, form-service (#11352)
  • Loading branch information
RehanY147 authored Jan 21, 2025
1 parent c2e5fbc commit 478af04
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
[formControl]="searchControl"
[placeholder]="'Search Input Fields' | translate"
[autocompleteOptions]="searchOptions()"
[label]="'Search' | translate"
></ix-input>

@for (section of sections(); track section) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { fakeAsync, tick } from '@angular/core/testing';
import {
FormControl, FormGroup, NgControl, ReactiveFormsModule,
} from '@angular/forms';
import { MatAutocomplete } from '@angular/material/autocomplete';
import { createHostFactory, mockProvider, SpectatorHost } from '@ngneat/spectator/jest';
import { of, Subject } from 'rxjs';
import { NavigateAndHighlightService } from 'app/directives/navigate-and-interact/navigate-and-highlight.service';
import { IxFormGlossaryComponent } from 'app/modules/forms/ix-forms/components/ix-form-glossary/ix-form-glossary.component';
import { IxFormSectionComponent } from 'app/modules/forms/ix-forms/components/ix-form-section/ix-form-section.component';
import { IxInputComponent } from 'app/modules/forms/ix-forms/components/ix-input/ix-input.component';
import { IxInputHarness } from 'app/modules/forms/ix-forms/components/ix-input/ix-input.harness';
import { IxFormService } from 'app/modules/forms/ix-forms/services/ix-form.service';
import { IxIconComponent } from 'app/modules/ix-icon/ix-icon.component';

describe('IxFormGlossaryComponent', () => {
let spectator: SpectatorHost<IxFormGlossaryComponent>;
let harnessLoader: HarnessLoader;
const statusChanges$ = new Subject<void>();
const element = document.createElement('div');

const createHost = createHostFactory({
component: IxFormGlossaryComponent,
imports: [
IxInputComponent,
ReactiveFormsModule,
IxFormSectionComponent,
IxIconComponent,
MatAutocomplete,
],
providers: [
mockProvider(IxFormService, {
controlSections$: of([
{
section: { label: () => 'Section' } as IxFormSectionComponent,
controls: [
{ valid: true, statusChanges: statusChanges$ } as unknown as NgControl,
{ valid: false, statusChanges: statusChanges$ } as unknown as NgControl,
],
},
]),
controlNamesWithLabels$: of([
{
label: 'Control1',
name: 'control1',
},
{
label: 'Control2',
name: 'control2',
},
]),
getElementByControlName: jest.fn(() => element),
}),
mockProvider(NavigateAndHighlightService),
],
});

beforeEach(() => {
spectator = createHost(`
<form [formGroup]="fg"><ix-form-section [label]="'Section'"><ix-input [formControlName]="'control1'" [label]="'Control1'"></ix-input> <ix-input [formControlName]="'control2'" [label]="'Control2'"></ix-input></ix-form-section></form> <ix-form-glossary></ix-form-glossary>
`, {
hostProps: {
fg: new FormGroup({
control1: new FormControl(),
control2: new FormControl(),
}),
},
});

harnessLoader = TestbedHarnessEnvironment.loader(spectator.fixture);
});

it('loads input options from form glossary', async () => {
expect(spectator.component).toBeTruthy();
const input = await harnessLoader.getHarness(IxInputHarness.with({ label: 'Search' }));
await input.setValue('Control2');
const matAutocomplete = await input.getMatAutoCompleteHarness();
const options = await matAutocomplete.getOptions();
const optionsText: string[] = [];
for (const option of options) {
optionsText.push(await option.getText());
}
expect(optionsText).toEqual(['Control2']);
expect(spectator.inject(NavigateAndHighlightService).scrollIntoView).toHaveBeenCalledWith(element);
});

it('shows sections as options', fakeAsync(() => {
spectator.detectChanges();
tick(100);
const sections = spectator.queryAll('.section');
expect(sections.map((section) => section.textContent)).toEqual([' Section ']);
}));
});
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ export class IxFormGlossaryComponent implements OnInit {

private handleSectionUpdates(): void {
this.formService.controlSections$.pipe(
delay(0),
untilDestroyed(this),
).subscribe({
next: (sectionsWithControls) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { mockProvider, createComponentFactory, Spectator } from '@ngneat/spectator/jest';
import { IxFormSectionComponent } from 'app/modules/forms/ix-forms/components/ix-form-section/ix-form-section.component';
import { IxFormService } from 'app/modules/forms/ix-forms/services/ix-form.service';

describe('IxFormSectionComponent', () => {
let spectator: Spectator<IxFormSectionComponent>;
const createComponent = createComponentFactory({
component: IxFormSectionComponent,
providers: [
mockProvider(IxFormService),
],
});

beforeEach(() => {
spectator = createComponent({
props: {
label: 'Test Section',
help: 'Test Help',
},
});
});

it('calls registerSectionControl when created', () => {
expect(spectator.inject(IxFormService).registerSectionControl).toHaveBeenCalledWith(null, spectator.component);
});

it('calls unregisterSectionControl when destroyed', () => {
spectator.component.ngOnDestroy();
expect(spectator.inject(IxFormService).unregisterSectionControl).toHaveBeenCalledWith(spectator.component, null);
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
import { MatAutocompleteHarness } from '@angular/material/autocomplete/testing';
import { MatInputHarness } from '@angular/material/input/testing';
import { IxLabelHarness } from 'app/modules/forms/ix-forms/components/ix-label/ix-label.harness';
import { IxFormControlHarness } from 'app/modules/forms/ix-forms/interfaces/ix-form-control-harness.interface';
Expand All @@ -17,6 +18,8 @@ export class IxInputHarness extends ComponentHarness implements IxFormControlHar
}

getMatInputHarness = this.locatorFor(MatInputHarness);
getMatAutoCompleteHarness = this.locatorFor(MatAutocompleteHarness);

getErrorText = getErrorText;

async getLabelText(): Promise<string> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,92 @@
import { ElementRef } from '@angular/core';
import { NgControl } from '@angular/forms';
import { createDirectiveFactory, mockProvider, SpectatorDirective } from '@ngneat/spectator/jest';
import { RegisteredControlDirective } from 'app/modules/forms/ix-forms/directives/registered-control.directive';
import {
ReactiveFormsModule, FormGroup, FormControl, NgControl,
} from '@angular/forms';
import { createDirectiveFactory, mockProvider } from '@ngneat/spectator/jest';
import { MockComponent } from 'ng-mocks';
import { IxFormSectionComponent } from 'app/modules/forms/ix-forms/components/ix-form-section/ix-form-section.component';
import { IxFormService } from 'app/modules/forms/ix-forms/services/ix-form.service';
import { RegisteredControlDirective } from './registered-control.directive';

// TODO: https://ixsystems.atlassian.net/browse/NAS-133118
describe.skip('RegisteredControlDirective', () => {
let spectator: SpectatorDirective<RegisteredControlDirective>;

describe('RegisteredControlDirective', () => {
function getGroupDiv(): HTMLDivElement {
const divElement = document.createElement('div');
divElement.setAttribute('ixRegisteredControl', '');
divElement.setAttribute('ix-label', 'Test Group');
divElement.setAttribute('ng-reflect-form-group-name', 'testGroup');
divElement.setAttribute('ng-reflect-label', 'Test Group');
divElement.setAttribute('ng-reflect-label', 'Test Group');
divElement.setAttribute('ng-reflect-name', 'testGroup');
divElement.classList.add('ng-untouched');
divElement.classList.add('ng-pristine');
divElement.classList.add('ng-valid');
const inputElement = document.createElement('input');
inputElement.classList.add('ng-untouched');
inputElement.setAttribute('ng-reflect-name', 'testControl');
inputElement.classList.add('ng-pristine');
inputElement.classList.add('ng-valid');
inputElement.setAttribute('formControlName', 'testControl');
divElement.appendChild(inputElement);
return divElement;
}
const testGroup = new FormGroup({
testControl: new FormControl(''),
});
const createDirective = createDirectiveFactory({
directive: RegisteredControlDirective,
imports: [ReactiveFormsModule, MockComponent(IxFormSectionComponent)],
providers: [
mockProvider(NgControl, {
name: 'testGroup',
control: testGroup,
}),
mockProvider(IxFormService),
mockProvider(NgControl, {}),
],
});

beforeEach(() => {
spectator = createDirective('<div ixRegisteredControl [label]="\'Test\'" [formGroupName]=\'test\'></div>');
it('registers control when control name is available', () => {
const spectator = createDirective(`
<div [formGroup]="fg"><div ixRegisteredControl [label]="'Test Group'" [formGroupName]="'testGroup'"><input formControlName="testControl"></div></div>
`, {
hostProps: {
fg: new FormGroup({
testGroup,
}),
},
});

expect(spectator.inject(IxFormService).registerControl).toHaveBeenCalled();
});

it('registers control and element ref of the element with form service', () => {
expect(spectator.inject(IxFormService).registerControl).toHaveBeenCalledWith(
spectator.inject(NgControl),
expect.any(ElementRef),
it('registers control and form section available', () => {
const spectator = createDirective(`
<div [formGroup]="fg"><ix-form-section [label]="'Test Section'"><div ixRegisteredControl [label]="'Test Group'" [formGroupName]="'testGroup'"><input formControlName="testControl"></div></ix-form-section></div>
`, {
hostProps: {
fg: new FormGroup({
testGroup,
}),
},
});
const formService = spectator.inject(IxFormService);
expect(
formService.registerControl,
).toHaveBeenCalledWith('testGroup', new ElementRef(getGroupDiv()));
const ixFormSection = document.createElement('ix-form-section');
ixFormSection.setAttribute('id', 'Test Section');
expect(formService.registerSectionControl).toHaveBeenCalledWith(
expect.objectContaining({ name: 'testGroup', control: testGroup }),
expect.objectContaining({
label: 'Test Section',
}),
);
spectator.directive.ngOnDestroy();
expect(formService.unregisterControl).toHaveBeenCalledWith('testGroup');
expect(formService.unregisterSectionControl).toHaveBeenCalledWith(
expect.objectContaining({
label: 'Test Section',
}),
expect.objectContaining({ name: 'testGroup', control: testGroup }),
);
});
});
7 changes: 1 addition & 6 deletions src/setup-jest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import {
MissingTranslationHandler, TranslateCompiler, TranslateLoader, TranslateModule, TranslateFakeLoader,
} from '@ngx-translate/core';
import failOnConsole from 'jest-fail-on-console';
import { MockDirective, MockProvider } from 'ng-mocks';
import { MockProvider } from 'ng-mocks';
import { TranslateMessageFormatCompiler } from 'ngx-translate-messageformat-compiler';
import {
Observable,
Expand Down Expand Up @@ -68,7 +68,6 @@ import {
} from 'app/modules/forms/ix-forms/components/ix-slide-toggle/ix-slide-toggle.component';
import { IxTextareaComponent } from 'app/modules/forms/ix-forms/components/ix-textarea/ix-textarea.component';
import { WarningComponent } from 'app/modules/forms/ix-forms/components/warning/warning.component';
import { RegisteredControlDirective } from 'app/modules/forms/ix-forms/directives/registered-control.directive';
import { IxIconRegistry } from 'app/modules/ix-icon/ix-icon-registry.service';
import { IxIconComponent } from 'app/modules/ix-icon/ix-icon.component';
import { IxTableComponent } from 'app/modules/ix-table/components/ix-table/ix-table.component';
Expand Down Expand Up @@ -99,9 +98,6 @@ failOnConsole({ silenceMessage: silenceJsDomCssParseError });
jest.setTimeout(30 * 1000);

defineGlobalsInjections({
declarations: [
MockDirective(RegisteredControlDirective),
],
imports: [
HttpClientModule,
MatCheckboxModule,
Expand Down Expand Up @@ -129,7 +125,6 @@ defineGlobalsInjections({
IxFieldsetComponent,
ModalHeaderComponent,
IxFormSectionComponent,
RegisteredControlDirective,
IxButtonGroupComponent,
IxExplorerComponent,
IxFileInputComponent,
Expand Down

0 comments on commit 478af04

Please sign in to comment.