Skip to content

Commit 776d7db

Browse files
test(weather): add unit tests for provider-utils
Add comprehensive test coverage for all provider-utils functions: - convertWeatherType: OpenWeatherMap icon conversion - applyTimezoneOffset: timezone offset application - limitDecimals: coordinate truncation - getSunTimes: sunrise/sunset calculation - isDayTime: daylight detection - formatTimezoneOffset: timezone string formatting - getDateString: YYYY-MM-DD date formatting
1 parent 075dd6d commit 776d7db

1 file changed

Lines changed: 167 additions & 0 deletions

File tree

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
const defaults = require("../../../../../js/defaults");
2+
3+
const providerUtils = require(`../../../../../${defaults.defaultModulesDir}/weather/provider-utils`);
4+
5+
describe("Weather provider utils tests", () => {
6+
describe("convertWeatherType", () => {
7+
it("should convert OpenWeatherMap day icons correctly", () => {
8+
expect(providerUtils.convertWeatherType("01d")).toBe("day-sunny");
9+
expect(providerUtils.convertWeatherType("02d")).toBe("day-cloudy");
10+
expect(providerUtils.convertWeatherType("10d")).toBe("rain");
11+
expect(providerUtils.convertWeatherType("13d")).toBe("snow");
12+
});
13+
14+
it("should convert OpenWeatherMap night icons correctly", () => {
15+
expect(providerUtils.convertWeatherType("01n")).toBe("night-clear");
16+
expect(providerUtils.convertWeatherType("02n")).toBe("night-cloudy");
17+
expect(providerUtils.convertWeatherType("10n")).toBe("night-rain");
18+
});
19+
20+
it("should return null for unknown weather types", () => {
21+
expect(providerUtils.convertWeatherType("99x")).toBeNull();
22+
expect(providerUtils.convertWeatherType("")).toBeNull();
23+
});
24+
});
25+
26+
describe("applyTimezoneOffset", () => {
27+
it("should apply positive offset correctly", () => {
28+
const date = new Date("2026-02-02T12:00:00Z");
29+
const result = providerUtils.applyTimezoneOffset(date, 120); // +2 hours
30+
// The function converts to UTC, then applies offset
31+
const expected = new Date(date.getTime() + date.getTimezoneOffset() * 60000 + 120 * 60000);
32+
expect(result.getTime()).toBe(expected.getTime());
33+
});
34+
35+
it("should apply negative offset correctly", () => {
36+
const date = new Date("2026-02-02T12:00:00Z");
37+
const result = providerUtils.applyTimezoneOffset(date, -300); // -5 hours
38+
const expected = new Date(date.getTime() + date.getTimezoneOffset() * 60000 - 300 * 60000);
39+
expect(result.getTime()).toBe(expected.getTime());
40+
});
41+
42+
it("should handle zero offset", () => {
43+
const date = new Date("2026-02-02T12:00:00Z");
44+
const result = providerUtils.applyTimezoneOffset(date, 0);
45+
const expected = new Date(date.getTime() + date.getTimezoneOffset() * 60000);
46+
expect(result.getTime()).toBe(expected.getTime());
47+
});
48+
});
49+
50+
describe("limitDecimals", () => {
51+
it("should truncate decimals correctly", () => {
52+
expect(providerUtils.limitDecimals(12.3456789, 4)).toBe(12.3456);
53+
expect(providerUtils.limitDecimals(12.3456789, 2)).toBe(12.34);
54+
});
55+
56+
it("should handle values with fewer decimals than limit", () => {
57+
expect(providerUtils.limitDecimals(12.34, 6)).toBe(12.34);
58+
expect(providerUtils.limitDecimals(12, 4)).toBe(12);
59+
});
60+
61+
it("should handle negative values", () => {
62+
expect(providerUtils.limitDecimals(-12.3456789, 2)).toBe(-12.34);
63+
});
64+
65+
it("should truncate not round", () => {
66+
expect(providerUtils.limitDecimals(12.9999, 2)).toBe(12.99);
67+
expect(providerUtils.limitDecimals(12.9999, 0)).toBe(12);
68+
});
69+
});
70+
71+
describe("getSunTimes", () => {
72+
it("should return sunrise and sunset times", () => {
73+
const date = new Date("2026-06-21T12:00:00Z"); // Summer solstice
74+
const lat = 52.52; // Berlin
75+
const lon = 13.405;
76+
77+
const result = providerUtils.getSunTimes(date, lat, lon);
78+
79+
expect(result).toHaveProperty("sunrise");
80+
expect(result).toHaveProperty("sunset");
81+
expect(result.sunrise).toBeInstanceOf(Date);
82+
expect(result.sunset).toBeInstanceOf(Date);
83+
expect(result.sunrise.getTime()).toBeLessThan(result.sunset.getTime());
84+
});
85+
86+
it("should handle different locations", () => {
87+
const date = new Date("2026-06-21T12:00:00Z");
88+
89+
// London
90+
const london = providerUtils.getSunTimes(date, 51.5074, -0.1278);
91+
// Tokyo
92+
const tokyo = providerUtils.getSunTimes(date, 35.6762, 139.6503);
93+
94+
expect(london.sunrise.getTime()).not.toBe(tokyo.sunrise.getTime());
95+
});
96+
});
97+
98+
describe("isDayTime", () => {
99+
it("should return true when time is between sunrise and sunset", () => {
100+
const sunrise = new Date("2026-02-02T07:00:00Z");
101+
const sunset = new Date("2026-02-02T17:00:00Z");
102+
const noon = new Date("2026-02-02T12:00:00Z");
103+
104+
expect(providerUtils.isDayTime(noon, sunrise, sunset)).toBe(true);
105+
});
106+
107+
it("should return false when time is before sunrise", () => {
108+
const sunrise = new Date("2026-02-02T07:00:00Z");
109+
const sunset = new Date("2026-02-02T17:00:00Z");
110+
const night = new Date("2026-02-02T03:00:00Z");
111+
112+
expect(providerUtils.isDayTime(night, sunrise, sunset)).toBe(false);
113+
});
114+
115+
it("should return false when time is after sunset", () => {
116+
const sunrise = new Date("2026-02-02T07:00:00Z");
117+
const sunset = new Date("2026-02-02T17:00:00Z");
118+
const night = new Date("2026-02-02T20:00:00Z");
119+
120+
expect(providerUtils.isDayTime(night, sunrise, sunset)).toBe(false);
121+
});
122+
123+
it("should return true if sunrise/sunset are null", () => {
124+
const noon = new Date("2026-02-02T12:00:00Z");
125+
expect(providerUtils.isDayTime(noon, null, null)).toBe(true);
126+
});
127+
});
128+
129+
describe("formatTimezoneOffset", () => {
130+
it("should format positive offsets correctly", () => {
131+
expect(providerUtils.formatTimezoneOffset(60)).toBe("+01:00");
132+
expect(providerUtils.formatTimezoneOffset(120)).toBe("+02:00");
133+
expect(providerUtils.formatTimezoneOffset(330)).toBe("+05:30"); // India
134+
});
135+
136+
it("should format negative offsets correctly", () => {
137+
expect(providerUtils.formatTimezoneOffset(-300)).toBe("-05:00"); // EST
138+
expect(providerUtils.formatTimezoneOffset(-480)).toBe("-08:00"); // PST
139+
});
140+
141+
it("should format zero offset correctly", () => {
142+
expect(providerUtils.formatTimezoneOffset(0)).toBe("+00:00");
143+
});
144+
145+
it("should pad single digits with zero", () => {
146+
expect(providerUtils.formatTimezoneOffset(5)).toBe("+00:05");
147+
expect(providerUtils.formatTimezoneOffset(-5)).toBe("-00:05");
148+
});
149+
});
150+
151+
describe("getDateString", () => {
152+
it("should format date as YYYY-MM-DD", () => {
153+
const date = new Date("2026-02-02T12:34:56Z");
154+
expect(providerUtils.getDateString(date)).toBe("2026-02-02");
155+
});
156+
157+
it("should handle single-digit months and days correctly", () => {
158+
const date = new Date("2026-01-05T12:00:00Z");
159+
expect(providerUtils.getDateString(date)).toBe("2026-01-05");
160+
});
161+
162+
it("should handle end of year", () => {
163+
const date = new Date("2025-12-31T23:59:59Z");
164+
expect(providerUtils.getDateString(date)).toBe("2025-12-31");
165+
});
166+
});
167+
});

0 commit comments

Comments
 (0)