Queue message sound while audio is priming

This commit is contained in:
Your Name
2026-09-30 17:05:32 +08:00
parent 06df51ca08
commit dd77ba903b
2 changed files with 57 additions and 1 deletions
@@ -130,6 +130,52 @@ test('failed gesture prime unmutes and retries on the next gesture', async () =>
assert.equal(attempts, 3);
});
async function delayedPrimeFixture() {
const handlers = new Map();
window.addEventListener = (type, handler) => handlers.set(type, handler);
window.removeEventListener = (type) => handlers.delete(type);
const plays = [];
let resolvePrime;
let rejectPrime;
const primePlayback = new Promise((resolve, reject) => { resolvePrime = resolve; rejectPrime = reject; });
let instance;
globalThis.Audio = class {
constructor() { instance = this; }
currentTime = 7;
muted = false;
play() { plays.push(this.muted); return plays.length === 1 ? primePlayback : Promise.resolve(); }
pause() {}
};
const sound = await freshSound();
return { handlers, plays, sound, get instance() { return instance; }, resolvePrime, rejectPrime };
}
test('messages during a successful delayed prime play once unmuted after priming', async () => {
const fixture = await delayedPrimeFixture();
const gesture = fixture.handlers.get('pointerdown')();
fixture.sound.playMessageNotificationSound();
fixture.sound.playMessageNotificationSound();
assert.deepEqual(fixture.plays, [true]);
fixture.resolvePrime();
await gesture;
assert.deepEqual(fixture.plays, [true, false]);
assert.equal(fixture.instance.currentTime, 0);
assert.equal(fixture.instance.muted, false);
assert.equal(fixture.handlers.size, 0);
});
test('messages during a failed delayed prime play once unmuted after priming', async () => {
const fixture = await delayedPrimeFixture();
const gesture = fixture.handlers.get('pointerdown')();
fixture.sound.playMessageNotificationSound();
assert.deepEqual(fixture.plays, [true]);
fixture.rejectPrime(new Error('blocked'));
await gesture;
assert.deepEqual(fixture.plays, [true, false]);
assert.equal(fixture.instance.muted, false);
assert.equal(fixture.handlers.size, 2);
});
test('incoming alerts gate own, visible and muted messages, but sound needs no notification permission', async () => {
let plays = 0;
globalThis.Audio = class { currentTime = 0; play() { plays++; return Promise.resolve(); } };