Skip to content

Commit

Permalink
Merge branch 'v6.4.0' into v6.X
Browse files Browse the repository at this point in the history
  • Loading branch information
SG-Noxoreos committed Apr 11, 2019
2 parents 862d8e5 + bd28322 commit 262ec20
Show file tree
Hide file tree
Showing 48 changed files with 474 additions and 196 deletions.
2 changes: 1 addition & 1 deletion extensions/@shopgate-product-reviews/extension-config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "6.3.1",
"version": "6.3.2",
"id": "@shopgate/product-reviews",
"components": [
{
Expand Down
12 changes: 6 additions & 6 deletions extensions/@shopgate-product-reviews/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shopgate/product-reviews",
"version": "6.3.1",
"version": "6.3.2",
"description": "Shopgate Connect Product Reviews extension.",
"license": "Apache-2.0",
"scripts": {
Expand All @@ -19,11 +19,11 @@
}
},
"devDependencies": {
"@shopgate/eslint-config": "6.3.1",
"@shopgate/pwa-common": "6.3.1",
"@shopgate/pwa-common-commerce": "6.3.1",
"@shopgate/pwa-core": "6.3.1",
"@shopgate/pwa-unit-test": "6.3.1",
"@shopgate/eslint-config": "6.3.2",
"@shopgate/pwa-common": "6.3.2",
"@shopgate/pwa-common-commerce": "6.3.2",
"@shopgate/pwa-core": "6.3.2",
"@shopgate/pwa-unit-test": "6.3.2",
"babel-plugin-react-transform": "^3.0.0",
"coveralls": "^3.0.0",
"eslint": "^4.17.0",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "6.3.1",
"version": "6.3.2",
"id": "@shopgate/tracking-ga-native",
"components": [
{
Expand Down
10 changes: 5 additions & 5 deletions extensions/@shopgate-tracking-ga-native/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shopgate/tracking-ga-native",
"version": "6.3.1",
"version": "6.3.2",
"description": "Shopgate Connect Google Analytics native tracker extension.",
"main": "frontend/index.js",
"repository": "shopgate/tracking-ga-native",
Expand All @@ -23,12 +23,12 @@
}
},
"dependencies": {
"@shopgate/tracking-core": "6.3.1"
"@shopgate/tracking-core": "6.3.2"
},
"devDependencies": {
"@shopgate/eslint-config": "6.3.1",
"@shopgate/pwa-common": "6.3.1",
"@shopgate/pwa-core": "6.3.1",
"@shopgate/eslint-config": "6.3.2",
"@shopgate/pwa-common": "6.3.2",
"@shopgate/pwa-core": "6.3.2",
"babel-core": "^6.26.3",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
Expand Down
2 changes: 1 addition & 1 deletion extensions/@shopgate-user-privacy/extension-config.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "6.3.1",
"version": "6.3.2",
"id": "@shopgate/user-privacy",
"configuration": {
"isActive": {
Expand Down
12 changes: 6 additions & 6 deletions extensions/@shopgate-user-privacy/frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shopgate/user-privacy",
"version": "6.3.1",
"version": "6.3.2",
"description": "Shopgate Connect User Privacy Extension",
"license": "Apache 2.0",
"repository": {
Expand All @@ -11,11 +11,11 @@
"lint": "eslint --ignore-path ../.gitignore --ext .js --ext .jsx ."
},
"devDependencies": {
"@shopgate/eslint-config": "6.3.1",
"@shopgate/pwa-common": "6.3.1",
"@shopgate/pwa-common-commerce": "6.3.1",
"@shopgate/pwa-core": "6.3.1",
"@shopgate/pwa-ui-shared": "6.3.1",
"@shopgate/eslint-config": "6.3.2",
"@shopgate/pwa-common": "6.3.2",
"@shopgate/pwa-common-commerce": "6.3.2",
"@shopgate/pwa-core": "6.3.2",
"@shopgate/pwa-ui-shared": "6.3.2",
"eslint": "^4.17.0",
"prop-types": "^15.6.0",
"react": "~16.8.4",
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"lerna": "2.9.0",
"version": "6.3.1",
"version": "6.3.2",
"packages": [
"extensions/@shopgate-product-reviews/frontend",
"extensions/@shopgate-tracking-ga-native/frontend",
Expand Down
1 change: 1 addition & 0 deletions libraries/commerce/cart/constants/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const CART_PATH = '/cart';
export const DEEPLINK_CART_ADD_PRODUCT_PATTERN = '/cart_add_product/:productId/:couponId';
export const DEEPLINK_CART_ADD_COUPON_PATTERN = '/cart_add_coupon/:couponId';

export const CART_ITEM_TYPE_COUPON = 'coupon';
Expand Down
17 changes: 16 additions & 1 deletion libraries/commerce/cart/selectors/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,26 @@ export const getGrandTotal = createSelector(
* Selects the shipping costs.
* @returns {Object|null}
*/
export const getShippingCosts = createSelector(
export const getShippingCost = createSelector(
getTotals,
totals => totals.find(total => total.type === CART_TOTALS_TYPE_SHIPPING) || null
);

/**
* Selects the summed up shipping costs of the cart.
* @returns {number}
*/
export const getShippingCosts = createSelector(
getShippingCost,
(shippingCost) => {
if (!shippingCost) {
return null;
}
const { amount = 0 } = shippingCost;
return amount;
}
);

/**
* Selects the tax value of the cart.
* @returns {Object}
Expand Down
24 changes: 24 additions & 0 deletions libraries/commerce/cart/streams/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
routeDidEnter$,
routeWillLeave$,
routeDidLeave$,
navigate$,
} from '@shopgate/pwa-common/streams/router';
import { getCurrentPathname } from '@shopgate/pwa-common/selectors/router';
import {
Expand Down Expand Up @@ -33,6 +34,8 @@ import {
DELETE_COUPONS_FROM_CART,
ERROR_DELETE_COUPONS_FROM_CART,
SUCCESS_DELETE_COUPONS_FROM_CART,

DEEPLINK_CART_ADD_PRODUCT_PATTERN,
} from '../constants';

/**
Expand Down Expand Up @@ -183,3 +186,24 @@ export const cartUpdateFailed$ = main$.filter(({ action }) => (
action.type === ERROR_ADD_COUPONS_TO_CART ||
action.type === ERROR_DELETE_COUPONS_FROM_CART
));

/**
* Gets triggered when /cart_add_product/123/COUPON route is navigated
* @type {Observable}
*/
export const routeAddProductNavigate$ = navigate$
.filter(({ action: { params: { pathname = '' } = {} } }) => (
pathname.includes(DEEPLINK_CART_ADD_PRODUCT_PATTERN.split('/')[1])
))
.map((params) => {
const [, , productId, couponCode] = params.action.params.pathname.split('/');
return {
...params,
action: {
...params.action,
productId: decodeURIComponent(productId),
couponCode: decodeURIComponent(couponCode),
},
};
});

32 changes: 30 additions & 2 deletions libraries/commerce/cart/streams/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { createMockStore } from '@shopgate/pwa-common/store';
import { ACTION_PUSH, ACTION_POP, ACTION_REPLACE } from '@virtuous/conductor';
import { CART_PATH } from '@shopgate/pwa-common-commerce/cart/constants';
import { routeWillEnter } from '@shopgate/pwa-common/action-creators/router';
import { routeWillEnter, navigate } from '@shopgate/pwa-common/action-creators/router';
import receiveCart from '@shopgate/pwa-common-commerce/cart/action-creators/receiveCart';
import { getCurrentPathname } from '@shopgate/pwa-common/selectors/router';
import { routeWithCouponWillEnter$, cartUpdatedWhileVisible$ } from './index';
import {
routeWithCouponWillEnter$,
cartUpdatedWhileVisible$,
routeAddProductNavigate$,
} from './index';

jest.mock('@shopgate/pwa-common/selectors/router', () => ({ getCurrentPathname: jest.fn() }));

Expand Down Expand Up @@ -85,4 +89,28 @@ describe('Cart streams', () => {
expect(subscriber).toHaveBeenCalled();
});
});

describe('routeAddProductNavigate$', () => {
let subscriber;
beforeEach(() => {
subscriber = jest.fn();
routeAddProductNavigate$.subscribe(subscriber);
});

it('should not emit when navigate does not map pattern', () => {
dispatch(navigate({ pathname: '/some_path' }));
expect(subscriber).not.toHaveBeenCalled();
});

it('should emit and map event correctly', () => {
dispatch(navigate({ pathname: '/cart_add_product/345%2F34%23/TEST-CODE' }));
expect(subscriber).toHaveBeenCalledTimes(1);
expect(subscriber).toHaveBeenCalledWith(expect.objectContaining({
action: expect.objectContaining({
productId: '345/34#',
couponCode: 'TEST-CODE',
}),
}));
});
});
});
70 changes: 68 additions & 2 deletions libraries/commerce/cart/subscriptions/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/observable/of';
import { Observable } from 'rxjs/Observable';
import event from '@shopgate/pwa-core/classes/Event';
import pipelineDependencies from '@shopgate/pwa-core/classes/PipelineDependencies';
import { redirects } from '@shopgate/pwa-common/collections';
Expand All @@ -8,8 +10,12 @@ import showModal from '@shopgate/pwa-common/actions/modal/showModal';
import fetchRegisterUrl from '@shopgate/pwa-common/actions/user/fetchRegisterUrl';
import { LoadingProvider } from '@shopgate/pwa-common/providers';
import { MODAL_PIPELINE_ERROR } from '@shopgate/pwa-common/constants/ModalTypes';
import { getProductById, getProductRoute, hasProductVariety } from '@shopgate/pwa-common-commerce/product';
import { historyReplace, historyPop } from '@shopgate/pwa-common/actions/router';
import { checkoutSucceeded$ } from '@shopgate/pwa-common-commerce/checkout';
import * as pipelines from '../constants/Pipelines';
import addCouponsToCart from '../actions/addCouponsToCart';
import addProductsToCart from '../actions/addProductsToCart';
import fetchCart from '../actions/fetchCart';
import {
cartDidEnter$,
Expand All @@ -25,10 +31,15 @@ import {
routeWithCouponWillEnter$,
remoteCartDidUpdate$,
cartUpdateFailed$,
routeAddProductNavigate$,
} from '../streams';
import setCartProductPendingCount from '../action-creators/setCartProductPendingCount';
import { CART_PATH, DEEPLINK_CART_ADD_COUPON_PATTERN } from '../constants';
import { checkoutSucceeded$ } from '../../checkout/streams';
import {
CART_PATH,
DEEPLINK_CART_ADD_COUPON_PATTERN,
DEEPLINK_CART_ADD_PRODUCT_PATTERN,
CART_ITEM_TYPE_PRODUCT,
} from '../constants';

/**
* Cart subscriptions.
Expand Down Expand Up @@ -76,6 +87,8 @@ export default function cart(subscribe) {

return null;
});
// This will be handled in 2 deferred subscriptions
redirects.set(DEEPLINK_CART_ADD_PRODUCT_PATTERN, () => null);
});

/**
Expand All @@ -92,9 +105,11 @@ export default function cart(subscribe) {

// Push (deeplink) with coupon concurrent to get cart on app start
pipelineDependencies.set(pipelines.SHOPGATE_CART_ADD_COUPONS, [
pipelines.SHOPGATE_CART_ADD_PRODUCTS,
pipelines.SHOPGATE_CART_GET_CART,
]);
pipelineDependencies.set(pipelines.SHOPGATE_CART_DELETE_COUPONS, [
pipelines.SHOPGATE_CART_ADD_PRODUCTS,
pipelines.SHOPGATE_CART_GET_CART,
]);

Expand Down Expand Up @@ -167,4 +182,55 @@ export default function cart(subscribe) {
dispatch(addCouponsToCart([coupon]));
}
});

/**
* Deeplink to add product to cart, eg /cart_add_product/123
*/
subscribe(routeAddProductNavigate$, ({ dispatch, action, getState }) => {
// NO product or variety
if (!getProductById(getState(), action)
|| hasProductVariety(getState(), action)) {
// Redirect to item page to select options/variant
dispatch(historyReplace({
pathname: getProductRoute(action.productId),
}));
} else {
dispatch(addProductsToCart([{
productId: action.productId,
quantity: 1,
}]));
dispatch(historyPop());
}
});

/**
* Deffer coupon adding to a cart, until we have at least 1 product
*/
const addCouponDeferred$ = routeAddProductNavigate$
// Only if coupon is given
.filter(({ action: { couponCode = '' } }) => !!couponCode)
.withLatestFrom(cartReceived$)
.switchMap(
([navigate, cartReceived]) => {
if (cartReceived.action.cart.cartItems.find(i => i.type === CART_ITEM_TYPE_PRODUCT)) {
// We have items in cart, add coupon immediately
return Observable.of(navigate);
}
// Wait until first product in cart to add a coupon
return cartReceived$.filter(cartReceivedNext => (
cartReceivedNext.action.cart.cartItems.find(i => i.type === CART_ITEM_TYPE_PRODUCT)
)).first();
},
([navigate]) => navigate
);

/**
* Deeplink to add product and coupon to cart, eg /cart_add_product/123/COUPON
*/
subscribe(addCouponDeferred$, async ({ dispatch, action }) => {
const { couponCode } = action;
if (couponCode) {
dispatch(addCouponsToCart([couponCode]));
}
});
}
15 changes: 9 additions & 6 deletions libraries/commerce/cart/subscriptions/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { redirects } from '@shopgate/pwa-common/collections';
import { appWillStart$ } from '@shopgate/pwa-common/streams/app';
import addCouponsToCart from '../actions/addCouponsToCart';
import { DEEPLINK_CART_ADD_COUPON_PATTERN } from '../constants';
import {
DEEPLINK_CART_ADD_COUPON_PATTERN,
DEEPLINK_CART_ADD_PRODUCT_PATTERN,
} from '../constants';
import { routeWithCouponWillEnter$ } from '../streams';
import subscription from './index';

Expand Down Expand Up @@ -34,11 +37,11 @@ describe('Cart subscriptions', () => {
it('should setup a redirect handler for cart_add_coupon deeplinks', () => {
callback();

expect(redirectsSetSpy).toHaveBeenCalledTimes(1);
expect(redirectsSetSpy).toHaveBeenCalledWith(
DEEPLINK_CART_ADD_COUPON_PATTERN,
expect.any(Function)
);
expect(redirectsSetSpy).toHaveBeenCalledTimes(2);
expect(redirectsSetSpy.mock.calls).toEqual([
[DEEPLINK_CART_ADD_COUPON_PATTERN, expect.any(Function)],
[DEEPLINK_CART_ADD_PRODUCT_PATTERN, expect.any(Function)],
]);
});

it('should dispatch the addCouponsToCart action when a cart_add_coupon deeplink was opened', () => {
Expand Down
10 changes: 5 additions & 5 deletions libraries/commerce/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@shopgate/pwa-common-commerce",
"version": "6.3.1",
"version": "6.3.2",
"description": "Commerce library for the Shopgate Connect PWA.",
"license": "Apache-2.0",
"author": "Shopgate <support@shopgate.com>",
Expand All @@ -19,10 +19,10 @@
"reselect": "^3.0.1"
},
"devDependencies": {
"@shopgate/pwa-common": "6.3.1",
"@shopgate/pwa-core": "6.3.1",
"@shopgate/pwa-unit-test": "6.3.1",
"@shopgate/tracking-core": "6.3.1",
"@shopgate/pwa-common": "6.3.2",
"@shopgate/pwa-core": "6.3.2",
"@shopgate/pwa-unit-test": "6.3.2",
"@shopgate/tracking-core": "6.3.2",
"lodash": "^4.17.4",
"react": "~16.8.4",
"react-dom": "~16.8.4"
Expand Down

0 comments on commit 262ec20

Please sign in to comment.