Skip to content

Commit

Permalink
feat: route to product detail page if only one search result was found (
Browse files Browse the repository at this point in the history
#1316)

- handled in `searchProducts$` effect
- adapted and added tests for new interaction
  • Loading branch information
shauke committed Nov 30, 2022
1 parent 9d063a9 commit 9964ebd
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 31 deletions.
17 changes: 16 additions & 1 deletion e2e/cypress/e2e/specs/shopping/search-products.b2c.e2e-spec.ts
Expand Up @@ -5,9 +5,12 @@ import { SearchResultPage } from '../../pages/shopping/search-result.page';

const _ = {
suggestTerm: 'ko',
searchTerm: 'kodak M552',
suggestItemText: 'Kodak',
searchTerm: 'kodak M552',
product: '7912057',
searchTermWithMoreResults: 'acer',
searchTermWithOneResult: 'acer c110',
oneResultProduct: '9438012',
};

describe('Searching User', () => {
Expand Down Expand Up @@ -36,4 +39,16 @@ describe('Searching User', () => {
page.breadcrumb.items.should('have.length', 4);
});
});

it(`should perform another search and land on search result page`, () => {
at(ProductDetailPage, page => page.header.searchBox.search(_.searchTermWithMoreResults));
at(SearchResultPage, page => page.productList.visibleProducts.should('have.length.gte', 1));
});

it(`should perform search with only one search result and land on product detail page`, () => {
at(SearchResultPage, page => page.header.searchBox.search(_.searchTermWithOneResult));
at(ProductDetailPage, page => {
page.sku.should('have.text', _.oneResultProduct);
});
});
});
Expand Up @@ -12,7 +12,7 @@ const _ = {
dollarPrice: '33.75',
euroPrice: '25,00',
},
searchTerm: 'conversion lens',
searchTerm: 'lens',
};

describe('Language Changing User', () => {
Expand Down
46 changes: 28 additions & 18 deletions src/app/core/store/shopping/search/search.effects.ts
@@ -1,4 +1,5 @@
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { routerNavigatedAction } from '@ngrx/router-store';
import { Store, select } from '@ngrx/store';
Expand All @@ -17,6 +18,7 @@ import {
} from 'rxjs/operators';

import { ProductListingMapper } from 'ish-core/models/product-listing/product-listing.mapper';
import { generateProductUrl } from 'ish-core/routing/product/product.route';
import { ProductsService } from 'ish-core/services/products/products.service';
import { SuggestService } from 'ish-core/services/suggest/suggest.service';
import { ofUrl, selectRouteParam } from 'ish-core/store/core/router';
Expand Down Expand Up @@ -48,7 +50,8 @@ export class SearchEffects {
private suggestService: SuggestService,
private httpStatusCodeService: HttpStatusCodeService,
private productListingMapper: ProductListingMapper,
private translateService: TranslateService
private translateService: TranslateService,
private router: Router
) {}

/**
Expand Down Expand Up @@ -81,23 +84,30 @@ export class SearchEffects {
map(([payload, pageSize]) => ({ ...payload, amount: pageSize, offset: (payload.page - 1) * pageSize })),
concatMap(({ searchTerm, amount, sorting, offset, page }) =>
this.productsService.searchProducts(searchTerm, amount, sorting, offset).pipe(
concatMap(({ total, products, sortableAttributes }) => [
...products.map(product => loadProductSuccess({ product })),
setProductListingPages(
this.productListingMapper.createPages(
products.map(p => p.sku),
'search',
searchTerm,
amount,
{
startPage: page,
sorting,
sortableAttributes,
itemCount: total,
}
)
),
]),
concatMap(({ total, products, sortableAttributes }) => {
// route to product detail page if only one product was found
if (total === 1) {
this.router.navigate([generateProductUrl(products[0])]);
}
// provide the data for the search result page
return [
...products.map(product => loadProductSuccess({ product })),
setProductListingPages(
this.productListingMapper.createPages(
products.map(p => p.sku),
'search',
searchTerm,
amount,
{
startPage: page,
sorting,
sortableAttributes,
itemCount: total,
}
)
),
];
}),
mapErrorToAction(searchProductsFail)
)
)
Expand Down
28 changes: 17 additions & 11 deletions src/app/core/store/shopping/shopping-store.spec.ts
Expand Up @@ -125,7 +125,7 @@ describe('Shopping Store', () => {
})
);
when(productsServiceMock.searchProducts('something', anyNumber(), anything(), anyNumber())).thenReturn(
of({ products: [{ sku: 'P2' } as Product], sortableAttributes: [], total: 1 })
of({ products: [{ sku: 'P1' }, { sku: 'P2' }] as Product[], sortableAttributes: [], total: 2 })
);

promotionsServiceMock = mock(PromotionsService);
Expand Down Expand Up @@ -281,8 +281,8 @@ describe('Shopping Store', () => {
tick(5000);
}));

it('should load the product for the search results', fakeAsync(() => {
expect(getProductIds(store.state)).toEqual(['P2']);
it('should load the products for the search results', fakeAsync(() => {
expect(getProductIds(store.state)).toEqual(['P1', 'P2']);
}));

it('should trigger required actions when searching', fakeAsync(() => {
Expand All @@ -307,12 +307,14 @@ describe('Shopping Store', () => {
sorting: undefined
[Filter Internal] Load Filter for Search:
searchTerm: "something"
[Products API] Load Product Success:
product: {"sku":"P1"}
[Products API] Load Product Success:
product: {"sku":"P2"}
[Product Listing Internal] Set Product Listing Pages:
1: ["P2"]
1: ["P1","P2"]
id: {"type":"search","value":"something"}
itemCount: 1
itemCount: 2
sortableAttributes: []
[Filter API] Load Filter Success:
filterNavigation: {}
Expand Down Expand Up @@ -535,12 +537,14 @@ describe('Shopping Store', () => {
sorting: undefined
[Filter Internal] Load Filter for Search:
searchTerm: "something"
[Products API] Load Product Success:
product: {"sku":"P1"}
[Products API] Load Product Success:
product: {"sku":"P2"}
[Product Listing Internal] Set Product Listing Pages:
1: ["P2"]
1: ["P1","P2"]
id: {"type":"search","value":"something"}
itemCount: 1
itemCount: 2
sortableAttributes: []
[Filter API] Load Filter Success:
filterNavigation: {}
Expand Down Expand Up @@ -885,8 +889,8 @@ describe('Shopping Store', () => {
tick(5000);
}));

it('should load the product for the search results', fakeAsync(() => {
expect(getProductIds(store.state)).toEqual(['P2']);
it('should load the products for the search results', fakeAsync(() => {
expect(getProductIds(store.state)).toEqual(['P1', 'P2']);
}));

it('should trigger required actions when searching', fakeAsync(() => {
Expand All @@ -910,12 +914,14 @@ describe('Shopping Store', () => {
sorting: undefined
[Filter Internal] Load Filter for Search:
searchTerm: "something"
[Products API] Load Product Success:
product: {"sku":"P1"}
[Products API] Load Product Success:
product: {"sku":"P2"}
[Product Listing Internal] Set Product Listing Pages:
1: ["P2"]
1: ["P1","P2"]
id: {"type":"search","value":"something"}
itemCount: 1
itemCount: 2
sortableAttributes: []
[Filter API] Load Filter Success:
filterNavigation: {}
Expand Down

0 comments on commit 9964ebd

Please sign in to comment.