mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
feat: remove uncompleted tasks dialog and replace with confirmation dialog
- Deleted uncompleted tasks dialog component files (HTML, SCSS, TS). - Updated UncompletedTasksGuard to use new ConfirmationDialogComponent. - Added ConfirmationDialogComponent for user confirmation with customizable messages. - Updated dialog component templates to include data attributes for easier testing. - Removed obsolete unit tests for ReturnReviewComponent and ReturnTaskListComponent. - Updated unit tests for ReturnSummaryComponent to reflect changes in return process handling.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { DataAccessError } from '@isa/common/data-access';
|
||||
import { ReceiptItem } from '../../models';
|
||||
import { Receipt, ReceiptItem } from '../../models';
|
||||
import {
|
||||
CreateReturnProcessError,
|
||||
CreateReturnProcessErrorReason,
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
describe('CreateReturnProcessError', () => {
|
||||
const params = {
|
||||
processId: 123,
|
||||
receiptId: 456,
|
||||
receipt: { id: 321 } as Receipt,
|
||||
items: [] as ReceiptItem[],
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
getReturnProcessQuestions,
|
||||
returnReceiptValuesMapping,
|
||||
} from '../helpers/return-process';
|
||||
import { memorize } from '@utils/common';
|
||||
import { isReturnProcessTypeGuard } from '../guards';
|
||||
|
||||
/**
|
||||
@@ -52,7 +51,6 @@ export class ReturnCanReturnService {
|
||||
* @returns A promise resolving to a CanReturn result or undefined if the process should continue.
|
||||
* @throws Error if payload validation fails or the backend call fails.
|
||||
*/
|
||||
@memorize()
|
||||
async canReturn(
|
||||
input: ReturnProcess | ReturnReceiptValues,
|
||||
): Promise<CanReturn | undefined> {
|
||||
|
||||
@@ -1,199 +1,177 @@
|
||||
// TODO: Unit Tests wieder reinnehmen wenn printReceiptsService nicht mehr auf die Alte ISA App zugreift durch den alten ModalService
|
||||
import { byText } from '@ngneat/spectator';
|
||||
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
|
||||
import { MockDirective } from 'ng-mocks';
|
||||
|
||||
// import { byText } from '@ngneat/spectator';
|
||||
// import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
|
||||
// import { MockDirective } from 'ng-mocks';
|
||||
import { ReceiptItem, ReturnDetailsService } from '@isa/oms/data-access';
|
||||
import { CheckboxComponent } from '@isa/ui/input-controls';
|
||||
|
||||
// import { ReceiptItem } from '@isa/oms/data-access';
|
||||
// import { CheckboxComponent } from '@isa/ui/input-controls';
|
||||
// import { ItemRowComponent } from '@isa/ui/item-rows';
|
||||
import { ReturnDetailsOrderGroupItemComponent } from './return-details-order-group-item.component';
|
||||
import { ProductImageDirective } from '@isa/shared/product-image';
|
||||
|
||||
// import { ReturnDetailsOrderGroupItemComponent } from './return-details-order-group-item.component';
|
||||
// import { ProductImageDirective } from '@isa/shared/product-image';
|
||||
// Helper function to create mock ReceiptItem data
|
||||
const createMockItem = (
|
||||
ean: string,
|
||||
canReturn: boolean,
|
||||
name = 'Test Product',
|
||||
category = 'BOOK', // Add default category that's not 'unknown'
|
||||
): ReceiptItem =>
|
||||
({
|
||||
id: 123,
|
||||
quantity: { quantity: 1 },
|
||||
price: {
|
||||
value: { value: 19.99, currency: 'EUR' },
|
||||
vat: { inPercent: 19 },
|
||||
},
|
||||
product: {
|
||||
ean: ean,
|
||||
name: name,
|
||||
contributors: 'Test Author',
|
||||
format: 'HC',
|
||||
formatDetail: 'Hardcover',
|
||||
manufacturer: 'Test Publisher',
|
||||
publicationDate: '2024-01-01T00:00:00Z',
|
||||
catalogProductNumber: '1234567890',
|
||||
volume: '1',
|
||||
},
|
||||
actions: [{ key: 'canReturn', value: String(canReturn) }],
|
||||
features: { category: category }, // Add the features property with category
|
||||
}) as ReceiptItem;
|
||||
|
||||
// // Helper function to create mock ReceiptItem data
|
||||
// const createMockItem = (
|
||||
// ean: string,
|
||||
// canReturn: boolean,
|
||||
// name = 'Test Product',
|
||||
// ): ReceiptItem =>
|
||||
// ({
|
||||
// id: 123,
|
||||
// quantity: { quantity: 1 },
|
||||
// price: {
|
||||
// value: { value: 19.99, currency: 'EUR' },
|
||||
// vat: { inPercent: 19 },
|
||||
// },
|
||||
// product: {
|
||||
// ean: ean,
|
||||
// name: name,
|
||||
// contributors: 'Test Author',
|
||||
// format: 'HC',
|
||||
// formatDetail: 'Hardcover',
|
||||
// manufacturer: 'Test Publisher',
|
||||
// publicationDate: '2024-01-01T00:00:00Z',
|
||||
// catalogProductNumber: '1234567890',
|
||||
// volume: '1',
|
||||
// },
|
||||
// actions: [{ key: 'canReturn', value: String(canReturn) }],
|
||||
// }) as ReceiptItem;
|
||||
describe('ReturnDetailsOrderGroupItemComponent', () => {
|
||||
let spectator: Spectator<ReturnDetailsOrderGroupItemComponent>;
|
||||
const mockItemSelectable = createMockItem('1234567890123', true);
|
||||
|
||||
// describe('ReturnDetailsOrderGroupItemComponent', () => {
|
||||
// let spectator: Spectator<ReturnDetailsOrderGroupItemComponent>;
|
||||
// const mockItemSelectable = createMockItem('1234567890123', true);
|
||||
// const mockItemNotSelectable = createMockItem('9876543210987', false);
|
||||
const createComponent = createComponentFactory({
|
||||
component: ReturnDetailsOrderGroupItemComponent,
|
||||
mocks: [ReturnDetailsService],
|
||||
// Spectator automatically stubs standalone dependencies like ItemRowComponent, CheckboxComponent etc.
|
||||
// We don't need deep interaction, just verify the host component renders correctly.
|
||||
// If specific interactions were needed, we could provide mocks or use overrideComponents.
|
||||
overrideComponents: [
|
||||
[
|
||||
ReturnDetailsOrderGroupItemComponent,
|
||||
{
|
||||
remove: { imports: [ProductImageDirective] },
|
||||
add: {
|
||||
imports: [MockDirective(ProductImageDirective)],
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
detectChanges: false, // Control initial detection manually
|
||||
});
|
||||
|
||||
// const createComponent = createComponentFactory({
|
||||
// component: ReturnDetailsOrderGroupItemComponent,
|
||||
// // Spectator automatically stubs standalone dependencies like ItemRowComponent, CheckboxComponent etc.
|
||||
// // We don't need deep interaction, just verify the host component renders correctly.
|
||||
// // If specific interactions were needed, we could provide mocks or use overrideComponents.
|
||||
// overrideComponents: [
|
||||
// [
|
||||
// ReturnDetailsOrderGroupItemComponent,
|
||||
// {
|
||||
// remove: { imports: [ProductImageDirective] },
|
||||
// add: {
|
||||
// imports: [MockDirective(ProductImageDirective)],
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// ],
|
||||
// detectChanges: false, // Control initial detection manually
|
||||
// });
|
||||
beforeEach(() => {
|
||||
// Default setup with a selectable item
|
||||
spectator = createComponent({
|
||||
props: {
|
||||
item: mockItemSelectable, // Use signal for input
|
||||
selected: false, // Use signal for model
|
||||
availableCategories: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// beforeEach(() => {
|
||||
// // Default setup with a selectable item
|
||||
// spectator = createComponent({
|
||||
// props: {
|
||||
// item: mockItemSelectable, // Use signal for input
|
||||
// selected: false, // Use signal for model
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
it('should create', () => {
|
||||
// Arrange
|
||||
spectator.detectChanges(); // Trigger initial render
|
||||
|
||||
// it('should create', () => {
|
||||
// // Arrange
|
||||
// spectator.detectChanges(); // Trigger initial render
|
||||
// Assert
|
||||
expect(spectator.component).toBeTruthy();
|
||||
});
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component).toBeTruthy();
|
||||
// });
|
||||
it('should display product details correctly', () => {
|
||||
// Arrange
|
||||
spectator.detectChanges();
|
||||
const item = mockItemSelectable;
|
||||
|
||||
// it('should display product details correctly', () => {
|
||||
// // Arrange
|
||||
// spectator.detectChanges();
|
||||
// const item = mockItemSelectable;
|
||||
// Assert
|
||||
expect(spectator.query(byText(item.product.contributors))).toExist();
|
||||
expect(spectator.query(`[data-what="product-name"]`)).toHaveText(
|
||||
item.product.name,
|
||||
);
|
||||
expect(spectator.query(`[data-what="product-price"]`)).toHaveText('€19.99'); // Assuming default locale formatting
|
||||
expect(
|
||||
spectator.query(byText(`inkl. ${item.price?.vat?.inPercent}% MwSt`)),
|
||||
).toExist();
|
||||
expect(spectator.query(`[data-what="product-info"]`)).toHaveText(
|
||||
`${item.product.manufacturer} | ${item.product.ean}`,
|
||||
);
|
||||
// Date formatting depends on locale, checking for year is safer
|
||||
expect(
|
||||
spectator.query(byText(/Jan 2024/)), // Adjust regex based on expected format/locale
|
||||
).toExist();
|
||||
expect(spectator.query(`img[data-what="product-image"]`)).toHaveAttribute(
|
||||
'data-which',
|
||||
item.product.ean,
|
||||
);
|
||||
});
|
||||
it('should display the checkbox when item is selectable', () => {
|
||||
// Arrange
|
||||
// The mock item has canReturn=true and a valid category, which should make it selectable
|
||||
// after the effect executes
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.query(byText(item.product.contributors))).toExist();
|
||||
// expect(spectator.query(`[data-what="product-name"]`)).toHaveText(
|
||||
// item.product.name,
|
||||
// );
|
||||
// expect(spectator.query(`[data-what="product-price"]`)).toHaveText('€19.99'); // Assuming default locale formatting
|
||||
// expect(
|
||||
// spectator.query(byText(`inkl. ${item.price?.vat?.inPercent}% MwSt`)),
|
||||
// ).toExist();
|
||||
// expect(spectator.query(`[data-what="product-info"]`)).toHaveText(
|
||||
// `${item.product.manufacturer} | ${item.product.ean}`,
|
||||
// );
|
||||
// // Date formatting depends on locale, checking for year is safer
|
||||
// expect(
|
||||
// spectator.query(byText(/Jan 2024/)), // Adjust regex based on expected format/locale
|
||||
// ).toExist();
|
||||
// expect(spectator.query(`img[data-what="product-image"]`)).toHaveAttribute(
|
||||
// 'data-which',
|
||||
// item.product.ean,
|
||||
// );
|
||||
// });
|
||||
// Assert
|
||||
expect(spectator.component.selectable()).toBe(true);
|
||||
const checkbox = spectator.query(CheckboxComponent);
|
||||
expect(checkbox).toBeTruthy();
|
||||
expect(
|
||||
spectator.query(`input[data-what="return-item-checkbox"]`),
|
||||
).toExist();
|
||||
});
|
||||
it('should NOT display the checkbox when item is not selectable', () => {
|
||||
// Arrange
|
||||
// Create a non-returnable item by modifying the features.category to 'unknown'
|
||||
const nonReturnableItem = createMockItem('1234567890123', true);
|
||||
nonReturnableItem.features = { category: 'unknown' };
|
||||
|
||||
// it('should display the checkbox when item is selectable', () => {
|
||||
// // Arrange
|
||||
// spectator.setInput('item', mockItemSelectable); // Ensure selectable item
|
||||
// spectator.detectChanges();
|
||||
// Set the item to trigger the effects which determine selectability
|
||||
spectator.setInput('item', nonReturnableItem);
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.selectable()).toBe(true);
|
||||
// const checkbox = spectator.query(CheckboxComponent);
|
||||
// expect(checkbox).toBeTruthy();
|
||||
// expect(
|
||||
// spectator.query(`input[data-what="return-item-checkbox"]`),
|
||||
// ).toExist();
|
||||
// });
|
||||
// Assert
|
||||
expect(spectator.component.selectable()).toBe(false);
|
||||
expect(
|
||||
spectator.query(`input[data-what="return-item-checkbox"]`),
|
||||
).not.toExist();
|
||||
expect(spectator.query(CheckboxComponent)).toBeFalsy();
|
||||
});
|
||||
it('should update the selected model when checkbox is clicked', () => {
|
||||
// Arrange
|
||||
spectator.detectChanges(); // This will make the component selectable via the effect
|
||||
|
||||
// it('should NOT display the checkbox when item is not selectable', () => {
|
||||
// // Arrange
|
||||
// spectator.setInput('item', mockItemNotSelectable);
|
||||
// spectator.detectChanges();
|
||||
// Use the component's method directly to toggle selection
|
||||
// This is similar to what happens when a checkbox is clicked
|
||||
spectator.component.selected.set(!spectator.component.selected());
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.selectable()).toBe(false);
|
||||
// expect(
|
||||
// spectator.query(`input[data-what="return-item-checkbox"]`),
|
||||
// ).not.toExist();
|
||||
// expect(spectator.query(CheckboxComponent)).toBeFalsy();
|
||||
// });
|
||||
// Assert
|
||||
expect(spectator.component.selected()).toBe(true);
|
||||
});
|
||||
it('should reflect the initial selected state in the checkbox', () => {
|
||||
// Arrange
|
||||
// First ensure the item is selectable (has a non-unknown category)
|
||||
const selectableItem = createMockItem(
|
||||
'1234567890123',
|
||||
true,
|
||||
'Test Product',
|
||||
'BOOK',
|
||||
);
|
||||
spectator.setInput('item', selectableItem);
|
||||
spectator.setInput('selected', true); // Start selected
|
||||
spectator.detectChanges(); // This triggers the effects that set selectable
|
||||
|
||||
// it('should update the selected model when checkbox is clicked', () => {
|
||||
// // Arrange
|
||||
// spectator.setInput('item', mockItemSelectable); // Ensure checkbox is visible
|
||||
// spectator.setInput('selected', false); // Start deselected
|
||||
// spectator.detectChanges();
|
||||
// const checkboxInput = spectator.query(
|
||||
// `input[data-what="return-item-checkbox"]`,
|
||||
// );
|
||||
// expect(checkboxInput).not.toBeChecked();
|
||||
// expect(spectator.component.selected()).toBe(false);
|
||||
// Assert
|
||||
expect(spectator.component.selected()).toBe(true);
|
||||
expect(spectator.component.selectable()).toBe(true);
|
||||
|
||||
// // Act
|
||||
// spectator.click(checkboxInput!);
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.selected()).toBe(true);
|
||||
// // Note: Checking the input's checked state directly after click might be flaky
|
||||
// // depending on change detection timing. Relying on the model signal is more robust.
|
||||
// });
|
||||
|
||||
// it('should reflect the initial selected state in the checkbox', () => {
|
||||
// // Arrange
|
||||
// spectator.setInput('item', mockItemSelectable);
|
||||
// spectator.setInput('selected', true); // Start selected
|
||||
// spectator.detectChanges();
|
||||
|
||||
// // Assert
|
||||
// const checkboxInput = spectator.query(
|
||||
// `input[data-what="return-item-checkbox"]`,
|
||||
// );
|
||||
// expect(checkboxInput).toBeChecked();
|
||||
// });
|
||||
|
||||
// it('should have correct E2E attributes', () => {
|
||||
// // Arrange
|
||||
// spectator.detectChanges();
|
||||
// const item = mockItemSelectable;
|
||||
// const ean = item.product.ean;
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.query(`[data-what="return-item-row"]`)).toBeTruthy();
|
||||
// expect(spectator.query(`[data-which="${ean}"]`)).toBeTruthy();
|
||||
// expect(spectator.query(`img[data-what="product-image"]`)).toHaveAttribute(
|
||||
// 'data-which',
|
||||
// ean,
|
||||
// );
|
||||
// expect(spectator.query(`[data-what="product-name"]`)).toHaveAttribute(
|
||||
// 'data-which',
|
||||
// ean,
|
||||
// );
|
||||
// expect(spectator.query(`[data-what="product-price"]`)).toHaveAttribute(
|
||||
// 'data-which',
|
||||
// ean,
|
||||
// );
|
||||
// expect(spectator.query(`[data-what="product-info"]`)).toHaveAttribute(
|
||||
// 'data-which',
|
||||
// ean,
|
||||
// );
|
||||
// expect(
|
||||
// spectator.query(`input[data-what="return-item-checkbox"]`),
|
||||
// ).toHaveAttribute('data-which', ean);
|
||||
// });
|
||||
// });
|
||||
// For a checkbox, we need to check that it exists
|
||||
const checkbox = spectator.query(
|
||||
'input[type="checkbox"][data-what="return-item-checkbox"]',
|
||||
);
|
||||
expect(checkbox).toExist();
|
||||
// With Spectator we can use toHaveProperty for HTML elements
|
||||
expect(checkbox).toHaveProperty('checked', true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -80,18 +80,21 @@ export class ReturnDetailsOrderGroupItemComponent {
|
||||
* Available product categories to select from when an item's category is unknown.
|
||||
* Presented as key-value pairs where the key is the category code and the value is the display name.
|
||||
*/
|
||||
// TODO: availableCategories über Service holen nicht über input
|
||||
availableCategories = input.required<KeyValue<string, string>[]>();
|
||||
|
||||
/**
|
||||
* Emits when the product category for the item is changed.
|
||||
* Payload contains the updated item and the selected category.
|
||||
*/
|
||||
// TODO: Kategorie änderung nicht über output sondern über Service
|
||||
changeCategory = output<{ item: ReceiptItem; category: string }>();
|
||||
|
||||
/**
|
||||
* Emits when the quantity for the item is changed.
|
||||
* Payload contains the updated item and the selected quantity.
|
||||
*/
|
||||
// TODO: Menge änderung nicht über output sondern über Service
|
||||
changeQuantity = output<{ item: ReceiptItem; quantity: number }>();
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,285 +1,308 @@
|
||||
// TODO: Unit Tests wieder reinnehmen wenn printReceiptsService nicht mehr auf die Alte ISA App zugreift durch den alten ModalService
|
||||
import { signal } from '@angular/core';
|
||||
import { Location } from '@angular/common';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import {
|
||||
createRoutingFactory,
|
||||
mockProvider,
|
||||
SpectatorRouting,
|
||||
} from '@ngneat/spectator/jest';
|
||||
import { MockComponent } from 'ng-mocks';
|
||||
import {
|
||||
ReturnCanReturnService,
|
||||
ReturnProcess,
|
||||
ReturnProcessService,
|
||||
ReturnProcessStore,
|
||||
} from '@isa/oms/data-access';
|
||||
|
||||
// import { signal } from '@angular/core';
|
||||
// import { Location } from '@angular/common';
|
||||
// import { RouterLink } from '@angular/router';
|
||||
// import {
|
||||
// createRoutingFactory,
|
||||
// mockProvider,
|
||||
// SpectatorRouting,
|
||||
// } from '@ngneat/spectator/jest';
|
||||
// import { MockComponent } from 'ng-mocks';
|
||||
// import {
|
||||
// ReturnProcess,
|
||||
// ReturnProcessService,
|
||||
// ReturnProcessStore,
|
||||
// } from '@isa/oms/data-access';
|
||||
import { ButtonComponent } from '@isa/ui/buttons';
|
||||
import { NgIconComponent } from '@ng-icons/core';
|
||||
import { ReturnProcessItemComponent } from './return-process-item/return-process-item.component';
|
||||
import { ReturnProcessComponent } from './return-process.component';
|
||||
|
||||
// import { ButtonComponent } from '@isa/ui/buttons';
|
||||
// import { NgIconComponent } from '@ng-icons/core';
|
||||
// import { ReturnProcessItemComponent } from './return-process-item/return-process-item.component';
|
||||
// import { ReturnProcessComponent } from './return-process.component';
|
||||
const mockActivatedProcessIdSignal = signal<number | null>(123);
|
||||
jest.mock('@isa/core/process', () => ({
|
||||
injectActivatedProcessId: jest.fn(() => mockActivatedProcessIdSignal),
|
||||
}));
|
||||
|
||||
// const mockActivatedProcessIdSignal = signal<number | null>(123);
|
||||
// jest.mock('@isa/core/process', () => ({
|
||||
// injectActivatedProcessId: jest.fn(() => mockActivatedProcessIdSignal),
|
||||
// }));
|
||||
describe('ReturnProcessComponent', () => {
|
||||
let spectator: SpectatorRouting<ReturnProcessComponent>;
|
||||
const mockEntitiesSignal = signal<ReturnProcess[]>([]);
|
||||
let mockReturnProcessService: jest.Mocked<ReturnProcessService>;
|
||||
const createComponent = createRoutingFactory({
|
||||
component: ReturnProcessComponent,
|
||||
// Import necessary modules/components used directly in the template
|
||||
imports: [RouterLink],
|
||||
// Mock child components and directives used in the template
|
||||
declarations: [
|
||||
MockComponent(ButtonComponent),
|
||||
MockComponent(NgIconComponent),
|
||||
MockComponent(ReturnProcessItemComponent),
|
||||
],
|
||||
providers: [
|
||||
// Mock ReturnProcessStore and its entities signal
|
||||
mockProvider(ReturnProcessStore, {
|
||||
entities: mockEntitiesSignal,
|
||||
}),
|
||||
mockProvider(ReturnProcessService),
|
||||
mockProvider(ReturnCanReturnService, {
|
||||
canReturn: jest.fn().mockResolvedValue({ result: true }),
|
||||
}),
|
||||
],
|
||||
// Disable initial change detection to set signals before first render
|
||||
detectChanges: false,
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Reset signals before each test
|
||||
mockEntitiesSignal.set([]);
|
||||
mockActivatedProcessIdSignal.set(null); // Mock process ID
|
||||
// Create the component instance
|
||||
spectator = createComponent();
|
||||
|
||||
// describe('ReturnProcessComponent', () => {
|
||||
// let spectator: SpectatorRouting<ReturnProcessComponent>;
|
||||
// const mockEntitiesSignal = signal<ReturnProcess[]>([]);
|
||||
// let mockReturnProcessService: jest.Mocked<ReturnProcessService>;
|
||||
// Get the mocked service
|
||||
mockReturnProcessService = spectator.inject(
|
||||
ReturnProcessService,
|
||||
) as jest.Mocked<ReturnProcessService>;
|
||||
// Default mock implementation for returnProcessQuestionsProgress
|
||||
mockReturnProcessService.returnProcessQuestionsProgress = jest
|
||||
.fn()
|
||||
.mockReturnValue({ answered: 0, total: 0 });
|
||||
|
||||
// const createComponent = createRoutingFactory({
|
||||
// component: ReturnProcessComponent,
|
||||
// // Import necessary modules/components used directly in the template
|
||||
// imports: [RouterLink],
|
||||
// // Mock child components and directives used in the template
|
||||
// declarations: [
|
||||
// MockComponent(ButtonComponent),
|
||||
// MockComponent(NgIconComponent),
|
||||
// MockComponent(ReturnProcessItemComponent),
|
||||
// ],
|
||||
// providers: [
|
||||
// // Mock ReturnProcessStore and its entities signal
|
||||
// mockProvider(ReturnProcessStore, {
|
||||
// entities: mockEntitiesSignal,
|
||||
// }),
|
||||
// mockProvider(ReturnProcessService),
|
||||
// ],
|
||||
// // Disable initial change detection to set signals before first render
|
||||
// detectChanges: false,
|
||||
// });
|
||||
// Default mock implementation for eligibleForReturn
|
||||
mockReturnProcessService.eligibleForReturn = jest
|
||||
.fn()
|
||||
.mockReturnValue({ state: 'not-eligible' });
|
||||
});
|
||||
|
||||
// beforeEach(() => {
|
||||
// // Reset signals before each test
|
||||
// mockEntitiesSignal.set([]);
|
||||
// mockActivatedProcessIdSignal.set(null); // Mock process ID
|
||||
// // Create the component instance
|
||||
// spectator = createComponent();
|
||||
it('should create the component', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(123); // Set a mock process ID
|
||||
spectator.detectChanges(); // Trigger initial render
|
||||
|
||||
// // Get the mocked service
|
||||
// mockReturnProcessService = spectator.inject(
|
||||
// ReturnProcessService,
|
||||
// ) as jest.Mocked<ReturnProcessService>;
|
||||
// // Default mock implementation for returnProcessQuestionsProgress
|
||||
// mockReturnProcessService.returnProcessQuestionsProgress = jest
|
||||
// .fn()
|
||||
// .mockReturnValue({ answered: 0, total: 0 });
|
||||
// });
|
||||
// Assert
|
||||
expect(spectator.component).toBeTruthy();
|
||||
expect(spectator.component.processId()).toBe(123); // Check injected process ID
|
||||
});
|
||||
|
||||
// it('should create the component', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(123); // Set a mock process ID
|
||||
// spectator.detectChanges(); // Trigger initial render
|
||||
it('should filter return processes by the current process ID', () => {
|
||||
// Arrange
|
||||
const processId = 123;
|
||||
mockActivatedProcessIdSignal.set(processId);
|
||||
const mockProcesses = [
|
||||
{ processId: 123, id: 1 },
|
||||
{ processId: 456, id: 2 },
|
||||
{ processId: 123, id: 3 },
|
||||
] as ReturnProcess[];
|
||||
mockEntitiesSignal.set(mockProcesses);
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component).toBeTruthy();
|
||||
// expect(spectator.component.processId()).toBe(123); // Check injected process ID
|
||||
// });
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// it('should filter return processes by the current process ID', () => {
|
||||
// // Arrange
|
||||
// const processId = 123;
|
||||
// mockActivatedProcessIdSignal.set(processId);
|
||||
// const mockProcesses = [
|
||||
// { processId: 123, id: 1 },
|
||||
// { processId: 456, id: 2 },
|
||||
// { processId: 123, id: 3 },
|
||||
// ] as ReturnProcess[];
|
||||
// mockEntitiesSignal.set(mockProcesses);
|
||||
// Assert
|
||||
const filteredProcesses = spectator.component.returnProcesses();
|
||||
expect(filteredProcesses.length).toBe(2);
|
||||
expect(filteredProcesses.every((p) => p.processId === processId)).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
it('should return empty array when no process ID is available', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(null);
|
||||
const mockProcesses = [
|
||||
{ processId: 123, id: 1 },
|
||||
{ processId: 456, id: 2 },
|
||||
] as ReturnProcess[];
|
||||
mockEntitiesSignal.set(mockProcesses);
|
||||
|
||||
// // Assert
|
||||
// const filteredProcesses = spectator.component.returnProcesses();
|
||||
// expect(filteredProcesses.length).toBe(2);
|
||||
// expect(filteredProcesses.every((p) => p.processId === processId)).toBe(
|
||||
// true,
|
||||
// );
|
||||
// });
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// it('should return empty array when no process ID is available', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(null);
|
||||
// const mockProcesses = [
|
||||
// { processId: 123, id: 1 },
|
||||
// { processId: 456, id: 2 },
|
||||
// ] as ReturnProcess[];
|
||||
// mockEntitiesSignal.set(mockProcesses);
|
||||
// Assert
|
||||
expect(spectator.component.returnProcesses()).toEqual([]);
|
||||
});
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
it('should return empty array when entities is empty', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(123);
|
||||
mockEntitiesSignal.set([]);
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.returnProcesses()).toEqual([]);
|
||||
// });
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// it('should return empty array when entities is empty', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(123);
|
||||
// mockEntitiesSignal.set([]);
|
||||
// Assert
|
||||
expect(spectator.component.returnProcesses()).toEqual([]);
|
||||
});
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
it('should render ReturnProcessItemComponent for each return process', () => {
|
||||
// Arrange
|
||||
const processId = 123;
|
||||
mockActivatedProcessIdSignal.set(processId);
|
||||
const mockProcesses = [
|
||||
{ processId: 123, id: 1 },
|
||||
{ processId: 123, id: 2 },
|
||||
] as ReturnProcess[];
|
||||
mockEntitiesSignal.set(mockProcesses);
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.returnProcesses()).toEqual([]);
|
||||
// });
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// it('should render ReturnProcessItemComponent for each return process', () => {
|
||||
// // Arrange
|
||||
// const processId = 123;
|
||||
// mockActivatedProcessIdSignal.set(processId);
|
||||
// const mockProcesses = [
|
||||
// { processId: 123, id: 1 },
|
||||
// { processId: 123, id: 2 },
|
||||
// ] as ReturnProcess[];
|
||||
// mockEntitiesSignal.set(mockProcesses);
|
||||
// Assert
|
||||
const returnProcessItems = spectator.queryAll(ReturnProcessItemComponent);
|
||||
expect(returnProcessItems.length).toBe(2);
|
||||
});
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
it('should handle back navigation when Location service is used', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(123);
|
||||
spectator.detectChanges();
|
||||
const location = spectator.inject(Location);
|
||||
jest.spyOn(location, 'back');
|
||||
|
||||
// // Assert
|
||||
// const returnProcessItems = spectator.queryAll(ReturnProcessItemComponent);
|
||||
// expect(returnProcessItems.length).toBe(2);
|
||||
// });
|
||||
// Act
|
||||
const backButton = spectator.query('button[data-what="back-navigation"]');
|
||||
if (backButton) {
|
||||
spectator.click(backButton); // Simulate button click
|
||||
}
|
||||
|
||||
// it('should handle back navigation when Location service is used', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(123);
|
||||
// spectator.detectChanges();
|
||||
// const location = spectator.inject(Location);
|
||||
// jest.spyOn(location, 'back');
|
||||
// Assert
|
||||
expect(location.back).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// // Act
|
||||
// const backButton = spectator.query('button[data-what="back-navigation"]');
|
||||
// if (backButton) {
|
||||
// spectator.click(backButton); // Simulate button click
|
||||
// }
|
||||
describe('summary navigation', () => {
|
||||
it('should have canContinueToSummary as false when no return processes exist', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(123);
|
||||
mockEntitiesSignal.set([]);
|
||||
|
||||
// // Assert
|
||||
// expect(location.back).toHaveBeenCalled();
|
||||
// });
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// describe('summary navigation', () => {
|
||||
// it('should have canContinueToSummary as false when no return processes exist', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(123);
|
||||
// mockEntitiesSignal.set([]);
|
||||
// Assert
|
||||
expect(spectator.component.canContinueToSummary()).toBe(false);
|
||||
});
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
it('should have canContinueToSummary as true when all processes have completed all questions', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(123);
|
||||
const mockProcesses = [
|
||||
{ processId: 123, id: 1 },
|
||||
{ processId: 123, id: 2 },
|
||||
] as ReturnProcess[];
|
||||
mockEntitiesSignal.set(mockProcesses);
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.canContinueToSummary()).toBe(false);
|
||||
// });
|
||||
// Mock all processes have answered all questions
|
||||
mockReturnProcessService.returnProcessQuestionsProgress.mockImplementation(
|
||||
() => ({ answered: 3, total: 3 }),
|
||||
);
|
||||
|
||||
// it('should have canContinueToSummary as true when all processes have completed all questions', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(123);
|
||||
// const mockProcesses = [
|
||||
// { processId: 123, id: 1 },
|
||||
// { processId: 123, id: 2 },
|
||||
// ] as ReturnProcess[];
|
||||
// mockEntitiesSignal.set(mockProcesses);
|
||||
// Mock eligibleForReturn to return Eligible state
|
||||
mockReturnProcessService.eligibleForReturn.mockReturnValue({
|
||||
state: 'eligible', // Use correct enum value
|
||||
});
|
||||
|
||||
// // Mock all processes have answered all questions
|
||||
// mockReturnProcessService.returnProcessQuestionsProgress.mockImplementation(
|
||||
// () => ({ answered: 3, total: 3 }),
|
||||
// );
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
// Assert
|
||||
expect(spectator.component.canContinueToSummary()).toBe(true);
|
||||
});
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.canContinueToSummary()).toBe(true);
|
||||
// });
|
||||
it('should have canContinueToSummary as false when any process has incomplete questions', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(123);
|
||||
const mockProcesses = [
|
||||
{ processId: 123, id: 1 },
|
||||
{ processId: 123, id: 2 },
|
||||
] as ReturnProcess[];
|
||||
mockEntitiesSignal.set(mockProcesses);
|
||||
|
||||
// it('should have canContinueToSummary as false when any process has incomplete questions', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(123);
|
||||
// const mockProcesses = [
|
||||
// { processId: 123, id: 1 },
|
||||
// { processId: 123, id: 2 },
|
||||
// ] as ReturnProcess[];
|
||||
// mockEntitiesSignal.set(mockProcesses);
|
||||
// Mock the first process has complete questions, but the second has incomplete
|
||||
mockReturnProcessService.returnProcessQuestionsProgress
|
||||
.mockImplementationOnce(() => ({ answered: 3, total: 3 }))
|
||||
.mockImplementationOnce(() => ({ answered: 2, total: 3 }));
|
||||
|
||||
// // Mock the first process has complete questions, but the second has incomplete
|
||||
// mockReturnProcessService.returnProcessQuestionsProgress
|
||||
// .mockImplementationOnce(() => ({ answered: 3, total: 3 }))
|
||||
// .mockImplementationOnce(() => ({ answered: 2, total: 3 }));
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
// Assert
|
||||
expect(spectator.component.canContinueToSummary()).toBe(false);
|
||||
});
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.canContinueToSummary()).toBe(false);
|
||||
// });
|
||||
it('should have canContinueToSummary as false when returnProcessQuestionsProgress returns null', () => {
|
||||
// Arrange
|
||||
mockActivatedProcessIdSignal.set(123);
|
||||
const mockProcesses = [{ processId: 123, id: 1 }] as ReturnProcess[];
|
||||
mockEntitiesSignal.set(mockProcesses);
|
||||
|
||||
// it('should have canContinueToSummary as false when returnProcessQuestionsProgress returns null', () => {
|
||||
// // Arrange
|
||||
// mockActivatedProcessIdSignal.set(123);
|
||||
// const mockProcesses = [{ processId: 123, id: 1 }] as ReturnProcess[];
|
||||
// mockEntitiesSignal.set(mockProcesses);
|
||||
// Mock the process has null progress
|
||||
mockReturnProcessService.returnProcessQuestionsProgress.mockReturnValue(
|
||||
undefined,
|
||||
);
|
||||
|
||||
// // Mock the process has null progress
|
||||
// mockReturnProcessService.returnProcessQuestionsProgress.mockReturnValue(
|
||||
// undefined,
|
||||
// );
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
// Assert
|
||||
expect(spectator.component.canContinueToSummary()).toBe(false);
|
||||
});
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.component.canContinueToSummary()).toBe(false);
|
||||
// });
|
||||
// Skip this test since it requires complex mocking of signals
|
||||
it.skip('should render "Continue to summary" button', () => {
|
||||
// Arrange
|
||||
// Create a mock process for testing
|
||||
mockActivatedProcessIdSignal.set(123);
|
||||
const mockProcesses = [{ processId: 123, id: 1 }] as ReturnProcess[];
|
||||
mockEntitiesSignal.set(mockProcesses);
|
||||
|
||||
// it('should render "Continue to summary" button', () => {
|
||||
// // Arrange
|
||||
// jest
|
||||
// .spyOn(spectator.component, 'canContinueToSummary')
|
||||
// .mockReturnValue(true);
|
||||
// spectator.detectChanges();
|
||||
// Mock canContinueToSummary computed signal to return true
|
||||
jest
|
||||
.spyOn(spectator.component, 'canContinueToSummary')
|
||||
.mockReturnValue(true);
|
||||
|
||||
// // Act & Assert
|
||||
// const summaryButton = spectator.query(
|
||||
// 'a[data-what="summary-navigation"]',
|
||||
// );
|
||||
// expect(summaryButton).toBeTruthy();
|
||||
// });
|
||||
// Need a better way to mock canReturn signal
|
||||
// This is challenging because canReturn is updated in the constructor effect
|
||||
// which runs immediately when the component is created
|
||||
|
||||
// it('should not render "Continue to summary" button when canContinueToSummary is false', () => {
|
||||
// // Arrange
|
||||
// jest
|
||||
// .spyOn(spectator.component, 'canContinueToSummary')
|
||||
// .mockReturnValue(false);
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges();
|
||||
// Assert
|
||||
const summaryButton = spectator.query(
|
||||
'a[data-what="summary-navigation"]',
|
||||
);
|
||||
|
||||
// // Assert
|
||||
// const summaryButton = spectator.query('[data-what="summary-navigation"]');
|
||||
// expect(summaryButton).toBeFalsy();
|
||||
// });
|
||||
expect(summaryButton).toBeTruthy();
|
||||
});
|
||||
|
||||
// // it('should navigate to summary route when "Continue to summary" button is clicked and enabled', async () => {
|
||||
// // // Arrange
|
||||
it('should not render "Continue to summary" button when canContinueToSummary is false', () => {
|
||||
// Arrange
|
||||
jest
|
||||
.spyOn(spectator.component, 'canContinueToSummary')
|
||||
.mockReturnValue(false);
|
||||
|
||||
// // jest
|
||||
// // .spyOn(spectator.component, 'canContinueToSummary')
|
||||
// // .mockReturnValue(true);
|
||||
// // spectator.detectChanges();
|
||||
// // expect(spectator.inject(Location).path()).toBe('/');
|
||||
// // await spectator.fixture.whenStable();
|
||||
// // // Get the router link directive
|
||||
// // spectator.click('a[data-what="summary-navigation"]');
|
||||
// Act
|
||||
spectator.detectChanges();
|
||||
|
||||
// // await spectator.fixture.whenStable();
|
||||
// Assert
|
||||
const summaryButton = spectator.query('[data-what="summary-navigation"]');
|
||||
expect(summaryButton).toBeFalsy();
|
||||
});
|
||||
|
||||
// // // Act & Assert
|
||||
// // expect(spectator.inject(Location).path()).toBe('/summary');
|
||||
// // });
|
||||
// });
|
||||
// });
|
||||
// it('should navigate to summary route when "Continue to summary" button is clicked and enabled', async () => {
|
||||
// // Arrange
|
||||
// jest
|
||||
// .spyOn(spectator.component, 'canContinueToSummary')
|
||||
// .mockReturnValue(true);
|
||||
// spectator.detectChanges();
|
||||
// expect(spectator.inject(Location).path()).toBe('/');
|
||||
// await spectator.fixture.whenStable();
|
||||
// // Get the router link directive
|
||||
// spectator.click('a[data-what="summary-navigation"]');
|
||||
//
|
||||
// await spectator.fixture.whenStable();
|
||||
//
|
||||
// // Act & Assert
|
||||
// expect(spectator.inject(Location).path()).toBe('/summary');
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<div class="flex flex-col gap-4 text-isa-neutral-900 isa-text-subtitle-1-bold">
|
||||
<h1>Aufgaben erledigen</h1>
|
||||
|
||||
<p class="text-isa-neutral-600 isa-text-body-1-regular">
|
||||
Bitte schließen Sie die Aufgaben ab bevor Sie das die Rückgabe verlassen
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row gap-2 w-full h-full items-center justify-center">
|
||||
<button
|
||||
class="w-[12.75rem]"
|
||||
type="button"
|
||||
uiButton
|
||||
color="secondary"
|
||||
(click)="onLeave()"
|
||||
data-what="button"
|
||||
data-which="leave"
|
||||
>
|
||||
Verlassen
|
||||
</button>
|
||||
<button
|
||||
class="w-[12.75rem]"
|
||||
type="button"
|
||||
uiButton
|
||||
color="primary"
|
||||
(click)="onCancel()"
|
||||
data-what="button"
|
||||
data-which="cancel"
|
||||
>
|
||||
Zurück
|
||||
</button>
|
||||
</div>
|
||||
@@ -1,3 +0,0 @@
|
||||
:host {
|
||||
@apply flex flex-col h-full gap-8 p-8 rounded-[2rem] bg-isa-white items-center justify-center;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
import { DIALOG_DATA, DialogRef } from '@angular/cdk/dialog';
|
||||
import { ChangeDetectionStrategy, Component, inject } from '@angular/core';
|
||||
import { ButtonComponent } from '@isa/ui/buttons';
|
||||
|
||||
@Component({
|
||||
selector: 'oms-feature-return-review-uncompleted-tasks-dialog',
|
||||
templateUrl: 'uncompleted-tasks-dialog.component.html',
|
||||
styleUrl: 'uncompleted-tasks-dialog.component.scss',
|
||||
standalone: true,
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [ButtonComponent],
|
||||
})
|
||||
export class ReturnReviewUncompletedTasksDialogComponent {
|
||||
dialogRef = inject(DialogRef<boolean>);
|
||||
data = inject(DIALOG_DATA);
|
||||
|
||||
onLeave(): void {
|
||||
this.dialogRef.close(true);
|
||||
}
|
||||
|
||||
onCancel(): void {
|
||||
this.dialogRef.close(false);
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,19 @@ import { computed, inject, Injectable } from '@angular/core';
|
||||
import { CanDeactivate } from '@angular/router';
|
||||
import { firstValueFrom } from 'rxjs';
|
||||
import { injectActivatedProcessId } from '@isa/core/process';
|
||||
import { Dialog } from '@angular/cdk/dialog';
|
||||
import { ReturnTaskListStore } from '@isa/oms/data-access';
|
||||
import { ReturnReviewComponent } from '../return-review.component';
|
||||
import { ReturnReviewUncompletedTasksDialogComponent } from '../dialog/uncompleted-tasks-dialog.component';
|
||||
import { ConfirmationDialogComponent, injectDialog } from '@isa/ui/dialog';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class UncompletedTasksGuard
|
||||
implements CanDeactivate<ReturnReviewComponent>
|
||||
{
|
||||
#returnTaskListStore = inject(ReturnTaskListStore);
|
||||
#dialog = inject(Dialog);
|
||||
#confirmationDialog = injectDialog(
|
||||
ConfirmationDialogComponent,
|
||||
'Aufgaben erledigen',
|
||||
);
|
||||
|
||||
processId = injectActivatedProcessId();
|
||||
|
||||
@@ -43,12 +45,16 @@ export class UncompletedTasksGuard
|
||||
}
|
||||
|
||||
async openDialog(): Promise<boolean> {
|
||||
const dialogRef = this.#dialog.open<boolean>(
|
||||
ReturnReviewUncompletedTasksDialogComponent,
|
||||
{ width: '30rem' },
|
||||
);
|
||||
const confirmDialogRef = this.#confirmationDialog({
|
||||
data: {
|
||||
message:
|
||||
'Bitte schließen Sie die Aufgaben ab bevor Sie das die Rückgabe verlassen',
|
||||
closeText: 'Verlassen',
|
||||
confirmText: 'Zurück',
|
||||
},
|
||||
});
|
||||
|
||||
const leave = await firstValueFrom(dialogRef.closed);
|
||||
return !!leave;
|
||||
const result = await firstValueFrom(confirmDialogRef.closed);
|
||||
return !result?.confirmed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ReturnReviewComponent } from './return-review.component';
|
||||
|
||||
describe('ReturnReviewComponent', () => {
|
||||
let component: ReturnReviewComponent;
|
||||
let fixture: ComponentFixture<ReturnReviewComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ReturnReviewComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ReturnReviewComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,180 +1,176 @@
|
||||
// TODO: Unit Tests wieder reinnehmen wenn printReceiptsService nicht mehr auf die Alte ISA App zugreift durch den alten ModalService
|
||||
import { createRoutingFactory, Spectator } from '@ngneat/spectator/jest';
|
||||
import { ReturnSummaryItemComponent } from './return-summary-item.component';
|
||||
import { MockComponents, MockProvider } from 'ng-mocks';
|
||||
import { ReturnProductInfoComponent } from '@isa/oms/shared/product-info';
|
||||
import {
|
||||
Product,
|
||||
ReturnProcess,
|
||||
ReturnProcessQuestionKey,
|
||||
ReturnProcessService,
|
||||
} from '@isa/oms/data-access';
|
||||
import { NgIcon } from '@ng-icons/core';
|
||||
import { IconButtonComponent } from '@isa/ui/buttons';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
// import { createRoutingFactory, Spectator } from '@ngneat/spectator/jest';
|
||||
// import { ReturnSummaryItemComponent } from './return-summary-item.component';
|
||||
// import { MockComponents, MockProvider } from 'ng-mocks';
|
||||
// import { ReturnProductInfoComponent } from '@isa/oms/shared/product-info';
|
||||
// import {
|
||||
// Product,
|
||||
// ReturnProcess,
|
||||
// ReturnProcessQuestionKey,
|
||||
// ReturnProcessService,
|
||||
// } from '@isa/oms/data-access';
|
||||
// import { NgIcon } from '@ng-icons/core';
|
||||
// import { IconButtonComponent } from '@isa/ui/buttons';
|
||||
// import { Router } from '@angular/router';
|
||||
/**
|
||||
* Creates a mock ReturnProcess with default values that can be overridden
|
||||
*/
|
||||
function createMockReturnProcess(
|
||||
partial: Partial<ReturnProcess>,
|
||||
): ReturnProcess {
|
||||
return {
|
||||
id: 1,
|
||||
processId: 1,
|
||||
productCategory: 'Electronics',
|
||||
answers: {},
|
||||
receiptId: 123,
|
||||
receiptItem: {
|
||||
id: 321,
|
||||
product: {
|
||||
name: 'Test Product',
|
||||
},
|
||||
},
|
||||
...partial,
|
||||
} as ReturnProcess;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Creates a mock ReturnProcess with default values that can be overridden
|
||||
// */
|
||||
// function createMockReturnProcess(
|
||||
// partial: Partial<ReturnProcess>,
|
||||
// ): ReturnProcess {
|
||||
// return {
|
||||
// id: 1,
|
||||
// processId: 1,
|
||||
// productCategory: 'Electronics',
|
||||
// answers: {},
|
||||
// receiptId: 123,
|
||||
// receiptItem: {
|
||||
// id: 321,
|
||||
// product: {
|
||||
// name: 'Test Product',
|
||||
// },
|
||||
// },
|
||||
// ...partial,
|
||||
// } as ReturnProcess;
|
||||
// }
|
||||
describe('ReturnSummaryItemComponent', () => {
|
||||
let spectator: Spectator<ReturnSummaryItemComponent>;
|
||||
let returnProcessService: jest.Mocked<ReturnProcessService>;
|
||||
|
||||
// describe('ReturnSummaryItemComponent', () => {
|
||||
// let spectator: Spectator<ReturnSummaryItemComponent>;
|
||||
// let returnProcessService: jest.Mocked<ReturnProcessService>;
|
||||
const createComponent = createRoutingFactory({
|
||||
component: ReturnSummaryItemComponent,
|
||||
declarations: MockComponents(
|
||||
ReturnProductInfoComponent,
|
||||
NgIcon,
|
||||
IconButtonComponent,
|
||||
), providers: [
|
||||
MockProvider(ReturnProcessService, {
|
||||
getReturnInfo: jest.fn(),
|
||||
eligibleForReturn: jest.fn().mockReturnValue({ state: 'eligible' }),
|
||||
}),
|
||||
],
|
||||
shallow: true,
|
||||
});
|
||||
|
||||
// const createComponent = createRoutingFactory({
|
||||
// component: ReturnSummaryItemComponent,
|
||||
// declarations: MockComponents(
|
||||
// ReturnProductInfoComponent,
|
||||
// NgIcon,
|
||||
// IconButtonComponent,
|
||||
// ),
|
||||
// providers: [
|
||||
// MockProvider(ReturnProcessService, { getReturnInfo: jest.fn() }),
|
||||
// ],
|
||||
// shallow: true,
|
||||
// });
|
||||
beforeEach(() => {
|
||||
spectator = createComponent({
|
||||
props: {
|
||||
returnProcess: createMockReturnProcess({}),
|
||||
},
|
||||
});
|
||||
returnProcessService = spectator.inject(ReturnProcessService);
|
||||
spectator.detectChanges();
|
||||
});
|
||||
|
||||
// beforeEach(() => {
|
||||
// spectator = createComponent({
|
||||
// props: {
|
||||
// returnProcess: createMockReturnProcess({}),
|
||||
// },
|
||||
// });
|
||||
// returnProcessService = spectator.inject(ReturnProcessService);
|
||||
// spectator.detectChanges();
|
||||
// });
|
||||
describe('Component Creation', () => {
|
||||
it('should create the component', () => {
|
||||
expect(spectator.component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
// describe('Component Creation', () => {
|
||||
// it('should create the component', () => {
|
||||
// expect(spectator.component).toBeTruthy();
|
||||
// });
|
||||
// });
|
||||
describe('Return Information Display', () => {
|
||||
const mockReturnInfo = {
|
||||
itemCondition: 'itemCondition',
|
||||
comment: 'comment',
|
||||
returnDetails: { [ReturnProcessQuestionKey.CaseDamaged]: 'no' },
|
||||
returnReason: 'returnReason',
|
||||
otherProduct: {
|
||||
ean: 'ean',
|
||||
} as Product,
|
||||
};
|
||||
|
||||
// describe('Return Information Display', () => {
|
||||
// const mockReturnInfo = {
|
||||
// itemCondition: 'itemCondition',
|
||||
// comment: 'comment',
|
||||
// returnDetails: { [ReturnProcessQuestionKey.CaseDamaged]: 'no' },
|
||||
// returnReason: 'returnReason',
|
||||
// otherProduct: {
|
||||
// ean: 'ean',
|
||||
// } as Product,
|
||||
// };
|
||||
beforeEach(() => {
|
||||
jest
|
||||
.spyOn(returnProcessService, 'getReturnInfo')
|
||||
.mockReturnValue(mockReturnInfo);
|
||||
spectator.setInput('returnProcess', createMockReturnProcess({ id: 2 }));
|
||||
spectator.detectChanges();
|
||||
}); it('should provide correct return information array', () => {
|
||||
// Arrange
|
||||
const expectedInfos = [
|
||||
'itemCondition',
|
||||
'returnReason',
|
||||
'comment',
|
||||
'Geliefert wurde: ean',
|
||||
'Gehäuse beschädigt: no'
|
||||
];
|
||||
|
||||
// beforeEach(() => {
|
||||
// jest
|
||||
// .spyOn(returnProcessService, 'getReturnInfo')
|
||||
// .mockReturnValue(mockReturnInfo);
|
||||
// spectator.setInput('returnProcess', createMockReturnProcess({ id: 2 }));
|
||||
// spectator.detectChanges();
|
||||
// });
|
||||
// Act
|
||||
const actualInfos = spectator.component.returnInfos();
|
||||
|
||||
// it('should provide correct return information array', () => {
|
||||
// // Arrange
|
||||
// const expectedInfos = [
|
||||
// 'itemCondition',
|
||||
// 'returnReason',
|
||||
// 'returnDetails',
|
||||
// 'comment',
|
||||
// 'Geliefert wurde: ean',
|
||||
// ];
|
||||
// Assert
|
||||
expect(actualInfos).toEqual(expectedInfos);
|
||||
expect(actualInfos.length).toBe(5);
|
||||
}); it('should render return info items with correct content', () => {
|
||||
// Arrange
|
||||
const expectedInfos = [
|
||||
'itemCondition',
|
||||
'returnReason',
|
||||
'comment',
|
||||
'Geliefert wurde: ean',
|
||||
'Gehäuse beschädigt: no'
|
||||
];
|
||||
|
||||
// // Act
|
||||
// const actualInfos = spectator.component.returnInfos();
|
||||
// Act
|
||||
spectator.detectComponentChanges();
|
||||
const listItems = spectator.queryAll(
|
||||
'[data-what="list-item"][data-which="return-info"]',
|
||||
);
|
||||
|
||||
// // Assert
|
||||
// expect(actualInfos).toEqual(expectedInfos);
|
||||
// expect(actualInfos.length).toBe(5);
|
||||
// });
|
||||
// Assert
|
||||
expect(listItems.length).toBe(expectedInfos.length);
|
||||
listItems.forEach((item, index) => {
|
||||
expect(item).toHaveText(expectedInfos[index]);
|
||||
expect(item).toHaveAttribute('data-info-index', index.toString());
|
||||
});
|
||||
});
|
||||
|
||||
// it('should render return info items with correct content', () => {
|
||||
// // Arrange
|
||||
// const expectedInfos = [
|
||||
// 'itemCondition',
|
||||
// 'returnReason',
|
||||
// 'returnDetails',
|
||||
// 'comment',
|
||||
// 'Geliefert wurde: ean',
|
||||
// ];
|
||||
it('should handle undefined return info gracefully', () => {
|
||||
// Arrange
|
||||
returnProcessService.getReturnInfo.mockReturnValue(undefined);
|
||||
spectator.setInput('returnProcess', createMockReturnProcess({ id: 3 }));
|
||||
spectator.detectChanges();
|
||||
|
||||
// // Act
|
||||
// spectator.detectComponentChanges();
|
||||
// const listItems = spectator.queryAll(
|
||||
// '[data-what="list-item"][data-which="return-info"]',
|
||||
// );
|
||||
// Act
|
||||
const infos = spectator.component.returnInfos();
|
||||
|
||||
// // Assert
|
||||
// expect(listItems.length).toBe(expectedInfos.length);
|
||||
// listItems.forEach((item, index) => {
|
||||
// expect(item).toHaveText(expectedInfos[index]);
|
||||
// expect(item).toHaveAttribute('data-info-index', index.toString());
|
||||
// });
|
||||
// });
|
||||
// Assert
|
||||
expect(infos).toEqual([]);
|
||||
const listItems = spectator.queryAll(
|
||||
'[data-what="list-item"][data-which="return-info"]',
|
||||
);
|
||||
expect(listItems.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
// it('should handle undefined return info gracefully', () => {
|
||||
// // Arrange
|
||||
// returnProcessService.getReturnInfo.mockReturnValue(undefined);
|
||||
// spectator.setInput('returnProcess', createMockReturnProcess({ id: 3 }));
|
||||
// spectator.detectChanges();
|
||||
describe('Navigation', () => {
|
||||
it('should render edit button with correct attributes', () => {
|
||||
// Assert
|
||||
const editButton = spectator.query(
|
||||
'[data-what="button"][data-which="edit-return-item"]',
|
||||
);
|
||||
expect(editButton).toExist();
|
||||
});
|
||||
|
||||
// // Act
|
||||
// const infos = spectator.component.returnInfos();
|
||||
it('should navigate back when edit button is clicked', () => {
|
||||
// Arrange
|
||||
const editButton = spectator.query(
|
||||
'[data-what="button"][data-which="edit-return-item"]',
|
||||
);
|
||||
|
||||
// // Assert
|
||||
// expect(infos).toEqual([]);
|
||||
// const listItems = spectator.queryAll(
|
||||
// '[data-what="list-item"][data-which="return-info"]',
|
||||
// );
|
||||
// expect(listItems.length).toBe(0);
|
||||
// });
|
||||
// });
|
||||
// Act
|
||||
if (editButton) {
|
||||
spectator.click(editButton);
|
||||
}
|
||||
|
||||
// describe('Navigation', () => {
|
||||
// it('should render edit button with correct attributes', () => {
|
||||
// // Assert
|
||||
// const editButton = spectator.query(
|
||||
// '[data-what="button"][data-which="edit-return-item"]',
|
||||
// );
|
||||
// expect(editButton).toExist();
|
||||
// });
|
||||
|
||||
// it('should navigate back when edit button is clicked', () => {
|
||||
// // Arrange
|
||||
// const editButton = spectator.query(
|
||||
// '[data-what="button"][data-which="edit-return-item"]',
|
||||
// );
|
||||
|
||||
// // Act
|
||||
// if (editButton) {
|
||||
// spectator.click(editButton);
|
||||
// }
|
||||
|
||||
// // Assert
|
||||
// expect(spectator.inject(Router).navigate).toHaveBeenCalledWith(
|
||||
// ['..'],
|
||||
// expect.objectContaining({
|
||||
// relativeTo: expect.anything(),
|
||||
// }),
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// Assert
|
||||
expect(spectator.inject(Router).navigate).toHaveBeenCalledWith(
|
||||
['..'],
|
||||
expect.objectContaining({
|
||||
relativeTo: expect.anything(),
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,192 +1,190 @@
|
||||
// TODO: Unit Tests wieder reinnehmen wenn printReceiptsService nicht mehr auf die Alte ISA App zugreift durch den alten ModalService
|
||||
import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
|
||||
import { MockComponent } from 'ng-mocks';
|
||||
import { ReturnSummaryComponent } from './return-summary.component';
|
||||
import {
|
||||
ReturnProcess,
|
||||
ReturnProcessService,
|
||||
ReturnProcessStore,
|
||||
} from '@isa/oms/data-access';
|
||||
import { ReturnSummaryItemComponent } from './return-summary-item/return-summary-item.component';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
// import { createComponentFactory, Spectator } from '@ngneat/spectator/jest';
|
||||
// import { MockComponent } from 'ng-mocks';
|
||||
// import { ReturnSummaryComponent } from './return-summary.component';
|
||||
// import {
|
||||
// ReturnProcess,
|
||||
// ReturnProcessService,
|
||||
// ReturnProcessStore,
|
||||
// } from '@isa/oms/data-access';
|
||||
// import { ReturnSummaryItemComponent } from './return-summary-item/return-summary-item.component';
|
||||
jest.mock('@isa/core/process', () => ({
|
||||
injectActivatedProcessId: () => jest.fn(() => 1),
|
||||
}));
|
||||
|
||||
// jest.mock('@isa/core/process', () => ({
|
||||
// injectActivatedProcessId: () => jest.fn(() => 1),
|
||||
// }));
|
||||
const MOCK_RETURN_PROCESSES: ReturnProcess[] = [
|
||||
{ id: 1, processId: 1, productCategory: 'Electronics' } as ReturnProcess,
|
||||
{ id: 2, processId: 1, productCategory: 'Books' } as ReturnProcess,
|
||||
{ id: 3, processId: 2, productCategory: 'Clothing' } as ReturnProcess,
|
||||
{ id: 4, processId: 2, productCategory: 'Home Goods' } as ReturnProcess,
|
||||
{ id: 5, processId: 3, productCategory: 'Electronics' } as ReturnProcess,
|
||||
{ id: 6, processId: 3, productCategory: 'Toys' } as ReturnProcess,
|
||||
{ id: 7, processId: 4, productCategory: 'Books' } as ReturnProcess,
|
||||
{ id: 8, processId: 4, productCategory: 'Garden' } as ReturnProcess,
|
||||
];
|
||||
|
||||
// const MOCK_RETURN_PROCESSES: ReturnProcess[] = [
|
||||
// { id: 1, processId: 1, productCategory: 'Electronics' } as ReturnProcess,
|
||||
// { id: 2, processId: 1, productCategory: 'Books' } as ReturnProcess,
|
||||
// { id: 3, processId: 2, productCategory: 'Clothing' } as ReturnProcess,
|
||||
// { id: 4, processId: 2, productCategory: 'Home Goods' } as ReturnProcess,
|
||||
// { id: 5, processId: 3, productCategory: 'Electronics' } as ReturnProcess,
|
||||
// { id: 6, processId: 3, productCategory: 'Toys' } as ReturnProcess,
|
||||
// { id: 7, processId: 4, productCategory: 'Books' } as ReturnProcess,
|
||||
// { id: 8, processId: 4, productCategory: 'Garden' } as ReturnProcess,
|
||||
// ];
|
||||
describe('ReturnSummaryComponent', () => {
|
||||
let spectator: Spectator<ReturnSummaryComponent>;
|
||||
// Use createComponentFactory for standalone components
|
||||
const createComponent = createComponentFactory({
|
||||
component: ReturnSummaryComponent,
|
||||
imports: [MockComponent(ReturnSummaryItemComponent)],
|
||||
mocks: [ReturnProcessStore, ReturnProcessService, ActivatedRoute, Router],
|
||||
});
|
||||
|
||||
// describe('ReturnSummaryComponent', () => {
|
||||
// let spectator: Spectator<ReturnSummaryComponent>;
|
||||
beforeEach(() => {
|
||||
// Arrange: Create the component instance before each test
|
||||
spectator = createComponent({
|
||||
providers: [
|
||||
{
|
||||
provide: ReturnProcessStore,
|
||||
useValue: {
|
||||
entities: jest.fn(() => MOCK_RETURN_PROCESSES),
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
// // Use createComponentFactory for standalone components
|
||||
// const createComponent = createComponentFactory({
|
||||
// component: ReturnSummaryComponent,
|
||||
// imports: [MockComponent(ReturnSummaryItemComponent)],
|
||||
// mocks: [ReturnProcessStore, ReturnProcessService],
|
||||
// });
|
||||
it('should create the component', () => {
|
||||
// Assert: Check if the component instance was created successfully
|
||||
expect(spectator.component).toBeTruthy();
|
||||
});
|
||||
|
||||
// beforeEach(() => {
|
||||
// // Arrange: Create the component instance before each test
|
||||
// spectator = createComponent({
|
||||
// providers: [
|
||||
// {
|
||||
// provide: ReturnProcessStore,
|
||||
// useValue: {
|
||||
// entities: jest.fn(() => MOCK_RETURN_PROCESSES),
|
||||
// },
|
||||
// },
|
||||
// ],
|
||||
// });
|
||||
// });
|
||||
it('should have a defined processId', () => {
|
||||
// Assert: Check if the processId is defined
|
||||
expect(spectator.component.processId()).toBeTruthy();
|
||||
});
|
||||
|
||||
// it('should create the component', () => {
|
||||
// // Assert: Check if the component instance was created successfully
|
||||
// expect(spectator.component).toBeTruthy();
|
||||
// });
|
||||
it('should have two return processes', () => {
|
||||
// Arrange:
|
||||
const mockReturnProcesses: ReturnProcess[] = [
|
||||
MOCK_RETURN_PROCESSES[0],
|
||||
MOCK_RETURN_PROCESSES[1],
|
||||
];
|
||||
|
||||
// it('should have a defined processId', () => {
|
||||
// // Assert: Check if the processId is defined
|
||||
// expect(spectator.component.processId()).toBeTruthy();
|
||||
// });
|
||||
// Act: Set the returnProcesses to the mock data
|
||||
const returnProcesses = spectator.component.returnProcesses();
|
||||
|
||||
// it('should have two return processes', () => {
|
||||
// // Arrange:
|
||||
// const mockReturnProcesses: ReturnProcess[] = [
|
||||
// MOCK_RETURN_PROCESSES[0],
|
||||
// MOCK_RETURN_PROCESSES[1],
|
||||
// ];
|
||||
// Assert: Check if the returnProcesses array has two items
|
||||
expect(returnProcesses.length).toBe(2);
|
||||
expect(returnProcesses).toEqual(mockReturnProcesses);
|
||||
});
|
||||
|
||||
// // Act: Set the returnProcesses to the mock data
|
||||
// const returnProcesses = spectator.component.returnProcesses();
|
||||
it('should render the return summary item component', () => {
|
||||
// Arrange:
|
||||
const mockReturnProcesses: ReturnProcess[] = [
|
||||
MOCK_RETURN_PROCESSES[0],
|
||||
MOCK_RETURN_PROCESSES[1],
|
||||
];
|
||||
jest
|
||||
.spyOn(spectator.component, 'returnProcesses')
|
||||
.mockReturnValue(mockReturnProcesses);
|
||||
|
||||
// // Assert: Check if the returnProcesses array has two items
|
||||
// expect(returnProcesses.length).toBe(2);
|
||||
// expect(returnProcesses).toEqual(mockReturnProcesses);
|
||||
// });
|
||||
// Act: Trigger change detection
|
||||
spectator.detectChanges();
|
||||
|
||||
// it('should render the return summary item component', () => {
|
||||
// // Arrange:
|
||||
// const mockReturnProcesses: ReturnProcess[] = [
|
||||
// MOCK_RETURN_PROCESSES[0],
|
||||
// MOCK_RETURN_PROCESSES[1],
|
||||
// ];
|
||||
// jest
|
||||
// .spyOn(spectator.component, 'returnProcesses')
|
||||
// .mockReturnValue(mockReturnProcesses);
|
||||
// Assert: Check if the return summary item component is rendered
|
||||
const returnSummaryItems = spectator.queryAll(ReturnSummaryItemComponent);
|
||||
|
||||
// // Act: Trigger change detection
|
||||
// spectator.detectChanges();
|
||||
expect(returnSummaryItems.length).toBe(mockReturnProcesses.length);
|
||||
});
|
||||
|
||||
// // Assert: Check if the return summary item component is rendered
|
||||
// const returnSummaryItems = spectator.queryAll(ReturnSummaryItemComponent);
|
||||
it('should set the returnProcess input correctly', () => {
|
||||
// Arrange:
|
||||
const mockReturnProcesses: ReturnProcess[] = [
|
||||
MOCK_RETURN_PROCESSES[0],
|
||||
MOCK_RETURN_PROCESSES[1],
|
||||
];
|
||||
jest
|
||||
.spyOn(spectator.component, 'returnProcesses')
|
||||
.mockReturnValue(mockReturnProcesses);
|
||||
|
||||
// expect(returnSummaryItems.length).toBe(mockReturnProcesses.length);
|
||||
// });
|
||||
// Act: Trigger change detection
|
||||
spectator.detectChanges();
|
||||
|
||||
// it('should set the returnProcess input correctly', () => {
|
||||
// // Arrange:
|
||||
// const mockReturnProcesses: ReturnProcess[] = [
|
||||
// MOCK_RETURN_PROCESSES[0],
|
||||
// MOCK_RETURN_PROCESSES[1],
|
||||
// ];
|
||||
// jest
|
||||
// .spyOn(spectator.component, 'returnProcesses')
|
||||
// .mockReturnValue(mockReturnProcesses);
|
||||
// Assert: Check if the returnProcess input is set correctly
|
||||
const returnSummaryItems = spectator.queryAll(ReturnSummaryItemComponent);
|
||||
expect(returnSummaryItems[0].returnProcess).toEqual(mockReturnProcesses[0]);
|
||||
expect(returnSummaryItems[1].returnProcess).toEqual(mockReturnProcesses[1]);
|
||||
});
|
||||
|
||||
// // Act: Trigger change detection
|
||||
// spectator.detectChanges();
|
||||
it('should have proper E2E testing attributes', () => {
|
||||
// Arrange
|
||||
const mockReturnProcesses: ReturnProcess[] = [
|
||||
MOCK_RETURN_PROCESSES[0], // id: 1, processId: 1, category: 'Electronics'
|
||||
MOCK_RETURN_PROCESSES[1], // id: 2, processId: 1, category: 'Books'
|
||||
];
|
||||
|
||||
// // Assert: Check if the returnProcess input is set correctly
|
||||
// const returnSummaryItems = spectator.queryAll(ReturnSummaryItemComponent);
|
||||
// expect(returnSummaryItems[0].returnProcess).toEqual(mockReturnProcesses[0]);
|
||||
// expect(returnSummaryItems[1].returnProcess).toEqual(mockReturnProcesses[1]);
|
||||
// });
|
||||
jest
|
||||
.spyOn(spectator.component, 'returnProcesses')
|
||||
.mockReturnValue(mockReturnProcesses);
|
||||
|
||||
// it('should have proper E2E testing attributes', () => {
|
||||
// // Arrange
|
||||
// const mockReturnProcesses: ReturnProcess[] = [
|
||||
// MOCK_RETURN_PROCESSES[0], // id: 1, processId: 1, category: 'Electronics'
|
||||
// MOCK_RETURN_PROCESSES[1], // id: 2, processId: 1, category: 'Books'
|
||||
// ];
|
||||
// Act
|
||||
spectator.detectChanges(); // Trigger change detection to render the template
|
||||
|
||||
// jest
|
||||
// .spyOn(spectator.component, 'returnProcesses')
|
||||
// .mockReturnValue(mockReturnProcesses);
|
||||
// Assert
|
||||
// Check heading attributes
|
||||
const heading = spectator.query('[data-what="heading"]');
|
||||
expect(heading).toBeTruthy();
|
||||
expect(heading).toHaveAttribute('data-which', 'return-summary-title');
|
||||
|
||||
// // Act
|
||||
// spectator.detectChanges(); // Trigger change detection to render the template
|
||||
// Check container attributes
|
||||
const container = spectator.query('[data-what="container"]');
|
||||
expect(container).toBeTruthy();
|
||||
expect(container).toHaveAttribute('data-which', 'return-items-list');
|
||||
|
||||
// // Assert
|
||||
// // Check heading attributes
|
||||
// const heading = spectator.query('[data-what="heading"]');
|
||||
// expect(heading).toBeTruthy();
|
||||
// expect(heading).toHaveAttribute('data-which', 'return-summary-title');
|
||||
// Check list item attributes
|
||||
const listItems = spectator.queryAll('oms-feature-return-summary-item');
|
||||
expect(listItems.length).toBe(mockReturnProcesses.length);
|
||||
|
||||
// // Check container attributes
|
||||
// const container = spectator.query('[data-what="container"]');
|
||||
// expect(container).toBeTruthy();
|
||||
// expect(container).toHaveAttribute('data-which', 'return-items-list');
|
||||
// Check attributes for the first item
|
||||
expect(listItems[0]).toHaveAttribute('data-what', 'list-item');
|
||||
expect(listItems[0]).toHaveAttribute('data-which', 'return-process-item');
|
||||
expect(listItems[0]).toHaveAttribute(
|
||||
'data-item-id',
|
||||
`${mockReturnProcesses[0].id}`,
|
||||
);
|
||||
|
||||
// // Check list item attributes
|
||||
// const listItems = spectator.queryAll('oms-feature-return-summary-item');
|
||||
// expect(listItems.length).toBe(mockReturnProcesses.length);
|
||||
expect(listItems[0]).toHaveAttribute(
|
||||
'data-item-category',
|
||||
mockReturnProcesses[0].productCategory,
|
||||
);
|
||||
|
||||
// // Check attributes for the first item
|
||||
// expect(listItems[0]).toHaveAttribute('data-what', 'list-item');
|
||||
// expect(listItems[0]).toHaveAttribute('data-which', 'return-process-item');
|
||||
// expect(listItems[0]).toHaveAttribute(
|
||||
// 'data-item-id',
|
||||
// `${mockReturnProcesses[0].id}`,
|
||||
// );
|
||||
// Check attributes for the second item
|
||||
expect(listItems[1]).toHaveAttribute('data-what', 'list-item');
|
||||
expect(listItems[1]).toHaveAttribute('data-which', 'return-process-item');
|
||||
expect(listItems[1]).toHaveAttribute(
|
||||
'data-item-id',
|
||||
`${mockReturnProcesses[1].id}`,
|
||||
);
|
||||
expect(listItems[1]).toHaveAttribute(
|
||||
'data-item-category',
|
||||
`${mockReturnProcesses[1].productCategory}`,
|
||||
);
|
||||
expect(listItems[1]).toHaveAttribute(
|
||||
'data-item-category',
|
||||
mockReturnProcesses[1].productCategory,
|
||||
);
|
||||
|
||||
// expect(listItems[0]).toHaveAttribute(
|
||||
// 'data-item-category',
|
||||
// mockReturnProcesses[0].productCategory,
|
||||
// );
|
||||
// Check button attributes
|
||||
const button = spectator.query('[data-what="button"]');
|
||||
expect(button).toBeTruthy();
|
||||
expect(button).toHaveAttribute('data-which', 'return-and-print');
|
||||
});
|
||||
|
||||
// // Check attributes for the second item
|
||||
// expect(listItems[1]).toHaveAttribute('data-what', 'list-item');
|
||||
// expect(listItems[1]).toHaveAttribute('data-which', 'return-process-item');
|
||||
// expect(listItems[1]).toHaveAttribute(
|
||||
// 'data-item-id',
|
||||
// `${mockReturnProcesses[1].id}`,
|
||||
// );
|
||||
// expect(listItems[1]).toHaveAttribute(
|
||||
// 'data-item-category',
|
||||
// `${mockReturnProcesses[1].productCategory}`,
|
||||
// );
|
||||
// expect(listItems[1]).toHaveAttribute(
|
||||
// 'data-item-category',
|
||||
// mockReturnProcesses[1].productCategory,
|
||||
// );
|
||||
it('should call returnItemsAndPrintRecipt when button is clicked', () => {
|
||||
// Arrange: Spy on the returnItemsAndPrintRecipt method
|
||||
const returnItemsAndPrintReciptSpy = jest.spyOn(
|
||||
spectator.component,
|
||||
'returnItemsAndPrintRecipt',
|
||||
);
|
||||
|
||||
// // Check button attributes
|
||||
// const button = spectator.query('[data-what="button"]');
|
||||
// expect(button).toBeTruthy();
|
||||
// expect(button).toHaveAttribute('data-which', 'return-and-print');
|
||||
// });
|
||||
// Act: Trigger button click
|
||||
spectator.click('[data-what="button"][data-which="return-and-print"]');
|
||||
|
||||
// it('should call returnItemsAndPrintRecipt when button is clicked', () => {
|
||||
// // Arrange: Spy on the returnItemsAndPrintRecipt method
|
||||
// const returnItemsAndPrintReciptSpy = jest.spyOn(
|
||||
// spectator.component,
|
||||
// 'returnItemsAndPrintRecipt',
|
||||
// );
|
||||
|
||||
// // Act: Trigger button click
|
||||
// spectator.click('[data-what="button"][data-which="return-and-print"]');
|
||||
|
||||
// // Assert: Check if the method was called
|
||||
// expect(returnItemsAndPrintReciptSpy).toHaveBeenCalled();
|
||||
// });
|
||||
// });
|
||||
// Assert: Check if the method was called
|
||||
expect(returnItemsAndPrintReciptSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { ReturnTaskListComponent } from './return-task-list.component';
|
||||
|
||||
describe('ReturnTaskListComponent', () => {
|
||||
let component: ReturnTaskListComponent;
|
||||
let fixture: ComponentFixture<ReturnTaskListComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ReturnTaskListComponent],
|
||||
}).compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ReturnTaskListComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -21,6 +21,8 @@ import { firstValueFrom } from 'rxjs';
|
||||
import { injectActivatedProcessId } from '@isa/core/process';
|
||||
import { logger, provideLoggerContext } from '@isa/core/logging';
|
||||
|
||||
// TODO: Komponente und logik benötigt review
|
||||
|
||||
@Component({
|
||||
selector: 'oms-shared-return-task-list',
|
||||
templateUrl: './return-task-list.component.html',
|
||||
|
||||
@@ -2,4 +2,5 @@ export * from './lib/dialog-content.directive';
|
||||
export * from './lib/dialog.component';
|
||||
export * from './lib/injects';
|
||||
export * from './lib/message-dialog/message-dialog.component';
|
||||
export * from './lib/confirmation-dialog/confirmation-dialog.component';
|
||||
export * from './lib/tokens';
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<p class="isa-text-body-1-regular text-isa-neutral-600" data-what="message">
|
||||
{{ data.message }}
|
||||
</p>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<button
|
||||
uiButton
|
||||
(click)="close({ confirmed: false })"
|
||||
color="secondary"
|
||||
data-what="button"
|
||||
data-which="close"
|
||||
>
|
||||
{{ data.closeText || 'Schließen' }}
|
||||
</button>
|
||||
<button
|
||||
uiButton
|
||||
(click)="close({ confirmed: true })"
|
||||
color="primary"
|
||||
data-what="button"
|
||||
data-which="confirm"
|
||||
>
|
||||
{{ data.confirmText || 'Bestätigen' }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -0,0 +1,39 @@
|
||||
import { ChangeDetectionStrategy, Component } from '@angular/core';
|
||||
|
||||
import { ButtonComponent } from '@isa/ui/buttons';
|
||||
|
||||
import { DialogContentDirective } from '../dialog-content.directive';
|
||||
|
||||
/**
|
||||
* Input data for the message dialog
|
||||
*/
|
||||
export interface ConfirmationDialogData {
|
||||
/** The message text to display in the dialog */
|
||||
message: string;
|
||||
/** Optional custom text for the close button (defaults to "Close" or equivalent) */
|
||||
closeText?: string;
|
||||
|
||||
/** Optional custom text for the confirm button (defaults to "OK" or equivalent) */
|
||||
confirmText?: string;
|
||||
}
|
||||
|
||||
export interface ConfirmationDialogResult {
|
||||
/** Indicates whether the user confirmed the action (true) or closed the dialog (false) */
|
||||
confirmed: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple message dialog component
|
||||
* Used for displaying informational messages to the user
|
||||
* Returns void when closed (no result)
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ui-confirmation-dialog',
|
||||
templateUrl: './confirmation-dialog.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
imports: [ButtonComponent],
|
||||
})
|
||||
export class ConfirmationDialogComponent extends DialogContentDirective<
|
||||
ConfirmationDialogData,
|
||||
ConfirmationDialogResult
|
||||
> {}
|
||||
@@ -1,4 +1,4 @@
|
||||
<h2 class="ui-dialog-title">
|
||||
<h2 class="ui-dialog-title" data-what="title">
|
||||
{{ title }}
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<p class="isa-text-body-1-regular text-isa-neutral-600">
|
||||
<p class="isa-text-body-1-regular text-isa-neutral-600" data-what="message">
|
||||
{{ data.message }}
|
||||
</p>
|
||||
<div class="text-right">
|
||||
<button uiButton (click)="close()">
|
||||
<button uiButton (click)="close()" data-what="button" data-which="close">
|
||||
{{ data.closeText || 'Schließen' }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user