feat: add mock for ScannerButtonComponent and update feedback dialog

- Created a mock for ScannerButtonComponent in test-mocks.ts to facilitate testing.
- Updated test-setup.ts to mock browser APIs for the test environment.
- Refactored SelectRemiQuantityAndReasonComponent to simplify addToRemiList logic and update feedback dialog usage.
- Modified feedback-dialog.component.html to safely access message data.
- Cleaned up package-lock.json by removing deprecated and unnecessary dependencies.
This commit is contained in:
Lorenz Hilpert
2025-07-22 15:06:25 +02:00
parent 2beeba5c92
commit 4111663d8c
9 changed files with 112 additions and 467 deletions

View File

@@ -6,7 +6,9 @@
<remi-feature-remission-list-select></remi-feature-remission-list-select>
<filter-controls-panel (triggerSearch)="search()"></filter-controls-panel>
<filter-controls-panel
(triggerSearch)="search(); searchTrigger.set('user')"
></filter-controls-panel>
<span
class="text-isa-neutral-900 isa-text-body-2-regular self-start"

View File

@@ -92,6 +92,8 @@ function querySettingsFactory() {
},
})
export class RemissionListComponent {
searchTrigger = signal<'user' | 'reload' | 'initial'>('initial');
/**
* Activated route instance for accessing route data and params.
*/
@@ -318,6 +320,9 @@ export class RemissionListComponent {
}
untracked(() => {
if (this.searchTrigger() !== 'user') {
return;
}
const isDepartment =
this.selectedRemissionListType() === RemissionListType.Abteilung;
@@ -329,6 +334,7 @@ export class RemissionListComponent {
}).closed.subscribe((result) => {
if (result) {
this.remissionResource.reload();
this.searchTrigger.set('reload');
}
});
});

View File

@@ -1,6 +1,7 @@
import { inject, resource } from '@angular/core';
import { ListResponseArgs, ResponseArgsError } from '@isa/common/data-access';
import {
QueryTokenInput,
RemissionListType,
RemissionSearchService,
RemissionStockService,
@@ -8,7 +9,6 @@ import {
ReturnItem,
ReturnSuggestion,
} from '@isa/remission/data-access';
import { QueryTokenInput } from 'libs/remission/data-access/src/lib/schemas';
import { parseISO, compareDesc } from 'date-fns';
/**
@@ -97,7 +97,7 @@ export const createRemissionListResource = (
res.result.sort((a, b) => {
const aIsManuallyAdded = a.source === 'manually-added';
const bIsManuallyAdded = b.source === 'manually-added';
// First priority: manually-added items come first
if (aIsManuallyAdded && !bIsManuallyAdded) {
return -1;
@@ -105,18 +105,18 @@ export const createRemissionListResource = (
if (!aIsManuallyAdded && bIsManuallyAdded) {
return 1;
}
// Second priority: sort by created date (latest first)
if (a.created && b.created) {
const dateA = parseISO(a.created);
const dateB = parseISO(b.created);
return compareDesc(dateA, dateB); // Descending order (latest first)
}
// Handle cases where created date might be missing
if (a.created && !b.created) return -1;
if (!a.created && b.created) return 1;
return 0;
});
}

View File

@@ -1,14 +1,57 @@
import './test-mocks'; // Import mocks before anything else
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RemissionStartDialogComponent } from './remission-start-dialog.component';
import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting } from '@angular/common/http/testing';
import { RemissionReturnReceiptService } from '@isa/remission/data-access';
import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
import { DialogComponent } from '@isa/ui/dialog';
import { vi } from 'vitest';
describe('RemissionStartDialogComponent', () => {
let component: RemissionStartDialogComponent;
let fixture: ComponentFixture<RemissionStartDialogComponent>;
beforeEach(async () => {
// Mock the dialog ref
const mockDialogRef = {
close: vi.fn(),
};
// Mock dialog data
const mockDialogData = { returnGroup: 'test-group' };
// Mock dialog component
const mockDialogComponent = {
title: '',
hideClose: false,
};
// Mock remission service
const mockRemissionService = {
createReturn: vi.fn().mockResolvedValue({ id: 1 }),
createReceipt: vi.fn().mockResolvedValue({
id: 1,
receiptNumber: '12345',
items: []
}),
assignPackage: vi.fn().mockResolvedValue({}),
};
await TestBed.configureTestingModule({
imports: [RemissionStartDialogComponent],
}).compileComponents();
imports: [
RemissionStartDialogComponent,
],
providers: [
provideHttpClient(),
provideHttpClientTesting(),
{ provide: RemissionReturnReceiptService, useValue: mockRemissionService },
{ provide: DialogRef, useValue: mockDialogRef },
{ provide: DIALOG_DATA, useValue: mockDialogData },
{ provide: DialogComponent, useValue: mockDialogComponent },
],
})
.compileComponents();
fixture = TestBed.createComponent(RemissionStartDialogComponent);
component = fixture.componentInstance;

View File

@@ -0,0 +1,18 @@
import { vi } from 'vitest';
import { Component, output } from '@angular/core';
// Mock ScannerButtonComponent
// eslint-disable-next-line @angular-eslint/component-selector
@Component({
selector: 'isa-scanner-button',
template: '<button>Scan</button>',
standalone: true,
})
export class MockScannerButtonComponent {
scanResult = output<string>();
}
// Mock the entire scanner module
vi.mock('@isa/shared/scanner', () => ({
ScannerButtonComponent: MockScannerButtonComponent,
}));

View File

@@ -7,6 +7,12 @@ import {
} from '@angular/platform-browser/testing';
import { getTestBed } from '@angular/core/testing';
// Mock browser APIs that are not available in test environment
global.URL = global.URL || {
createObjectURL: () => 'mocked-object-url',
revokeObjectURL: () => {},
} as any;
getTestBed().initTestEnvironment(
BrowserTestingModule,
platformBrowserTesting(),

View File

@@ -44,9 +44,7 @@ export interface QuantityAndReason {
})
export class SelectRemiQuantityAndReasonComponent {
#remiService = inject(RemissionSearchService);
#feedbackDialog = injectFeedbackDialog({
data: { message: 'Wurde zur Remi Liste hinzugefügt' },
});
#feedbackDialog = injectFeedbackDialog();
host = inject(SearchItemToRemitDialogComponent);
quantitiesAndResons = model<QuantityAndReason[]>([
@@ -137,10 +135,13 @@ export class SelectRemiQuantityAndReasonComponent {
});
async addToRemiList() {
if (
this.canAddToRemiListResource.status() !== 'resolved' ||
!this.canAddToRemiListResource.value()?.failed?.length
) {
const canAddValue = this.canAddToRemiListResource.value();
if (!canAddValue) {
return;
}
if (canAddValue.failed?.length) {
return;
}
@@ -152,7 +153,9 @@ export class SelectRemiQuantityAndReasonComponent {
result = await this.#remiService.addToList(this.params());
}
this.#feedbackDialog();
this.#feedbackDialog({
data: { message: 'Wurde zur Remi Liste hinzugefügt' },
});
this.host.close(result);
}