Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 21 additions & 20 deletions packages/extension/src/iframe-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,31 +129,18 @@ describe('IframeManager', () => {
expect(removeSpy).not.toHaveBeenCalled();
});

it('warns of unresolved messages', async () => {
it('rejects unresolved messages', async () => {
const id = 'foo';
const messageCount = 7;
const awaitCount = 2;

vi.mocked(snapsUtils.createWindow).mockImplementationOnce(vi.fn());

const manager = new IframeManager();

vi.spyOn(manager, 'sendMessage').mockImplementationOnce(vi.fn());

const { port1, port2 } = new MessageChannel();

await manager.create({ id, getPort: makeGetPort(port1) });

const warnSpy = vi.spyOn(console, 'warn');

const messagePromises = Array(messageCount)
.fill(0)
.map(async (_, i) =>
manager.sendMessage(id, { type: Command.Evaluate, data: `${i}+1` }),
);

// resolve the first `awaitCount` promises
for (let i = 0; i < awaitCount; i++) {
const postMessage = (i: number): void => {
port2.postMessage({
done: false,
value: {
Expand All @@ -167,15 +154,29 @@ describe('IframeManager', () => {
},
},
});
};

await manager.create({ id, getPort: makeGetPort(port1) });

const messagePromises = Array(messageCount)
.fill(0)
.map(async (_, i) =>
manager.sendMessage(id, { type: Command.Evaluate, data: `${i}+1` }),
);

// resolve the first `awaitCount` promises
for (let i = 0; i < awaitCount; i++) {
postMessage(i);
await messagePromises[i];
}

await manager.delete(id);
expect(warnSpy).toHaveBeenCalledTimes(messageCount - awaitCount);
// This test assumes messageIds begin at 1, not 0
expect(warnSpy).toHaveBeenLastCalledWith(
`Unhandled orphaned message: ${id}-${messageCount}`,
);

// reject the rest of the promises
for (let i = awaitCount; i < messageCount; i++) {
postMessage(i);
await expect(messagePromises[i]).rejects.toThrow('Vat was deleted');
}
});
});

Expand Down
8 changes: 5 additions & 3 deletions packages/extension/src/iframe-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,11 @@ export class IframeManager {
}

const closeP = vat.streams.return();
// TODO: Handle orphaned messages
for (const [messageId] of vat.unresolvedMessages) {
console.warn(`Unhandled orphaned message: ${messageId}`);

// Handle orphaned messages
for (const [messageId, promiseCallback] of vat.unresolvedMessages) {
promiseCallback?.reject(new Error('Vat was deleted'));
vat.unresolvedMessages.delete(messageId);
}
this.#vats.delete(id);

Expand Down