Files
FarmaFinder/apps/backend/__tests__/hours.test.js
T
Antoni Nuñez Romeu e3e7d2f60b
Run Tests on Branches / Detect Changes (push) Successful in 17s
Run Tests on Branches / Backend Tests (push) Successful in 2m44s
Run Tests on Branches / Frontend Tests (push) Successful in 1m59s
Run Tests on Branches / Frontend Mobile Tests (push) Has been skipped
Run Tests on Branches / Parapharmacy API Tests (push) Has been skipped
Run Tests on Branches / PIP Platform Tests (push) Has been skipped
feat: pharmacy hours status and open now filter
- Add is_open_now and is_always_open helpers in backend
- Add backend endpoint enrichment with is_open and is_24h fields
- Add client-side getOpenStatus with 24h, opens-at, opens-tomorrow support
- Add open-now filter toggle in PublicView and SearchView
- Add pharmacy no-hours fallback display
- Add sticky pharmacy controls on scroll
- Add admin hours editor with 24h toggle
- Add translations (es/ca) for all hour-related strings
- Add backend tests for hours logic and pharmacy endpoint
- Remove unused backup test files
2026-07-27 14:32:05 +02:00

159 lines
5.5 KiB
JavaScript

import { isOpenNow, isAlwaysOpen } from '../src/hours.js';
const HOURS_24_7 = {
mon: ['00:00', '24:00'],
tue: ['00:00', '24:00'],
wed: ['00:00', '24:00'],
thu: ['00:00', '24:00'],
fri: ['00:00', '24:00'],
sat: ['00:00', '24:00'],
sun: ['00:00', '24:00'],
};
const HOURS_NORMAL_WEEK = {
mon: ['09:00', '21:00'],
tue: ['09:00', '21:00'],
wed: ['09:00', '21:00'],
thu: ['09:00', '21:00'],
fri: ['09:00', '21:00'],
sat: ['09:00', '14:00'],
sun: null,
};
const HOURS_ALL_CLOSED = {
mon: null, tue: null, wed: null, thu: null, fri: null, sat: null, sun: null,
};
const HOURS_MIDNIGHT_CROSS = {
mon: ['22:00', '02:00'],
tue: ['09:00', '21:00'],
wed: null, thu: null, fri: null, sat: null, sun: null,
};
const at = (iso) => new Date(iso);
describe('isAlwaysOpen', () => {
test('all 7 days 00:00-24:00 → true', () => {
expect(isAlwaysOpen(HOURS_24_7)).toBe(true);
});
test('accepts JSON string', () => {
expect(isAlwaysOpen(JSON.stringify(HOURS_24_7))).toBe(true);
});
test('one day different → false', () => {
expect(isAlwaysOpen({ ...HOURS_24_7, sun: ['00:00', '23:59'] })).toBe(false);
});
test('one day null → false', () => {
expect(isAlwaysOpen({ ...HOURS_24_7, sun: null })).toBe(false);
});
test('null input → false', () => {
expect(isAlwaysOpen(null)).toBe(false);
expect(isAlwaysOpen('')).toBe(false);
expect(isAlwaysOpen(undefined)).toBe(false);
});
test('malformed JSON → false', () => {
expect(isAlwaysOpen('{not-json')).toBe(false);
});
});
describe('isOpenNow', () => {
test('null/empty input → null', () => {
expect(isOpenNow(null)).toBeNull();
expect(isOpenNow('')).toBeNull();
expect(isOpenNow(undefined)).toBeNull();
});
test('malformed JSON → null', () => {
expect(isOpenNow('{garbage')).toBeNull();
});
test('24/7 → { isOpen: true, kind: "24h" }', () => {
const s = isOpenNow(HOURS_24_7, at('2026-07-27T10:00:00'));
expect(s).toEqual({ isOpen: true, kind: '24h' });
});
test('24/7 at midnight → still 24h', () => {
const s = isOpenNow(HOURS_24_7, at('2026-07-27T00:00:00'));
expect(s).toEqual({ isOpen: true, kind: '24h' });
});
test('24/7 (JSON string) → kind 24h', () => {
const s = isOpenNow(JSON.stringify(HOURS_24_7), at('2026-07-27T15:00:00'));
expect(s).toEqual({ isOpen: true, kind: '24h' });
});
test('normal weekday at 10:00 (monday) → open, closesAt 21:00', () => {
// 2026-07-27 is a Monday (verify with date -d)
const s = isOpenNow(HOURS_NORMAL_WEEK, at('2026-07-27T10:30:00'));
expect(s).toEqual({ isOpen: true, kind: 'open', closesAt: '21:00' });
});
test('normal weekday at 21:30 (monday) → closed, nextOpen tuesday 09:00', () => {
const s = isOpenNow(HOURS_NORMAL_WEEK, at('2026-07-27T21:30:00'));
expect(s.isOpen).toBe(false);
expect(s.kind).toBe('after-close');
expect(s.nextOpen).toEqual({ day: 'tue', time: '09:00' });
});
test('normal weekday at 08:30 (monday) → closed before-open, opensAt 09:00', () => {
const s = isOpenNow(HOURS_NORMAL_WEEK, at('2026-07-27T08:30:00'));
expect(s).toEqual({ isOpen: false, kind: 'before-open', opensAt: '09:00', nextOpen: null });
});
test('sunday with no hours → closed, nextOpen monday 09:00', () => {
// 2026-07-26 is a Sunday
const s = isOpenNow(HOURS_NORMAL_WEEK, at('2026-07-26T10:00:00'));
expect(s.isOpen).toBe(false);
expect(s.kind).toBe('closed');
expect(s.nextOpen).toEqual({ day: 'mon', time: '09:00' });
});
test('all week closed → closed, no nextOpen', () => {
const s = isOpenNow(HOURS_ALL_CLOSED, at('2026-07-27T10:00:00'));
expect(s).toEqual({ isOpen: false, kind: 'closed', nextOpen: null });
});
test('midnight-crossing: monday 22:00-02:00, at 23:00 → open', () => {
const s = isOpenNow(HOURS_MIDNIGHT_CROSS, at('2026-07-27T23:00:00'));
expect(s.isOpen).toBe(true);
expect(s.kind).toBe('open');
expect(s.closesAt).toBe('02:00');
});
test('midnight-crossing: monday 22:00-02:00, at 01:00 → open (yesterday range still active)', () => {
// Tuesday 01:00 → it's inside monday's 22:00-02:00 range (extended past midnight)
const s = isOpenNow(HOURS_MIDNIGHT_CROSS, at('2026-07-28T01:00:00'));
expect(s.isOpen).toBe(true);
expect(s.kind).toBe('open');
});
test('midnight-crossing: at tuesday 03:00, today opens at 09:00 → before-open', () => {
// Tuesday 03:00 with monday 22:00-02:00 already finished; today's tue is 09:00-21:00.
const s = isOpenNow(HOURS_MIDNIGHT_CROSS, at('2026-07-28T03:00:00'));
expect(s).toEqual({ isOpen: false, kind: 'before-open', opensAt: '09:00', nextOpen: null });
});
test('midnight-crossing: same day before today opens → before-open with today time', () => {
// HOURS_MIDNIGHT_CROSS: mon 22:00-02:00 (crossing). At monday 10:00, before today's 22:00.
const s = isOpenNow(HOURS_MIDNIGHT_CROSS, at('2026-07-27T10:00:00'));
expect(s).toEqual({ isOpen: false, kind: 'before-open', opensAt: '22:00', nextOpen: null });
});
test('saturday morning at 10:00 (with 09:00-14:00) → open, closesAt 14:00', () => {
// 2026-07-25 is a Saturday
const s = isOpenNow(HOURS_NORMAL_WEEK, at('2026-07-25T10:00:00'));
expect(s).toEqual({ isOpen: true, kind: 'open', closesAt: '14:00' });
});
test('saturday at 15:00 → closed, nextOpen monday 09:00', () => {
const s = isOpenNow(HOURS_NORMAL_WEEK, at('2026-07-25T15:00:00'));
expect(s.isOpen).toBe(false);
expect(s.kind).toBe('after-close');
expect(s.nextOpen).toEqual({ day: 'mon', time: '09:00' });
});
});