@ordergroove/offers 2.34.0 → 2.34.1-alpha-PR-737-9.24
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/dist/bundle-report.html +41 -31
- package/dist/examples.js +278 -121
- package/dist/examples.js.map +2 -2
- package/dist/offers.js +138 -63
- package/dist/offers.js.map +3 -3
- package/examples/index.js +17 -1
- package/package.json +3 -3
- package/src/components/OptinButton.js +11 -2
- package/src/components/OptinStatus.js +2 -0
- package/src/components/PrepaidButton.js +98 -0
- package/src/components/PrepaidSelect.js +74 -0
- package/src/components/PrepaidStatus.js +61 -0
- package/src/components/PrepaidToggle.js +6 -36
- package/src/components/__tests__/OptinButton.spec.js +10 -0
- package/src/components/__tests__/PrepaidButton.spec.js +77 -0
- package/src/components/__tests__/PrepaidSelect.spec.js +81 -0
- package/src/components/__tests__/PrepaidToggle.spec.js +8 -16
- package/src/components/__tests__/utils.js +15 -0
- package/src/core/reducer.js +3 -1
- package/src/make-api.js +4 -0
package/examples/index.js
CHANGED
|
@@ -58,9 +58,11 @@ const settings = {
|
|
|
58
58
|
const textCopy = {
|
|
59
59
|
showTooltip: true,
|
|
60
60
|
offerOptInLabel: 'Subscribe to save',
|
|
61
|
+
prepaidOptInLabel: 'Prepaid Subscription',
|
|
61
62
|
offerIncentiveText: 'Save {{ogIncentive DiscountPercent}} when you subscribe',
|
|
62
63
|
offerOptOutLabel: 'Deliver one-time only',
|
|
63
64
|
offerEveryLabel: 'Deliver every',
|
|
65
|
+
prepaidShipmentsLabel: 'Number of prepaid shipments',
|
|
64
66
|
offerTooltipTrigger: '[?]',
|
|
65
67
|
offerTooltipContent: 'Seems this is a great subscription offering. Many fun details about this program exist.',
|
|
66
68
|
optinButtonLabel: '•',
|
|
@@ -78,7 +80,9 @@ const textCopy = {
|
|
|
78
80
|
upsellModalCancelLabel: 'Cancel',
|
|
79
81
|
defaultFrequencyCopy: '(Recommended)',
|
|
80
82
|
prepaidShipmentSelectAppend: 'and save {{ogPrepaid PercentageSavings}}, delivered monthly',
|
|
81
|
-
prepaidExplainer: 'You will be billed {{ogPrepaid TotalPrice}} today ({{ogPrepaid PerDeliveryPrice}}/delivery)'
|
|
83
|
+
prepaidExplainer: 'You will be billed {{ogPrepaid TotalPrice}} today ({{ogPrepaid PerDeliveryPrice}}/delivery)',
|
|
84
|
+
subscribeToSaveExplainer: 'You will be billed {{ogPrice Regular}} today',
|
|
85
|
+
prepaidOfferIncentiveText: 'Save {{ogPrepaid PercentageSavings}} when paying upfront',
|
|
82
86
|
};
|
|
83
87
|
|
|
84
88
|
const offersExamples = [
|
|
@@ -191,6 +195,18 @@ const offersExamples = [
|
|
|
191
195
|
textCopy: { ...textCopy }
|
|
192
196
|
}
|
|
193
197
|
},
|
|
198
|
+
{
|
|
199
|
+
name: 'Prepaid Button PDP',
|
|
200
|
+
defaultPreviewMode: 'prepaid',
|
|
201
|
+
selector: 'og-offer[location="prepaid-button-pdp"]',
|
|
202
|
+
config: {
|
|
203
|
+
settings: {
|
|
204
|
+
...settings,
|
|
205
|
+
offerType: 'prepaid-enabled-button'
|
|
206
|
+
},
|
|
207
|
+
textCopy: { ...textCopy }
|
|
208
|
+
}
|
|
209
|
+
},
|
|
194
210
|
{
|
|
195
211
|
name: 'Prepaid Cart',
|
|
196
212
|
defaultPreviewMode: 'prepaid',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ordergroove/offers",
|
|
3
|
-
"version": "2.34.
|
|
3
|
+
"version": "2.34.1-alpha-PR-737-9.24+1283e175",
|
|
4
4
|
"description": "offer state component",
|
|
5
5
|
"author": "Eugenio Lattanzio <eugenio63@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/ordergroove/plush-toys#readme",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"throttle-debounce": "^2.1.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@ordergroove/offers-templates": "^0.9.
|
|
48
|
+
"@ordergroove/offers-templates": "^0.9.1-alpha-PR-737-9.24+1283e175"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "1283e175ce345b5235170707b551e44913f8be92"
|
|
51
51
|
}
|
|
@@ -13,7 +13,9 @@ export class OptinButton extends OptinStatus {
|
|
|
13
13
|
...super.properties,
|
|
14
14
|
frequency: { type: String, reflect: true },
|
|
15
15
|
defaultFrequency,
|
|
16
|
-
optinButtonLabel: { type: String }
|
|
16
|
+
optinButtonLabel: { type: String },
|
|
17
|
+
prepaidShipmentsOptedIn: { type: Number },
|
|
18
|
+
disableWhenPrepaidEnabled: { type: Boolean, reflect: true, attribute: 'disable-when-prepaid-enabled' }
|
|
17
19
|
};
|
|
18
20
|
}
|
|
19
21
|
|
|
@@ -51,10 +53,17 @@ export class OptinButton extends OptinStatus {
|
|
|
51
53
|
ev.preventDefault();
|
|
52
54
|
}
|
|
53
55
|
|
|
56
|
+
get isActive() {
|
|
57
|
+
if (this.disableWhenPrepaidEnabled && this.prepaidShipmentsOptedIn > 0) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return this.subscribed;
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
render() {
|
|
55
64
|
return html`
|
|
56
65
|
<slot name="default">
|
|
57
|
-
<button id="action-trigger" class="btn radio ${this.
|
|
66
|
+
<button id="action-trigger" class="btn radio ${this.isActive ? ' active' : ''}"></button>
|
|
58
67
|
<label for="action-trigger">
|
|
59
68
|
<slot>
|
|
60
69
|
<slot name="label"><og-text key="offerOptInLabel"></og-text></slot>
|
|
@@ -2,6 +2,7 @@ import { html, css } from 'lit-element';
|
|
|
2
2
|
import {
|
|
3
3
|
makeOptedinSelector,
|
|
4
4
|
makeProductDefaultFrequencySelector,
|
|
5
|
+
makeProductPrepaidShipmentsOptedInSelector,
|
|
5
6
|
makeProductFrequencySelector,
|
|
6
7
|
configSelector,
|
|
7
8
|
templatesSelector
|
|
@@ -131,6 +132,7 @@ export const mapStateToProps = (state, ownProps = {}) => ({
|
|
|
131
132
|
subscribed: makeOptedinSelector(ownProps.product)(state),
|
|
132
133
|
frequency: makeProductFrequencySelector(ownProps.product)(state),
|
|
133
134
|
productDefaultFrequency: makeProductDefaultFrequencySelector((ownProps.product || {}).id)(state),
|
|
135
|
+
prepaidShipmentsOptedIn: makeProductPrepaidShipmentsOptedInSelector(ownProps.product)(state),
|
|
134
136
|
...configSelector(state, ownProps, 'defaultFrequency'),
|
|
135
137
|
...configSelector(state, ownProps, 'frequencies'),
|
|
136
138
|
...templatesSelector(state, ownProps)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { html, css } from 'lit-element';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
makeProductPrepaidShipmentOptionsSelector,
|
|
5
|
+
makeProductPrepaidShipmentsOptedInSelector,
|
|
6
|
+
makePrepaidShipmentsSelectedSelector
|
|
7
|
+
} from '../core/selectors';
|
|
8
|
+
import { productChangePrepaidShipments } from '../core/actions';
|
|
9
|
+
import { connect } from '../core/connect';
|
|
10
|
+
import { PrepaidStatus } from './PrepaidStatus';
|
|
11
|
+
|
|
12
|
+
export class PrepaidButton extends PrepaidStatus {
|
|
13
|
+
constructor() {
|
|
14
|
+
super();
|
|
15
|
+
this.addEventListener('click', this.handleClick.bind(this));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static get styles() {
|
|
19
|
+
return css`
|
|
20
|
+
:host {
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
display: inline-block;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
:host[hidden] {
|
|
26
|
+
display: none;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.btn {
|
|
30
|
+
position: relative;
|
|
31
|
+
width: var(--og-radio-width, 1.4em);
|
|
32
|
+
height: var(--og-radio-height, 1.4em);
|
|
33
|
+
margin: var(--og-radio-margin, 0);
|
|
34
|
+
padding: 0;
|
|
35
|
+
border: 1px solid var(--og-primary-color, var(--og-border-color, black));
|
|
36
|
+
background: #fff;
|
|
37
|
+
border-radius: 100%;
|
|
38
|
+
vertical-align: middle;
|
|
39
|
+
color: var(--og-primary-color, var(--og-btn-color, black));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.radio {
|
|
43
|
+
text-indent: -9999px;
|
|
44
|
+
flex-shrink: 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.radio {
|
|
48
|
+
border-color: var(--og-checkbox-border-color, black);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.radio.active::after {
|
|
52
|
+
position: absolute;
|
|
53
|
+
left: 0;
|
|
54
|
+
top: 0;
|
|
55
|
+
width: 100%;
|
|
56
|
+
height: 100%;
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
background: var(--og-checkbox-border-color, black);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.radio.active::after {
|
|
62
|
+
content: ' ';
|
|
63
|
+
border-radius: 100%;
|
|
64
|
+
border: 2px solid #fff;
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
handleClick(ev) {
|
|
70
|
+
if (!this.checked) {
|
|
71
|
+
this.productChangePrepaidShipments(this.product, this.selectedNumberOfShipments, this.offer);
|
|
72
|
+
} else {
|
|
73
|
+
this.productChangePrepaidShipments(this.product, null, this.offer);
|
|
74
|
+
}
|
|
75
|
+
ev.preventDefault();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
render() {
|
|
79
|
+
return html`
|
|
80
|
+
<slot name="default">
|
|
81
|
+
<button id="action-trigger" class="btn radio ${this.checked ? 'active' : ''}"></button>
|
|
82
|
+
<label for="action-trigger">
|
|
83
|
+
<slot name="label"><og-text key="prepaidOptInLabel"></og-text></slot>
|
|
84
|
+
</label>
|
|
85
|
+
</slot>
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const mapStateToProps = (state, ownProps) => ({
|
|
91
|
+
options: makeProductPrepaidShipmentOptionsSelector(ownProps.product.id)(state),
|
|
92
|
+
shipmentsOptedIn: makeProductPrepaidShipmentsOptedInSelector(ownProps.product)(state),
|
|
93
|
+
prepaidShipmentsSelected: makePrepaidShipmentsSelectedSelector(ownProps.product)(state)
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export const ConnectedPrepaidButton = connect(mapStateToProps, { productChangePrepaidShipments })(PrepaidButton);
|
|
97
|
+
|
|
98
|
+
export default ConnectedPrepaidButton;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { 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 { PrepaidStatus } from './PrepaidStatus';
|
|
10
|
+
|
|
11
|
+
export class PrepaidSelect extends PrepaidStatus {
|
|
12
|
+
constructor() {
|
|
13
|
+
super();
|
|
14
|
+
this.options = [];
|
|
15
|
+
this.text = 'shipments';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
...super.properties,
|
|
21
|
+
text: { type: String }
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static get styles() {
|
|
26
|
+
return css`
|
|
27
|
+
og-select {
|
|
28
|
+
display: inline-block;
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
background-color: var(--og-select-bg-color, #fff);
|
|
31
|
+
border: var(--og-select-border, 1px solid #aaa);
|
|
32
|
+
border-width: var(--og-select-border-width, 1px);
|
|
33
|
+
box-shadow: 0 1px 0 1px rgba(0, 0, 0, 0.04);
|
|
34
|
+
z-index: 1;
|
|
35
|
+
}
|
|
36
|
+
`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
render() {
|
|
40
|
+
if (this.options.length === 0) {
|
|
41
|
+
return html``;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const displayOptions = this.options.map(value => ({
|
|
45
|
+
value: value,
|
|
46
|
+
text: `${value} ${this.text}`
|
|
47
|
+
}));
|
|
48
|
+
|
|
49
|
+
return html`
|
|
50
|
+
${this.options.length > 1
|
|
51
|
+
? html`
|
|
52
|
+
<og-select
|
|
53
|
+
.options=${displayOptions}
|
|
54
|
+
.selected=${this.selectedNumberOfShipments}
|
|
55
|
+
.onChange="${e => this.handleSelect(e)}"
|
|
56
|
+
></og-select>
|
|
57
|
+
`
|
|
58
|
+
: html`
|
|
59
|
+
<span>${displayOptions[0].text}</span>
|
|
60
|
+
`}
|
|
61
|
+
<slot name="append"></slot>
|
|
62
|
+
`;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const mapStateToProps = (state, ownProps) => ({
|
|
67
|
+
options: makeProductPrepaidShipmentOptionsSelector(ownProps.product.id)(state),
|
|
68
|
+
shipmentsOptedIn: makeProductPrepaidShipmentsOptedInSelector(ownProps.product)(state),
|
|
69
|
+
prepaidShipmentsSelected: makePrepaidShipmentsSelectedSelector(ownProps.product)(state)
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
const ConnectedPrepaidSelect = connect(mapStateToProps, { productChangePrepaidShipments })(PrepaidSelect);
|
|
73
|
+
|
|
74
|
+
export { ConnectedPrepaidSelect };
|
|
@@ -0,0 +1,61 @@
|
|
|
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 PrepaidStatus extends withProduct(LitElement) {
|
|
12
|
+
static get properties() {
|
|
13
|
+
return {
|
|
14
|
+
options: { type: Array },
|
|
15
|
+
shipmentsOptedIn: { type: Number },
|
|
16
|
+
prepaidShipmentsSelected: { type: Number },
|
|
17
|
+
defaultPrepaidShipments: { type: Number, attribute: 'default-prepaid-shipments' }
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get checked() {
|
|
22
|
+
return this.shipmentsOptedIn > 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get selectedNumberOfShipments() {
|
|
26
|
+
return this.prepaidShipmentsSelected || this.shipmentsOptedIn || this.getDefaultPrepaidShipments();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getDefaultPrepaidShipments() {
|
|
30
|
+
return this.options.includes(this.defaultPrepaidShipments)
|
|
31
|
+
? this.defaultPrepaidShipments
|
|
32
|
+
: this.options[1] || this.options[0];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
handleChange(e) {
|
|
36
|
+
if (e.target.checked) {
|
|
37
|
+
this.productChangePrepaidShipments(this.product, this.selectedNumberOfShipments, this.offer);
|
|
38
|
+
} else {
|
|
39
|
+
this.productChangePrepaidShipments(this.product, null, this.offer);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
handleSelect({ target: { value } }) {
|
|
44
|
+
const valueAsNumber = +value;
|
|
45
|
+
this.productChangePrepaidShipments(this.product, valueAsNumber, this.offer);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
render() {
|
|
49
|
+
return html``;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export const mapStateToProps = (state, ownProps) => ({
|
|
54
|
+
options: makeProductPrepaidShipmentOptionsSelector(ownProps.product.id)(state),
|
|
55
|
+
shipmentsOptedIn: makeProductPrepaidShipmentsOptedInSelector(ownProps.product)(state),
|
|
56
|
+
prepaidShipmentsSelected: makePrepaidShipmentsSelectedSelector(ownProps.product)(state)
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export const ConnectedPrepaidStatus = connect(mapStateToProps, { productChangePrepaidShipments })(PrepaidStatus);
|
|
60
|
+
|
|
61
|
+
export default ConnectedPrepaidStatus;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { html, css } from 'lit-element';
|
|
2
2
|
import { connect } from '../core/connect';
|
|
3
3
|
import {
|
|
4
4
|
makeProductPrepaidShipmentOptionsSelector,
|
|
@@ -6,9 +6,9 @@ import {
|
|
|
6
6
|
makePrepaidShipmentsSelectedSelector
|
|
7
7
|
} from '../core/selectors';
|
|
8
8
|
import { productChangePrepaidShipments } from '../core/actions';
|
|
9
|
-
import {
|
|
9
|
+
import { PrepaidStatus } from './PrepaidStatus';
|
|
10
10
|
|
|
11
|
-
export class PrepaidToggle extends
|
|
11
|
+
export class PrepaidToggle extends PrepaidStatus {
|
|
12
12
|
constructor() {
|
|
13
13
|
super();
|
|
14
14
|
this.options = [];
|
|
@@ -17,11 +17,8 @@ export class PrepaidToggle extends withProduct(LitElement) {
|
|
|
17
17
|
|
|
18
18
|
static get properties() {
|
|
19
19
|
return {
|
|
20
|
-
|
|
21
|
-
text: { type: String }
|
|
22
|
-
shipmentsOptedIn: { type: Number },
|
|
23
|
-
prepaidShipmentsSelected: { type: Number },
|
|
24
|
-
defaultPrepaidShipments: { type: Number, attribute: 'default-prepaid-shipments' }
|
|
20
|
+
...super.properties,
|
|
21
|
+
text: { type: String }
|
|
25
22
|
};
|
|
26
23
|
}
|
|
27
24
|
|
|
@@ -47,33 +44,6 @@ export class PrepaidToggle extends withProduct(LitElement) {
|
|
|
47
44
|
`;
|
|
48
45
|
}
|
|
49
46
|
|
|
50
|
-
get checked() {
|
|
51
|
-
return this.shipmentsOptedIn > 1;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
get selectedShipments() {
|
|
55
|
-
return this.prepaidShipmentsSelected || this.shipmentsOptedIn || this.getDefaultPrepaidShipments();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getDefaultPrepaidShipments() {
|
|
59
|
-
return this.options.includes(this.defaultPrepaidShipments)
|
|
60
|
-
? this.defaultPrepaidShipments
|
|
61
|
-
: this.options[1] || this.options[0];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
handleChange(e) {
|
|
65
|
-
if (e.target.checked) {
|
|
66
|
-
this.productChangePrepaidShipments(this.product, this.selectedShipments, this.offer);
|
|
67
|
-
} else {
|
|
68
|
-
this.productChangePrepaidShipments(this.product, null, this.offer);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
handleSelect({ target: { value } }) {
|
|
73
|
-
const valueAsNumber = +value;
|
|
74
|
-
this.productChangePrepaidShipments(this.product, valueAsNumber, this.offer);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
47
|
render() {
|
|
78
48
|
if (this.options.length === 0) {
|
|
79
49
|
return html``;
|
|
@@ -93,7 +63,7 @@ export class PrepaidToggle extends withProduct(LitElement) {
|
|
|
93
63
|
? html`
|
|
94
64
|
<og-select
|
|
95
65
|
.options=${displayOptions}
|
|
96
|
-
.selected=${this.
|
|
66
|
+
.selected=${this.selectedNumberOfShipments}
|
|
97
67
|
.onChange="${e => this.handleSelect(e)}"
|
|
98
68
|
></og-select>
|
|
99
69
|
`
|
|
@@ -20,6 +20,16 @@ describe('OptinButton', function() {
|
|
|
20
20
|
await appendToBody(element);
|
|
21
21
|
expect(element.shadowRoot.querySelector('button').innerText).toEqual('');
|
|
22
22
|
});
|
|
23
|
+
|
|
24
|
+
it('should show empty label if subscribed when opted in to prepaid', async () => {
|
|
25
|
+
const element = new OptinButton();
|
|
26
|
+
element.setAttribute('product', '123');
|
|
27
|
+
element.setAttribute('disable-when-prepaid-enabled', true);
|
|
28
|
+
element.subscribed = true;
|
|
29
|
+
element.prepaidShipmentsOptedIn = 3;
|
|
30
|
+
await appendToBody(element);
|
|
31
|
+
expect(element.shadowRoot.querySelector('button').innerText).toEqual('');
|
|
32
|
+
});
|
|
23
33
|
});
|
|
24
34
|
|
|
25
35
|
describe('dispatch', () => {
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { html } from 'lit-html';
|
|
2
|
+
import { PrepaidButton } from '../PrepaidButton';
|
|
3
|
+
import { simulateClick, querySelector, renderTemplate } from './utils';
|
|
4
|
+
|
|
5
|
+
const TEST_CONTAINER_ID = 'test-container';
|
|
6
|
+
const TAG_NAME_UNDER_TEST = 'og-some-prepaid-button';
|
|
7
|
+
customElements.define(TAG_NAME_UNDER_TEST, PrepaidButton);
|
|
8
|
+
|
|
9
|
+
function getPrepaidButtonTemplate(options = [3, 6]) {
|
|
10
|
+
return html`
|
|
11
|
+
<og-some-prepaid-button product="yum product" .options=${options}> </og-some-prepaid-button>
|
|
12
|
+
`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function expectPrepaidShipmentsAction(button, numShipments) {
|
|
16
|
+
expect(button.productChangePrepaidShipments).toHaveBeenCalledWith({ id: 'yum product' }, numShipments, undefined);
|
|
17
|
+
button.productChangePrepaidShipments.calls.reset();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe('PrepaidButton', () => {
|
|
21
|
+
let button;
|
|
22
|
+
|
|
23
|
+
beforeEach(async () => {
|
|
24
|
+
// create a dedicated container to render the templates into
|
|
25
|
+
// otherwise we get race conditions
|
|
26
|
+
const testContainer = document.createElement('div');
|
|
27
|
+
testContainer.id = TEST_CONTAINER_ID;
|
|
28
|
+
document.body.appendChild(testContainer);
|
|
29
|
+
button = await renderTemplate(getPrepaidButtonTemplate(), TAG_NAME_UNDER_TEST);
|
|
30
|
+
button.productChangePrepaidShipments = jasmine.createSpy('productChangePrepaidShipments');
|
|
31
|
+
await button.updateComplete;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
document.body.querySelector('og-some-prepaid-button').remove();
|
|
36
|
+
|
|
37
|
+
const testContainer = document.getElementById(TEST_CONTAINER_ID);
|
|
38
|
+
testContainer.remove();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('should optin to prepaid', async () => {
|
|
42
|
+
await simulateClick(button, 'button');
|
|
43
|
+
await button.updateComplete;
|
|
44
|
+
|
|
45
|
+
expectPrepaidShipmentsAction(button, 6);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('should optin to prepaid when default option is set', async () => {
|
|
49
|
+
button.defaultPrepaidShipments = 3;
|
|
50
|
+
|
|
51
|
+
await simulateClick(button, 'button');
|
|
52
|
+
await button.updateComplete;
|
|
53
|
+
|
|
54
|
+
expectPrepaidShipmentsAction(button, 3);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should render active button', async () => {
|
|
58
|
+
button.productChangePrepaidShipments = jasmine.createSpy('productChangePrepaidShipments');
|
|
59
|
+
button.shipmentsOptedIn = 3;
|
|
60
|
+
await button.updateComplete;
|
|
61
|
+
|
|
62
|
+
expect(querySelector(button, 'button.active')).toBeTruthy();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('should render inactive button', async () => {
|
|
66
|
+
expect(querySelector(button, 'button.active')).toBeFalsy();
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should optout from prepaid', async () => {
|
|
70
|
+
button.shipmentsOptedIn = 3;
|
|
71
|
+
|
|
72
|
+
await simulateClick(button, 'button');
|
|
73
|
+
await button.updateComplete;
|
|
74
|
+
|
|
75
|
+
expectPrepaidShipmentsAction(button, null);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { html } from 'lit-html';
|
|
2
|
+
import { PrepaidSelect } from '../PrepaidSelect';
|
|
3
|
+
import { renderTemplate } from './utils';
|
|
4
|
+
|
|
5
|
+
const TEST_CONTAINER_ID = 'test-container';
|
|
6
|
+
const TAG_NAME_UNDER_TEST = 'og-some-prepaid-select';
|
|
7
|
+
customElements.define(TAG_NAME_UNDER_TEST, PrepaidSelect);
|
|
8
|
+
|
|
9
|
+
function getPrepaidSelectTemplate(options = [3, 6]) {
|
|
10
|
+
return html`
|
|
11
|
+
<og-some-prepaid-select product="yum product" .options=${options}> </og-some-prepaid-select>
|
|
12
|
+
`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('PrepaidSelect', () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
// create a dedicated container to render the templates into
|
|
18
|
+
// otherwise we get race conditions
|
|
19
|
+
const testContainer = document.createElement('div');
|
|
20
|
+
testContainer.id = TEST_CONTAINER_ID;
|
|
21
|
+
document.body.appendChild(testContainer);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
const testContainer = document.getElementById(TEST_CONTAINER_ID);
|
|
26
|
+
testContainer.remove();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it('should render with select options', async () => {
|
|
30
|
+
const selectElement = await renderTemplate(getPrepaidSelectTemplate(), TAG_NAME_UNDER_TEST);
|
|
31
|
+
|
|
32
|
+
const select = selectElement.shadowRoot.querySelector('og-select');
|
|
33
|
+
expect(select).toBeTruthy();
|
|
34
|
+
expect(select.options).toEqual([
|
|
35
|
+
{ value: 3, text: '3 shipments' },
|
|
36
|
+
{ value: 6, text: '6 shipments' }
|
|
37
|
+
]);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('should render static text when only one option and opt in', async () => {
|
|
41
|
+
const selectElement = await renderTemplate(getPrepaidSelectTemplate([3]), TAG_NAME_UNDER_TEST);
|
|
42
|
+
selectElement.productChangePrepaidShipments = jasmine.createSpy('productChangePrepaidShipments');
|
|
43
|
+
|
|
44
|
+
const select = selectElement.shadowRoot.querySelector('og-select');
|
|
45
|
+
expect(select).toBeFalsy();
|
|
46
|
+
|
|
47
|
+
const label = selectElement.shadowRoot.querySelector('span');
|
|
48
|
+
expect(label.innerText).toBe('3 shipments');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should preselect a value if shipments is set', async () => {
|
|
52
|
+
const selectElement = await renderTemplate(getPrepaidSelectTemplate(), TAG_NAME_UNDER_TEST);
|
|
53
|
+
selectElement.shipmentsOptedIn = 6;
|
|
54
|
+
|
|
55
|
+
await selectElement.updateComplete;
|
|
56
|
+
|
|
57
|
+
const select = selectElement.shadowRoot.querySelector('og-select');
|
|
58
|
+
expect(select.selected).toBe(6);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('should handle empty options', async () => {
|
|
62
|
+
const selectElement = await renderTemplate(getPrepaidSelectTemplate([]), TAG_NAME_UNDER_TEST);
|
|
63
|
+
// should render an empty component and not throw
|
|
64
|
+
expect(selectElement.shadowRoot.textContent).toBe('');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('should select default prepaid shipments if provided', async () => {
|
|
68
|
+
const selectElement = await renderTemplate(getPrepaidSelectTemplate([3, 6, 9]), TAG_NAME_UNDER_TEST);
|
|
69
|
+
selectElement.defaultPrepaidShipments = 9;
|
|
70
|
+
|
|
71
|
+
await selectElement.updateComplete;
|
|
72
|
+
|
|
73
|
+
const select = selectElement.shadowRoot.querySelector('og-select');
|
|
74
|
+
expect(select.selected).toBe(9);
|
|
75
|
+
|
|
76
|
+
// if provided default value is not present in options, it should fall back to the 2nd option
|
|
77
|
+
selectElement.defaultPrepaidShipments = 10;
|
|
78
|
+
await selectElement.updateComplete;
|
|
79
|
+
expect(select.selected).toBe(6);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
import { html
|
|
1
|
+
import { html } from 'lit-html';
|
|
2
2
|
import { PrepaidToggle } from '../PrepaidToggle';
|
|
3
|
+
import { renderTemplate } from './utils';
|
|
3
4
|
|
|
4
5
|
const TEST_CONTAINER_ID = 'test-container';
|
|
5
6
|
const TAG_NAME_UNDER_TEST = 'og-some-prepaid-toggle';
|
|
6
7
|
customElements.define(TAG_NAME_UNDER_TEST, PrepaidToggle);
|
|
7
8
|
|
|
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
9
|
function getPrepaidToggleTemplate(options = [3, 6]) {
|
|
18
10
|
return html`
|
|
19
11
|
<og-some-prepaid-toggle product="yum product" .options=${options}> </og-some-prepaid-toggle>
|
|
@@ -51,7 +43,7 @@ describe('PrepaidToggle', () => {
|
|
|
51
43
|
});
|
|
52
44
|
|
|
53
45
|
it('should render with select options', async () => {
|
|
54
|
-
const toggle = await renderTemplate(getPrepaidToggleTemplate());
|
|
46
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate(), TAG_NAME_UNDER_TEST);
|
|
55
47
|
|
|
56
48
|
const select = toggle.shadowRoot.querySelector('og-select');
|
|
57
49
|
expect(select).toBeTruthy();
|
|
@@ -62,7 +54,7 @@ describe('PrepaidToggle', () => {
|
|
|
62
54
|
});
|
|
63
55
|
|
|
64
56
|
it('should render static text when only one option and opt in', async () => {
|
|
65
|
-
const toggle = await renderTemplate(getPrepaidToggleTemplate([3]));
|
|
57
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate([3]), TAG_NAME_UNDER_TEST);
|
|
66
58
|
toggle.productChangePrepaidShipments = jasmine.createSpy('productChangePrepaidShipments');
|
|
67
59
|
|
|
68
60
|
const select = toggle.shadowRoot.querySelector('og-select');
|
|
@@ -76,7 +68,7 @@ describe('PrepaidToggle', () => {
|
|
|
76
68
|
});
|
|
77
69
|
|
|
78
70
|
it('should opt into prepaid when no default shipments set', async () => {
|
|
79
|
-
const toggle = await renderTemplate(getPrepaidToggleTemplate());
|
|
71
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate(), TAG_NAME_UNDER_TEST);
|
|
80
72
|
toggle.productChangePrepaidShipments = jasmine.createSpy('productChangePrepaidShipments');
|
|
81
73
|
const checkbox = toggle.shadowRoot.querySelector('input');
|
|
82
74
|
|
|
@@ -101,7 +93,7 @@ describe('PrepaidToggle', () => {
|
|
|
101
93
|
});
|
|
102
94
|
|
|
103
95
|
it('should preselect a value if shipments is set', async () => {
|
|
104
|
-
const toggle = await renderTemplate(getPrepaidToggleTemplate());
|
|
96
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate(), TAG_NAME_UNDER_TEST);
|
|
105
97
|
toggle.shipmentsOptedIn = 6;
|
|
106
98
|
|
|
107
99
|
await toggle.updateComplete;
|
|
@@ -114,13 +106,13 @@ describe('PrepaidToggle', () => {
|
|
|
114
106
|
});
|
|
115
107
|
|
|
116
108
|
it('should handle empty options', async () => {
|
|
117
|
-
const toggle = await renderTemplate(getPrepaidToggleTemplate([]));
|
|
109
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate([]), TAG_NAME_UNDER_TEST);
|
|
118
110
|
// should render an empty component and not throw
|
|
119
111
|
expect(toggle.shadowRoot.textContent).toBe('');
|
|
120
112
|
});
|
|
121
113
|
|
|
122
114
|
it('should select default prepaid shipments if provided', async () => {
|
|
123
|
-
const toggle = await renderTemplate(getPrepaidToggleTemplate([3, 6, 9]));
|
|
115
|
+
const toggle = await renderTemplate(getPrepaidToggleTemplate([3, 6, 9]), TAG_NAME_UNDER_TEST);
|
|
124
116
|
toggle.defaultPrepaidShipments = 9;
|
|
125
117
|
|
|
126
118
|
await toggle.updateComplete;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { render } from 'lit-html';
|
|
2
|
+
|
|
1
3
|
export const appendToBody = async element => {
|
|
2
4
|
document.querySelector('body').appendChild(element);
|
|
3
5
|
await element.updateComplete;
|
|
@@ -16,3 +18,16 @@ export const simulateChange = async (element, value) => {
|
|
|
16
18
|
};
|
|
17
19
|
|
|
18
20
|
export const querySelector = (element, sel) => (element.shadowRoot || element.host).querySelector(sel);
|
|
21
|
+
|
|
22
|
+
export async function renderTemplate(
|
|
23
|
+
template,
|
|
24
|
+
TAG_NAME_UNDER_TEST = 'og-some-prepaid-button',
|
|
25
|
+
TEST_CONTAINER_ID = 'test-container'
|
|
26
|
+
) {
|
|
27
|
+
// make sure the element was cleaned up
|
|
28
|
+
expect(document.body.querySelector(TAG_NAME_UNDER_TEST)).toBeFalsy();
|
|
29
|
+
render(template, document.getElementById(TEST_CONTAINER_ID));
|
|
30
|
+
const element = document.querySelector(TAG_NAME_UNDER_TEST);
|
|
31
|
+
await element.updateComplete;
|
|
32
|
+
return element;
|
|
33
|
+
}
|