mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-28 22:42:11 +01:00
test(search-item-to-remit-dialog): enhance unit tests for component behavior and signal integration
This commit is contained in:
@@ -2,23 +2,46 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { SearchItemToRemitDialogComponent } from './search-item-to-remit-dialog.component';
|
||||
import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
|
||||
import { DialogComponent } from '@isa/ui/dialog';
|
||||
import { MockComponents } from 'ng-mocks';
|
||||
import { TextButtonComponent } from '@isa/ui/buttons';
|
||||
import { SearchItemToRemitListComponent } from './search-item-to-remit-list.component';
|
||||
import { SelectRemiQuantityAndReasonComponent } from './select-remi-quantity-and-reason.component';
|
||||
import { signal } from '@angular/core';
|
||||
import { Item } from '@isa/catalogue/data-access';
|
||||
import { By } from '@angular/platform-browser';
|
||||
|
||||
describe('SearchItemToRemitDialogComponent', () => {
|
||||
let component: SearchItemToRemitDialogComponent;
|
||||
let fixture: ComponentFixture<SearchItemToRemitDialogComponent>;
|
||||
let mockDialogRef: {
|
||||
updateSize: ReturnType<typeof vi.fn>;
|
||||
close: ReturnType<typeof vi.fn>;
|
||||
};
|
||||
let mockDialogComponent: {
|
||||
title: ReturnType<typeof signal>;
|
||||
};
|
||||
|
||||
const mockItem = {
|
||||
id: 1,
|
||||
product: {
|
||||
id: 1,
|
||||
name: 'Test Product',
|
||||
},
|
||||
catalogAvailability: {},
|
||||
} as unknown as Item;
|
||||
|
||||
beforeEach(async () => {
|
||||
const mockDialogRef = {
|
||||
updateSize: jest.fn(),
|
||||
close: jest.fn(),
|
||||
mockDialogRef = {
|
||||
updateSize: vi.fn(),
|
||||
close: vi.fn(),
|
||||
};
|
||||
|
||||
mockDialogComponent = {
|
||||
title: signal(''),
|
||||
};
|
||||
|
||||
const mockData = { searchTerm: 'test' };
|
||||
|
||||
const mockDialogComponent = {
|
||||
// Mock DialogComponent properties if needed
|
||||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SearchItemToRemitDialogComponent],
|
||||
providers: [
|
||||
@@ -26,15 +49,329 @@ describe('SearchItemToRemitDialogComponent', () => {
|
||||
{ provide: DIALOG_DATA, useValue: mockData },
|
||||
{ provide: DialogComponent, useValue: mockDialogComponent },
|
||||
],
|
||||
}).compileComponents();
|
||||
})
|
||||
.overrideComponent(SearchItemToRemitDialogComponent, {
|
||||
remove: {
|
||||
imports: [
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
],
|
||||
},
|
||||
add: {
|
||||
imports: MockComponents(
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
),
|
||||
},
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SearchItemToRemitDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
describe('Component Setup and Initialization', () => {
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should initialize searchTerm from string data', () => {
|
||||
fixture.detectChanges();
|
||||
expect(component.searchTerm()).toBe('test');
|
||||
});
|
||||
|
||||
it('should initialize searchTerm from Signal data', async () => {
|
||||
const searchTermSignal = signal('signal test');
|
||||
const mockSignalData = { searchTerm: searchTermSignal };
|
||||
|
||||
TestBed.resetTestingModule();
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SearchItemToRemitDialogComponent],
|
||||
providers: [
|
||||
{ provide: DialogRef, useValue: mockDialogRef },
|
||||
{ provide: DIALOG_DATA, useValue: mockSignalData },
|
||||
{ provide: DialogComponent, useValue: mockDialogComponent },
|
||||
],
|
||||
})
|
||||
.overrideComponent(SearchItemToRemitDialogComponent, {
|
||||
remove: {
|
||||
imports: [
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
],
|
||||
},
|
||||
add: {
|
||||
imports: MockComponents(
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
),
|
||||
},
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SearchItemToRemitDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.searchTerm()).toBe('signal test');
|
||||
|
||||
// Test that it reacts to signal changes
|
||||
searchTermSignal.set('updated signal test');
|
||||
fixture.detectChanges();
|
||||
expect(component.searchTerm()).toBe('updated signal test');
|
||||
});
|
||||
|
||||
it('should initialize item signal as undefined', () => {
|
||||
fixture.detectChanges();
|
||||
expect(component.item()).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should extend DialogContentDirective', () => {
|
||||
expect(component.dialogRef).toBeDefined();
|
||||
expect(component.data).toBeDefined();
|
||||
expect(component.close).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Signal and Effect Behavior', () => {
|
||||
it('should update dialog size to auto when item is undefined', () => {
|
||||
fixture.detectChanges();
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('auto');
|
||||
});
|
||||
|
||||
it('should update dialog size to 36rem when item is set', () => {
|
||||
fixture.detectChanges();
|
||||
mockDialogRef.updateSize.mockClear();
|
||||
|
||||
component.item.set(mockItem);
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('36rem');
|
||||
});
|
||||
|
||||
it('should update searchTerm when linkedSignal source changes', () => {
|
||||
const searchTermSignal = signal('initial');
|
||||
const mockSignalData = { searchTerm: searchTermSignal };
|
||||
|
||||
TestBed.resetTestingModule();
|
||||
TestBed.configureTestingModule({
|
||||
imports: [SearchItemToRemitDialogComponent],
|
||||
providers: [
|
||||
{ provide: DialogRef, useValue: mockDialogRef },
|
||||
{ provide: DIALOG_DATA, useValue: mockSignalData },
|
||||
{ provide: DialogComponent, useValue: mockDialogComponent },
|
||||
],
|
||||
})
|
||||
.overrideComponent(SearchItemToRemitDialogComponent, {
|
||||
remove: {
|
||||
imports: [
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
],
|
||||
},
|
||||
add: {
|
||||
imports: MockComponents(
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
),
|
||||
},
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SearchItemToRemitDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.searchTerm()).toBe('initial');
|
||||
|
||||
searchTermSignal.set('updated');
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.searchTerm()).toBe('updated');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Template Behavior', () => {
|
||||
it('should show search list component when item is undefined', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const searchList = fixture.debugElement.query(
|
||||
By.css('remi-search-item-to-remit-list'),
|
||||
);
|
||||
const selectQuantity = fixture.debugElement.query(
|
||||
By.css('remi-select-remi-quantity-and-reason'),
|
||||
);
|
||||
|
||||
expect(searchList).toBeTruthy();
|
||||
expect(selectQuantity).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should show select quantity component when item is set', () => {
|
||||
component.item.set(mockItem);
|
||||
fixture.detectChanges();
|
||||
|
||||
const searchList = fixture.debugElement.query(
|
||||
By.css('remi-search-item-to-remit-list'),
|
||||
);
|
||||
const selectQuantity = fixture.debugElement.query(
|
||||
By.css('remi-select-remi-quantity-and-reason'),
|
||||
);
|
||||
|
||||
expect(searchList).toBeFalsy();
|
||||
expect(selectQuantity).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show close button only when item is undefined', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
let closeButton = fixture.debugElement.query(
|
||||
By.css('button[uiTextButton]'),
|
||||
);
|
||||
expect(closeButton).toBeTruthy();
|
||||
expect(closeButton.nativeElement.textContent.trim()).toBe('Schließen');
|
||||
|
||||
component.item.set(mockItem);
|
||||
fixture.detectChanges();
|
||||
|
||||
closeButton = fixture.debugElement.query(By.css('button[uiTextButton]'));
|
||||
expect(closeButton).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should call close with undefined when close button is clicked', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const closeButton = fixture.debugElement.query(
|
||||
By.css('button[uiTextButton]'),
|
||||
);
|
||||
closeButton.nativeElement.click();
|
||||
|
||||
expect(mockDialogRef.close).toHaveBeenCalledWith(undefined);
|
||||
});
|
||||
|
||||
it('should have correct button attributes', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const closeButton = fixture.debugElement.query(By.css('button'));
|
||||
const buttonEl = closeButton.nativeElement;
|
||||
|
||||
expect(buttonEl.type).toBe('button');
|
||||
expect(buttonEl.classList.contains('absolute')).toBe(true);
|
||||
expect(buttonEl.classList.contains('top-1')).toBe(true);
|
||||
expect(buttonEl.classList.contains('right-[1.33rem]')).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('DialogRef Integration', () => {
|
||||
it('should call dialogRef.updateSize on initialization', () => {
|
||||
fixture.detectChanges();
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('auto');
|
||||
});
|
||||
|
||||
it('should call dialogRef.updateSize when item changes', () => {
|
||||
fixture.detectChanges();
|
||||
mockDialogRef.updateSize.mockClear();
|
||||
|
||||
component.item.set(mockItem);
|
||||
fixture.detectChanges();
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('36rem');
|
||||
|
||||
component.item.set(undefined);
|
||||
fixture.detectChanges();
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('auto');
|
||||
});
|
||||
|
||||
it('should inherit close method from DialogContentDirective', () => {
|
||||
const closeSpy = vi.spyOn(component, 'close');
|
||||
component.close(mockItem);
|
||||
|
||||
expect(closeSpy).toHaveBeenCalledWith(mockItem);
|
||||
expect(mockDialogRef.close).toHaveBeenCalledWith(mockItem);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edge Cases and Error Handling', () => {
|
||||
it('should handle empty searchTerm', async () => {
|
||||
const emptyData = { searchTerm: '' };
|
||||
|
||||
TestBed.resetTestingModule();
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [SearchItemToRemitDialogComponent],
|
||||
providers: [
|
||||
{ provide: DialogRef, useValue: mockDialogRef },
|
||||
{ provide: DIALOG_DATA, useValue: emptyData },
|
||||
{ provide: DialogComponent, useValue: mockDialogComponent },
|
||||
],
|
||||
})
|
||||
.overrideComponent(SearchItemToRemitDialogComponent, {
|
||||
remove: {
|
||||
imports: [
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
],
|
||||
},
|
||||
add: {
|
||||
imports: MockComponents(
|
||||
TextButtonComponent,
|
||||
SearchItemToRemitListComponent,
|
||||
SelectRemiQuantityAndReasonComponent,
|
||||
),
|
||||
},
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(SearchItemToRemitDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.searchTerm()).toBe('');
|
||||
});
|
||||
|
||||
it('should handle multiple rapid item changes', () => {
|
||||
fixture.detectChanges();
|
||||
mockDialogRef.updateSize.mockClear();
|
||||
|
||||
// First change
|
||||
component.item.set(mockItem);
|
||||
fixture.detectChanges();
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('36rem');
|
||||
|
||||
// Second change
|
||||
component.item.set(undefined);
|
||||
fixture.detectChanges();
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('auto');
|
||||
|
||||
// Third change
|
||||
component.item.set(mockItem);
|
||||
fixture.detectChanges();
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledWith('36rem');
|
||||
|
||||
// Total calls
|
||||
expect(mockDialogRef.updateSize).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it('should handle component destruction gracefully', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
// Component destruction should not throw errors
|
||||
expect(() => {
|
||||
fixture.destroy();
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it('should maintain data integrity', () => {
|
||||
const originalData = { searchTerm: 'test' };
|
||||
fixture.detectChanges();
|
||||
|
||||
// Data should remain unchanged
|
||||
expect(component.data).toEqual(originalData);
|
||||
expect(component.data.searchTerm).toBe('test');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user