Skip to content

Commit 966882b

Browse files
authored
Merge pull request #8288 from jrjohnson/5908-first-week-year
Fix New Year Errors
2 parents ef3bebd + 00bdbeb commit 966882b

File tree

5 files changed

+200
-103
lines changed

5 files changed

+200
-103
lines changed
Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
import Component from '@glimmer/component';
22
import { DateTime } from 'luxon';
3+
34
export default class DashboardWeekComponent extends Component {
45
get expanded() {
5-
const now = DateTime.now();
6-
const lastSunday = now.set({ weekday: 1 }).minus({ week: 1 }).toFormat('W');
7-
const thisSunday = now.set({ weekday: 1 }).toFormat('W');
8-
const nextSunday = now.set({ weekday: 1 }).plus({ week: 1 }).toFormat('W');
6+
const lastSunday = this.thisThursday.minus({ week: 1 }).toFormat('W');
7+
const thisSunday = this.thisThursday.toFormat('W');
8+
const nextSunday = this.thisThursday.plus({ week: 1 }).toFormat('W');
99

1010
return `${lastSunday}-${thisSunday}-${nextSunday}`;
1111
}
12+
13+
get thisThursday() {
14+
const thursday = DateTime.fromObject({
15+
weekday: 4,
16+
hour: 0,
17+
minute: 0,
18+
second: 0,
19+
});
20+
21+
// In this component the week always starts on Sunday, but luxon's starts on Monday
22+
// If today is sunday, we need to add a week to get the correct Thursday
23+
if (DateTime.now().weekday === 7) {
24+
return thursday.plus({ weeks: 1 });
25+
}
26+
27+
return thursday;
28+
}
29+
1230
get year() {
13-
return DateTime.now().year;
31+
return this.thisThursday.weekYear;
1432
}
33+
1534
get week() {
16-
const today = DateTime.now();
17-
// In this component the week always starts on Sunday, but luxon's starts on Monday
18-
// so we need to adjust the week number to account for that.
19-
if (today.weekday === 7) {
20-
return today.weekNumber + 1;
21-
} else {
22-
return today.weekNumber;
23-
}
35+
return this.thisThursday.weekNumber;
2436
}
2537
}

packages/ilios-common/addon/components/week-glance.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,33 @@ export default class WeeklyGlance extends Component {
2929
}
3030

3131
get thursdayOfTheWeek() {
32-
return DateTime.fromObject({
32+
const thursday = DateTime.fromObject({
3333
weekYear: this.args.year,
3434
weekNumber: this.args.week,
3535
weekday: 4,
3636
hour: 0,
3737
minute: 0,
3838
second: 0,
39-
}).toJSDate();
39+
});
40+
41+
if (!thursday.isValid) {
42+
console.error('Invalid date', thursday.invalidReason, this.args.year, this.args.week);
43+
return null;
44+
}
45+
return thursday.toJSDate();
4046
}
4147

4248
get midnightAtTheStartOfTheWeekDateTime() {
49+
if (!this.thursdayOfTheWeek) {
50+
return null;
51+
}
4352
return DateTime.fromJSDate(this.localeDays.firstDayOfDateWeek(this.thursdayOfTheWeek));
4453
}
4554

4655
get midnightAtTheEndOfTheWeekDateTime() {
56+
if (!this.thursdayOfTheWeek) {
57+
return null;
58+
}
4759
return DateTime.fromJSDate(this.localeDays.lastDayOfDateWeek(this.thursdayOfTheWeek));
4860
}
4961

packages/ilios-common/addon/components/weekly-events.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { DateTime } from 'luxon';
44

