Skip to content

Commit

Permalink
fixup! feat: SEO friendly localized URLs for product detail pages (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
dhhyi committed Feb 17, 2020
1 parent 14a54cf commit 7b94af8
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 15 deletions.
15 changes: 7 additions & 8 deletions src/app/core/store/shopping/products/products.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,13 @@ describe('Products Effects', () => {
});

describe('redirectIfErrorInProducts$', () => {
it('should redirect if triggered on product detail page', fakeAsync(() => {
when(router.url).thenReturn('/category/A/product/SKU');

const action = new fromActions.LoadProductFail({ sku: 'SKU', error: { status: 404 } as HttpError });
beforeEach(() => {
store$.dispatch(new fromActions.LoadProductFail({ sku: 'SKU', error: { status: 404 } as HttpError }));
store$.dispatch(new fromActions.SelectProduct({ sku: 'SKU' }));
});

it('should redirect if triggered on product detail page', fakeAsync(() => {
const action = new RouteNavigation({ path: 'pr', params: { sku: 'SKU' } });
actions$ = of(action);

effects.redirectIfErrorInProducts$.subscribe(noop, fail, noop);
Expand All @@ -362,10 +364,7 @@ describe('Products Effects', () => {
}));

it('should not redirect if triggered on page other than product detail page', done => {
when(router.url).thenReturn('/search/term');

const action = new fromActions.LoadProductFail({ sku: 'SKU', error: { status: 404 } as HttpError });

const action = new RouteNavigation({ path: 'any' });
actions$ = of(action);

effects.redirectIfErrorInProducts$.subscribe(fail, fail, done);
Expand Down
16 changes: 14 additions & 2 deletions src/app/core/store/shopping/products/products.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ import {
concatMap,
distinct,
distinctUntilChanged,
distinctUntilKeyChanged,
filter,
groupBy,
map,
mergeMap,
switchMap,
switchMapTo,
take,
takeUntil,
tap,
throttleTime,
Expand Down Expand Up @@ -223,6 +226,7 @@ export class ProductsEffects {
this.store.pipe(
select(productsSelectors.getSelectedProduct),
whenTruthy(),
filter(p => !ProductHelper.isFailedLoading(p)),
filter(product => !product.defaultCategory()),
mapToProperty('defaultCategoryId'),
whenTruthy(),
Expand Down Expand Up @@ -268,8 +272,16 @@ export class ProductsEffects {

@Effect({ dispatch: false })
redirectIfErrorInProducts$ = this.actions$.pipe(
ofType(productsActions.ProductsActionTypes.LoadProductFail),
filter(() => this.router.url.includes('/product/')),
ofProductRoute(),
switchMapTo(
this.store.pipe(
select(productsSelectors.getSelectedProduct),
whenTruthy(),
distinctUntilKeyChanged('sku'),
filter(ProductHelper.isFailedLoading),
take(1)
)
),
tap(() => this.httpStatusCodeService.setStatusAndRedirect(404))
);

Expand Down
4 changes: 1 addition & 3 deletions src/app/core/store/shopping/products/products.selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,7 @@ export const getProducts = createSelector(
export const getSelectedProduct = createSelector(
state => state,
getSelectedProductId,
getFailed,
(state, sku, failed): ProductView | VariationProductView | VariationProductMasterView =>
failed.includes(sku) ? undefined : getProduct(state, { sku })
(state, sku): ProductView | VariationProductView | VariationProductMasterView => getProduct(state, { sku })
);

export const getProductVariationOptions = createSelector(
Expand Down
10 changes: 9 additions & 1 deletion src/app/core/store/shopping/recently/recently.effects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import { cold, hot } from 'jest-marbles';
import { Observable } from 'rxjs';

import { FeatureToggleModule } from 'ish-core/feature-toggle.module';
import { HttpError } from 'ish-core/models/http-error/http-error.model';
import { Product } from 'ish-core/models/product/product.model';
import { ApplyConfiguration } from 'ish-core/store/configuration';
import { configurationReducer } from 'ish-core/store/configuration/configuration.reducer';
import { LoadProductSuccess, SelectProduct } from 'ish-core/store/shopping/products';
import { LoadProductFail, LoadProductSuccess, SelectProduct } from 'ish-core/store/shopping/products';
import { shoppingReducers } from 'ish-core/store/shopping/shopping-store.module';
import { ngrxTesting } from 'ish-core/utils/dev/ngrx-testing';

Expand Down Expand Up @@ -54,6 +55,13 @@ describe('Recently Effects', () => {
expect(effects.viewedProduct$).toBeObservable(cold('a', { a: new AddToRecently({ sku: 'A' }) }));
});

it('should not fire when product failed loading', () => {
store$.dispatch(new LoadProductFail({ error: {} as HttpError, sku: 'A' }));
store$.dispatch(new SelectProduct({ sku: 'A' }));

expect(effects.viewedProduct$).toBeObservable(cold('------'));
});

it('should not fire when product is deselected', () => {
store$.dispatch(new SelectProduct({ sku: undefined }));

Expand Down
1 change: 1 addition & 0 deletions src/app/core/store/shopping/recently/recently.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export class RecentlyEffects {
viewedProduct$ = this.store.pipe(
select(getSelectedProduct),
whenTruthy(),
filter(p => !ProductHelper.isFailedLoading(p)),
distinctUntilKeyChanged('sku'),
filter(
product =>
Expand Down
3 changes: 2 additions & 1 deletion src/app/extensions/seo/store/seo/seo.effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Store, select } from '@ngrx/store';
import { MetaService } from '@ngx-meta/core';
import { TranslateService } from '@ngx-translate/core';
import { mapToParam, ofRoute } from 'ngrx-router';
import { debounce, distinctUntilKeyChanged, first, map, switchMap, tap } from 'rxjs/operators';
import { debounce, distinctUntilKeyChanged, filter, first, map, switchMap, tap } from 'rxjs/operators';

import { ProductHelper } from 'ish-core/models/product/product.helper';
import { SeoAttributes } from 'ish-core/models/seo-attribute/seo-attribute.model';
Expand Down Expand Up @@ -83,6 +83,7 @@ export class SeoEffects {
this.store.pipe(
select(getSelectedProduct),
whenTruthy(),
filter(p => !ProductHelper.isFailedLoading(p)),
map(p => (ProductHelper.isVariationProduct(p) && p.productMaster()) || p),
distinctUntilKeyChanged('sku'),
whenTruthy(),
Expand Down

0 comments on commit 7b94af8

Please sign in to comment.