@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.
Files changed (64) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/build.js +5 -0
  3. package/dist/bundle-report.html +221 -63
  4. package/dist/examples.js +385 -1897
  5. package/dist/examples.js.map +7 -1
  6. package/dist/offers.js +266 -214
  7. package/dist/offers.js.map +7 -1
  8. package/examples/index.html +3 -0
  9. package/examples/index.js +19 -6
  10. package/karma-functional.conf.js +12 -10
  11. package/karma.conf.js +20 -10
  12. package/package.json +10 -15
  13. package/src/__tests__/offers.spec.js +111 -0
  14. package/src/__tests__/test-mode.spec.js +16 -0
  15. package/src/components/FrequencyStatus.js +2 -2
  16. package/src/components/IncentiveText.js +1 -1
  17. package/src/components/Offer.js +21 -15
  18. package/src/components/OptinButton.js +2 -5
  19. package/src/components/OptinSelect.js +2 -2
  20. package/src/components/OptinToggle.js +1 -4
  21. package/src/components/OptoutButton.js +1 -4
  22. package/src/components/Price.js +54 -0
  23. package/src/components/SelectFrequency.js +4 -8
  24. package/src/components/UpsellButton.js +2 -5
  25. package/src/components/UpsellModal.js +6 -10
  26. package/src/components/__tests__/FrequencyStatus.spec.js +33 -38
  27. package/src/components/__tests__/IncentiveText.spec.js +1 -1
  28. package/src/components/__tests__/Modal.spec.js +1 -1
  29. package/src/components/__tests__/NextUpcomingOrder.spec.js +1 -1
  30. package/src/components/__tests__/OG.fspec.js +2 -2
  31. package/src/components/__tests__/Offer.spec.js +5 -7
  32. package/src/components/__tests__/OptinButton.spec.js +1 -1
  33. package/src/components/__tests__/OptinSelect.spec.js +1 -1
  34. package/src/components/__tests__/OptinStatus.spec.js +1 -1
  35. package/src/components/__tests__/Price.fspec.js +43 -0
  36. package/src/components/__tests__/Select.spec.js +1 -1
  37. package/src/components/__tests__/SelectFrequency.spec.js +17 -6
  38. package/src/components/__tests__/Text.spec.js +1 -1
  39. package/src/components/__tests__/Tooltip.spec.js +1 -1
  40. package/src/components/__tests__/UpsellButton.spec.js +4 -6
  41. package/src/components/__tests__/When.spec.js +1 -1
  42. package/src/core/__tests__/api.spec.js +10 -3
  43. package/src/core/__tests__/base.spec.js +8 -2
  44. package/src/core/__tests__/reducer.spec.js +1 -1
  45. package/src/core/actions.js +16 -10
  46. package/src/core/adapters.js +3 -3
  47. package/src/core/api.js +4 -1
  48. package/src/core/constants.js +1 -0
  49. package/src/core/localStorage.js +1 -1
  50. package/src/core/middleware.js +9 -7
  51. package/src/core/reducer.js +10 -0
  52. package/src/core/selectors.js +19 -33
  53. package/src/index.js +187 -153
  54. package/src/init-func-tests.js +1 -2
  55. package/src/init-test.js +3 -0
  56. package/src/test-mode.js +5 -3
  57. package/dist/index.html +0 -125
  58. package/dist/offers-preview-mode.bundle.js +0 -2
  59. package/dist/offers-preview-mode.bundle.js.map +0 -1
  60. package/dist/offers-test-mode.bundle.js +0 -100
  61. package/dist/offers-test-mode.bundle.js.map +0 -1
  62. package/src/_tests_/offers.spec.js +0 -18
  63. package/src/_tests_/test-mode.spec.js +0 -15
  64. 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('og-some-frequency-status', FrequencyStatus);
4
+ customElements.define(`og-some-frequency-this-test`, FrequencyStatus);
5
5
 