55
export default class WeeklyEvents extends Component {
66
get weeksInYear() {
7-
const weeksInTheYear = DateTime.now().set({ year: this.args.year }).weeksInWeekYear;
7+
const { weeksInWeekYear } = DateTime.fromObject({ year: this.args.year });
88
const weeks = [];
9-
for (let i = 1; i <= weeksInTheYear; i++) {
9+
for (let i = 1; i <= weeksInWeekYear; i++) {
1010
weeks.push(`${i}`);
1111
}
1212
return weeks;

packages/test-app/tests/integration/components/dashboard/week-test.js

Lines changed: 113 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,26 @@ module('Integration | Component | dashboard/week', function (hooks) {
3434

3535
return expectedTitle;
3636
};
37+
38+
this.setupEvents = function (events) {
39+
class UserEvents extends Service {
40+
async getEvents() {
41+
return events;
42+
}
43+
}
44+
this.owner.register('service:user-events', UserEvents);
45+
};
46+
47+
this.testTitleOnDate = async function (assert, obj, expectedTitle) {
48+
const dt = DateTime.fromObject(obj);
49+
freezeDateAt(dt.toJSDate());
50+
await render(hbs`<Dashboard::Week />`);
51+
assert.strictEqual(
52+
component.weekGlance.title,
53+
expectedTitle,
54+
`correct title on ${dt.toISODate()}`,
55+
);
56+
};
3757
});
3858

3959
hooks.afterEach(() => {
@@ -75,12 +95,7 @@ module('Integration | Component | dashboard/week', function (hooks) {
7595
});
7696

7797
const { userevents } = this.server.db;
78-
class UserEvents extends Service {
79-
async getEvents() {
80-
return userevents;
81-
}
82-
}
83-
this.owner.register('service:user-events', UserEvents);
98+
this.setupEvents(userevents);
8499

85100
await render(hbs`<Dashboard::Week />`);
86101
const expectedTitle = this.getTitle();
@@ -92,14 +107,7 @@ module('Integration | Component | dashboard/week', function (hooks) {
92107
});
93108

94109
test('it renders blank', async function (assert) {
95-
class UserEvents extends Service {
96-
async getEvents() {
97-
return [];
98-
}
99-
}
100-
this.owner.register('service:user-events', UserEvents);
101-
this.userEvents = this.owner.lookup('service:user-events');
102-
110+
this.setupEvents([]);
103111
await render(hbs`<Dashboard::Week />`);
104112
const expectedTitle = this.getTitle();
105113
assert.strictEqual(component.weeklyLink, 'All Weeks');
@@ -108,95 +116,114 @@ module('Integration | Component | dashboard/week', function (hooks) {
108116
});
109117

110118
test('right week on sunday #5308', async function (assert) {
111-
class UserEvents extends Service {
112-
async getEvents() {
113-
return [];
114-
}
115-
}
116-
this.owner.register('service:user-events', UserEvents);
117-
this.userEvents = this.owner.lookup('service:user-events');
118-
freezeDateAt(DateTime.fromObject({ year: 2024, month: 3, day: 10 }).toJSDate());
119-
120-
await render(hbs`<Dashboard::Week />`);
121-
assert.strictEqual(component.weekGlance.title, 'March 10-16 Week at a Glance');
119+
assert.expect(1);
120+
await this.testTitleOnDate(
121+
assert,
122+
{ year: 2024, month: 3, day: 10 },
123+
'March 10-16 Week at a Glance',
124+
);
122125
});
123126

124127
test('right week on monday #5308', async function (assert) {
125-
class UserEvents extends Service {
126-
async getEvents() {
127-
return [];
128-
}
129-
}
130-
this.owner.register('service:user-events', UserEvents);
131-
this.userEvents = this.owner.lookup('service:user-events');
132-
freezeDateAt(DateTime.fromObject({ year: 2023, month: 8, day: 7 }).toJSDate());
133-
134-
await render(hbs`<Dashboard::Week />`);
135-
assert.strictEqual(component.weekGlance.title, 'August 6-12 Week at a Glance');
128+
assert.expect(1);
129+
await this.testTitleOnDate(
130+
assert,
131+
{ year: 2023, month: 8, day: 7 },
132+
'August 6-12 Week at a Glance',
133+
);
136134
});
137135

138136
test('right week on tuesday #5308', async function (assert) {
139-
class UserEvents extends Service {
140-
async getEvents() {
141-
return [];
142-
}
143-
}
144-
this.owner.register('service:user-events', UserEvents);
145-
this.userEvents = this.owner.lookup('service:user-events');
146-
freezeDateAt(DateTime.fromObject({ year: 2022, month: 12, day: 6 }).toJSDate());
147-
await render(hbs`<Dashboard::Week />`);
148-
assert.strictEqual(component.weekGlance.title, 'December 4-10 Week at a Glance');
137+
assert.expect(1);
138+
await this.testTitleOnDate(
139+
assert,
140+
{ year: 2022, month: 12, day: 6 },
141+
'December 4-10 Week at a Glance',
142+
);
149143
});
150144

151145
test('right week on wednesday #5308', async function (assert) {
152-
class UserEvents extends Service {
153-
async getEvents() {
154-
return [];
155-
}
156-
}
157-
this.owner.register('service:user-events', UserEvents);
158-
this.userEvents = this.owner.lookup('service:user-events');
159-
freezeDateAt(DateTime.fromObject({ year: 2022, month: 7, day: 13 }).toJSDate());
160-
await render(hbs`<Dashboard::Week />`);
161-
assert.strictEqual(component.weekGlance.title, 'July 10-16 Week at a Glance');
146+
assert.expect(1);
147+
await this.testTitleOnDate(
148+
assert,
149+
{ year: 2022, month: 7, day: 13 },
150+
'July 10-16 Week at a Glance',
151+
);
162152
});
163153

164154
test('right week on thursday #5308', async function (assert) {
165-
class UserEvents extends Service {
166-
async getEvents() {
167-
return [];
168-
}
169-
}
170-
this.owner.register('service:user-events', UserEvents);
171-
this.userEvents = this.owner.lookup('service:user-events');
172-
freezeDateAt(DateTime.fromObject({ year: 2021, month: 5, day: 13 }).toJSDate());
173-
await render(hbs`<Dashboard::Week />`);
174-
assert.strictEqual(component.weekGlance.title, 'May 9-15 Week at a Glance');
155+
assert.expect(1);
156+
await this.testTitleOnDate(
157+
assert,
158+
{ year: 2021, month: 5, day: 13 },
159+
'May 9-15 Week at a Glance',
160+
);
175161
});
176162

177163
test('right week on friday #5308', async function (assert) {
178-
class UserEvents extends Service {
179-
async getEvents() {
180-
return [];
181-
}
182-
}
183-
this.owner.register('service:user-events', UserEvents);
184-
this.userEvents = this.owner.lookup('service:user-events');
185-
freezeDateAt(DateTime.fromObject({ year: 2021, month: 9, day: 24 }).toJSDate());
186-
await render(hbs`<Dashboard::Week />`);
187-
assert.strictEqual(component.weekGlance.title, 'September 19-25 Week at a Glance');
164+
assert.expect(1);
165+
await this.testTitleOnDate(
166+
assert,
167+
{ year: 2021, month: 9, day: 24 },
168+
'September 19-25 Week at a Glance',
169+
);
188170
});
189171

190172
test('right week on saturday #5308', async function (assert) {
191-
class UserEvents extends Service {
192-
async getEvents() {
193-
return [];
194-
}
195-
}
196-
this.owner.register('service:user-events', UserEvents);
197-
this.userEvents = this.owner.lookup('service:user-events');
198-
freezeDateAt(DateTime.fromObject({ year: 2022, month: 7, day: 30 }).toJSDate());
199-
await render(hbs`<Dashboard::Week />`);
200-
assert.strictEqual(component.weekGlance.title, 'July 24-30 Week at a Glance');
173+
assert.expect(1);
174+
await this.testTitleOnDate(
175+
assert,
176+
{ year: 2022, month: 7, day: 30 },
177+
'July 24-30 Week at a Glance',
178+
);
179+
});
180+
181+
test('correct at the end of 2023 and the start of 2024', async function (assert) {
182+
assert.expect(7);
183+
this.setupEvents([]);
184+
const title = 'December 31 - January 6 Week at a Glance';
185+
await this.testTitleOnDate(assert, { year: 2023, month: 12, day: 31 }, title);
186+
await this.testTitleOnDate(assert, { year: 2024, month: 1, day: 1 }, title);
187+
await this.testTitleOnDate(assert, { year: 2024, month: 1, day: 2 }, title);
188+
await this.testTitleOnDate(assert, { year: 2024, month: 1, day: 3 }, title);
189+
await this.testTitleOnDate(assert, { year: 2024, month: 1, day: 4 }, title);
190+
await this.testTitleOnDate(assert, { year: 2024, month: 1, day: 5 }, title);
191+
await this.testTitleOnDate(assert, { year: 2024, month: 1, day: 6 }, title);
192+
});
193+
194+
test('correct at the end of 2024 and start of 2025', async function (assert) {
195+
assert.expect(7);
196+
this.setupEvents([]);
197+
const title = 'December 29 - January 4 Week at a Glance';
198+
await this.testTitleOnDate(assert, { year: 2024, month: 12, day: 29 }, title);
199+
await this.testTitleOnDate(assert, { year: 2024, month: 12, day: 30 }, title);
200+
await this.testTitleOnDate(assert, { year: 2024, month: 12, day: 31 }, title);
201+
await this.testTitleOnDate(assert, { year: 2025, month: 1, day: 1 }, title);
202+
await this.testTitleOnDate(assert, { year: 2025, month: 1, day: 2 }, title);
203+
await this.testTitleOnDate(assert, { year: 2025, month: 1, day: 3 }, title);
204+
await this.testTitleOnDate(assert, { year: 2025, month: 1, day: 4 }, title);
205+
});
206+
207+
test('correct at the end of 2025 and start of 2026', async function (assert) {
208+
assert.expect(7);
209+
this.setupEvents([]);
210+
const title = 'December 28 - January 3 Week at a Glance';
211+
await this.testTitleOnDate(assert, { year: 2025, month: 12, day: 28 }, title);
212+
await this.testTitleOnDate(assert, { year: 2025, month: 12, day: 29 }, title);
213+
await this.testTitleOnDate(assert, { year: 2025, month: 12, day: 30 }, title);
214+
await this.testTitleOnDate(assert, { year: 2025, month: 12, day: 31 }, title);
215+
await this.testTitleOnDate(assert, { year: 2026, month: 1, day: 1 }, title);
216+
await this.testTitleOnDate(assert, { year: 2026, month: 1, day: 2 }, title);
217+
await this.testTitleOnDate(assert, { year: 2026, month: 1, day: 3 }, title);
218+
});
219+
220+
test('correct on some random day', async function (assert) {
221+
assert.expect(1);
222+
this.setupEvents([]);
223+
await this.testTitleOnDate(
224+
assert,
225+
{ year: 2005, month: 6, day: 24 },
226+
'June 19-25 Week at a Glance',
227+
);
201228
});
202229
});

packages/test-app/tests/integration/components/weekly-events-test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,50 @@ module('Integration | Component | weekly events', function (hooks) {
114114
assert.strictEqual(component.topNavigation.title, '2016');
115115
assert.strictEqual(component.bottomNavigation.title, '2016');
116116
});
117+
118+
test('it renders 2024 ilios/ilios#5908', async function (assert) {
119+
await render(
120+
hbs`<WeeklyEvents
121+
@year={{2024}}
122+
@expandedWeeks={{(array)}}
123+
@setYear={{(noop)}}
124+
@toggleOpenWeek={{(noop)}}
125+
/>`,
126+
);
127+
assert.strictEqual(component.topNavigation.title, '2024');
128+
assert.strictEqual(component.weeks.length, 52);
129+
assert.strictEqual(component.weeks[0].title, 'December 31 - January 6');
130+
assert.strictEqual(component.weeks[51].title, 'December 22-28');
131+
});
132+
133+
test('it renders 2025 ilios/ilios#5908', async function (assert) {
134+
await render(
135+
hbs`<WeeklyEvents
136+
@year={{2025}}
137+
@expandedWeeks={{(array)}}
138+
@setYear={{(noop)}}
139+
@toggleOpenWeek={{(noop)}}
140+
/>`,
141+
);
142+
assert.strictEqual(component.topNavigation.title, '2025');
143+
assert.strictEqual(component.weeks.length, 52);
144+
assert.strictEqual(component.weeks[0].title, 'December 29 - January 4');
145+
assert.strictEqual(component.weeks[51].title, 'December 21-27');
146+
});
147+
148+
test('it renders 2026 ilios/ilios#5908', async function (assert) {
149+
assert.expect(4);
150+
await render(
151+
hbs`<WeeklyEvents
152+
@year={{2026}}
153+
@expandedWeeks={{(array)}}
154+
@setYear={{(noop)}}
155+
@toggleOpenWeek={{(noop)}}
156+
/>`,
157+
);
158+
assert.strictEqual(component.topNavigation.title, '2026');
159+
assert.strictEqual(component.weeks.length, 53);
160+
assert.strictEqual(component.weeks[0].title, 'December 28 - January 3');
161+
assert.strictEqual(component.weeks[52].title, 'December 27 - January 2');
162+
});
117163
});

0 commit comments

Comments
 (0)