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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "webjamsocketserver",
"description": "Uses latest version of socketcluster-server",
"version": "3.0.10",
"version": "3.0.11",
"license": "MIT",
"type": "module",
"main": "build/src/index.js",
Expand Down
10 changes: 7 additions & 3 deletions src/AgController/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -308,9 +308,13 @@ class AgController {
if (!gig.venue || !gig.datetime || !gig.city || !gig.usState) throw new Error('Invalid gig data');
r = await this.gigController.findByIdAndUpdate(id, gig);
} catch (e) {
const eMessage = (e as Error).message;
debug(eMessage);
return eMessage;
// Rethrow (#253, same pattern as handleImage/JaMmusic#1199): swallowing
// this and returning the error message meant editDoc's catch (which
// already transmits socketError) never saw the failure, so neither
// socketError nor gigUpdated was ever sent. Let editDoc's own try/catch
// handle it.
debug((e as Error).message);
throw e;
}
this.server.exchange.transmitPublish('gigUpdated', r);
return 'Gig updated';
Expand Down
140 changes: 134 additions & 6 deletions test/AgController/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,16 +263,22 @@ describe('AgControler', () => {
});
expect(r).toBe('Gig updated');
});
it('handles error from updates a tours', async () => {
it('rethrows a database failure from updateGig instead of swallowing it (#253)', async () => {
const agController = new AgController(aStub);
agController.gigController.findByIdAndUpdate = vi.fn(() => Promise.reject(new Error('bad')));
r = await agController.updateGig({
await expect(agController.updateGig({
tourId: testId,
tour: {
venue: 'venue', datetime: new Date(), city: 'city', usState: 'state',
},
});
expect(r).toBe('bad');
venue: 'venue', datetime: new Date(), city: 'city', usState: 'state',
},
})).rejects.toThrow('bad');
});
it('rethrows a validation failure from updateGig instead of swallowing it (#253)', async () => {
const agController = new AgController(aStub);
await expect(agController.updateGig({
gigId: testId,
gig: {},
})).rejects.toThrow('Invalid gig data');
});
it('does not process the newTour message from client when token is not valid', async () => {
const agController = new AgController(aStub);
Expand Down Expand Up @@ -1012,6 +1018,128 @@ describe('AgControler', () => {
await delay(1000);
expect(agController.server.exchange.transmitPublish).not.toHaveBeenCalled();
});
it('transmits socketError with Invalid gig data when editGig fails validation (#253)', async () => {
const agController = new AgController(aStub);
agController.clients = ['123'];
agController.verifyAdminWrite = vi.fn(() => Promise.resolve());
const sStub:any = {
socket: {
id: '123',
transmit: vi.fn(),
receiver: () => ({
createConsumer: () => ({
next: () => Promise.resolve({
value: {
gigId: '123',
token: 'token',
gig: {},
},
done: true,
}),
}),
}),
},
};
agController.server.exchange.transmitPublish = vi.fn();
agController.editDoc(sStub, 'editGig');
await delay(1000);
expect(sStub.socket.transmit).toHaveBeenCalledWith('socketError', { editGig: 'Invalid gig data' });
expect(agController.server.exchange.transmitPublish).not.toHaveBeenCalled();
});
it('transmits socketError with the db message when editGig fails at the database layer (#253)', async () => {
const agController = new AgController(aStub);
agController.clients = ['123'];
agController.verifyAdminWrite = vi.fn(() => Promise.resolve());
agController.gigController.findByIdAndUpdate = vi.fn(() => Promise.reject(new Error('db exploded')));
const sStub:any = {
socket: {
id: '123',
transmit: vi.fn(),
receiver: () => ({
createConsumer: () => ({
next: () => Promise.resolve({
value: {
gigId: '123',
token: 'token',
gig: {
venue: 'venue', datetime: new Date(), city: 'city', usState: 'state',
},
},
done: true,
}),
}),
}),
},
};
agController.server.exchange.transmitPublish = vi.fn();
agController.editDoc(sStub, 'editGig');
await delay(1000);
expect(sStub.socket.transmit).toHaveBeenCalledWith('socketError', { editGig: 'db exploded' });
expect(agController.server.exchange.transmitPublish).not.toHaveBeenCalled();
});
it('publishes gigUpdated exactly once and transmits no socketError on a successful editGig (#253)', async () => {
const agController = new AgController(aStub);
agController.clients = ['123'];
agController.verifyAdminWrite = vi.fn(() => Promise.resolve());
agController.gigController.findByIdAndUpdate = vi.fn(() => Promise.resolve({ _id: '123' }));
const sStub:any = {
socket: {
id: '123',
transmit: vi.fn(),
receiver: () => ({
createConsumer: () => ({
next: () => Promise.resolve({
value: {
gigId: '123',
token: 'token',
gig: {
venue: 'venue', datetime: new Date(), city: 'city', usState: 'state',
},
},
done: true,
}),
}),
}),
},
};
agController.server.exchange.transmitPublish = vi.fn();
agController.editDoc(sStub, 'editGig');
await delay(1000);
expect(agController.server.exchange.transmitPublish).toHaveBeenCalledTimes(1);
expect(agController.server.exchange.transmitPublish).toHaveBeenCalledWith('gigUpdated', { _id: '123' });
expect(sStub.socket.transmit).not.toHaveBeenCalledWith('socketError', expect.anything());
});
it('behaves identically for the legacy editTour alias on a database failure (#253)', async () => {
const agController = new AgController(aStub);
agController.clients = ['123'];
agController.verifyAdminWrite = vi.fn(() => Promise.resolve());
agController.gigController.findByIdAndUpdate = vi.fn(() => Promise.reject(new Error('bad')));
const sStub:any = {
socket: {
id: '123',
transmit: vi.fn(),
receiver: () => ({
createConsumer: () => ({
next: () => Promise.resolve({
value: {
tourId: '123',
token: 'token',
tour: {
venue: 'venue', datetime: new Date(), city: 'city', usState: 'state',
},
},
done: true,
}),
}),
}),
},
};
agController.server.exchange.transmitPublish = vi.fn();
agController.editDoc(sStub, 'editTour');
await delay(1000);
expect(sStub.socket.transmit).toHaveBeenCalledWith('socketError', { editTour: 'bad' });
expect(agController.server.exchange.transmitPublish).not.toHaveBeenCalled();
});
it('handles missing token when the deleteTour message from client', async () => {
const agController = new AgController(aStub);
agController.clients = ['123'];
Expand Down