mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
test(plugins): cover the mock double and the child proxy for addEntryPhoto
The handler had eight cases, its two doubles had none, which Sonar counted as new code without coverage. The mock is the more useful of the two to pin anyway: an importer developing against it should hit the same refusals it will hit in production, so the SVG, the missing extension, the empty payload and the size cap are all asserted against the double rather than only against the host.
This commit is contained in:
@@ -288,6 +288,38 @@ describe('createMockHost', () => {
|
||||
await expect(ungranted.ctx.journal.createJourney({ title: 'x' })).rejects.toThrow(/PERMISSION_DENIED/);
|
||||
});
|
||||
|
||||
it('journal.addEntryPhoto refuses in the mock what the host refuses in production', async () => {
|
||||
const png = Buffer.from('89504e470d0a1a0a', 'hex').toString('base64');
|
||||
const host = createMockHost({
|
||||
grants: ['db:write:journal'],
|
||||
actingUserId: 42,
|
||||
journals: [{ id: 1, title: 'Japan' }],
|
||||
journalEntries: [{ id: 5, journey_id: 1, entry_date: '2027-04-01' }],
|
||||
});
|
||||
|
||||
const photo = await host.ctx.journal.addEntryPhoto(5, { name: 'tokyo.jpg', content_base64: png, caption: 'Arrival' });
|
||||
expect(photo).toMatchObject({ entry_id: 5, caption: 'Arrival' });
|
||||
|
||||
// An importer that hits one of these in the mock would hit it in production too,
|
||||
// which is the whole point of the double refusing the same things.
|
||||
await expect(host.ctx.journal.addEntryPhoto(999, { name: 'a.jpg', content_base64: png }))
|
||||
.rejects.toThrow(/RESOURCE_FORBIDDEN/);
|
||||
await expect(host.ctx.journal.addEntryPhoto(5, { name: 'map.svg', content_base64: png }))
|
||||
.rejects.toThrow(/not an allowed image type/);
|
||||
await expect(host.ctx.journal.addEntryPhoto(5, { name: 'noext', content_base64: png }))
|
||||
.rejects.toThrow(/not an allowed image type/);
|
||||
await expect(host.ctx.journal.addEntryPhoto(5, { name: '', content_base64: png }))
|
||||
.rejects.toThrow(/name is required/);
|
||||
await expect(host.ctx.journal.addEntryPhoto(5, { name: 'a.jpg', content_base64: '' }))
|
||||
.rejects.toThrow(/content_base64 is required/);
|
||||
await expect(host.ctx.journal.addEntryPhoto(5, { name: 'a.jpg', content_base64: 'A'.repeat(15 * 1024 * 1024) }))
|
||||
.rejects.toThrow(/10MB plugin upload cap/);
|
||||
|
||||
const ungranted = createMockHost({ grants: [], actingUserId: 42, journalEntries: [{ id: 5, journey_id: 1 }] });
|
||||
await expect(ungranted.ctx.journal.addEntryPhoto(5, { name: 'a.jpg', content_base64: png }))
|
||||
.rejects.toThrow(/PERMISSION_DENIED/);
|
||||
});
|
||||
|
||||
it('creates a trip for the acting user and serves rates + collab reads against the grants', async () => {
|
||||
const { ctx } = createMockHost({
|
||||
grants: ['db:create:trips', 'rates:read', 'db:read:collab'],
|
||||
|
||||
@@ -29,6 +29,9 @@ describe('createPluginContext', () => {
|
||||
await ctx.trips.getById(1);
|
||||
expect(rpc).toHaveBeenCalledWith('trips.getById', { tripId: 1, _inv: 'inv-1' });
|
||||
|
||||
await ctx.journal.addEntryPhoto(5, { name: 'a.jpg', content_base64: 'eA==' });
|
||||
expect(rpc).toHaveBeenCalledWith('journal.addEntryPhoto', { entryId: 5, input: { name: 'a.jpg', content_base64: 'eA==' }, _inv: 'inv-1' });
|
||||
|
||||
await ctx.ws.broadcastToTrip(1, 'ping', { a: 1 });
|
||||
// carries _inv so the host can bind the acting user — without it the broadcast was refused
|
||||
expect(rpc).toHaveBeenCalledWith('ws.broadcastToTrip', { tripId: 1, event: 'ping', data: { a: 1 }, _inv: 'inv-1' });
|
||||
|
||||
Reference in New Issue
Block a user