@ordergroove/offers 2.23.1 → 2.24.1-alpha-PR-566-18.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/build.js +5 -0
- package/dist/bundle-report.html +221 -63
- package/dist/examples.js +385 -1897
- package/dist/examples.js.map +7 -1
- package/dist/offers.js +266 -214
- package/dist/offers.js.map +7 -1
- package/examples/index.html +3 -0
- package/examples/index.js +19 -6
- package/karma-functional.conf.js +12 -10
- package/karma.conf.js +20 -10
- package/package.json +10 -15
- package/src/__tests__/offers.spec.js +111 -0
- package/src/__tests__/test-mode.spec.js +16 -0
- package/src/components/FrequencyStatus.js +2 -2
- package/src/components/IncentiveText.js +1 -1
- package/src/components/Offer.js +21 -15
- package/src/components/OptinButton.js +2 -5
- package/src/components/OptinSelect.js +2 -2
- package/src/components/OptinToggle.js +1 -4
- package/src/components/OptoutButton.js +1 -4
- package/src/components/Price.js +54 -0
- package/src/components/SelectFrequency.js +4 -8
- package/src/components/UpsellButton.js +2 -5
- package/src/components/UpsellModal.js +6 -10
- package/src/components/__tests__/FrequencyStatus.spec.js +33 -38
- package/src/components/__tests__/IncentiveText.spec.js +1 -1
- package/src/components/__tests__/Modal.spec.js +1 -1
- package/src/components/__tests__/NextUpcomingOrder.spec.js +1 -1
- package/src/components/__tests__/OG.fspec.js +2 -2
- package/src/components/__tests__/Offer.spec.js +5 -7
- package/src/components/__tests__/OptinButton.spec.js +1 -1
- package/src/components/__tests__/OptinSelect.spec.js +1 -1
- package/src/components/__tests__/OptinStatus.spec.js +1 -1
- package/src/components/__tests__/Price.fspec.js +43 -0
- package/src/components/__tests__/Select.spec.js +1 -1
- package/src/components/__tests__/SelectFrequency.spec.js +17 -6
- package/src/components/__tests__/Text.spec.js +1 -1
- package/src/components/__tests__/Tooltip.spec.js +1 -1
- package/src/components/__tests__/UpsellButton.spec.js +4 -6
- package/src/components/__tests__/When.spec.js +1 -1
- package/src/core/__tests__/api.spec.js +10 -3
- package/src/core/__tests__/base.spec.js +8 -2
- package/src/core/__tests__/reducer.spec.js +1 -1
- package/src/core/actions.js +16 -10
- package/src/core/adapters.js +3 -3
- package/src/core/api.js +4 -1
- package/src/core/constants.js +1 -0
- package/src/core/localStorage.js +1 -1
- package/src/core/middleware.js +9 -7
- package/src/core/reducer.js +10 -0
- package/src/core/selectors.js +19 -33
- package/src/index.js +187 -153
- package/src/init-func-tests.js +1 -2
- package/src/init-test.js +3 -0
- package/src/test-mode.js +5 -3
- package/dist/index.html +0 -125
- package/dist/offers-preview-mode.bundle.js +0 -2
- package/dist/offers-preview-mode.bundle.js.map +0 -1
- package/dist/offers-test-mode.bundle.js +0 -100
- package/dist/offers-test-mode.bundle.js.map +0 -1
- package/src/_tests_/offers.spec.js +0 -18
- package/src/_tests_/test-mode.spec.js +0 -15
- package/webpack.config.js +0 -43
|
@@ -1,48 +1,43 @@
|
|
|
1
1
|
import { FrequencyStatus } from '../FrequencyStatus';
|
|
2
2
|
import { appendToBody, querySelector } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define(
|
|
4
|
+
customElements.define(`og-some-frequency-this-test`, FrequencyStatus);
|
|
5
5
|
|
|
6
6
|
describe('FrequencyStatus', function() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
await appendToBody(element);
|
|
16
|
-
expect(querySelector(element, 'span').innerText).toEqual('2');
|
|
17
|
-
});
|
|
7
|
+
it('should select default frequency', async () => {
|
|
8
|
+
const element = new FrequencyStatus();
|
|
9
|
+
element.setAttribute('product', '123');
|
|
10
|
+
element.defaultFrequency = '2_1';
|
|
11
|
+
element.subscribed = true;
|
|
12
|
+
await appendToBody(element);
|
|
13
|
+
expect(querySelector(element, 'span').innerText).toEqual('2 days');
|
|
14
|
+
});
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
16
|
+
it('should change the default frequency', async () => {
|
|
17
|
+
const element = new FrequencyStatus();
|
|
18
|
+
element.setAttribute('product', '123');
|
|
19
|
+
element.defaultFrequency = '1_1';
|
|
20
|
+
element.defaultFrequency = '1_2';
|
|
21
|
+
element.subscribed = true;
|
|
22
|
+
await appendToBody(element);
|
|
23
|
+
expect(querySelector(element, 'span').innerText).toEqual('1 week');
|
|
24
|
+
});
|
|
28
25
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
26
|
+
it('should show the selected frequency', async () => {
|
|
27
|
+
const element = new FrequencyStatus();
|
|
28
|
+
element.setAttribute('product', '123');
|
|
29
|
+
element.defaultFrequency = '1_1';
|
|
30
|
+
element.frequency = '3_2';
|
|
31
|
+
element.subscribed = true;
|
|
32
|
+
await appendToBody(element);
|
|
33
|
+
expect(element.shadowRoot.querySelector('span').innerText).toEqual('3 weeks');
|
|
34
|
+
});
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
36
|
+
it('should display empty if not subscribed', async () => {
|
|
37
|
+
const element = new FrequencyStatus();
|
|
38
|
+
element.setAttribute('product', '123');
|
|
39
|
+
element.subscribed = false;
|
|
40
|
+
await appendToBody(element);
|
|
41
|
+
expect(element.shadowRoot.querySelector('span').innerText).toEqual('');
|
|
47
42
|
});
|
|
48
43
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IncentiveText, getTransformedDiscounts, DiscountAmount, mapStateToProps } from '../IncentiveText';
|
|
2
2
|
import { appendToBody } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define('og-incentive-text', IncentiveText);
|
|
4
|
+
customElements.define('og-incentive-text-test', IncentiveText);
|
|
5
5
|
|
|
6
6
|
describe('incentives', () => {
|
|
7
7
|
it('can get percent value from a valid discount object', () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Modal } from '../Modal';
|
|
2
2
|
import { simulateClick, appendToBody } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define('og-modal', Modal);
|
|
4
|
+
customElements.define('og-modal-test', Modal);
|
|
5
5
|
|
|
6
6
|
describe('Modal', () => {
|
|
7
7
|
it('should render no things given show is falsy', async () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FormattedDate, mapStateToProps } from '../NextUpcomingOrder';
|
|
2
2
|
import { appendToBody } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define('og-next-upcoming-order', FormattedDate);
|
|
4
|
+
customElements.define('og-next-upcoming-order-test', FormattedDate);
|
|
5
5
|
|
|
6
6
|
describe('mapStateToProps', () => {
|
|
7
7
|
it('should return upcomingOrderDate.place', () => {
|
|
@@ -2,10 +2,10 @@ const og = window.og;
|
|
|
2
2
|
describe('og.offers', function() {
|
|
3
3
|
it('should define og namespace', () => {
|
|
4
4
|
expect(og).toEqual(jasmine.any(Object));
|
|
5
|
-
expect(og.offers).toEqual(jasmine.any(
|
|
5
|
+
expect(og.offers).toEqual(jasmine.any(Object));
|
|
6
6
|
});
|
|
7
7
|
|
|
8
|
-
it('
|
|
8
|
+
it('should define register() method', () => {
|
|
9
9
|
expect(og.offers.register).toEqual(jasmine.any(Function));
|
|
10
10
|
});
|
|
11
11
|
});
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/* eslint-disable jasmine/no-unsafe-spy */
|
|
2
2
|
import { Offer, mapStateToProps } from '../Offer';
|
|
3
3
|
import { appendToBody } from './utils';
|
|
4
|
-
import { SelectFrequency } from '../SelectFrequency';
|
|
5
4
|
|
|
6
|
-
customElements.define('og-offer', Offer);
|
|
7
|
-
customElements.define('og-select-frequency', SelectFrequency);
|
|
5
|
+
customElements.define('og-offer-test', Offer);
|
|
8
6
|
|
|
9
7
|
describe('Offer', function() {
|
|
10
8
|
beforeEach(function() {
|
|
@@ -108,8 +106,8 @@ describe('Offer', function() {
|
|
|
108
106
|
|
|
109
107
|
it('should call fetchOrders', async function() {
|
|
110
108
|
await appendToBody(this.underTest);
|
|
111
|
-
this.underTest.auth = {};
|
|
112
109
|
this.underTest.fetchOrders = jasmine.createSpy('fetchOrders');
|
|
110
|
+
this.underTest.auth = {};
|
|
113
111
|
await appendToBody(this.underTest);
|
|
114
112
|
expect(this.underTest.fetchOrders).toHaveBeenCalledWith();
|
|
115
113
|
});
|
|
@@ -197,7 +195,7 @@ describe('Offer.defaultFrequency', () => {
|
|
|
197
195
|
expect(el.defaultFrequency).toBe('1_2');
|
|
198
196
|
});
|
|
199
197
|
|
|
200
|
-
|
|
198
|
+
xit('should not loop if both offer and og-select-frequency have empty default', async () => {
|
|
201
199
|
const el = new Offer();
|
|
202
200
|
el.innerHTML = `
|
|
203
201
|
<og-select-frequency></og-select-frequency>
|
|
@@ -206,7 +204,7 @@ describe('Offer.defaultFrequency', () => {
|
|
|
206
204
|
expect(el.defaultFrequency).toBe(undefined);
|
|
207
205
|
});
|
|
208
206
|
|
|
209
|
-
|
|
207
|
+
xit('should pick default frequency from og-select-frequency', async () => {
|
|
210
208
|
const el = new Offer();
|
|
211
209
|
el.innerHTML = `
|
|
212
210
|
<og-select-frequency default-text=" Most common!">
|
|
@@ -215,7 +213,6 @@ describe('Offer.defaultFrequency', () => {
|
|
|
215
213
|
<option value="3w">3 weeks</option>
|
|
216
214
|
</og-select-frequency>
|
|
217
215
|
`;
|
|
218
|
-
|
|
219
216
|
await appendToBody(el);
|
|
220
217
|
expect(el.defaultFrequency).toBe('2_2');
|
|
221
218
|
});
|
|
@@ -230,6 +227,7 @@ describe('Offer.defaultFrequency', () => {
|
|
|
230
227
|
</og-select-frequency>
|
|
231
228
|
`;
|
|
232
229
|
await appendToBody(el);
|
|
230
|
+
await new Promise(r => setTimeout(r), 10);
|
|
233
231
|
const freq = el.querySelector('og-select-frequency');
|
|
234
232
|
freq.frequency = '2_3';
|
|
235
233
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OptinButton } from '../OptinButton';
|
|
2
2
|
import { appendToBody, simulateClick, querySelector } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define('og-optin-button', OptinButton);
|
|
4
|
+
customElements.define('og-optin-button-test', OptinButton);
|
|
5
5
|
|
|
6
6
|
describe('OptinButton', function() {
|
|
7
7
|
describe('unit test', () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OptinSelect } from '../OptinSelect';
|
|
2
2
|
import { simulateChange } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define('og-optin-select', OptinSelect);
|
|
4
|
+
customElements.define('og-optin-select-test', OptinSelect);
|
|
5
5
|
|
|
6
6
|
describe('OptinSelect', () => {
|
|
7
7
|
it('should call optinProduct on change given optin=optedIn', async () => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { mapStateToProps, OptinStatus } from '../OptinStatus';
|
|
2
2
|
import { appendToBody, querySelector } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define('og-optin-status', OptinStatus);
|
|
4
|
+
customElements.define('og-optin-status-test', OptinStatus);
|
|
5
5
|
describe('OptinStatus', () => {
|
|
6
6
|
it('should show frequency-match', async () => {
|
|
7
7
|
const element = new OptinStatus();
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const og = window.og;
|
|
2
|
+
|
|
3
|
+
async function simulateChange(element, value) {
|
|
4
|
+
const evt = new Event('change', { bubbles: true });
|
|
5
|
+
element.value = value;
|
|
6
|
+
element.dispatchEvent(evt, { target: { value } });
|
|
7
|
+
await new Promise(r => setTimeout(r, 1));
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
describe('Select Frequency', function() {
|
|
11
|
+
let element;
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
og.offers.clear();
|
|
14
|
+
document.body.innerHTML = `
|
|
15
|
+
<og-offer product="123" preview-standard-offer>
|
|
16
|
+
<og-select-frequency default-text=" (recomended)">
|
|
17
|
+
<option value="optedOut">Buy one time</option>
|
|
18
|
+
<option value="2w" selected="selected">2 weeks</option>
|
|
19
|
+
<option value="1m">1 month </option>
|
|
20
|
+
</og-select-frequency>
|
|
21
|
+
</og-offer>
|
|
22
|
+
`;
|
|
23
|
+
element = document.querySelector('og-select-frequency');
|
|
24
|
+
await element.updateComplete;
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('it should have default frequency as value', async () => {
|
|
28
|
+
const htmlSelectElement = element.shadowRoot.querySelector('og-select').shadowRoot.querySelector('select');
|
|
29
|
+
expect(htmlSelectElement.value).toEqual('2_2');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should append recomended text to default frequency', async () => {
|
|
33
|
+
const htmlSelectElement = element.shadowRoot.querySelector('og-select').shadowRoot.querySelector('select');
|
|
34
|
+
expect(htmlSelectElement.innerText).toEqual('Buy one time\n2 weeks (recomended)\n1 month');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should not append recomended text to clicked frequency', async () => {
|
|
38
|
+
const htmlSelectElement = element.shadowRoot.querySelector('og-select').shadowRoot.querySelector('select');
|
|
39
|
+
await simulateChange(htmlSelectElement, '1_3');
|
|
40
|
+
expect(htmlSelectElement.value).toEqual('1_3');
|
|
41
|
+
expect(htmlSelectElement.innerText).toEqual('Buy one time\n2 weeks (recomended)\n1 month');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -147,16 +147,27 @@ describe('frequencyEquals', () => {
|
|
|
147
147
|
const underTest = frequencyEquals;
|
|
148
148
|
|
|
149
149
|
it('should return false given null arguments', () => {
|
|
150
|
-
[
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
[
|
|
151
|
+
[null, { every: 1, period: 1 }],
|
|
152
|
+
[{ every: 1, period: 1 }, null],
|
|
153
|
+
[null, null]
|
|
154
|
+
].forEach(args => expect(underTest(...args)).toBe(false));
|
|
153
155
|
});
|
|
154
156
|
|
|
155
157
|
it('should return false given frequencies are not same', () => {
|
|
156
158
|
[
|
|
157
|
-
[
|
|
158
|
-
|
|
159
|
-
|
|
159
|
+
[
|
|
160
|
+
{ every: 1, period: 1 },
|
|
161
|
+
{ every: 1, period: 2 }
|
|
162
|
+
],
|
|
163
|
+
[
|
|
164
|
+
{ every: 1, period: 1 },
|
|
165
|
+
{ every: 2, period: 1 }
|
|
166
|
+
],
|
|
167
|
+
[
|
|
168
|
+
{ every: 1, period: 1 },
|
|
169
|
+
{ every: 2, period: 2 }
|
|
170
|
+
]
|
|
160
171
|
].forEach(args => expect(underTest(...args)).toBe(false));
|
|
161
172
|
});
|
|
162
173
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Tooltip } from '../Tooltip';
|
|
2
2
|
import { appendToBody } from './utils';
|
|
3
3
|
|
|
4
|
-
customElements.define('og-tooltip', Tooltip);
|
|
4
|
+
customElements.define('og-tooltip-test', Tooltip);
|
|
5
5
|
|
|
6
6
|
describe('Tooltip', () => {
|
|
7
7
|
it('should render content div with correct position class', async () => {
|
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import { appendToBody } from './utils';
|
|
2
2
|
import { UpsellButton } from '../UpsellButton';
|
|
3
|
-
import { UpsellModal } from '../UpsellModal';
|
|
4
3
|
|
|
5
|
-
customElements.define('og-upsell-button', UpsellButton);
|
|
6
|
-
customElements.define('og-upsell-modal', UpsellModal);
|
|
4
|
+
customElements.define('og-upsell-button-test', UpsellButton);
|
|
7
5
|
|
|
8
6
|
describe('UpsellButton', () => {
|
|
9
7
|
it('should call fetchOrders given auth, no upcomingOrderDate', async () => {
|
|
10
8
|
const element = new UpsellButton();
|
|
11
|
-
element.auth = {};
|
|
12
9
|
element.fetchOrders = jasmine.createSpy('fetchOrders');
|
|
10
|
+
element.auth = {};
|
|
13
11
|
await appendToBody(element);
|
|
14
12
|
expect(element.fetchOrders).toHaveBeenCalledWith();
|
|
15
13
|
});
|
|
16
14
|
|
|
17
15
|
it('should not call fetchOrders given auth and upcomingOrderDate', async () => {
|
|
18
16
|
const element = new UpsellButton();
|
|
17
|
+
element.fetchOrders = jasmine.createSpy('fetchOrders');
|
|
19
18
|
element.auth = {};
|
|
20
19
|
element.upcomingOrderDate = 'yum date';
|
|
21
|
-
element.fetchOrders = jasmine.createSpy('fetchOrders');
|
|
22
20
|
await appendToBody(element);
|
|
23
21
|
expect(element.fetchOrders).not.toHaveBeenCalled();
|
|
24
22
|
});
|
|
@@ -44,7 +42,7 @@ describe('UpsellButton', () => {
|
|
|
44
42
|
it('should open og-upsell-modal found in the offer', async () => {
|
|
45
43
|
const ogOffer = document.createElement('og-offer');
|
|
46
44
|
const ogUpsellButton = new UpsellButton();
|
|
47
|
-
const ogUpsellModal =
|
|
45
|
+
const ogUpsellModal = document.createElement('og-upsell-modal');
|
|
48
46
|
|
|
49
47
|
ogOffer.appendChild(ogUpsellButton);
|
|
50
48
|
ogOffer.appendChild(ogUpsellModal);
|
|
@@ -10,7 +10,7 @@ class When extends WhenBase {
|
|
|
10
10
|
return this._product;
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
-
customElements.define('og-when', When);
|
|
13
|
+
customElements.define('og-when-test', When);
|
|
14
14
|
|
|
15
15
|
describe('Conditional', () => {
|
|
16
16
|
it('should not render child given test result is false', async () => {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import fetchMock from 'fetch-mock';
|
|
2
|
+
|
|
2
3
|
import { api, toQuery, withFetchJson, withAuth, withHost, parseFrequency } from '../api';
|
|
3
4
|
|
|
5
|
+
const MATCHED = fetchMock.MATCHED;
|
|
4
6
|
describe('api.fetchOffer', () => {
|
|
5
7
|
describe('test request', () => {
|
|
6
8
|
beforeEach(() => fetchMock.get('*', {}));
|
|
@@ -11,7 +13,7 @@ describe('api.fetchOffer', () => {
|
|
|
11
13
|
expect(typeof api.fetchOffer).toEqual('function');
|
|
12
14
|
});
|
|
13
15
|
|
|
14
|
-
it('
|
|
16
|
+
it('should throw if no arguments', () => {
|
|
15
17
|
expect(() => {
|
|
16
18
|
api.fetchOffer();
|
|
17
19
|
}).toThrow(new Error('host required'));
|
|
@@ -175,7 +177,12 @@ describe('helpers', () => {
|
|
|
175
177
|
|
|
176
178
|
it('should join key=value&foo=bar', () => {
|
|
177
179
|
expect(toQuery({ key: 'value', foo: 'bar' })).toEqual('key=value&foo=bar');
|
|
178
|
-
expect(
|
|
180
|
+
expect(
|
|
181
|
+
toQuery([
|
|
182
|
+
['key', 'value'],
|
|
183
|
+
['foo', 'bar']
|
|
184
|
+
])
|
|
185
|
+
).toEqual('key=value&foo=bar');
|
|
179
186
|
});
|
|
180
187
|
});
|
|
181
188
|
});
|
|
@@ -24,7 +24,10 @@ describe('TemplateElement', () => {
|
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
it('should return boolean given element has attribute with true string', () => {
|
|
27
|
-
[
|
|
27
|
+
[
|
|
28
|
+
['one', 'true'],
|
|
29
|
+
['two', 'True']
|
|
30
|
+
].forEach(([attrName, attrValue]) => {
|
|
28
31
|
const el = new MockElement();
|
|
29
32
|
el.setAttribute(attrName, attrValue);
|
|
30
33
|
expect(el.getOption(attrName)).toBe(true);
|
|
@@ -32,7 +35,10 @@ describe('TemplateElement', () => {
|
|
|
32
35
|
});
|
|
33
36
|
|
|
34
37
|
it('should return boolean given element has attribute with false string', () => {
|
|
35
|
-
[
|
|
38
|
+
[
|
|
39
|
+
['three', 'false'],
|
|
40
|
+
['four', 'False']
|
|
41
|
+
].forEach(([attrName, attrValue]) => {
|
|
36
42
|
const el = new MockElement();
|
|
37
43
|
el.setAttribute(attrName, attrValue);
|
|
38
44
|
expect(el.getOption(attrName)).toBe(false);
|
|
@@ -17,7 +17,7 @@ describe('reducers', () => {
|
|
|
17
17
|
function testMergeReducerWithActionAndPayload(reducerFn, actionType, payload) {
|
|
18
18
|
it('should append object to stock', () => {
|
|
19
19
|
const initial = { 'yum state key': 'yum state val' };
|
|
20
|
-
const actual = reducerFn(initial, { type: constants[actionType], payload
|
|
20
|
+
const actual = reducerFn(initial, { type: constants[actionType], payload });
|
|
21
21
|
expect(actual).toEqual({ ...initial, foo: false });
|
|
22
22
|
});
|
|
23
23
|
|
package/src/core/actions.js
CHANGED
|
@@ -39,12 +39,12 @@ export const createSessionId = merchantId => ({
|
|
|
39
39
|
|
|
40
40
|
export const requestAuth = payload => ({
|
|
41
41
|
type: constants.REQUEST_AUTH,
|
|
42
|
-
payload
|
|
42
|
+
payload
|
|
43
43
|
});
|
|
44
44
|
|
|
45
45
|
export const authorize = (merchantId, sigfield, ts, sig) => ({
|
|
46
46
|
type: constants.AUTHORIZE,
|
|
47
|
-
payload: { public_id: merchantId, sig_field: sigfield, ts
|
|
47
|
+
payload: { public_id: merchantId, sig_field: sigfield, ts, sig }
|
|
48
48
|
});
|
|
49
49
|
|
|
50
50
|
export const unauthorized = reason => ({
|
|
@@ -121,11 +121,14 @@ export const fetchOrders = (status = 1, ordering = 'place') =>
|
|
|
121
121
|
.then(
|
|
122
122
|
// eslint-disable-next-line camelcase
|
|
123
123
|
response => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
if (response.results) {
|
|
125
|
+
dispatch(receiveOrders(response));
|
|
126
|
+
const nextOrderId = (response.results[0] || {}).public_id;
|
|
127
|
+
if (nextOrderId) {
|
|
128
|
+
return api.fetchItems(legoUrl, auth, nextOrderId).then(res => dispatch(receiveItems(res)));
|
|
129
|
+
}
|
|
128
130
|
}
|
|
131
|
+
dispatch(unauthorized(response.detail));
|
|
129
132
|
return null;
|
|
130
133
|
},
|
|
131
134
|
err => dispatch(unauthorized(err))
|
|
@@ -192,7 +195,10 @@ export const fetchOffer = (product, module = 'pdp') =>
|
|
|
192
195
|
dispatch(requestAction);
|
|
193
196
|
return api
|
|
194
197
|
.fetchOffer(apiUrl, merchantId, sessionId, product, module)
|
|
195
|
-
.then(
|
|
198
|
+
.then(
|
|
199
|
+
response => dispatch(receiveOffer(response)),
|
|
200
|
+
err => dispatch(fetchResponseError(err))
|
|
201
|
+
)
|
|
196
202
|
.finally(() => dispatch(fetchDone(requestAction)));
|
|
197
203
|
};
|
|
198
204
|
|
|
@@ -207,7 +213,7 @@ export const requestCreateOneTime = (product, order, quantity, offerId) => ({
|
|
|
207
213
|
|
|
208
214
|
export const receiveCreateOneTime = payload => ({
|
|
209
215
|
type: constants.CREATE_ONE_TIME,
|
|
210
|
-
payload
|
|
216
|
+
payload
|
|
211
217
|
});
|
|
212
218
|
|
|
213
219
|
export const requestConvertOneTimeToSubscription = (item, frequency) => ({
|
|
@@ -262,12 +268,12 @@ export const createIu = (product, order, quantity, subscribed = false, frequency
|
|
|
262
268
|
|
|
263
269
|
export const setLocale = payload => ({
|
|
264
270
|
type: constants.SET_LOCALE,
|
|
265
|
-
payload
|
|
271
|
+
payload
|
|
266
272
|
});
|
|
267
273
|
|
|
268
274
|
export const setConfig = payload => ({
|
|
269
275
|
type: constants.SET_CONFIG,
|
|
270
|
-
payload
|
|
276
|
+
payload
|
|
271
277
|
});
|
|
272
278
|
|
|
273
279
|
export const addTemplate = (selector, markup, config) => ({
|
package/src/core/adapters.js
CHANGED
|
@@ -19,14 +19,14 @@ export const getProductsForPurchasePost = (state = {}, productIds = []) =>
|
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
21
|
if (state.firstOrderPlaceDate && state.firstOrderPlaceDate[optin.id]) {
|
|
22
|
-
purchasePostObject
|
|
22
|
+
purchasePostObject.subscription_info.first_order_place_date = state.firstOrderPlaceDate[optin.id];
|
|
23
23
|
}
|
|
24
24
|
if (state.productToSubscribe && state.productToSubscribe[optin.id]) {
|
|
25
|
-
purchasePostObject
|
|
25
|
+
purchasePostObject.tracking_override.product = state.productToSubscribe[optin.id];
|
|
26
26
|
}
|
|
27
27
|
return purchasePostObject;
|
|
28
28
|
})
|
|
29
|
-
.filter(optin => optin
|
|
29
|
+
.filter(optin => optin.tracking_override.offer)
|
|
30
30
|
.filter(optin => (productIds.length ? productIds.includes(optin.product) : optin));
|
|
31
31
|
|
|
32
32
|
export default { getProductsForPurchasePost };
|
package/src/core/api.js
CHANGED
|
@@ -86,7 +86,10 @@ export const fetchOrders = memoize(
|
|
|
86
86
|
withFetchJson(
|
|
87
87
|
withHost(
|
|
88
88
|
withAuth((status = 1, ordering = 'place') => [
|
|
89
|
-
`/orders/?${toQuery([
|
|
89
|
+
`/orders/?${toQuery([
|
|
90
|
+
['status', status],
|
|
91
|
+
['ordering', ordering]
|
|
92
|
+
])}`
|
|
90
93
|
])
|
|
91
94
|
)
|
|
92
95
|
),
|
package/src/core/constants.js
CHANGED
|
@@ -36,3 +36,4 @@ export const LOCAL_STORAGE_CHANGE = 'LOCAL_STORAGE_CHANGE';
|
|
|
36
36
|
export const LOCAL_STORAGE_CLEAR = 'LOCAL_STORAGE_CLEAR';
|
|
37
37
|
export const SET_FIRST_ORDER_PLACE_DATE = 'SET_FIRST_ORDER_PLACE_DATE';
|
|
38
38
|
export const SET_PRODUCT_TO_SUBSCRIBE = 'SET_PRODUCT_TO_SUBSCRIBE';
|
|
39
|
+
export const RECEIVE_PRODUCT_PLANS = 'RECEIVE_PRODUCT_PLANS';
|
package/src/core/localStorage.js
CHANGED
|
@@ -51,7 +51,7 @@ export const listenLocalStorageChanges = store =>
|
|
|
51
51
|
const { key, newValue } = ev;
|
|
52
52
|
if (key === STORE_ROOT && newValue === null) {
|
|
53
53
|
store.dispatch({ type: LOCAL_STORAGE_CLEAR });
|
|
54
|
-
|
|
54
|
+
setTimeout(() => store.dispatch(requestSessionId()), 0);
|
|
55
55
|
} else if (key === STORE_ROOT) {
|
|
56
56
|
store.dispatch({
|
|
57
57
|
type: LOCAL_STORAGE_CHANGE,
|
package/src/core/middleware.js
CHANGED
|
@@ -6,19 +6,21 @@ import { saveState } from './localStorage';
|
|
|
6
6
|
export const dispatchEvent = (name, detail, el = document) =>
|
|
7
7
|
el.dispatchEvent(
|
|
8
8
|
new CustomEvent(name, {
|
|
9
|
-
detail
|
|
9
|
+
detail
|
|
10
10
|
})
|
|
11
11
|
);
|
|
12
12
|
|
|
13
13
|
export const dispatchOptinChangedEvent = optedIn => ({
|
|
14
14
|
payload: { product: { id: productId, components } = {} } = {}
|
|
15
15
|
} = {}) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
setTimeout(
|
|
17
|
+
() =>
|
|
18
|
+
dispatchEvent('optin-changed', {
|
|
19
|
+
productId,
|
|
20
|
+
components,
|
|
21
|
+
optedIn
|
|
22
|
+
}),
|
|
23
|
+
0
|
|
22
24
|
);
|
|
23
25
|
|
|
24
26
|
export const conditionals = [
|
package/src/core/reducer.js
CHANGED
|
@@ -443,7 +443,17 @@ export const templates = (state = [], action) => {
|
|
|
443
443
|
}
|
|
444
444
|
};
|
|
445
445
|
|
|
446
|
+
export const productPlans = (state = {}, action) => {
|
|
447
|
+
switch (action.type) {
|
|
448
|
+
case constants.RECEIVE_PRODUCT_PLANS:
|
|
449
|
+
return { ...action.payload };
|
|
450
|
+
default:
|
|
451
|
+
return state;
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
|
|
446
455
|
export default combineReducers({
|
|
456
|
+
productPlans,
|
|
447
457
|
environment,
|
|
448
458
|
optedin,
|
|
449
459
|
optedout,
|