From 0282cdb5296ce6d5f939e52a589f255d3dc21363 Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Thu, 22 Oct 2026 01:11:50 -0700 Subject: [PATCH] Frontend tests --- ...om-fields-query-dropdown.component.spec.ts | 79 ++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts index d1e755032..dbe77757a 100644 --- a/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts +++ b/src-ui/src/app/components/common/custom-fields-query-dropdown/custom-fields-query-dropdown.component.spec.ts @@ -3,7 +3,7 @@ import { provideHttpClientTesting } from '@angular/common/http/testing' import { LOCALE_ID } from '@angular/core' import { ComponentFixture, TestBed } from '@angular/core/testing' import { FormsModule, ReactiveFormsModule } from '@angular/forms' -import { NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap' +import { NgbDateAdapter, NgbDropdownModule } from '@ng-bootstrap/ng-bootstrap' import { NgSelectModule } from '@ng-select/ng-select' import { allIcons, NgxBootstrapIconsModule } from 'ngx-bootstrap-icons' import { of } from 'rxjs' @@ -11,6 +11,7 @@ import { CustomField, CustomFieldDataType } from 'src/app/data/custom-field' import { CUSTOM_FIELD_QUERY_OPERATORS_BY_GROUP, CustomFieldQueryLogicalOperator, + CustomFieldQueryOperator, CustomFieldQueryOperatorGroups, } from 'src/app/data/custom-field-query' import { CustomFieldsService } from 'src/app/services/rest/custom-fields.service' @@ -19,6 +20,7 @@ import { CustomFieldQueryElement, CustomFieldQueryExpression, } from 'src/app/utils/custom-field-query-element' +import { ISODateAdapter } from 'src/app/utils/ngb-iso-date-adapter' import { CustomFieldQueriesModel, CustomFieldsQueryDropdownComponent, @@ -48,6 +50,12 @@ const customFields = [ data_type: CustomFieldDataType.Monetary, extra_data: { default_currency: 'EUR' }, }, + { + id: 4, + name: 'Test Date Field', + data_type: CustomFieldDataType.Date, + extra_data: {}, + }, ] describe('CustomFieldsQueryDropdownComponent', () => { @@ -69,6 +77,7 @@ describe('CustomFieldsQueryDropdownComponent', () => { provideHttpClient(withInterceptorsFromDi()), provideHttpClientTesting(), { provide: LOCALE_ID, useValue: 'de' }, + { provide: NgbDateAdapter, useClass: ISODateAdapter }, ], }).compileComponents() @@ -237,6 +246,74 @@ describe('CustomFieldsQueryDropdownComponent', () => { expect(component.selectionModel.queries.length).toBe(1) }) + it('should build relative date values from amount and unit', async () => { + component.useDropdown = false + const atom = new CustomFieldQueryAtom([ + 4, + CustomFieldQueryOperator.GreaterThanOrEqual, + '2026-10-22', + ]) + component.selectionModel.addAtom(atom) + fixture.detectChanges() + await fixture.whenStable() + const query = (selector: string) => + fixture.nativeElement.querySelector(selector) + const toggle: HTMLButtonElement = query('button[title="Relative date"]') + expect(query('[ngbDatepicker]')).not.toBeNull() + + toggle.click() + fixture.detectChanges() + await fixture.whenStable() + expect(atom.value).toBeNull() + const amount: HTMLInputElement = query('input[aria-label="Amount"]') + const unit: HTMLSelectElement = query('select[aria-label="Unit"]') + amount.value = '30' + amount.dispatchEvent(new Event('input')) + expect(atom.serialize()).toEqual([4, 'gte', '30 days ago']) + unit.selectedIndex = 6 + unit.dispatchEvent(new Event('change')) + expect(atom.serialize()).toEqual([4, 'gte', 'in 30 weeks']) + unit.selectedIndex = 0 + unit.dispatchEvent(new Event('change')) + fixture.detectChanges() + expect(atom.serialize()).toEqual([4, 'gte', 'today']) + expect(query('input[aria-label="Amount"]')).toBeNull() + + toggle.click() + fixture.detectChanges() + expect(atom.value).toBeNull() + expect(query('[ngbDatepicker]')).not.toBeNull() + }) + + it('should restore a saved relative date value', async () => { + component.useDropdown = false + const atom = new CustomFieldQueryAtom([ + 4, + CustomFieldQueryOperator.Exact, + 'in 2 months', + ]) + component.selectionModel.addAtom(atom) + fixture.detectChanges() + await fixture.whenStable() + expect(component.getRelativeDate(atom)).toEqual({ + amount: 2, + unit: 'in {n} months', + }) + expect( + fixture.nativeElement.querySelector('input[aria-label="Amount"]').value + ).toBe('2') + + const today = new CustomFieldQueryAtom([ + 4, + CustomFieldQueryOperator.Exact, + 'today', + ]) + expect(component.getRelativeDate(today)).toEqual({ + amount: null, + unit: 'today', + }) + }) + describe('CustomFieldQueriesModel', () => { let model: CustomFieldQueriesModel