mirror of
https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend
synced 2025-12-31 09:37:15 +01:00
Merged PR 1885: Remi Add Flow - ohne offener Remi
Related work items: #5135
This commit is contained in:
committed by
Nino Righi
parent
b015e97e1f
commit
442670bdd0
@@ -0,0 +1,222 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { of } from 'rxjs';
|
||||
import { CatalougeSearchService } from './catalouge-search.service';
|
||||
import { SearchService } from '@generated/swagger/cat-search-api';
|
||||
import { Item } from '../models';
|
||||
import { SearchByTermInput } from '../schemas/catalouge-search.schemas';
|
||||
|
||||
describe('CatalougeSearchService', () => {
|
||||
let service: CatalougeSearchService;
|
||||
let searchServiceSpy: jest.Mocked<SearchService>;
|
||||
|
||||
beforeEach(() => {
|
||||
const searchServiceMock = {
|
||||
SearchByEAN: jest.fn(),
|
||||
SearchSearch: jest.fn(),
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
CatalougeSearchService,
|
||||
{ provide: SearchService, useValue: searchServiceMock },
|
||||
],
|
||||
});
|
||||
|
||||
service = TestBed.inject(CatalougeSearchService);
|
||||
searchServiceSpy = TestBed.inject(SearchService) as jest.Mocked<SearchService>;
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('searchByEans', () => {
|
||||
it('should return items when search is successful', (done) => {
|
||||
// Arrange
|
||||
const mockItems: Item[] = [
|
||||
{ id: 1, product: { name: 'Item 1' }, catalogAvailability: { available: true } } as unknown as Item,
|
||||
{ id: 2, product: { name: 'Item 2' }, catalogAvailability: { available: true } } as unknown as Item,
|
||||
];
|
||||
const mockResponse = {
|
||||
error: false,
|
||||
result: mockItems,
|
||||
};
|
||||
searchServiceSpy.SearchByEAN.mockReturnValue(of(mockResponse));
|
||||
|
||||
// Act
|
||||
service.searchByEans('123456789', '987654321').subscribe({
|
||||
next: (result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(mockItems);
|
||||
expect(searchServiceSpy.SearchByEAN).toHaveBeenCalledWith(['123456789', '987654321']);
|
||||
done();
|
||||
},
|
||||
error: done.fail,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error when response has error', (done) => {
|
||||
// Arrange
|
||||
const mockResponse = {
|
||||
error: true,
|
||||
message: 'Search failed',
|
||||
};
|
||||
searchServiceSpy.SearchByEAN.mockReturnValue(of(mockResponse));
|
||||
|
||||
// Act
|
||||
service.searchByEans('123456789').subscribe({
|
||||
next: () => done.fail('Should have thrown error'),
|
||||
error: (error) => {
|
||||
// Assert
|
||||
expect(error).toBeInstanceOf(Error);
|
||||
expect(error.message).toBe('Search failed');
|
||||
done();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle single EAN', (done) => {
|
||||
// Arrange
|
||||
const mockItems: Item[] = [{ id: 1, product: { name: 'Item 1' }, catalogAvailability: { available: true } } as unknown as Item];
|
||||
const mockResponse = {
|
||||
error: false,
|
||||
result: mockItems,
|
||||
};
|
||||
searchServiceSpy.SearchByEAN.mockReturnValue(of(mockResponse));
|
||||
|
||||
// Act
|
||||
service.searchByEans('123456789').subscribe({
|
||||
next: (result) => {
|
||||
// Assert
|
||||
expect(result).toEqual(mockItems);
|
||||
expect(searchServiceSpy.SearchByEAN).toHaveBeenCalledWith(['123456789']);
|
||||
done();
|
||||
},
|
||||
error: done.fail,
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle empty EAN array', (done) => {
|
||||
// Arrange
|
||||
const mockResponse = {
|
||||
error: false,
|
||||
result: [],
|
||||
};
|
||||
searchServiceSpy.SearchByEAN.mockReturnValue(of(mockResponse));
|
||||
|
||||
// Act
|
||||
service.searchByEans().subscribe({
|
||||
next: (result) => {
|
||||
// Assert
|
||||
expect(result).toEqual([]);
|
||||
expect(searchServiceSpy.SearchByEAN).toHaveBeenCalledWith([]);
|
||||
done();
|
||||
},
|
||||
error: done.fail,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('searchByTerm', () => {
|
||||
it('should return search results when successful', async () => {
|
||||
// Arrange
|
||||
const mockItems: Item[] = [
|
||||
{ id: 1, product: { name: 'Test Item' }, catalogAvailability: { available: true } } as unknown as Item,
|
||||
];
|
||||
const mockResponse = {
|
||||
error: false,
|
||||
result: mockItems,
|
||||
total: 1,
|
||||
};
|
||||
searchServiceSpy.SearchSearch.mockReturnValue(of(mockResponse));
|
||||
|
||||
const params: SearchByTermInput = {
|
||||
searchTerm: 'test',
|
||||
skip: 0,
|
||||
take: 10,
|
||||
};
|
||||
const abortController = new AbortController();
|
||||
|
||||
// Act
|
||||
const result = await service.searchByTerm(params, abortController.signal);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(mockResponse);
|
||||
expect(searchServiceSpy.SearchSearch).toHaveBeenCalledWith({
|
||||
input: { qs: 'test' },
|
||||
skip: 0,
|
||||
take: 10,
|
||||
doNotTrack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw error when response has error', async () => {
|
||||
// Arrange
|
||||
const mockResponse = {
|
||||
error: true,
|
||||
message: 'Search failed',
|
||||
};
|
||||
searchServiceSpy.SearchSearch.mockReturnValue(of(mockResponse));
|
||||
|
||||
const params: SearchByTermInput = {
|
||||
searchTerm: 'test',
|
||||
skip: 0,
|
||||
take: 10,
|
||||
};
|
||||
const abortController = new AbortController();
|
||||
|
||||
// Act & Assert
|
||||
await expect(service.searchByTerm(params, abortController.signal))
|
||||
.rejects
|
||||
.toThrow('Search failed');
|
||||
});
|
||||
|
||||
it('should handle abort signal', async () => {
|
||||
// Arrange
|
||||
const abortController = new AbortController();
|
||||
const mockResponse = {
|
||||
error: false,
|
||||
result: [],
|
||||
};
|
||||
searchServiceSpy.SearchSearch.mockReturnValue(of(mockResponse));
|
||||
|
||||
const params: SearchByTermInput = {
|
||||
searchTerm: 'test',
|
||||
skip: 0,
|
||||
take: 10,
|
||||
};
|
||||
|
||||
// Act
|
||||
const result = await service.searchByTerm(params, abortController.signal);
|
||||
|
||||
// Assert
|
||||
expect(result).toEqual(mockResponse);
|
||||
expect(searchServiceSpy.SearchSearch).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should use default values when not provided', async () => {
|
||||
// Arrange
|
||||
const mockResponse = {
|
||||
error: false,
|
||||
result: [],
|
||||
};
|
||||
searchServiceSpy.SearchSearch.mockReturnValue(of(mockResponse));
|
||||
|
||||
const params: SearchByTermInput = {
|
||||
searchTerm: 'test',
|
||||
};
|
||||
const abortController = new AbortController();
|
||||
|
||||
// Act
|
||||
await service.searchByTerm(params, abortController.signal);
|
||||
|
||||
// Assert
|
||||
expect(searchServiceSpy.SearchSearch).toHaveBeenCalledWith({
|
||||
input: { qs: 'test' },
|
||||
skip: 0,
|
||||
take: 20,
|
||||
doNotTrack: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,52 +1,53 @@
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { SearchService } from '@generated/swagger/cat-search-api';
|
||||
import { firstValueFrom, map, Observable } from 'rxjs';
|
||||
import { takeUntilAborted } from '@isa/common/data-access';
|
||||
import { Item } from '../models';
|
||||
import {
|
||||
SearchByTermInput,
|
||||
SearchByTermSchema,
|
||||
} from '../schemas/catalouge-search.schemas';
|
||||
import { ListResponseArgs } from '@isa/common/data-access';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CatalougeSearchService {
|
||||
#searchService = inject(SearchService);
|
||||
|
||||
searchByEans(...ean: string[]): Observable<Item[]> {
|
||||
return this.#searchService.SearchByEAN(ean).pipe(
|
||||
map((res) => {
|
||||
if (res.error) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
return res.result as Item[];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async searchByTerm(
|
||||
params: SearchByTermInput,
|
||||
abortSignal: AbortSignal,
|
||||
): Promise<ListResponseArgs<Item>> {
|
||||
const { searchTerm, skip, take } = SearchByTermSchema.parse(params);
|
||||
|
||||
const req$ = this.#searchService
|
||||
.SearchSearch({
|
||||
filter: {
|
||||
qs: searchTerm,
|
||||
},
|
||||
skip,
|
||||
take,
|
||||
})
|
||||
.pipe(takeUntilAborted(abortSignal));
|
||||
|
||||
const res = await firstValueFrom(req$);
|
||||
|
||||
if (res.error) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
return res as ListResponseArgs<Item>;
|
||||
}
|
||||
}
|
||||
import { inject, Injectable } from '@angular/core';
|
||||
import { SearchService } from '@generated/swagger/cat-search-api';
|
||||
import { firstValueFrom, map, Observable } from 'rxjs';
|
||||
import { takeUntilAborted } from '@isa/common/data-access';
|
||||
import { Item } from '../models';
|
||||
import {
|
||||
SearchByTermInput,
|
||||
SearchByTermSchema,
|
||||
} from '../schemas/catalouge-search.schemas';
|
||||
import { ListResponseArgs } from '@isa/common/data-access';
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CatalougeSearchService {
|
||||
#searchService = inject(SearchService);
|
||||
|
||||
searchByEans(...ean: string[]): Observable<Item[]> {
|
||||
return this.#searchService.SearchByEAN(ean).pipe(
|
||||
map((res) => {
|
||||
if (res.error) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
return res.result as Item[];
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
async searchByTerm(
|
||||
params: SearchByTermInput,
|
||||
abortSignal: AbortSignal,
|
||||
): Promise<ListResponseArgs<Item>> {
|
||||
const { searchTerm, skip, take } = SearchByTermSchema.parse(params);
|
||||
|
||||
const req$ = this.#searchService
|
||||
.SearchSearch({
|
||||
input: {
|
||||
qs: searchTerm,
|
||||
},
|
||||
skip,
|
||||
take,
|
||||
doNotTrack: true,
|
||||
})
|
||||
.pipe(takeUntilAborted(abortSignal));
|
||||
|
||||
const res = await firstValueFrom(req$);
|
||||
|
||||
if (res.error) {
|
||||
throw new Error(res.message);
|
||||
}
|
||||
|
||||
return res as ListResponseArgs<Item>;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user