diff --git a/src/app/components/admin/datetime-templates/datetime-templates.component.html b/src/app/components/admin/datetime-templates/datetime-templates.component.html index df6f4dca2..72aefca0a 100644 --- a/src/app/components/admin/datetime-templates/datetime-templates.component.html +++ b/src/app/components/admin/datetime-templates/datetime-templates.component.html @@ -3,22 +3,17 @@
<baw-zoned-datetime [value]="fakeDateWithZone" />
@@ -90,7 +85,7 @@ baw-zoned-datetime (Implicit)
<baw-zoned-datetime [value]="fakeDateWithZone" dateOnly />
@@ -100,7 +95,7 @@ baw-zoned-datetime (Implicit)
<baw-zoned-datetime [value]="fakeDateWithZone" timeOnly />
@@ -112,7 +107,7 @@ baw-zoned-datetime (Implicit)
baw-zoned-datetime (Explicit)
- Zoned Date & Time Instants:
+ Zoned Date & Time Instants:
<baw-zoned-datetime [value]="fakeDate" [timezone]="fakeTimezone" />
@@ -122,7 +117,7 @@ baw-zoned-datetime (Explicit)
- Zoned Date Instants:
+ Zoned Date Instants:
<baw-zoned-datetime [value]="fakeDate" [timezone]="fakeTimezone" dateOnly />
@@ -136,7 +131,7 @@ baw-zoned-datetime (Explicit)
- Zoned Time Instants:
+ Zoned Time Instants:
<baw-zoned-datetime [value]="fakeDate" [timezone]="fakeTimezone" timeOnly />
@@ -154,7 +149,7 @@ baw-zoned-datetime (Explicit)
baw-duration
- Durations (sexagesimal):
+ Durations (sexagesimal):
<baw-duration [value]="fakeDuration" />
@@ -164,7 +159,7 @@ baw-duration
- Duration (ISO 8601):
+ Duration (ISO 8601):
<baw-duration [value]="fakeDuration" iso8601 />
@@ -174,7 +169,7 @@ baw-duration
- Duration (Humanized):
+ Duration (Humanized):
<baw-duration [value]="fakeDuration" humanized />
@@ -188,7 +183,7 @@ baw-duration
baw-time-since
- Relative Date & Time Instants:
+ Relative Date & Time Instants:
<baw-time-since [value]="fakeDate" />
diff --git a/src/app/components/admin/datetime-templates/datetime-templates.component.ts b/src/app/components/admin/datetime-templates/datetime-templates.component.ts
index 94527e1e1..76695b70a 100644
--- a/src/app/components/admin/datetime-templates/datetime-templates.component.ts
+++ b/src/app/components/admin/datetime-templates/datetime-templates.component.ts
@@ -1,4 +1,4 @@
-import { Component, OnInit } from "@angular/core";
+import { Component } from "@angular/core";
import { List } from "immutable";
import { PageComponent } from "@helpers/page/pageComponent";
import { DateTime, Duration } from "luxon";
@@ -9,28 +9,21 @@ import { adminMenuItemActions } from "../dashboard/dashboard.component";
selector: "baw-admin-datetime-templates",
templateUrl: "datetime-templates.component.html",
})
-class DateTimeExampleComponent extends PageComponent implements OnInit {
+class DateTimeExampleComponent extends PageComponent {
public constructor() {
super();
}
protected fakeTimezone = "Australia/Perth";
- protected fakeDate;
- protected fakeDuration;
+ protected fakeDate = DateTime.now();
+ protected fakeDuration = Duration.fromObject({ hours: 1, minutes: 30 });
- public ngOnInit(): void {
- this.fakeDate = DateTime.now();
- this.fakeDuration = Duration.fromObject({ hours: 1, minutes: 30 });
- }
-
- protected get fakeUserDate(): DateTime {
- const luxonDateTime = this.fakeDate instanceof DateTime ? this.fakeDate : DateTime.fromISO(this.fakeDate);
- return luxonDateTime;
- }
-
- // used for implicit timezone tests
protected get fakeDateWithZone(): DateTime {
- const luxonDateTime = this.fakeDate instanceof DateTime ? this.fakeDate : DateTime.fromISO(this.fakeDate);
+ const luxonDateTime =
+ this.fakeDate instanceof DateTime
+ ? this.fakeDate
+ : DateTime.fromISO(this.fakeDate);
+
return luxonDateTime.setZone(this.fakeTimezone, { keepLocalTime: true });
}
@@ -45,12 +38,17 @@ class DateTimeExampleComponent extends PageComponent implements OnInit {
protected updateFakeDate(event: any): void {
const inputValue: string = event.target.value;
- const newDate = DateTime.fromISO(inputValue).setZone(this.fakeTimezone, { keepLocalTime: true });
+ const newDate = DateTime.fromFormat(inputValue, "yyyy-MM-dd HH:mm:ss");
if (newDate.isValid) {
this.fakeDate = newDate;
}
}
+
+ // used in the date/time input
+ protected formatDate(dateTime: DateTime): string {
+ return dateTime.toFormat("yyyy-MM-dd HH:mm:ss");
+ }
}
DateTimeExampleComponent.linkToRoute({
diff --git a/src/app/components/shared/datetime/abstract-datetime.component.spec.ts b/src/app/components/shared/datetime/abstract-datetime.component.spec.ts
new file mode 100644
index 000000000..1fa7d03f5
--- /dev/null
+++ b/src/app/components/shared/datetime/abstract-datetime.component.spec.ts
@@ -0,0 +1,23 @@
+import { AbstractDatetimeComponent } from "./abstract-datetime.component";
+
+describe("AbstractDatetimeComponent", () => {
+ let abstractDatetimeComponent: AbstractDatetimeComponent;
+
+ beforeEach(() => {
+ abstractDatetimeComponent = new AbstractDatetimeComponentMock();
+ });
+
+ it("should create", () => {
+ expect(abstractDatetimeComponent).toBeTruthy();
+ });
+
+ it("should have a default prefix of an empty string", () => {
+ expect(abstractDatetimeComponent.suffix()).toEqual("");
+ });
+});
+
+class AbstractDatetimeComponentMock extends AbstractDatetimeComponent {
+ public formattedValue = () => "";
+ public tooltipValue = () => "";
+ public rawDateTime = () => "";
+}
diff --git a/src/app/components/shared/datetime/datetime/datetime.component.spec.ts b/src/app/components/shared/datetime/datetime/datetime.component.spec.ts
index 27baacccc..011f079a6 100644
--- a/src/app/components/shared/datetime/datetime/datetime.component.spec.ts
+++ b/src/app/components/shared/datetime/datetime/datetime.component.spec.ts
@@ -14,13 +14,13 @@ describe("DatetimeComponent", () => {
});
function setup(): void {
- // to ensure that tests pass for all timezones, we set the default timezone to utc
- // this will ensure that all DateTime objects are created in utc instead of the test runners local timezone
+ // to ensure that tests pass for all timezones, we set the default timezone to Australia/Perth
+ // this mocks the test runners timezone to be Australia/Perth so that they will assert correctly in all timezones
Settings.defaultZone = "Australia/Perth";
- // utc datetime should be localised to "Australia/Perth"
+ // utc datetime should be localized to "Australia/Perth"
let fakeDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
- fakeDateTime = fakeDateTime.setZone("utc");
+ fakeDateTime = fakeDateTime.toUTC();
spectator = createComponent({ detectChanges: false });
spectator.component.value = fakeDateTime;
@@ -36,6 +36,9 @@ describe("DatetimeComponent", () => {
expect(spectator.component).toBeInstanceOf(DatetimeComponent);
});
+ // the output time should be localized to the users timezone
+ // eg. Because this fake DateTime was created using UTC+0, it should be localized to UTC+8
+ // adding 8 hours to the UTC time
it("should display the full date and time in the users local timezone by default", () => {
const fakeDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
const expectedDateTime = "2020-01-01 20:10:11";
@@ -81,17 +84,6 @@ describe("DatetimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedDateTime);
});
- it("should show a full utc date time in the users timezone", () => {
- const fakeDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
- const expectedDateTime = "2020-01-01 20:10:11";
-
- spectator.component.value = fakeDateTime;
-
- spectator.detectChanges();
-
- expect(spectator.element).toHaveExactTrimmedText(expectedDateTime);
- });
-
it("should have a tooltip that displays the full un-localized date, time and utc offset for a JavaScript date object", () => {
const expectedTooltip = "2020-01-01 20:10:11 (Australia/Perth UTC+08:00)";
const mockDate = new Date("2020-01-01T12:10:11.000Z");
@@ -112,7 +104,7 @@ describe("DatetimeComponent", () => {
assertTooltip(componentElement(), expectedTooltip);
});
- it("should localize an iso8601 date/time with an offset to the users local timezone", () => {
+ it("should localize an iso8601 date/time with an offset", () => {
const expectedDateTime = "2020-01-01 19:10:11";
const mockDateTime = new Date("2020-01-01T12:10:11.000+01:00");
@@ -122,7 +114,7 @@ describe("DatetimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedDateTime);
});
- it("should localize a Luxon DateTime object with a timezone offset to the users local timezone", () => {
+ it("should localize a Luxon DateTime object with a timezone offset", () => {
const expectedDateTime = "2020-01-01 19:10:11";
const mockDateTime = DateTime.fromISO("2020-01-01T12:10:11.000+01:00");
@@ -133,8 +125,8 @@ describe("DatetimeComponent", () => {
});
it("should have the correct tooltip for a Luxon DateTime object with an offset, but no timezone", () => {
- // since tooltips should always be localized to the users timezone, we know that the tooltip should
- // include timezone information
+ // since tooltips should always be localized to the users timezone, we know the users timezone name
+ // so unlike the zoned-datetime component, the tooltip should include timezone information
const expectedTooltip = "2020-01-01 19:10:11 (Australia/Perth UTC+08:00)";
const mockDateTime = new Date("2020-01-01T12:10:11.000+01:00");
diff --git a/src/app/components/shared/datetime/duration/duration.component.ts b/src/app/components/shared/datetime/duration/duration.component.ts
index a70afdd20..d0d50ebda 100644
--- a/src/app/components/shared/datetime/duration/duration.component.ts
+++ b/src/app/components/shared/datetime/duration/duration.component.ts
@@ -19,7 +19,7 @@ export class DurationComponent extends AbstractDatetimeComponent {
@Input() public iso8601: string | boolean;
public formattedValue(): string {
- // we use isInstantiated() to check if the humanized attribute is set (empty)
+ // we use isInstantiated() to check if the humanized attribute is set
// and we also check that it is not set to false
// by allowing boolean values, we support reactive formats (e.g. [humanized]="isHumanized")
if (isInstantiated(this.humanized) && this.humanized !== false) {
diff --git a/src/app/components/shared/datetime/time-since/time-since.component.spec.ts b/src/app/components/shared/datetime/time-since/time-since.component.spec.ts
index 990e06094..9d060f042 100644
--- a/src/app/components/shared/datetime/time-since/time-since.component.spec.ts
+++ b/src/app/components/shared/datetime/time-since/time-since.component.spec.ts
@@ -47,7 +47,7 @@ describe("RelativeTimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedText);
});
- it("should not emit seconds or miliseconds in the formatted text", () => {
+ it("should not emit seconds or milliseconds in the formatted text", () => {
const expectedText = "4 hours 42 minutes ago";
const fakeDuration = Duration.fromObject({
hours: 4,
@@ -62,7 +62,7 @@ describe("RelativeTimeComponent", () => {
expect(spectator.element).toHaveExactTrimmedText(expectedText);
});
- it("should round up times to the nearest second", () => {
+ it("should round up times to the nearest minute", () => {
const expectedText = "4 hours 42 minutes ago";
const fakeDuration = Duration.fromObject({
hours: 4,
diff --git a/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.spec.ts b/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.spec.ts
index b8e3f3323..1d814fb26 100644
--- a/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.spec.ts
+++ b/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.spec.ts
@@ -59,7 +59,9 @@ describe("ZonedDateTimeComponent", () => {
const expectedTooltip = "2020-01-01 12:10:11 (Australia/Darwin UTC+09:30)";
// set the implicit timezone
- mockDateTime = mockDateTime.setZone("utc");
+ mockDateTime = mockDateTime.setZone("Australia/Brisbane", {
+ keepLocalTime: true,
+ });
// set the explicit timezone to UTC+08:00
spectator.component.timezone = "Australia/Darwin"; // UTC+09:30
@@ -91,6 +93,7 @@ describe("ZonedDateTimeComponent", () => {
testDateTime = testDateTime.setZone(implicitTimezone, { keepLocalTime: true });
spectator.component.timezone = undefined;
spectator.component.value = testDateTime;
+
spectator.component.ngOnChanges();
spectator.detectChanges();
@@ -106,7 +109,9 @@ describe("ZonedDateTimeComponent", () => {
let implicitDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
// don't recalculate the time by using keepLocalTime: true
- implicitDateTime = implicitDateTime.setZone(implicitTimezone, { keepLocalTime: true });
+ implicitDateTime = implicitDateTime.setZone(implicitTimezone, {
+ keepLocalTime: true,
+ });
spectator.component.value = implicitDateTime;
spectator.detectChanges();
@@ -130,14 +135,16 @@ describe("ZonedDateTimeComponent", () => {
let mockDateTime = DateTime.fromISO("2020-01-01T12:10:11.000Z");
// set the implicit date/time timezone to UTC+09:30
- // we use keepLocalTime = true because otherwise, the time will be localised to Australia/Darwin
+ // we use keepLocalTime = true because otherwise, the time adjusted and localized to Australia/Darwin
// eg. The time will be 12:10:11 + 09:30 = 21:40:11 without us ever localising it
+ // because we want to check if the component is localising it, we can disable this behavior when creating
+ // our fake DateTime object
mockDateTime = mockDateTime.setZone("Australia/Darwin", {
keepLocalTime: true,
- }); // utc+09:30
+ });
if (!implicitTimezone) {
- spectator.component.timezone = "Australia/Darwin";
+ spectator.component.timezone = "Australia/Darwin"; // utc+09:30
}
spectator.component.value = mockDateTime;
@@ -151,13 +158,14 @@ describe("ZonedDateTimeComponent", () => {
const expectedDate = "2020-01-01 12:10:11";
// Australia/Darwin is the same timezone used in the explicit and implicit tests
+ // by using Settings.defaultZone, we mock the runners timezone to Australia/Darwin
Settings.defaultZone = "Australia/Darwin";
spectator.detectChanges();
expect(spectator.element).toHaveExactTrimmedText(expectedDate);
});
- it("should not localise the date/time to the defined timezone", () => {
+ it("should not localize the date/time to the defined timezone", () => {
const expectedDate = "2020-01-01 12:10:11";
spectator.detectChanges();
@@ -182,7 +190,7 @@ describe("ZonedDateTimeComponent", () => {
// if we are using UTC+0, we do not know the timezone, however, we know the offset
// we should therefore emit the offset in the tooltip, but not the timezone
- it("should have a tooltip that displays the date/time and the timezone of UTC+0", () => {
+ it("should use the correct tooltip when we know the offset, but not timezone", () => {
const expectedTooltip = "2020-01-01 12:10:11 (UTC+00:00)";
spectator.component.timezone = "utc";
@@ -191,13 +199,15 @@ describe("ZonedDateTimeComponent", () => {
assertTooltip(componentElement(), expectedTooltip);
});
- it("should have a tooltip that displays the date/time and the timezone of UTC+0", () => {
- const expectedTooltip = "2020-01-01 12:10:11 (Australia/Darwin UTC+09:30)";
+ it("should have a tooltip that displays the date/time and the timezone", () => {
+ const expectedTooltip =
+ "2020-01-01 12:10:11 (Australia/Darwin UTC+09:30)";
assertTooltip(componentElement(), expectedTooltip);
});
it("should update timezone correctly when assigned a new value", () => {
- const expectedTooltip = "2020-01-01 12:10:11 (Australia/Brisbane UTC+10:00)";
+ const expectedTooltip =
+ "2020-01-01 12:10:11 (Australia/Brisbane UTC+10:00)";
spectator.component.timezone = "Australia/Brisbane";
spectator.detectChanges();
diff --git a/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.ts b/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.ts
index f9670dfe0..3fc9064cd 100644
--- a/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.ts
+++ b/src/app/components/shared/datetime/zoned-datetime/zoned-datetime.component.ts
@@ -26,7 +26,7 @@ export class ZonedDateTimeComponent
// this component is the same as the datetime component except that it allows
// us to explicitly override the timezone set in the Luxon DateTime object
- @Input() public override timezone: Zone | TimezoneInformation | string;
+ @Input() public override timezone?: Zone | TimezoneInformation | string;
private isImplicitTimezone = false;
// we use ngOnChanges so that the timezone can be reactively implicitly set
@@ -38,6 +38,9 @@ export class ZonedDateTimeComponent
// if the timezone hasn't been explicitly set in the template (e.g.