AAE-39612 Registering click event on form widget twice (#11323)

* AAE-39612 Remove click from base and add it directly to the implementations

* AAE-39612 Add unit tests for the Text Widgets

* AAE-39612 Add unit tests for the Date Widgets

* AAE-39612 Add unit tests for the UI Widgets

* AAE-39612 Add unit tests for the People Widgets

* AAE-39612 Add unit tests for the Display Text Widgets

* AAE-39612 Add unit tests for the Base Viewer Widget

* AAE-39612 Add unit tests for the Object View Widgets

* AAE-39612 Add unit tests for the File Upload Widgets

* AAE-39612 Add unit tests for the Data Table Widget
This commit is contained in:
Wiktor Danielewski
2025-11-04 12:08:04 +01:00
committed by GitHub
parent f7d26d904f
commit c4f276e228
40 changed files with 597 additions and 92 deletions
@@ -40,6 +40,24 @@ describe('AmountWidgetComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
it('should setup currency from field', () => {
const currency = 'UAH';
widget.field = new FormFieldModel(null, {
@@ -52,6 +52,24 @@ describe('BaseViewerWidgetComponent', () => {
widget = fixture.componentInstance;
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event');
widget.field = new FormFieldModel(new FormModel(), { value: { urlFile: '' } });
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
it('should set the file id corretly when the field value is an array', (done) => {
assertFileId([fakePngAnswer], '1933', fakeForm, widget, fixture, done);
});
@@ -29,15 +29,7 @@ import { WidgetComponent } from '../widget.component';
templateUrl: './base-viewer.widget.html',
styleUrls: ['./base-viewer.widget.scss'],
host: {
'(click)': 'event($event)',
'(blur)': 'event($event)',
'(change)': 'event($event)',
'(focus)': 'event($event)',
'(focusin)': 'event($event)',
'(focusout)': 'event($event)',
'(input)': 'event($event)',
'(invalid)': 'event($event)',
'(select)': 'event($event)'
'(click)': 'event($event)'
},
imports: [TranslatePipe, ViewerComponent, ErrorWidgetComponent],
encapsulation: ViewEncapsulation.None
@@ -18,7 +18,6 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { UnitTestingUtils } from '../../../../testing';
import { FormFieldModel, FormFieldTypes, FormModel } from '../core';
import { CheckboxWidgetComponent } from './checkbox.widget';
@@ -31,7 +30,7 @@ describe('CheckboxWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [MatCheckboxModule]
imports: [CheckboxWidgetComponent]
});
fixture = TestBed.createComponent(CheckboxWidgetComponent);
widget = fixture.componentInstance;
@@ -39,7 +38,23 @@ describe('CheckboxWidgetComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
});
afterEach(() => fixture.destroy());
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
describe('when template is ready', () => {
beforeEach(() => {
@@ -23,9 +23,6 @@ import { FormFieldTypes } from '../core/form-field-types';
import { HarnessLoader, TestKey } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { addMinutes } from 'date-fns';
import { MatDialogModule } from '@angular/material/dialog';
import { MatDatetimepickerModule, MatNativeDatetimeModule } from '@mat-datetimepicker/core';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { UnitTestingUtils } from '../../../../testing/unit-testing-utils';
describe('DateTimeWidgetComponent', () => {
@@ -37,7 +34,7 @@ describe('DateTimeWidgetComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [MatDialogModule, MatNativeDatetimeModule, MatDatepickerModule, MatDatetimepickerModule, DateTimeWidgetComponent]
imports: [DateTimeWidgetComponent]
});
fixture = TestBed.createComponent(DateTimeWidgetComponent);
widget = fixture.componentInstance;
@@ -51,6 +48,24 @@ describe('DateTimeWidgetComponent', () => {
TestBed.resetTestingModule();
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
it('should not call onFieldChanged on init', () => {
spyOn(widget, 'onFieldChanged').and.callThrough();
expect(widget.onFieldChanged).not.toHaveBeenCalled();
@@ -43,6 +43,9 @@ import { ReactiveFormWidget } from '../reactive-widget.interface';
],
templateUrl: './date-time.widget.html',
styleUrls: ['./date-time.widget.scss'],
host: {
'(click)': 'event($event)'
},
imports: [NgIf, TranslatePipe, MatFormFieldModule, MatInputModule, MatDatetimepickerModule, ReactiveFormsModule, ErrorWidgetComponent],
encapsulation: ViewEncapsulation.None
})
@@ -42,6 +42,24 @@ describe('DateWidgetComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement);
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
it('should not call onFieldChanged on init', () => {
spyOn(widget, 'onFieldChanged').and.callThrough();
expect(widget.onFieldChanged).not.toHaveBeenCalled();
@@ -18,7 +18,6 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatInputModule } from '@angular/material/input';
import { UnitTestingUtils } from '../../../../testing';
import { FormService } from '../../../services/form.service';
import { FormFieldModel, FormFieldTypes, FormModel } from '../core';
@@ -32,7 +31,7 @@ describe('DecimalComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [MatInputModule, DecimalWidgetComponent],
imports: [DecimalWidgetComponent],
providers: [FormService]
});
@@ -42,6 +41,24 @@ describe('DecimalComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
@@ -0,0 +1,52 @@
/*!
* @license
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { FormFieldModel, FormModel } from '../core';
import { DisplayTextWidgetComponent } from './display-text.widget';
describe('DisplayTextWidgetComponent', () => {
let fixture: ComponentFixture<DisplayTextWidgetComponent>;
let widget: DisplayTextWidgetComponent;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [DisplayTextWidgetComponent]
});
fixture = TestBed.createComponent(DisplayTextWidgetComponent);
widget = fixture.componentInstance;
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
});
@@ -34,6 +34,24 @@ describe('HyperlinkWidgetComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement);
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
it('should get link text from field display text', () => {
const text = 'hello world';
@@ -40,6 +40,24 @@ describe('MultilineTextWidgetComponentComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
describe('when tooltip is set', () => {
beforeEach(() => {
widget.field = new FormFieldModel(new FormModel({ taskId: '<id>' }), {
@@ -18,8 +18,6 @@
import { HarnessLoader } from '@angular/cdk/testing';
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { UnitTestingUtils } from '../../../../testing';
import { FormFieldModel, FormFieldTypes, FormModel } from '../core';
import { NumberWidgetComponent } from './number.widget';
@@ -36,7 +34,7 @@ describe('NumberWidgetComponent', () => {
mockDecimalNumberPipe = jasmine.createSpyObj('DecimalNumberPipe', ['transform']);
await TestBed.configureTestingModule({
imports: [MatInputModule, MatIconModule]
imports: [NumberWidgetComponent]
})
.overrideComponent(NumberWidgetComponent, {
set: {
@@ -51,8 +49,22 @@ describe('NumberWidgetComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
});
it('should create', () => {
expect(widget).toBeTruthy();
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
describe('with readonly true', () => {
@@ -43,6 +43,24 @@ describe('TextWidgetComponent', () => {
testingUtils = new UnitTestingUtils(fixture.debugElement, loader);
});
describe('event tracking', () => {
let eventSpy: jasmine.Spy;
beforeEach(() => {
eventSpy = spyOn(widget, 'event').and.callThrough();
widget.field = new FormFieldModel(new FormModel(), {});
fixture.detectChanges();
});
it('should call event method only once when widget is clicked', () => {
const clickEvent = new MouseEvent('click', { bubbles: true });
fixture.debugElement.nativeElement.dispatchEvent(clickEvent);
expect(eventSpy).toHaveBeenCalledTimes(1);
expect(eventSpy).toHaveBeenCalledWith(clickEvent);
});
});
describe('when template is ready', () => {
describe('and no mask is configured on text element', () => {
it('should raise ngModelChange event', async () => {
@@ -29,7 +29,6 @@ import { FormFieldModel } from './core';
selector: 'base-widget',
template: '',
host: {
'(click)': 'event($event)',
'(blur)': 'event($event)',
'(change)': 'event($event)',
'(focus)': 'event($event)',