The server ledger is cleared by an explicit ack, never by the check-in response, so a dismissal that cannot reach the service must be persisted and retried or the device rings again later. Add a durable pending-ack queue (404 means the alert ended: settled, drop it), map the 409 ERR_ALARM_TRIGGERED_OFFLINE check-in into a normal trigger for the same takeover, and make a 404 an ending rather than a missed alarm. This also carries the expiry/endings state the screens render.
46 lines
1.8 KiB
TypeScript
46 lines
1.8 KiB
TypeScript
export {};
|
|
|
|
/**
|
|
* Dismiss must silence the phone locally, first, without the owner.
|
|
*
|
|
* Source contract: JSX/native playback can't be executed headlessly here, so we
|
|
* pin the order the code depends on — `stopAlarm()` before any server call or
|
|
* event clearing in the acknowledge path — and that playback has no timer that
|
|
* could silence it "by itself".
|
|
*/
|
|
declare const __dirname: string;
|
|
const fs: { readFileSync(p: string, enc: string): string } = jest.requireActual('fs');
|
|
const path: { join(...parts: string[]): string } = jest.requireActual('path');
|
|
|
|
const screen = fs.readFileSync(
|
|
path.join(__dirname, '..', 'src', 'screens', 'LiveAlarmScreen.tsx'),
|
|
'utf8',
|
|
);
|
|
const nativeTs = fs.readFileSync(
|
|
path.join(__dirname, '..', 'src', 'services', 'alarmNative.ts'),
|
|
'utf8',
|
|
);
|
|
|
|
describe('local dismiss contract', () => {
|
|
it('silences first and only then drops the live event', () => {
|
|
const ackAt = screen.indexOf('const ack = useCallback');
|
|
expect(ackAt).toBeGreaterThan(-1);
|
|
const ack = screen.slice(ackAt, ackAt + 900);
|
|
expect(ack.indexOf('await stopAlarm()')).toBeGreaterThan(-1);
|
|
expect(ack.indexOf('await stopAlarm()')).toBeLessThan(ack.indexOf('clearLiveEvent()'));
|
|
});
|
|
|
|
it('stops both audio and vibration through the native bridge', () => {
|
|
expect(nativeTs).toContain('stopAlarm');
|
|
expect(nativeTs).toContain('AlarmModule');
|
|
});
|
|
|
|
it('does not schedule its own auto-stop in JS', () => {
|
|
expect(screen).not.toMatch(/autoStop/i);
|
|
// The 1 s interval is the displayed count-up only; it must not stop audio.
|
|
const countUp = screen.slice(screen.indexOf('The count-up ticks'), screen.indexOf('The count-up ticks') + 300);
|
|
expect(countUp).toContain('setInterval');
|
|
expect(countUp).not.toContain('stopAlarm');
|
|
});
|
|
});
|