
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Evergreen ILS". The branch, main has been updated via 8dbeb06ce59a6376fc239ddea0e8c44996e168ef (commit) from 4c0c258397b4c0f0452aaf04f993255003b52008 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8dbeb06ce59a6376fc239ddea0e8c44996e168ef Author: Jane Sandberg <js7389@princeton.edu> Date: Mon Mar 31 16:23:02 2025 -0700 LP2074112 follow-up: address NG0203: inject() must be called from an injection context errors in angular tests The affected angular unit tests all had two characteristics in common: * They tested a component that extends DialogComponent * They had tried to avoid using the extensive boilerplate necessary to use Angular Dependency Injection in test contexts by explicitly calling the component's constructor (i.e. treating the components like a plain old typescript object). LP2074112 forced the issue of Angular DI by including the newer "inject" dependency injection syntax in the DialogComponent. This commit gets these tests passing again by using Angular's TestBed boilerplate to join the dependency injection world. Signed-off-by: Jane Sandberg <js7389@princeton.edu> diff --git a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.spec.ts b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.spec.ts index ab3123ca00..3e5c83561c 100644 --- a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.spec.ts +++ b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.spec.ts @@ -5,8 +5,9 @@ import { FmRecordEditorComponent } from './fm-editor.component'; import { FormatService } from '@eg/core/format.service'; import { OrgService } from '@eg/core/org.service'; import { PcrudService } from '@eg/core/pcrud.service'; -import { waitForAsync } from '@angular/core/testing'; +import { TestBed, waitForAsync } from '@angular/core/testing'; import { of } from 'rxjs'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; describe('FmRecordEditorComponent', () => { let component: FmRecordEditorComponent; @@ -43,9 +44,18 @@ describe('FmRecordEditorComponent', () => { } }); - component = new FmRecordEditorComponent( - mockModal, mockIdl, mockToast, mockFormat, mockOrg, mockPcrud - ); + TestBed.configureTestingModule({ + providers: [ + {provide: NgbModal, useValue: mockModal}, + {provide: IdlService, useValue: mockIdl}, + {provide: ToastService, useValue: mockToast}, + {provide: FormatService, useValue: mockFormat}, + {provide: OrgService, useValue: mockOrg}, + {provide: PcrudService, useValue: mockPcrud} + ], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + component = TestBed.createComponent(FmRecordEditorComponent).componentInstance; }); describe('hidden fields', () => { diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-associate-material.component.spec.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-associate-material.component.spec.ts index 28d4d9933e..799ce6ba7f 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-associate-material.component.spec.ts +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/course-reserves/course-associate-material.component.spec.ts @@ -1,18 +1,20 @@ import { PermService } from '@eg/core/perm.service'; -import { waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { ToastService } from '@eg/share/toast/toast.service'; import { CourseService } from '@eg/staff/share/course.service'; import { AuthService } from '@eg/core/auth.service'; import { NetService } from '@eg/core/net.service'; import { PcrudService } from '@eg/core/pcrud.service'; import { CourseAssociateMaterialComponent } from './course-associate-material.component'; -import {NgbModal} from '@ng-bootstrap/ng-bootstrap'; +import {NgbModal, NgbNav} from '@ng-bootstrap/ng-bootstrap'; import { of } from 'rxjs'; import { DialogComponent } from '@eg/share/dialog/dialog.component'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; describe('CourseAssociateMaterialComponent', () => { let component: CourseAssociateMaterialComponent; + let fixture: ComponentFixture<CourseAssociateMaterialComponent>; const mockLibrary = { id: () => 5, @@ -35,10 +37,10 @@ describe('CourseAssociateMaterialComponent', () => { a: [], classname: 'acmc', _isfieldmapper: true, - owning_lib: () => mockLibrary2 + owning_lib: () => mockLibrary2, + course_number: () => 'HIST123' }; - const authServiceSpy = jasmine.createSpyObj<AuthService>(['token']); const courseServiceSpy = jasmine.createSpyObj<CourseService>(['associateMaterials']); courseServiceSpy.associateMaterials.and.returnValue({item: mockItem, material: new Promise(() => {})}); const netServiceSpy = jasmine.createSpyObj<NetService>(['request']); @@ -53,10 +55,25 @@ describe('CourseAssociateMaterialComponent', () => { const rejectedDialogComponentSpy = jasmine.createSpyObj<DialogComponent>(['open']); rejectedDialogComponentSpy.open.and.returnValue(of(false)); + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + providers: [ + {provide: AuthService, useValue: jasmine.createSpyObj<AuthService>(['token'])}, + {provide: CourseService, useValue: courseServiceSpy}, + {provide: NetService, useValue: netServiceSpy}, + {provide: PcrudService, useValue: pcrudServiceSpy}, + {provide: ToastService, useValue: toastServiceSpy}, + {provide: PermService, useValue: permServiceSpy}, + {provide: NgbModal, useValue: modalSpy}, + ], + schemas: [NO_ERRORS_SCHEMA], + imports: [NgbNav] + }).compileComponents(); + })); + beforeEach(() => { - component = new CourseAssociateMaterialComponent(authServiceSpy, courseServiceSpy, - netServiceSpy, pcrudServiceSpy, - toastServiceSpy, permServiceSpy, modalSpy); + fixture = TestBed.createComponent(CourseAssociateMaterialComponent); + component = fixture.componentInstance; component.confirmOtherLibraryDialog = dialogComponentSpy; component.currentCourse = mockCourse; }); diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/edit-org-unit-setting-dialog.component.spec.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/edit-org-unit-setting-dialog.component.spec.ts index 30cbc66d02..b58fdebb81 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/edit-org-unit-setting-dialog.component.spec.ts +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/edit-org-unit-setting-dialog.component.spec.ts @@ -1,10 +1,11 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { EditOuSettingDialogComponent } from './edit-org-unit-setting-dialog.component'; -import { TestBed, waitForAsync } from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { AfterViewInit, CUSTOM_ELEMENTS_SCHEMA, ChangeDetectorRef, Component, TemplateRef, ViewChild } from '@angular/core'; const modal = jasmine.createSpyObj<NgbModal>(['open']); -let component = new EditOuSettingDialogComponent(modal); +let fixture: ComponentFixture<EditOuSettingDialogComponent>; +let component: EditOuSettingDialogComponent; @Component({ template: ` @@ -25,6 +26,20 @@ class MockModalComponent implements AfterViewInit { } describe('EditOuSettingDialogComponent', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + { provide: NgbModal, useValue: modal} + ], declarations: [ + MockModalComponent, + EditOuSettingDialogComponent + ], schemas: [ + CUSTOM_ELEMENTS_SCHEMA + ] + }).compileComponents(); + fixture = TestBed.createComponent(EditOuSettingDialogComponent); + component = fixture.componentInstance; + }); describe('inputType()', () => { describe('when setting name is lib.timezone', () => { it('returns timezone', () => { @@ -48,19 +63,9 @@ describe('EditOuSettingDialogComponent', () => { }); describe('template', () => { it(('displays a timezone select if the entry is lib.timezone'), waitForAsync(() => { - TestBed.configureTestingModule({ - providers: [ - { provide: NgbModal, useValue: modal} - ], declarations: [ - MockModalComponent, - EditOuSettingDialogComponent - ], schemas: [ - CUSTOM_ELEMENTS_SCHEMA - ] - }).compileComponents(); - const fixture = TestBed.createComponent(MockModalComponent); - const mockModal = fixture.debugElement.componentInstance; - fixture.detectChanges(); + const mockModalFixture = TestBed.createComponent(MockModalComponent); + const mockModal = mockModalFixture.debugElement.componentInstance; + mockModalFixture.detectChanges(); mockModal.ngAfterViewInit(); component = mockModal.componentRef; const entry = { @@ -68,8 +73,8 @@ describe('EditOuSettingDialogComponent', () => { dataType: 'string' }; component.entry = entry; - const editElement: HTMLElement = fixture.nativeElement; - fixture.detectChanges(); + const editElement: HTMLElement = mockModalFixture.nativeElement; + mockModalFixture.detectChanges(); expect(editElement.querySelectorAll('eg-timezone-select').length).toEqual(1); })); }); diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/org-unit-setting-history-dialog.component.spec.ts b/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/org-unit-setting-history-dialog.component.spec.ts index 6453be286d..739809e1b3 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/org-unit-setting-history-dialog.component.spec.ts +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/org-unit-settings/org-unit-setting-history-dialog.component.spec.ts @@ -1,6 +1,8 @@ import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; import { OrgService } from '@eg/core/org.service'; import { OuSettingHistoryDialogComponent } from './org-unit-setting-history-dialog.component'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; describe('OuSettingHistoryDialogComponent', () => { const mockOrg = { @@ -10,10 +12,25 @@ describe('OuSettingHistoryDialogComponent', () => { id: () => 22 }; + let component: OuSettingHistoryDialogComponent; + let fixture: ComponentFixture<OuSettingHistoryDialogComponent>; + + const orgServiceSpy = jasmine.createSpyObj<OrgService>(['get']); const modalSpy = jasmine.createSpyObj<NgbModal>(['open']); orgServiceSpy.get.and.returnValue(mockOrg); - const component = new OuSettingHistoryDialogComponent(orgServiceSpy, modalSpy); + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + {provide: OrgService, useValue: orgServiceSpy}, + {provide: NgbModal, useValue: modalSpy} + ], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + fixture = TestBed.createComponent(OuSettingHistoryDialogComponent); + component = fixture.componentInstance; + }); it('can revert a change back to a null value', () => { const mockLog = { diff --git a/Open-ILS/src/eg2/src/app/staff/booking/create-reservation-dialog.component.spec.ts b/Open-ILS/src/eg2/src/app/staff/booking/create-reservation-dialog.component.spec.ts index 5c93a93920..710a6f75b4 100644 --- a/Open-ILS/src/eg2/src/app/staff/booking/create-reservation-dialog.component.spec.ts +++ b/Open-ILS/src/eg2/src/app/staff/booking/create-reservation-dialog.component.spec.ts @@ -6,6 +6,13 @@ import { NetService } from '@eg/core/net.service'; import { of } from 'rxjs'; import { AuthService } from '@eg/core/auth.service'; import * as moment from 'moment'; +import { TestBed } from '@angular/core/testing'; +import { OrgService } from '@eg/core/org.service'; +import { PcrudService } from '@eg/core/pcrud.service'; +import { Router } from '@angular/router'; +import { NgbModal } from '@ng-bootstrap/ng-bootstrap'; +import { ToastService } from '@eg/share/toast/toast.service'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; let component: CreateReservationDialogComponent; @@ -24,8 +31,21 @@ describe('CreateReservationDialogComponent', () => { 'textcode': 'RESOURCE_IN_USE', 'desc': 'Resource is in use at this time' })); - component = new CreateReservationDialogComponent(mockAuth, mockFormat, - mockNet, null, null, null, null, mockPbv, null); + TestBed.configureTestingModule({ + providers: [ + {provide: AuthService, useValue: mockAuth}, + {provide: FormatService, useValue: mockFormat}, + {provide: NetService, useValue: mockNet}, + {provide: OrgService, useValue: null}, + {provide: PcrudService, useValue: null}, + {provide: Router, useValue: null}, + {provide: NgbModal, useValue: null}, + {provide: PatronBarcodeValidator, useValue: mockPbv}, + {provide: ToastService, useValue: null} + ], + schemas: [NO_ERRORS_SCHEMA], + }).compileComponents(); + component = TestBed.createComponent(CreateReservationDialogComponent).componentInstance; component.ngOnInit(); component.setDefaultTimes([moment()], 15); component.targetResourceType = {id: 10, label: 'Friendly penguin'}; ----------------------------------------------------------------------- Summary of changes: .../eg2/src/app/share/fm-editor/fm-editor.spec.ts | 18 +++++++--- .../course-associate-material.component.spec.ts | 31 +++++++++++++---- .../edit-org-unit-setting-dialog.component.spec.ts | 39 ++++++++++++---------- ...g-unit-setting-history-dialog.component.spec.ts | 19 ++++++++++- .../create-reservation-dialog.component.spec.ts | 24 +++++++++++-- 5 files changed, 100 insertions(+), 31 deletions(-) hooks/post-receive -- Evergreen ILS