Merge pull request #3210 from Safelite/feature/CASH-2571

CASH-2572 | Fix initialization logic & Styling
This commit is contained in:
scottkiener-at-safelite 2026-06-05 10:41:48 -04:00 committed by GitHub
commit 60c3b1e398
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 15 deletions

View file

@ -112,8 +112,8 @@ describe("date-picker.vue", () => {
wrapper.unmount();
});
test("returns empty array when availableDates is empty", () => {
const wrapper = mountDesktop({ availableDates: [] });
test("returns empty array when availableDates is null", () => {
const wrapper = mountDesktop({ availableDates: null });
expect(wrapper.vm.allDates).toEqual([]);
wrapper.unmount();
});
@ -427,7 +427,7 @@ describe("date-picker.vue", () => {
describe("initializeWindow", () => {
test("sets the initialized flag to true", async () => {
const wrapper = mountDesktop({ availableDates: [] });
const wrapper = mountDesktop({ availableDates: null });
expect(wrapper.vm.initialized).toBe(false);
await wrapper.setProps({ availableDates: AVAILABLE_DATES });
expect(wrapper.vm.initialized).toBe(true);
@ -436,7 +436,7 @@ describe("date-picker.vue", () => {
test("positions windowStart to the window containing the first available date", async () => {
const wrapper = mountDesktop({
availableDates: [],
availableDates: null,
startDate: "2026-01-01",
endDate: "2026-01-10",
});
@ -447,7 +447,7 @@ describe("date-picker.vue", () => {
});
test("emits update:modelValue with the first available date", async () => {
const wrapper = mountDesktop({ availableDates: [] });
const wrapper = mountDesktop({ availableDates: null });
await wrapper.setProps({ availableDates: AVAILABLE_DATES });
expect(wrapper.emitted("update:modelValue")[0][0]).toBe("2026-01-21");
wrapper.unmount();
@ -455,7 +455,7 @@ describe("date-picker.vue", () => {
test("positions windowStart to the last window and does not emit when no dates are available", async () => {
const wrapper = mountDesktop({
availableDates: [],
availableDates: null,
startDate: "2026-01-01",
endDate: "2026-01-10",
});
@ -468,7 +468,7 @@ describe("date-picker.vue", () => {
});
test("does not re-run after initialized flag is set", async () => {
const wrapper = mountDesktop({ availableDates: [] });
const wrapper = mountDesktop({ availableDates: null });
await wrapper.setProps({ availableDates: AVAILABLE_DATES });
const emissionCount = wrapper.emitted("update:modelValue").length;
// Add a newly available date within the range to trigger the watcher again
@ -481,8 +481,8 @@ describe("date-picker.vue", () => {
describe("allDates watcher", () => {
test("calls initializeWindow when dates first arrive with no modelValue set", async () => {
const wrapper = mountDesktop({ availableDates: [] });
// No dates → mounted() does nothing; initialized stays false
const wrapper = mountDesktop({ availableDates: null });
// null availableDates → allDates=[] → mounted() does nothing; initialized stays false
expect(wrapper.vm.initialized).toBe(false);
await wrapper.setProps({ availableDates: AVAILABLE_DATES });
expect(wrapper.vm.initialized).toBe(true);
@ -492,7 +492,7 @@ describe("date-picker.vue", () => {
test("clears pendingAutoSelect and advances the window when pendingAutoSelect is true", async () => {
const wrapper = mountDesktop({
availableDates: [],
availableDates: null,
startDate: "2026-01-01",
endDate: "2026-01-10",
});
@ -506,11 +506,11 @@ describe("date-picker.vue", () => {
wrapper.unmount();
});
test("takes no action when allDates becomes empty", async () => {
test("takes no action when availableDates becomes null", async () => {
const wrapper = mountDesktop({ availableDates: AVAILABLE_DATES });
// mounted() calls initializeWindow() → emits; record count
const emissionCount = wrapper.emitted("update:modelValue").length;
await wrapper.setProps({ availableDates: [] });
await wrapper.setProps({ availableDates: null });
// watcher fires with newDates=[] → early return, nothing changes
expect(wrapper.emitted("update:modelValue").length).toBe(emissionCount);
wrapper.unmount();

View file

@ -80,8 +80,8 @@ export default {
name: "datePicker",
props: {
availableDates: {
type: Array,
default: () => [],
default: null,
validator: (v) => v === null || Array.isArray(v),
},
startDate: {
type: String,
@ -111,9 +111,11 @@ export default {
},
computed: {
allDates() {
if (this.availableDates === null) return [];
const availableSet = new Set(this.availableDates);
if (!this.availableDates.length || !this.startDate || !this.endDate) return [];
if (!this.startDate || !this.endDate) return [];
const first = parseLocalDate(this.startDate);
const last = parseLocalDate(this.endDate);

View file

@ -122,6 +122,7 @@ export default {
timeSlots: resultMap.mobileTimeSlots ?? null,
}
: null;
vm.datesLoaded = true;
});
},
computed: {
@ -129,6 +130,7 @@ export default {
return this.getCmsContent("ServiceLocationText", "Text");
},
availableDates() {
if (!this.datesLoaded) return null;
const inshopDates = this.inShopProvidersAndTimeslots.flatMap(({ timeSlots }) =>
(timeSlots?.days ?? []).map((d) => d.date)
);
@ -142,6 +144,7 @@ export default {
return {
selectedDate: null,
isLoadingDates: false,
datesLoaded: false,
datePickerStartDate: toDateString(0),
datePickerEndDate: toDateString(SCHEDULE_FETCH_DAYS - 1),
inShopProvidersAndTimeslots: [],
@ -220,4 +223,8 @@ export default {
.dark-header {
color: $black;
}
h5 {
line-height: 32px;
font-size: 1.25rem;
}
</style>