@ordergroove/offers 2.29.0 → 2.29.1-alpha-PR-707-2.113
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/README.md +22 -1
- package/dist/bundle-report.html +72 -59
- package/dist/examples.js +262 -105
- package/dist/examples.js.map +2 -2
- package/dist/offers.js +82 -32
- package/dist/offers.js.map +3 -3
- package/examples/index.js +230 -218
- package/package.json +2 -2
- package/src/components/PrepaidData.js +110 -0
- package/src/components/PrepaidToggle.js +108 -0
- package/src/components/Price.js +6 -6
- package/src/components/Select.js +6 -1
- package/src/components/__tests__/PrepaidData.spec.js +173 -0
- package/src/components/__tests__/PrepaidToggle.spec.js +115 -0
- package/src/components/__tests__/Price.spec.js +96 -0
- package/src/core/__tests__/adapters.spec.js +232 -1
- package/src/core/__tests__/descriptors.spec.js +56 -0
- package/src/core/__tests__/reducer.spec.js +153 -1
- package/src/core/__tests__/selectors.spec.js +34 -1
- package/src/core/actions.js +5 -0
- package/src/core/adapters.js +48 -2
- package/src/core/constants.js +1 -0
- package/src/core/descriptors.js +7 -1
- package/src/core/reducer.js +35 -14
- package/src/core/selectors.js +32 -0
- package/src/core/utils.ts +16 -0
- package/src/make-api.js +4 -0
- package/src/shopify/__tests__/productPlan.spec.js +513 -0
- package/src/shopify/__tests__/shopifyReducer.spec.js +630 -19
- package/src/shopify/__tests__/utils.spec.js +25 -0
- package/src/shopify/reducers/productPlans.ts +134 -0
- package/src/shopify/shopifyMiddleware.ts +3 -0
- package/src/shopify/shopifyReducer.js +96 -47
- package/src/shopify/shopifyTrackingMiddleware.ts +1 -1
- package/src/shopify/types/productPlan.ts +11 -0
- package/src/shopify/types/shopify.ts +98 -0
- package/src/shopify/utils.ts +3 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { LitElement, html, css } from 'lit-element';
|
|
2
|
+
import { connect } from '../core/connect';
|
|
3
|
+
import {
|
|
4
|
+
makeProductPrepaidShipmentOptionsSelector,
|
|
5
|
+
makeProductPrepaidShipmentsOptedInSelector,
|
|
6
|
+
makePrepaidShipmentsSelectedSelector
|
|
7
|
+
} from '../core/selectors';
|
|
8
|
+
import { productChangePrepaidShipments } from '../core/actions';
|
|
9
|
+
import { withProduct } from '../core/resolveProperties';
|
|
10
|
+
|
|
11
|
+
export class PrepaidToggle extends withProduct(LitElement) {
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
this.options = [];
|
|
15
|
+
this.text = 'shipments';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
options: { type: Array },
|
|
21
|
+
text: { type: String },
|
|
22
|
+
shipmentsOptedIn: { type: Number },
|
|
23
|
+
prepaidShipmentsSelected: { type: Number }
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// copied from SelectFrequency
|
|
28
|
+
static get styles() {
|
|
29
|
+
return css`
|
|
30
|
+
og-select {
|
|
31
|
+
display: inline-block;
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
background-color: var(--og-select-bg-color, #fff);
|
|
34
|
+
border: var(--og-select-border, 1px solid #aaa);
|
|
35
|
+
border-width: var(--og-select-border-width, 1px);
|
|
36
|
+
box-shadow: 0 1px 0 1px rgba(0, 0, 0, 0.04);
|
|
37
|
+
z-index: 1;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
input {
|
|
41
|
+
width: 1.2em;
|
|
42
|
+
height: 1.2em;
|
|
43
|
+
accent-color: var(--og-prepaid-checkbox-color, black);
|
|
44
|
+
border-radius: 4px;
|
|
45
|
+
}
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
get checked() {
|
|
50
|
+
return this.shipmentsOptedIn > 1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
handleChange(e) {
|
|
54
|
+
if (e.target.checked) {
|
|
55
|
+
const selectedShipments = this.prepaidShipmentsSelected || this.options[0];
|
|
56
|
+
this.productChangePrepaidShipments(this.product, selectedShipments, this.offer);
|
|
57
|
+
} else {
|
|
58
|
+
this.productChangePrepaidShipments(this.product, null, this.offer);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
handleSelect({ target: { value } }) {
|
|
63
|
+
const valueAsNumber = +value;
|
|
64
|
+
this.productChangePrepaidShipments(this.product, valueAsNumber, this.offer);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
render() {
|
|
68
|
+
if (this.options.length === 0) {
|
|
69
|
+
return html``;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const displayOptions = this.options.map(value => ({
|
|
73
|
+
value: value,
|
|
74
|
+
text: `${value} ${this.text}`
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
return html`
|
|
78
|
+
<div>
|
|
79
|
+
<input id="cbx" type="checkbox" .checked=${this.checked} @change=${this.handleChange} />
|
|
80
|
+
<label for="cbx">
|
|
81
|
+
<slot name="label">Prepay for</slot>
|
|
82
|
+
${this.options.length > 1
|
|
83
|
+
? html`
|
|
84
|
+
<og-select
|
|
85
|
+
.options=${displayOptions}
|
|
86
|
+
.selected=${this.prepaidShipmentsSelected || this.shipmentsOptedIn}
|
|
87
|
+
.onChange="${e => this.handleSelect(e)}"
|
|
88
|
+
></og-select>
|
|
89
|
+
`
|
|
90
|
+
: html`
|
|
91
|
+
<span>${displayOptions[0].text}</span>
|
|
92
|
+
`}
|
|
93
|
+
<slot name="append"></slot>
|
|
94
|
+
</label>
|
|
95
|
+
</div>
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const mapStateToProps = (state, ownProps) => ({
|
|
101
|
+
options: makeProductPrepaidShipmentOptionsSelector(ownProps.product.id)(state),
|
|
102
|
+
shipmentsOptedIn: makeProductPrepaidShipmentsOptedInSelector(ownProps.product)(state),
|
|
103
|
+
prepaidShipmentsSelected: makePrepaidShipmentsSelectedSelector(ownProps.product)(state)
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const ConnectedPrepaidToggle = connect(mapStateToProps, { productChangePrepaidShipments })(PrepaidToggle);
|
|
107
|
+
|
|
108
|
+
export { ConnectedPrepaidToggle };
|
package/src/components/Price.js
CHANGED
|
@@ -4,6 +4,7 @@ import { connect } from '../core/connect';
|
|
|
4
4
|
import { withProduct } from '../core/resolveProperties';
|
|
5
5
|
import { TemplateElement } from '../core/base';
|
|
6
6
|
import { makeProductFrequencySelector } from '../core/selectors';
|
|
7
|
+
import { safeProductId } from '../core/utils';
|
|
7
8
|
|
|
8
9
|
export class Price extends withProduct(TemplateElement) {
|
|
9
10
|
static get properties() {
|
|
@@ -18,14 +19,13 @@ export class Price extends withProduct(TemplateElement) {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
get value() {
|
|
21
|
-
|
|
22
|
-
// this code omits the <line_hash>. We dont support colon : in product_id so this hack wont affect other platforms
|
|
23
|
-
const realProductId = this.product.id?.split(':')[0];
|
|
22
|
+
const realProductId = safeProductId(this.product);
|
|
24
23
|
const frequency = this.frequency || this.configDefaultFrequency || this.offer?.defaultFrequency;
|
|
25
|
-
const plans = this.productPlans[realProductId] ||
|
|
26
|
-
const currentPlan = plans
|
|
24
|
+
const plans = this.productPlans[realProductId] || [];
|
|
25
|
+
const currentPlan = plans.find(plan => plan.frequency === frequency);
|
|
27
26
|
if (!currentPlan) return '';
|
|
28
|
-
const
|
|
27
|
+
const { regularPrice, discountRate, subscriptionPrice } = currentPlan;
|
|
28
|
+
|
|
29
29
|
if (subscriptionPrice === regularPrice) return '';
|
|
30
30
|
|
|
31
31
|
if (this.regular) {
|
package/src/components/Select.js
CHANGED
|
@@ -70,7 +70,12 @@ export class Select extends LitElement {
|
|
|
70
70
|
<select @change="${handleOnChange}">
|
|
71
71
|
${this.options.map(
|
|
72
72
|
option => html`
|
|
73
|
-
<option
|
|
73
|
+
<option
|
|
74
|
+
value="${option.value}"
|
|
75
|
+
?selected=${option.value === this.selected}
|
|
76
|
+
.selected=${option.value === this.selected}
|
|
77
|
+
>${option.text}</option
|
|
78
|
+
>
|
|
74
79
|
`
|
|
75
80
|
)}
|
|
76
81
|
</select>
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { html, render } from 'lit-html';
|
|
2
|
+
import { PrepaidData } from '../PrepaidData';
|
|
3
|
+
|
|
4
|
+
const TEST_CONTAINER_ID = 'test-container';
|
|
5
|
+
const TAG_NAME_UNDER_TEST = 'og-some-prepaid-data';
|
|
6
|
+
customElements.define(TAG_NAME_UNDER_TEST, PrepaidData);
|
|
7
|
+
|
|
8
|
+
const productPlanPayload = {
|
|
9
|
+
'yum id': [
|
|
10
|
+
{
|
|
11
|
+
frequency: 'selling-plan-id-1',
|
|
12
|
+
regularPrice: '$5.00',
|
|
13
|
+
subscriptionPrice: '$4.50',
|
|
14
|
+
discountRate: '$.50',
|
|
15
|
+
prepaidShipments: null
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
frequency: 'prepaid-selling-plan-id-1',
|
|
19
|
+
regularPrice: '$5.00',
|
|
20
|
+
subscriptionPrice: '$4.00',
|
|
21
|
+
discountRate: '20%',
|
|
22
|
+
prepaidShipments: 3,
|
|
23
|
+
regularPrepaidPrice: '$12.00',
|
|
24
|
+
prepaidSavingsPerShipment: '$1.00',
|
|
25
|
+
prepaidSavingsTotal: '$3.00',
|
|
26
|
+
prepaidExtraSavingsPercentage: '10%'
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
frequency: 'prepaid-selling-plan-id-2',
|
|
30
|
+
regularPrice: '$5.00',
|
|
31
|
+
subscriptionPrice: '$4.00',
|
|
32
|
+
discountRate: '20%',
|
|
33
|
+
prepaidShipments: 6,
|
|
34
|
+
regularPrepaidPrice: '$24.00',
|
|
35
|
+
prepaidSavingsPerShipment: '$1.00',
|
|
36
|
+
prepaidSavingsTotal: '$6.00',
|
|
37
|
+
prepaidExtraSavingsPercentage: '10%'
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
frequency: 'prepaid-selling-plan-id-2',
|
|
41
|
+
regularPrice: '$5.00',
|
|
42
|
+
subscriptionPrice: '$3.75',
|
|
43
|
+
discountRate: '25%',
|
|
44
|
+
prepaidShipments: 12,
|
|
45
|
+
regularPrepaidPrice: '$45.00',
|
|
46
|
+
prepaidSavingsPerShipment: '$1.25',
|
|
47
|
+
prepaidSavingsTotal: '$15.00',
|
|
48
|
+
prepaidExtraSavingsPercentage: '15%'
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
async function renderPrepaidDataTemplate({
|
|
54
|
+
template,
|
|
55
|
+
shipmentsOptedIn = null,
|
|
56
|
+
prepaidShipmentsSelected = null,
|
|
57
|
+
productPlans = productPlanPayload
|
|
58
|
+
}) {
|
|
59
|
+
// make sure the element was cleaned up
|
|
60
|
+
expect(document.body.querySelector(TAG_NAME_UNDER_TEST)).toBeFalsy();
|
|
61
|
+
render(template, document.getElementById(TEST_CONTAINER_ID));
|
|
62
|
+
const element = document.querySelector(TAG_NAME_UNDER_TEST);
|
|
63
|
+
element.shipmentsOptedIn = shipmentsOptedIn;
|
|
64
|
+
element.prepaidShipmentsSelected = prepaidShipmentsSelected;
|
|
65
|
+
element.productPlans = productPlans;
|
|
66
|
+
await element.updateComplete;
|
|
67
|
+
return element;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
describe('PrepaidData', () => {
|
|
71
|
+
beforeEach(() => {
|
|
72
|
+
// create a dedicated container to render the templates into
|
|
73
|
+
// otherwise we get race conditions
|
|
74
|
+
const testContainer = document.createElement('div');
|
|
75
|
+
testContainer.id = TEST_CONTAINER_ID;
|
|
76
|
+
document.body.appendChild(testContainer);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
afterEach(() => {
|
|
80
|
+
const testContainer = document.getElementById(TEST_CONTAINER_ID);
|
|
81
|
+
testContainer.remove();
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should render total prepaid price for first prepaid product plan', async () => {
|
|
85
|
+
const template = html`
|
|
86
|
+
<og-some-prepaid-data total-price product="yum id"></og-some-prepaid-data>
|
|
87
|
+
`;
|
|
88
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
89
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
90
|
+
expect(insideText).toBe('$12.00');
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('should render total prepaid price for 6 shipments', async () => {
|
|
94
|
+
const template = html`
|
|
95
|
+
<og-some-prepaid-data total-price product="yum id"></og-some-prepaid-data>
|
|
96
|
+
`;
|
|
97
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template: template, prepaidShipmentsSelected: 6 });
|
|
98
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
99
|
+
expect(insideText).toBe('$24.00');
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should render total prepaid price for 12 shipments based on optedIn shipment', async () => {
|
|
103
|
+
const template = html`
|
|
104
|
+
<og-some-prepaid-data total-price product="yum id"></og-some-prepaid-data>
|
|
105
|
+
`;
|
|
106
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template: template, shipmentsOptedIn: 12 });
|
|
107
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
108
|
+
expect(insideText).toBe('$45.00');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should render per delivery price', async () => {
|
|
112
|
+
const template = html`
|
|
113
|
+
<og-some-prepaid-data per-delivery-price product="yum id"></og-some-prepaid-data>
|
|
114
|
+
`;
|
|
115
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
116
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
117
|
+
expect(insideText).toBe('$4.00');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should render total savings price', async () => {
|
|
121
|
+
const template = html`
|
|
122
|
+
<og-some-prepaid-data total-savings product="yum id"></og-some-prepaid-data>
|
|
123
|
+
`;
|
|
124
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
125
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
126
|
+
expect(insideText).toBe('$3.00');
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it('should render per delivery savings price', async () => {
|
|
130
|
+
const template = html`
|
|
131
|
+
<og-some-prepaid-data per-delivery-savings product="yum id"></og-some-prepaid-data>
|
|
132
|
+
`;
|
|
133
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
134
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
135
|
+
expect(insideText).toBe('$1.00');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should render percentage savings', async () => {
|
|
139
|
+
const template = html`
|
|
140
|
+
<og-some-prepaid-data percentage-savings product="yum id"></og-some-prepaid-data>
|
|
141
|
+
`;
|
|
142
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
143
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
144
|
+
expect(insideText).toBe('20%');
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('should render extraPercentageSavings savings', async () => {
|
|
148
|
+
const template = html`
|
|
149
|
+
<og-some-prepaid-data extra-percentage-savings product="yum id"></og-some-prepaid-data>
|
|
150
|
+
`;
|
|
151
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
152
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
153
|
+
expect(insideText).toBe('10%');
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('should render numberOfShipments', async () => {
|
|
157
|
+
const template = html`
|
|
158
|
+
<og-some-prepaid-data number-of-shipments product="yum id"></og-some-prepaid-data>
|
|
159
|
+
`;
|
|
160
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
161
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
162
|
+
expect(insideText).toBe('3');
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should render nothing when no property is provided', async () => {
|
|
166
|
+
const template = html`
|
|
167
|
+
<og-some-prepaid-data product="yum id"></og-some-prepaid-data>
|
|
168
|
+
`;
|
|
169
|
+
const prepaidDataDiv = await renderPrepaidDataTemplate({ template });
|
|
170
|
+
const insideText = prepaidDataDiv.shadowRoot.textContent.trim();
|
|
171
|
+
expect(insideText).toBe('');
|
|
172
|
+
});
|
|
173
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { html, render } from 'lit-html';
|
|
2
|
+
import { PrepaidToggle } from '../PrepaidToggle';
|
|
3
|
+
|
|
4
|
+
const TEST_CONTAINER_ID = 'test-container';
|
|
5
|
+
const TAG_NAME_UNDER_TEST = 'og-some-prepaid-toggle';
|
|
6
|
+
customElements.define(TAG_NAME_UNDER_TEST, PrepaidToggle);
|
|
7
|
+
|
|
8
|
+
async function renderTemplate(template) {
|
|
9
|
+
// make sure the element was cleaned up
|
|
10
|
+
expect(document.body.querySelector(TAG_NAME_UNDER_TEST)).toBeFalsy();
|
|
11
|
+
render(template, document.getElementById(TEST_CONTAINER_ID));
|
|
12
|
+
const element = document.querySelector(TAG_NAME_UNDER_TEST);
|
|
13
|
+
await element.updateComplete;
|
|
14
|
+
return element;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getPrepaidToggleTemplate(options = [3, 6]) {
|
|
18
|
+
return html`
|
|
19
|
+
<og-some-prepaid-toggle product="yum product" .options=${options}> </og-some-prepaid-toggle>
|
|
20
|
+
`;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function expectPrepaidShipmentsAction(toggle, numShipments) {
|
|
24
|
+
expect(toggle.productChangePrepaidShipments).toHaveBeenCalledWith({ id: 'yum product' }, numShipments, undefined);
|
|
25
|
+
toggle.productChangePrepaidShipments.calls.reset();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function toggleCheckbox(checkbox) {
|
|
29
|
+
checkbox.checked = !checkbox.checked;
|
|
30
|
+
checkbox.dispatchEvent(new Event('change'));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function selectOption(ogSelect, value) {
|
|
34
|
+
const innerSelect = ogSelect.shadowRoot.querySelector('select');
|
|
35
|
+
innerSelect.value = value;
|
|
36
|
+
innerSelect.dispatchEvent(new Event('change'));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
describe('PrepaidToggle', () => {
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
// create a dedicated container to render the templates into
|
|
42
|
+
// otherwise we get race conditions
|
|
43
|
+
const testContainer = document.createElement('div');
|
|
44
|
+
testContainer.id = TEST_CONTAINER_ID;
|
|
45
|
+
document.body.appendChild(testContainer);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
afterEach(() => {
|
|
49
|
+
const testContainer = document.getElementById(TEST_CONTAINER_ID);
|
|
50
|
+
testContainer.remove();
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it('should render with select options', async () => {
|
|
54
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate());
|
|
55
|
+
|
|
56
|
+
const select = toggle.shadowRoot.querySelector('og-select');
|
|
57
|
+
expect(select).toBeTruthy();
|
|
58
|
+
expect(select.options).toEqual([
|
|
59
|
+
{ value: 3, text: '3 shipments' },
|
|
60
|
+
{ value: 6, text: '6 shipments' }
|
|
61
|
+
]);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should render static text when only one option', async () => {
|
|
65
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate([3]));
|
|
66
|
+
const select = toggle.shadowRoot.querySelector('og-select');
|
|
67
|
+
expect(select).toBeFalsy();
|
|
68
|
+
const label = toggle.shadowRoot.querySelector('label');
|
|
69
|
+
expect(label.innerText).toBe('Prepay for 3 shipments');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should opt into prepaid', async () => {
|
|
73
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate());
|
|
74
|
+
toggle.productChangePrepaidShipments = jasmine.createSpy('productChangePrepaidShipments');
|
|
75
|
+
const checkbox = toggle.shadowRoot.querySelector('input');
|
|
76
|
+
|
|
77
|
+
// checking checkbox selects default value
|
|
78
|
+
toggleCheckbox(checkbox);
|
|
79
|
+
expectPrepaidShipmentsAction(toggle, 3);
|
|
80
|
+
|
|
81
|
+
// changing select changes selection
|
|
82
|
+
const select = toggle.shadowRoot.querySelector('og-select');
|
|
83
|
+
selectOption(select, 6);
|
|
84
|
+
// This is changed on the prepaidShipmentsSelected reducer by the productChangePrepaidShipments action
|
|
85
|
+
toggle.prepaidShipmentsSelected = 6;
|
|
86
|
+
expectPrepaidShipmentsAction(toggle, 6);
|
|
87
|
+
|
|
88
|
+
// unchecking checkbox opts out of prepaid
|
|
89
|
+
toggleCheckbox(checkbox);
|
|
90
|
+
expectPrepaidShipmentsAction(toggle, null);
|
|
91
|
+
|
|
92
|
+
// checking checkbox again opts into previously selected value
|
|
93
|
+
toggleCheckbox(checkbox);
|
|
94
|
+
expectPrepaidShipmentsAction(toggle, 6);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('should preselect a value if shipments is set', async () => {
|
|
98
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate());
|
|
99
|
+
toggle.shipmentsOptedIn = 6;
|
|
100
|
+
|
|
101
|
+
await toggle.updateComplete;
|
|
102
|
+
|
|
103
|
+
const checkbox = toggle.shadowRoot.querySelector('input');
|
|
104
|
+
expect(checkbox.checked).toBe(true);
|
|
105
|
+
|
|
106
|
+
const select = toggle.shadowRoot.querySelector('og-select');
|
|
107
|
+
expect(select.selected).toBe(6);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should handle empty options', async () => {
|
|
111
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate([]));
|
|
112
|
+
// should render an empty component and not throw
|
|
113
|
+
expect(toggle.shadowRoot.textContent).toBe('');
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { html, render } from 'lit-html';
|
|
2
|
+
import { Price } from '../Price';
|
|
3
|
+
|
|
4
|
+
const TEST_CONTAINER_ID = 'test-container';
|
|
5
|
+
const TAG_NAME_UNDER_TEST = 'og-some-price';
|
|
6
|
+
customElements.define(TAG_NAME_UNDER_TEST, Price);
|
|
7
|
+
|
|
8
|
+
async function renderPriceTemplate(
|
|
9
|
+
template,
|
|
10
|
+
properties = {
|
|
11
|
+
frequency: '1_3',
|
|
12
|
+
productPlans: {
|
|
13
|
+
'yum id': [
|
|
14
|
+
{
|
|
15
|
+
frequency: '1_3',
|
|
16
|
+
regularPrice: '$1.00',
|
|
17
|
+
discountRate: '10%',
|
|
18
|
+
subscriptionPrice: '$0.90'
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
) {
|
|
24
|
+
// make sure the element was cleaned up
|
|
25
|
+
expect(document.body.querySelector(TAG_NAME_UNDER_TEST)).toBeFalsy();
|
|
26
|
+
render(template, document.getElementById(TEST_CONTAINER_ID));
|
|
27
|
+
const element = document.querySelector(TAG_NAME_UNDER_TEST);
|
|
28
|
+
element.frequency = properties.frequency;
|
|
29
|
+
element.productPlans = properties.productPlans;
|
|
30
|
+
await element.updateComplete;
|
|
31
|
+
return element;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe('Price', () => {
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
// create a dedicated container to render the templates into
|
|
37
|
+
// otherwise we get race conditions
|
|
38
|
+
const testContainer = document.createElement('div');
|
|
39
|
+
testContainer.id = TEST_CONTAINER_ID;
|
|
40
|
+
document.body.appendChild(testContainer);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
afterEach(() => {
|
|
44
|
+
const testContainer = document.getElementById(TEST_CONTAINER_ID);
|
|
45
|
+
testContainer.remove();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should render subscription price', async () => {
|
|
49
|
+
const template = html`
|
|
50
|
+
<og-some-price product="yum id"> </og-some-price>
|
|
51
|
+
`;
|
|
52
|
+
const priceDiv = await renderPriceTemplate(template);
|
|
53
|
+
const insideText = priceDiv.shadowRoot.textContent.trim();
|
|
54
|
+
expect(insideText).toBe('$0.90');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should render regular price', async () => {
|
|
58
|
+
const template = html`
|
|
59
|
+
<og-some-price regular product="yum id"> </og-some-price>
|
|
60
|
+
`;
|
|
61
|
+
const priceDiv = await renderPriceTemplate(template);
|
|
62
|
+
const insideText = priceDiv.shadowRoot.textContent.trim();
|
|
63
|
+
expect(insideText).toBe('$1.00');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should render discount price', async () => {
|
|
67
|
+
const template = html`
|
|
68
|
+
<og-some-price discount product="yum id"> </og-some-price>
|
|
69
|
+
`;
|
|
70
|
+
const priceDiv = await renderPriceTemplate(template);
|
|
71
|
+
const insideText = priceDiv.shadowRoot.textContent.trim();
|
|
72
|
+
expect(insideText).toBe('10%');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should render empty price when subscription is equal to regular', async () => {
|
|
76
|
+
const template = html`
|
|
77
|
+
<og-some-price discount product="yum id"> </og-some-price>
|
|
78
|
+
`;
|
|
79
|
+
const priceDiv = await renderPriceTemplate(template, {
|
|
80
|
+
frequency: '1_3',
|
|
81
|
+
productPlans: {
|
|
82
|
+
'yum id': [
|
|
83
|
+
{
|
|
84
|
+
frequency: '1_3',
|
|
85
|
+
regularPrice: '$1.00',
|
|
86
|
+
discountRate: '10%',
|
|
87
|
+
subscriptionPrice: '$1.00'
|
|
88
|
+
}
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
const ogPrice = priceDiv.shadowRoot.innerHTML;
|
|
93
|
+
expect(ogPrice).not.toContain('10%');
|
|
94
|
+
expect(ogPrice).not.toContain('$1.00');
|
|
95
|
+
});
|
|
96
|
+
});
|