| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- /**
- * The per-category alert defaults are server-backed (#2824 review round 4).
- *
- * They seed the alert rule written onto each sensor row when one is bound, so
- * two admins binding sensors from different browsers must not seed different
- * rules, and a backup/restore has to carry them. Only `showOnCard` stays in
- * localStorage: show_on_card is decided per sensor and this is nothing more
- * than the form's pre-selection.
- */
- import { describe, it, expect, beforeEach, vi } from 'vitest';
- import {
- defaultLocationSensorDefaults,
- loadLocationSensorDefaults,
- saveLocationSensorShowOnCardDefaults,
- serializeLocationSensorAlertDefaults,
- } from '../../utils/locationSensorDefaults';
- beforeEach(() => {
- vi.mocked(localStorage.getItem).mockReset();
- vi.mocked(localStorage.setItem).mockReset();
- });
- describe('location sensor alert defaults — server-backed', () => {
- it('falls back to the built-ins when the setting is empty', () => {
- expect(loadLocationSensorDefaults('')).toEqual(defaultLocationSensorDefaults());
- expect(loadLocationSensorDefaults(undefined)).toEqual(defaultLocationSensorDefaults());
- expect(loadLocationSensorDefaults(null)).toEqual(defaultLocationSensorDefaults());
- });
- it('takes the alert fields from the server value', () => {
- const json = JSON.stringify({
- humidity: { alertAbove: '45', alertBelow: '15', notifyOnAlert: true },
- });
- const defaults = loadLocationSensorDefaults(json);
- expect(defaults.humidity.alertAbove).toBe('45');
- expect(defaults.humidity.alertBelow).toBe('15');
- expect(defaults.humidity.notifyOnAlert).toBe(true);
- // Categories absent from the setting keep their built-ins.
- expect(defaults.temperature).toEqual(defaultLocationSensorDefaults().temperature);
- });
- it('round-trips through serialize', () => {
- const original = defaultLocationSensorDefaults();
- original.temperature.alertAbove = '35';
- original.battery.notifyOnAlert = true;
- const reloaded = loadLocationSensorDefaults(serializeLocationSensorAlertDefaults(original));
- expect(reloaded.temperature.alertAbove).toBe('35');
- expect(reloaded.battery.notifyOnAlert).toBe(true);
- });
- it('never puts showOnCard in the server value — it is per sensor, not per installation', () => {
- const defaults = defaultLocationSensorDefaults();
- defaults.humidity.showOnCard = false;
- const parsed = JSON.parse(serializeLocationSensorAlertDefaults(defaults));
- expect(parsed.humidity).not.toHaveProperty('showOnCard');
- expect(Object.keys(parsed.humidity).sort()).toEqual(['alertAbove', 'alertBelow', 'notifyOnAlert']);
- });
- // setup.ts replaces localStorage with bare vi.fn() stubs that store nothing,
- // so these drive it explicitly rather than round-tripping through it.
- it('writes only the per-category booleans to localStorage', () => {
- const defaults = defaultLocationSensorDefaults();
- defaults.humidity.showOnCard = false;
- saveLocationSensorShowOnCardDefaults(defaults);
- expect(localStorage.setItem).toHaveBeenCalledWith(
- 'bambuddy-location-sensor-show-on-card-defaults',
- JSON.stringify({ temperature: true, humidity: false, battery: true })
- );
- });
- it('applies the stored showOnCard over the built-in, independent of the server value', () => {
- vi.mocked(localStorage.getItem).mockReturnValue(JSON.stringify({ humidity: false }));
- const reloaded = loadLocationSensorDefaults(
- serializeLocationSensorAlertDefaults(defaultLocationSensorDefaults())
- );
- expect(reloaded.humidity.showOnCard).toBe(false);
- expect(reloaded.temperature.showOnCard).toBe(true);
- });
- it('survives a corrupted setting instead of blocking the dialog', () => {
- expect(loadLocationSensorDefaults('not json at all')).toEqual(defaultLocationSensorDefaults());
- });
- it('ignores unexpected keys and wrong types in the stored value', () => {
- const json = JSON.stringify({
- humidity: { alertAbove: 45, notifyOnAlert: 'yes', showOnCard: false, injected: 'x' },
- });
- const defaults = loadLocationSensorDefaults(json);
- // Wrong types are rejected, built-ins survive.
- expect(defaults.humidity.alertAbove).toBe(defaultLocationSensorDefaults().humidity.alertAbove);
- expect(defaults.humidity.notifyOnAlert).toBe(false);
- // showOnCard from the server value must not win over the local preference.
- expect(defaults.humidity.showOnCard).toBe(true);
- expect(defaults.humidity).not.toHaveProperty('injected');
- });
- });
|