6
6
  describe('FrequencyStatus', function() {
7
- describe('unit test', () => {
8
- beforeEach(() => {});
9
-
10
- it('should select default frequency', async () => {
11
- const element = new FrequencyStatus();
12
- element.setAttribute('product', '123');
13
- element.defaultFrequency = '2_1';
14
- element.subscribed = true;
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
- it('should change the default frequency', async () => {
20
- const element = new FrequencyStatus();
21
- element.setAttribute('product', '123');
22
- element.defaultFrequency = '1_1';
23
- element.defaultFrequency = '1_2';
24
- element.subscribed = true;
25
- await appendToBody(element);
26
- expect(element.shadowRoot.querySelector('span').innerText).toEqual('1');
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
- it('should show the selected frequency', async () => {
30
- const element = new FrequencyStatus();
31
- element.setAttribute('product', '123');
32
- element.defaultFrequency = '1_1';
33
- element.frequency = '3_2';
34
- element.subscribed = true;
35
- await appendToBody(element);
36
- expect(element.shadowRoot.querySelector('span').innerText).toEqual('3');
37
- expect(querySelector(element, '[key="frequencyPeriods"][variant="2"][pluralize="3"]')).toBeTruthy();
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
- it('should display empty if not subscribed', async () => {
41
- const element = new FrequencyStatus();
42
- element.setAttribute('product', '123');
43
- element.subscribed = false;
44
- await appendToBody(element);
45
- expect(element.shadowRoot.querySelector('span').innerText).toEqual('');
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(Function));
5
+ expect(og.offers).toEqual(jasmine.any(Object));
6
6
  });
7
7
 
8
- it('shoul define register() method', () => {
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
- it('should not loop if both offer and og-select-frequency have empty default', async () => {
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
- it('should pick default frequency from og-select-frequency', async () => {
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
+ });
@@ -1,7 +1,7 @@
1
1
  import { Select } from '../Select';
2
2
  import { appendToBody } from './utils';
3
3
 
4
- customElements.define('og-select', Select);
4
+ customElements.define('og-select-test', Select);
5
5
 
6
6
  describe('Select', () => {
7
7
  it('should render all options', async () => {
@@ -147,16 +147,27 @@ describe('frequencyEquals', () => {
147
147
  const underTest = frequencyEquals;
148
148
 
149
149
  it('should return false given null arguments', () => {
150
- [[null, { every: 1, period: 1 }], [{ every: 1, period: 1 }, null], [null, null]].forEach(args =>
151
- expect(underTest(...args)).toBe(false)
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
- [{ every: 1, period: 1 }, { every: 1, period: 2 }],
158
- [{ every: 1, period: 1 }, { every: 2, period: 1 }],
159
- [{ every: 1, period: 1 }, { every: 2, period: 2 }]
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 { Text } from '../Text';
2
2
  import { appendToBody } from './utils';
3
3
 
4
- customElements.define('og-text', Text);
4
+ customElements.define('og-text-test', Text);
5
5
 
6
6
  describe('Text', () => {
7
7
  it('should show the i18n text matching the key', async () => {
@@ -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 = new UpsellModal();
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 { MATCHED, fetchMock } from 'fetch-mock';
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('shoud throw if no arguments', () => {
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(toQuery([['key', 'value'], ['foo', 'bar']])).toEqual('key=value&foo=bar');
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
- [['one', 'true'], ['two', 'True']].forEach(([attrName, attrValue]) => {
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
- [['three', 'false'], ['four', 'False']].forEach(([attrName, attrValue]) => {
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: payload });
20
+ const actual = reducerFn(initial, { type: constants[actionType], payload });
21
21
  expect(actual).toEqual({ ...initial, foo: false });
22
22
  });
23
23
 
@@ -39,12 +39,12 @@ export const createSessionId = merchantId => ({
39
39
 
40
40
  export const requestAuth = payload => ({
41
41
  type: constants.REQUEST_AUTH,
42
- payload: 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: ts, sig: sig }
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
- dispatch(receiveOrders(response));
125
- const nextOrderId = (response.results[0] || {}).public_id;
126
- if (nextOrderId) {
127
- return api.fetchItems(legoUrl, auth, nextOrderId).then(res => dispatch(receiveItems(res)));
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(response => dispatch(receiveOffer(response)), err => dispatch(fetchResponseError(err)))
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: 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: payload
271
+ payload
266
272
  });
267
273
 
268
274
  export const setConfig = payload => ({
269
275
  type: constants.SET_CONFIG,
270
- payload: payload
276
+ payload
271
277
  });
272
278
 
273
279
  export const addTemplate = (selector, markup, config) => ({
@@ -19,14 +19,14 @@ export const getProductsForPurchasePost = (state = {}, productIds = []) =>
19
19
  }
20
20
  };
21
21
  if (state.firstOrderPlaceDate && state.firstOrderPlaceDate[optin.id]) {
22
- purchasePostObject['subscription_info']['first_order_place_date'] = state.firstOrderPlaceDate[optin.id];
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['tracking_override']['product'] = state.productToSubscribe[optin.id];
25
+ purchasePostObject.tracking_override.product = state.productToSubscribe[optin.id];
26
26
  }
27
27
  return purchasePostObject;
28
28
  })
29
- .filter(optin => optin['tracking_override'].offer)
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([['status', status], ['ordering', ordering]])}`
89
+ `/orders/?${toQuery([
90
+ ['status', status],
91
+ ['ordering', ordering]
92
+ ])}`
90
93
  ])
91
94
  )
92
95
  ),
@@ -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';
@@ -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
- setImmediate(() => store.dispatch(requestSessionId()));
54
+ setTimeout(() => store.dispatch(requestSessionId()), 0);
55
55
  } else if (key === STORE_ROOT) {
56
56
  store.dispatch({
57
57
  type: LOCAL_STORAGE_CHANGE,
@@ -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: 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
- setImmediate(() =>
17
- dispatchEvent('optin-changed', {
18
- productId: productId,
19
- components: components,
20
- optedIn: optedIn
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 = [
@@ -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,