fix: make bulwark respect server limits
If you have a large number of tags, getTagCounts would not be able to get the unread counts because it did not respect maxCallsInRequest, even though the value was actually read out, it was just ignored. There are also other places where the limits were not respected. Batching is now generalized in a helper that also takes maxObjectsInSet, which also was ignored, into account and is applied to all functions. In addition, the dev mock now also advertises and enforces the limits, so these issues can get picked up during development. Possible closes #699 Possibly closes #399
This commit is contained in:
@@ -232,6 +232,53 @@ describe('dev-jmap mock server', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /api - request limits', () => {
|
||||
it('should refuse a request with more method calls than it advertises', async () => {
|
||||
const methodCalls = Array.from({ length: 17 }, (_, i) => [
|
||||
'Email/query',
|
||||
{ accountId: 'dev-account-001', limit: 0, calculateTotal: true },
|
||||
`c${i}`,
|
||||
]);
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', host: 'localhost:3000' },
|
||||
body: JSON.stringify({ methodCalls }),
|
||||
});
|
||||
const res = await POST(req, { params: Promise.resolve({ path: ['api'] }) });
|
||||
const data = await res.json();
|
||||
expect(res.status).toBe(400);
|
||||
expect(data.type).toBe('urn:ietf:params:jmap:error:limit');
|
||||
expect(data.limit).toBe('maxCallsInRequest');
|
||||
});
|
||||
|
||||
it('should reject an over-sized /set with requestTooLarge', async () => {
|
||||
const destroy = Array.from({ length: 501 }, (_, i) => `email-${i}`);
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', host: 'localhost:3000' },
|
||||
body: JSON.stringify({ methodCalls: [['Email/set', { accountId: 'dev-account-001', destroy }, '0']] }),
|
||||
});
|
||||
const res = await POST(req, { params: Promise.resolve({ path: ['api'] }) });
|
||||
const data = await res.json();
|
||||
expect(res.status).toBe(200);
|
||||
expect(data.methodResponses[0][0]).toBe('error');
|
||||
expect(data.methodResponses[0][1].type).toBe('requestTooLarge');
|
||||
});
|
||||
|
||||
it('should reject an over-sized /get with requestTooLarge', async () => {
|
||||
const ids = Array.from({ length: 501 }, (_, i) => `email-${i}`);
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/api', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json', host: 'localhost:3000' },
|
||||
body: JSON.stringify({ methodCalls: [['Email/get', { accountId: 'dev-account-001', ids }, '0']] }),
|
||||
});
|
||||
const res = await POST(req, { params: Promise.resolve({ path: ['api'] }) });
|
||||
const data = await res.json();
|
||||
expect(data.methodResponses[0][0]).toBe('error');
|
||||
expect(data.methodResponses[0][1].type).toBe('requestTooLarge');
|
||||
});
|
||||
});
|
||||
|
||||
describe('POST /upload', () => {
|
||||
it('should return a fake blob response', async () => {
|
||||
const req = makeRequest('http://localhost:3000/api/dev-jmap/upload/dev-account-001/', {
|
||||
|
||||
Reference in New Issue
Block a user