Files
pulse-signage/test/weather-forecast.test.js
T
lzstealth 5e23d16483
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile, web, pulse-signage-web) (push) Successful in 1m7s
Publish Docker Image / build-and-push-existing-registry (./build/Dockerfile.player, player, pulse-signage-player) (push) Successful in 31s
Release v2.17.2: normalize weather providers and fix unit placeholders
2026-10-23 02:39:13 +01:00

72 lines
3.4 KiB
JavaScript

const test = require('node:test');
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const { fetchWeatherLocationForecast } = require('../src/data/weather');
test('Open-Meteo hourly forecast starts at the current hour and spans 24 hours', async () => {
const originalFetch = global.fetch;
const originalDateNow = Date.now;
let requestUrl;
global.fetch = async function (url) {
requestUrl = new URL(url);
return { ok: true, json: async function () { return { hourly: { time: [] } }; } };
};
Date.now = function () { return new Date('2026-08-28T12:34:00Z').getTime(); };
try {
await fetchWeatherLocationForecast({ query: async function () { return [[]]; } }, {
latitude: 51.5,
longitude: -0.1,
timezone: 'Europe/London',
provider: 'open-meteo'
});
} finally {
global.fetch = originalFetch;
Date.now = originalDateNow;
}
assert.equal(requestUrl.searchParams.get('forecast_hours'), '24');
assert.equal(requestUrl.searchParams.get('forecast_days'), '7');
});
test('weather forecast preview only shows the fetch hint without a snapshot', () => {
const template = fs.readFileSync(path.join(__dirname, '..', 'src', 'web', 'views', 'data-sources', 'weather', 'forecast-preview.hbs'), 'utf8');
assert.match(template, /\{\{#if weatherPreview\.hasSnapshot\}\}[\s\S]*weather-daily-forecast[\s\S]*weather-hourly-forecast[\s\S]*\{\{\/if\}\}/);
assert.match(template, /id="weather-daily-forecast" class="weather-daily-forecast"/);
assert.match(template, /id="weather-hourly-forecast" class="d-none"/);
assert.doesNotMatch(template, /Hourly forecast · next 24 hours/);
assert.match(template, /Daily and hourly forecasts will appear here after the first successful fetch\./);
});
test('Pirate Weather fetch persists normalized fields and source units for mixed-unit display', async () => {
const { convertWeatherSnapshot } = require('../src/data/weather-units');
const originalFetch = global.fetch;
let requestUrl;
global.fetch = async function (url) {
requestUrl = new URL(url);
return { ok: true, json: async function () {
return { timezone: 'Europe/London', currently: { time: 1792756800, temperature: 68, windSpeed: 10, precipIntensity: 1, icon: 'clear-day' } };
} };
};
try {
const pool = { query: async function () { return [[{ setting_key: 'weather.pirate_weather_api_key', setting_value: JSON.stringify('test-key') }]]; } };
const result = await fetchWeatherLocationForecast(pool, {
latitude: 51.5, longitude: -0.1, timezone: 'Europe/London', provider: 'pirate-weather',
temperature_unit: 'fahrenheit', wind_unit: 'kmh', precipitation_unit: 'mm'
});
assert.equal(requestUrl.searchParams.get('units'), 'us');
assert.equal(result.snapshot.current.temperature_2m, 68);
assert.equal(result.snapshot.current_units.wind_speed_10m, 'mph');
assert.equal(result.snapshot.current_units.precipitation, 'in');
assert.deepEqual(JSON.parse(result.responseJson), JSON.parse(JSON.stringify(result.snapshot)));
const display = convertWeatherSnapshot(JSON.parse(result.responseJson), { temperature: 'fahrenheit', wind: 'kmh', precipitation: 'mm' });
assert.equal(display.current.temperature_2m, 68);
assert.equal(display.current.wind_speed_10m, 16.1);
assert.equal(display.current.precipitation, 25.4);
} finally {
global.fetch = originalFetch;
}
});