@session-services/web-elements 0.1.21 → 0.1.22
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/cjs/session-services-ticketing.cjs.entry.js +67 -57
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.css +36 -9
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.js +13 -10
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.logic.js +33 -26
- package/dist/collection/components/session-services-ticketing/session-services-ticketing.logic.test.js +106 -14
- package/dist/components/session-services-ticketing.js +67 -57
- package/dist/esm/session-services-ticketing.entry.js +67 -57
- package/dist/session-services-elements/p-94173d1b.entry.js +1 -0
- package/dist/session-services-elements/session-services-elements.esm.js +1 -1
- package/dist/types/components/session-services-ticketing/session-services-ticketing.logic.d.ts +4 -1
- package/package.json +2 -2
- package/dist/session-services-elements/p-b8703bf3.entry.js +0 -1
package/dist/collection/components/session-services-ticketing/session-services-ticketing.css
CHANGED
|
@@ -184,7 +184,13 @@
|
|
|
184
184
|
padding: 0;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
button,
|
|
188
|
+
input,
|
|
189
|
+
select,
|
|
190
|
+
textarea {
|
|
191
|
+
font: inherit;
|
|
192
|
+
}
|
|
193
|
+
|
|
188
194
|
*:focus {
|
|
189
195
|
outline: none;
|
|
190
196
|
}
|
|
@@ -569,7 +575,7 @@
|
|
|
569
575
|
justify-content: center;
|
|
570
576
|
padding: 0;
|
|
571
577
|
background: transparent;
|
|
572
|
-
color: var(--internal-
|
|
578
|
+
color: var(--internal-destructive);
|
|
573
579
|
border: none;
|
|
574
580
|
font-size: var(--internal-font-size-sm);
|
|
575
581
|
font-weight: var(--internal-font-weight-medium);
|
|
@@ -591,6 +597,7 @@
|
|
|
591
597
|
.admission-price-wrapper {
|
|
592
598
|
display: flex;
|
|
593
599
|
flex-direction: column;
|
|
600
|
+
row-gap: calc(var(--internal-spacing-xs) * 0.5);
|
|
594
601
|
}
|
|
595
602
|
|
|
596
603
|
.admission-price {
|
|
@@ -614,12 +621,18 @@
|
|
|
614
621
|
text-decoration: line-through;
|
|
615
622
|
}
|
|
616
623
|
|
|
624
|
+
.admission-booking-fee {
|
|
625
|
+
color: var(--internal-muted-foreground);
|
|
626
|
+
font-size: var(--internal-font-size-xs);
|
|
627
|
+
font-weight: var(--internal-font-weight-medium);
|
|
628
|
+
line-height: 1.2;
|
|
629
|
+
}
|
|
630
|
+
|
|
617
631
|
.admission-savings,
|
|
618
632
|
.admission-availability {
|
|
619
633
|
font-size: var(--internal-font-size-xs);
|
|
620
634
|
font-weight: var(--internal-font-weight-medium);
|
|
621
|
-
line-height: 1.
|
|
622
|
-
margin-top: var(--internal-spacing-xs);
|
|
635
|
+
line-height: 1.2;
|
|
623
636
|
}
|
|
624
637
|
|
|
625
638
|
.admission-savings {
|
|
@@ -654,6 +667,10 @@
|
|
|
654
667
|
transition: all var(--internal-transition-fast);
|
|
655
668
|
}
|
|
656
669
|
|
|
670
|
+
.quantity-controls:has(.quantity-value:focus-visible) {
|
|
671
|
+
box-shadow: 0 0 0 2px var(--internal-ring);
|
|
672
|
+
}
|
|
673
|
+
|
|
657
674
|
.quantity-btn {
|
|
658
675
|
width: calc(var(--internal-spacing-lg) * 1.5);
|
|
659
676
|
height: calc(var(--internal-spacing-lg) * 1.5);
|
|
@@ -715,6 +732,10 @@
|
|
|
715
732
|
padding: 0 var(--internal-spacing-xs);
|
|
716
733
|
}
|
|
717
734
|
|
|
735
|
+
.quantity-value:focus-visible {
|
|
736
|
+
outline: none;
|
|
737
|
+
}
|
|
738
|
+
|
|
718
739
|
.quantity-value::-webkit-inner-spin-button,
|
|
719
740
|
.quantity-value::-webkit-outer-spin-button {
|
|
720
741
|
appearance: none;
|
|
@@ -733,20 +754,26 @@
|
|
|
733
754
|
justify-content: center;
|
|
734
755
|
min-width: calc(var(--internal-spacing-lg) * 1.5 * 2 + 2.5rem);
|
|
735
756
|
height: calc(var(--internal-spacing-lg) * 1.5);
|
|
736
|
-
padding: 0
|
|
737
|
-
background:
|
|
738
|
-
border
|
|
757
|
+
padding: 0;
|
|
758
|
+
background: transparent;
|
|
759
|
+
border: none;
|
|
760
|
+
box-shadow: none;
|
|
739
761
|
}
|
|
740
762
|
|
|
741
763
|
.sold-out-controls,
|
|
742
764
|
.sold-out-text {
|
|
743
|
-
color: var(--internal-
|
|
765
|
+
color: var(--internal-destructive);
|
|
744
766
|
font-size: var(--internal-font-size-xs);
|
|
745
767
|
font-weight: var(--internal-font-weight-medium);
|
|
746
768
|
letter-spacing: 0.025em;
|
|
747
769
|
text-transform: uppercase;
|
|
748
770
|
}
|
|
749
771
|
|
|
772
|
+
.sold-out-controls.success,
|
|
773
|
+
.sold-out-controls.success .sold-out-text {
|
|
774
|
+
color: var(--internal-success);
|
|
775
|
+
}
|
|
776
|
+
|
|
750
777
|
.checkout-actions {
|
|
751
778
|
margin: var(--internal-spacing-lg) 0 0 0;
|
|
752
779
|
width: 100%;
|
|
@@ -816,7 +843,7 @@
|
|
|
816
843
|
background: var(--internal-secondary);
|
|
817
844
|
color: var(--internal-foreground);
|
|
818
845
|
border-radius: calc(var(--internal-radius) - 2px);
|
|
819
|
-
font-size: var(--internal-font-size-
|
|
846
|
+
font-size: var(--internal-font-size-xs);
|
|
820
847
|
font-weight: var(--internal-font-weight-medium);
|
|
821
848
|
cursor: pointer;
|
|
822
849
|
transition: all var(--internal-transition-fast);
|
|
@@ -981,21 +981,21 @@ export class SessionsTicketing {
|
|
|
981
981
|
previewItem: quoteItemsBySelection(this.previewQuote).get(key),
|
|
982
982
|
});
|
|
983
983
|
const savings = admissionPriceSavings(price);
|
|
984
|
-
return (h("div", { class: "admission-price-info" }, h("div", { class: "admission-price-wrapper" }, this.renderAdmissionPrice(price),
|
|
984
|
+
return (h("div", { class: "admission-price-info" }, h("div", { class: "admission-price-wrapper" }, savings > 0 && (h("span", { class: "admission-savings" }, "Save ", this.formatPriceValue(savings))), this.renderAdmissionPrice(price), price.fees > 0 && (h("span", { class: "admission-booking-fee" }, this.formatPriceValue(price.fees), " Booking Fee")), state.showScarcity && (h("span", { class: "admission-availability" }, admission.available, " tickets remaining")), state.label && (h("span", { class: `admission-sale-label ${state.label.tone}` }, state.label.text))), this.renderAdmissionControls(admission, sectionId, state, mode)));
|
|
985
985
|
}
|
|
986
986
|
renderAdmissionPrice(price) {
|
|
987
987
|
if (price.discounted) {
|
|
988
|
-
return (h("span", { class: "admission-price-row" }, h("span", { class: "admission-price discounted" }, this.formatPriceValue(price.
|
|
988
|
+
return (h("span", { class: "admission-price-row" }, h("span", { class: "admission-price discounted" }, this.formatPriceValue(price.base)), price.gross !== undefined && (h("span", { class: "admission-price-original" }, this.formatPriceValue(price.gross)))));
|
|
989
989
|
}
|
|
990
|
-
return (h("span", { class: "admission-price" }, this.formatPriceValue(price.
|
|
990
|
+
return (h("span", { class: "admission-price" }, this.formatPriceValue(price.base)));
|
|
991
991
|
}
|
|
992
992
|
renderAdmissionControls(admission, sectionId, state, mode) {
|
|
993
|
-
if (
|
|
994
|
-
return
|
|
995
|
-
if (!state.soldOut) {
|
|
996
|
-
return this.renderQuantityControls(admission, sectionId, state.disabled, state.maxQuantity);
|
|
993
|
+
if (state.statusLabel) {
|
|
994
|
+
return (h("div", { class: `sold-out-controls ${state.statusTone ?? ""}` }, h("span", { class: "sold-out-text" }, state.statusLabel)));
|
|
997
995
|
}
|
|
998
|
-
|
|
996
|
+
if (mode === "door")
|
|
997
|
+
return null;
|
|
998
|
+
return this.renderQuantityControls(admission, sectionId, state.disabled, state.maxQuantity);
|
|
999
999
|
}
|
|
1000
1000
|
renderAdmission(admission, event, section, isSectionSoldOut = false, mode = "default") {
|
|
1001
1001
|
const state = getAdmissionDisplayState({
|
|
@@ -1011,13 +1011,16 @@ export class SessionsTicketing {
|
|
|
1011
1011
|
return `admission-card ${state.soldOut ? "sold-out" : ""} ${state.disabled && !state.soldOut ? "unavailable" : ""} ${section ? "" : "solo-admission"}`;
|
|
1012
1012
|
}
|
|
1013
1013
|
getAdmissionAriaLabel(admission, section, state) {
|
|
1014
|
-
const status = this.admissionStatusText(admission, state.soldOut);
|
|
1014
|
+
const status = state.statusLabel ?? this.admissionStatusText(admission, state.soldOut);
|
|
1015
1015
|
return admissionAriaLabel(admission, section, status);
|
|
1016
1016
|
}
|
|
1017
1017
|
admissionStatusText(admission, soldOut) {
|
|
1018
1018
|
if (soldOut)
|
|
1019
1019
|
return "Sold Out";
|
|
1020
|
-
|
|
1020
|
+
if ((admission.price.booking ?? 0) <= 0) {
|
|
1021
|
+
return this.formatPriceValue(admission.price.base);
|
|
1022
|
+
}
|
|
1023
|
+
return `${this.formatPriceValue(admission.price.base)} plus ${this.formatPriceValue(admission.price.booking)} booking fee`;
|
|
1021
1024
|
}
|
|
1022
1025
|
renderAdmissionHeader(admission) {
|
|
1023
1026
|
return (h("div", { class: "admission-header" }, h("div", { class: "admission-header-text" }, h("h3", { class: "admission-title" }, admission.name), admission.subtitle && (h("p", { class: "admission-subtitle" }, admission.subtitle))), this.renderMoreInfoButton(admission)));
|
package/dist/collection/components/session-services-ticketing/session-services-ticketing.logic.js
CHANGED
|
@@ -62,25 +62,7 @@ function hasPurchasableAdmissions(event) {
|
|
|
62
62
|
const zone = eventTimeZone(event);
|
|
63
63
|
return event.admissions.some((admission) => isAdmissionPurchasable(admission, zone, sections));
|
|
64
64
|
}
|
|
65
|
-
function postSaleLabel(value) {
|
|
66
|
-
if (value === "SOLD_OUT")
|
|
67
|
-
return "Sold out";
|
|
68
|
-
if (value === "DOOR")
|
|
69
|
-
return "Tickets available at the door";
|
|
70
|
-
return "Sale ended";
|
|
71
|
-
}
|
|
72
|
-
function postSaleTone(value) {
|
|
73
|
-
if (value === "DOOR")
|
|
74
|
-
return "success";
|
|
75
|
-
return "muted";
|
|
76
|
-
}
|
|
77
65
|
function admissionSaleLabel(admission, zone) {
|
|
78
|
-
if (isNaiveDateTimePast(admission.saleEndsAt, zone)) {
|
|
79
|
-
return {
|
|
80
|
-
text: postSaleLabel(admission.saleEndsBehavior),
|
|
81
|
-
tone: postSaleTone(admission.saleEndsBehavior),
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
66
|
if (!isNaiveDateTimeFuture(admission.saleStartsAt, zone)) {
|
|
85
67
|
return null;
|
|
86
68
|
}
|
|
@@ -89,6 +71,16 @@ function admissionSaleLabel(admission, zone) {
|
|
|
89
71
|
tone: "muted",
|
|
90
72
|
};
|
|
91
73
|
}
|
|
74
|
+
function admissionStatus(input) {
|
|
75
|
+
if (input.value === "DOOR" && (input.soldOut || input.saleEnded)) {
|
|
76
|
+
return { text: "Available At Door", tone: "success" };
|
|
77
|
+
}
|
|
78
|
+
if (input.soldOut)
|
|
79
|
+
return { text: "Sold Out", tone: "destructive" };
|
|
80
|
+
if (!input.saleEnded)
|
|
81
|
+
return null;
|
|
82
|
+
return { text: "Sale Ended", tone: "destructive" };
|
|
83
|
+
}
|
|
92
84
|
function endedStatus(admissions, zone) {
|
|
93
85
|
const ended = admissions.filter((admission) => isNaiveDateTimePast(admission.saleEndsAt, zone));
|
|
94
86
|
if (ended.length === 0)
|
|
@@ -189,12 +181,19 @@ export function getAdmissionDisplayState(input) {
|
|
|
189
181
|
const zone = eventTimeZone(input.event);
|
|
190
182
|
const saleNotStarted = isNaiveDateTimeFuture(input.admission.saleStartsAt, zone);
|
|
191
183
|
const saleEnded = isNaiveDateTimePast(input.admission.saleEndsAt, zone);
|
|
184
|
+
const saleEndedSoldOut = saleEnded && input.admission.saleEndsBehavior === "SOLD_OUT";
|
|
192
185
|
const soldOut = Boolean(input.sectionSoldOut) ||
|
|
186
|
+
saleEndedSoldOut ||
|
|
193
187
|
isAdmissionSoldOut({
|
|
194
188
|
admission: input.admission,
|
|
195
189
|
section: input.section,
|
|
196
190
|
});
|
|
197
191
|
const disabled = soldOut || saleNotStarted || saleEnded;
|
|
192
|
+
const status = admissionStatus({
|
|
193
|
+
saleEnded,
|
|
194
|
+
soldOut,
|
|
195
|
+
value: input.admission.saleEndsBehavior,
|
|
196
|
+
});
|
|
198
197
|
return {
|
|
199
198
|
disabled,
|
|
200
199
|
label: admissionSaleLabel(input.admission, zone),
|
|
@@ -202,6 +201,8 @@ export function getAdmissionDisplayState(input) {
|
|
|
202
201
|
postSale: saleEnded,
|
|
203
202
|
showScarcity: showScarcity(input.admission, soldOut, disabled),
|
|
204
203
|
soldOut,
|
|
204
|
+
statusLabel: status?.text ?? null,
|
|
205
|
+
statusTone: status?.tone ?? null,
|
|
205
206
|
};
|
|
206
207
|
}
|
|
207
208
|
function quoteItemUnits(item) {
|
|
@@ -211,29 +212,35 @@ export function getAdmissionPriceDisplay(input) {
|
|
|
211
212
|
const item = input.quoteItem ?? input.previewItem;
|
|
212
213
|
if (item) {
|
|
213
214
|
const units = quoteItemUnits(item);
|
|
214
|
-
const
|
|
215
|
+
const base = Math.round(Math.max((item.price.base + item.price.discount) / units, 0));
|
|
216
|
+
const fees = Math.round(item.price.booking / units);
|
|
215
217
|
if (!item.price.discount || item.price.discount >= 0) {
|
|
216
218
|
return {
|
|
219
|
+
base,
|
|
217
220
|
discounted: false,
|
|
218
|
-
|
|
221
|
+
fees,
|
|
219
222
|
};
|
|
220
223
|
}
|
|
221
224
|
return {
|
|
225
|
+
base,
|
|
222
226
|
discounted: true,
|
|
223
|
-
|
|
224
|
-
|
|
227
|
+
fees,
|
|
228
|
+
gross: Math.round(item.price.base / units),
|
|
225
229
|
};
|
|
226
230
|
}
|
|
227
231
|
if (input.initialPrice && input.initialPrice.discount < 0) {
|
|
232
|
+
const fees = input.admission.price.booking ?? 0;
|
|
228
233
|
return {
|
|
234
|
+
base: Math.max(input.initialPrice.total - fees, 0),
|
|
229
235
|
discounted: true,
|
|
230
|
-
|
|
231
|
-
|
|
236
|
+
fees,
|
|
237
|
+
gross: Math.max(input.initialPrice.gross - fees, 0),
|
|
232
238
|
};
|
|
233
239
|
}
|
|
234
240
|
return {
|
|
241
|
+
base: input.admission.price.base ?? 0,
|
|
235
242
|
discounted: false,
|
|
236
|
-
|
|
243
|
+
fees: input.admission.price.booking ?? 0,
|
|
237
244
|
};
|
|
238
245
|
}
|
|
239
246
|
export function quoteItemsBySelection(quote) {
|
|
@@ -242,7 +249,7 @@ export function quoteItemsBySelection(quote) {
|
|
|
242
249
|
export function admissionPriceSavings(price) {
|
|
243
250
|
if (!price.discounted || price.gross === undefined)
|
|
244
251
|
return 0;
|
|
245
|
-
return Math.max(price.gross - price.
|
|
252
|
+
return Math.max(price.gross - price.base, 0);
|
|
246
253
|
}
|
|
247
254
|
export function previewQuoteItems(event) {
|
|
248
255
|
const ids = new Set(event.sections.map((section) => section.id));
|
|
@@ -158,6 +158,92 @@ describe("session-services-ticketing logic", () => {
|
|
|
158
158
|
expect(state.disabled).toBe(true);
|
|
159
159
|
expect(state.label?.text).toContain("On sale");
|
|
160
160
|
});
|
|
161
|
+
it("treats sold-out sale endings as sold out instead of a price label", () => {
|
|
162
|
+
const data = event({
|
|
163
|
+
admissions: [
|
|
164
|
+
admission({
|
|
165
|
+
saleEndsAt: pastEnd,
|
|
166
|
+
saleEndsBehavior: "SOLD_OUT",
|
|
167
|
+
}),
|
|
168
|
+
],
|
|
169
|
+
});
|
|
170
|
+
const state = getAdmissionDisplayState({
|
|
171
|
+
admission: data.admissions[0],
|
|
172
|
+
event: data,
|
|
173
|
+
});
|
|
174
|
+
expect(state.disabled).toBe(true);
|
|
175
|
+
expect(state.label).toBeNull();
|
|
176
|
+
expect(state.soldOut).toBe(true);
|
|
177
|
+
expect(state.statusLabel).toBe("Sold Out");
|
|
178
|
+
expect(state.statusTone).toBe("destructive");
|
|
179
|
+
});
|
|
180
|
+
it("moves post-sale labels into admission status", () => {
|
|
181
|
+
const data = event({
|
|
182
|
+
admissions: [
|
|
183
|
+
admission({
|
|
184
|
+
saleEndsAt: pastEnd,
|
|
185
|
+
saleEndsBehavior: "SALE_ENDED",
|
|
186
|
+
}),
|
|
187
|
+
admission({
|
|
188
|
+
id: "adm_door",
|
|
189
|
+
saleEndsAt: pastEnd,
|
|
190
|
+
saleEndsBehavior: "DOOR",
|
|
191
|
+
}),
|
|
192
|
+
],
|
|
193
|
+
});
|
|
194
|
+
const ended = getAdmissionDisplayState({
|
|
195
|
+
admission: data.admissions[0],
|
|
196
|
+
event: data,
|
|
197
|
+
});
|
|
198
|
+
const door = getAdmissionDisplayState({
|
|
199
|
+
admission: data.admissions[1],
|
|
200
|
+
event: data,
|
|
201
|
+
});
|
|
202
|
+
expect(ended.label).toBeNull();
|
|
203
|
+
expect(ended.statusLabel).toBe("Sale Ended");
|
|
204
|
+
expect(ended.statusTone).toBe("destructive");
|
|
205
|
+
expect(door.label).toBeNull();
|
|
206
|
+
expect(door.statusLabel).toBe("Available At Door");
|
|
207
|
+
expect(door.statusTone).toBe("success");
|
|
208
|
+
});
|
|
209
|
+
it("shows sold-out door admissions as available at door while online sales continue", () => {
|
|
210
|
+
const data = event({
|
|
211
|
+
admissions: [
|
|
212
|
+
admission({
|
|
213
|
+
id: "adm_first_release",
|
|
214
|
+
available: 0,
|
|
215
|
+
sold: 54,
|
|
216
|
+
capacity: 54,
|
|
217
|
+
order: 20,
|
|
218
|
+
saleEndsAt: futureEnd,
|
|
219
|
+
saleEndsBehavior: "DOOR",
|
|
220
|
+
}),
|
|
221
|
+
admission({
|
|
222
|
+
id: "adm_final_release",
|
|
223
|
+
available: 997,
|
|
224
|
+
sold: 3,
|
|
225
|
+
capacity: 1000,
|
|
226
|
+
order: 40,
|
|
227
|
+
saleEndsAt: futureEnd,
|
|
228
|
+
saleEndsBehavior: "DOOR",
|
|
229
|
+
}),
|
|
230
|
+
],
|
|
231
|
+
});
|
|
232
|
+
const first = getAdmissionDisplayState({
|
|
233
|
+
admission: data.admissions[0],
|
|
234
|
+
event: data,
|
|
235
|
+
});
|
|
236
|
+
const final = getAdmissionDisplayState({
|
|
237
|
+
admission: data.admissions[1],
|
|
238
|
+
event: data,
|
|
239
|
+
});
|
|
240
|
+
expect(first.disabled).toBe(true);
|
|
241
|
+
expect(first.soldOut).toBe(true);
|
|
242
|
+
expect(first.statusLabel).toBe("Available At Door");
|
|
243
|
+
expect(first.statusTone).toBe("success");
|
|
244
|
+
expect(final.disabled).toBe(false);
|
|
245
|
+
expect(final.statusLabel).toBeNull();
|
|
246
|
+
});
|
|
161
247
|
it("orders top-level sections and unsectioned admissions together", () => {
|
|
162
248
|
const main = section({ id: "sec_main", order: 2 });
|
|
163
249
|
const early = admission({ id: "adm_early", order: 1 });
|
|
@@ -185,12 +271,13 @@ describe("session-services-ticketing logic", () => {
|
|
|
185
271
|
quoteItem: quoteItem(),
|
|
186
272
|
});
|
|
187
273
|
expect(price).toEqual({
|
|
274
|
+
base: 1000,
|
|
188
275
|
discounted: true,
|
|
189
|
-
|
|
190
|
-
|
|
276
|
+
fees: 200,
|
|
277
|
+
gross: 2000,
|
|
191
278
|
});
|
|
192
279
|
});
|
|
193
|
-
it("uses quote item
|
|
280
|
+
it("uses quote item base pricing without discount styling", () => {
|
|
194
281
|
const price = getAdmissionPriceDisplay({
|
|
195
282
|
admission: admission(),
|
|
196
283
|
mode: "default",
|
|
@@ -208,19 +295,20 @@ describe("session-services-ticketing logic", () => {
|
|
|
208
295
|
}),
|
|
209
296
|
});
|
|
210
297
|
expect(price).toEqual({
|
|
298
|
+
base: 2000,
|
|
211
299
|
discounted: false,
|
|
212
|
-
|
|
300
|
+
fees: 200,
|
|
213
301
|
});
|
|
214
302
|
});
|
|
215
|
-
it("
|
|
303
|
+
it("separates admission base and booking fees for every mode", () => {
|
|
216
304
|
expect(getAdmissionPriceDisplay({
|
|
217
305
|
admission: admission(),
|
|
218
306
|
mode: "default",
|
|
219
|
-
})
|
|
307
|
+
})).toMatchObject({ base: 2000, fees: 200 });
|
|
220
308
|
expect(getAdmissionPriceDisplay({
|
|
221
309
|
admission: admission(),
|
|
222
310
|
mode: "door",
|
|
223
|
-
})
|
|
311
|
+
})).toMatchObject({ base: 2000, fees: 200 });
|
|
224
312
|
});
|
|
225
313
|
it("uses discounted initial preview pricing when available", () => {
|
|
226
314
|
const price = getAdmissionPriceDisplay({
|
|
@@ -233,20 +321,23 @@ describe("session-services-ticketing logic", () => {
|
|
|
233
321
|
mode: "default",
|
|
234
322
|
});
|
|
235
323
|
expect(price).toEqual({
|
|
324
|
+
base: 1000,
|
|
236
325
|
discounted: true,
|
|
237
|
-
|
|
238
|
-
|
|
326
|
+
fees: 200,
|
|
327
|
+
gross: 2000,
|
|
239
328
|
});
|
|
240
329
|
});
|
|
241
330
|
it("calculates admission savings from discounted display prices", () => {
|
|
242
331
|
expect(admissionPriceSavings({
|
|
332
|
+
base: 1000,
|
|
243
333
|
discounted: true,
|
|
244
|
-
|
|
245
|
-
|
|
334
|
+
fees: 200,
|
|
335
|
+
gross: 2000,
|
|
246
336
|
})).toBe(1000);
|
|
247
337
|
expect(admissionPriceSavings({
|
|
338
|
+
base: 2200,
|
|
248
339
|
discounted: false,
|
|
249
|
-
|
|
340
|
+
fees: 200,
|
|
250
341
|
})).toBe(0);
|
|
251
342
|
});
|
|
252
343
|
it("divides preview quote pricing by preview quantity", () => {
|
|
@@ -268,9 +359,10 @@ describe("session-services-ticketing logic", () => {
|
|
|
268
359
|
}),
|
|
269
360
|
});
|
|
270
361
|
expect(price).toEqual({
|
|
362
|
+
base: 1000,
|
|
271
363
|
discounted: true,
|
|
272
|
-
|
|
273
|
-
|
|
364
|
+
fees: 200,
|
|
365
|
+
gross: 2000,
|
|
274
366
|
});
|
|
275
367
|
});
|
|
276
368
|
});
|