Skip to content

Commit 6c8c983

Browse files
committed
Address PR comments
Change-type: squash
1 parent dcd4fde commit 6c8c983

File tree

8 files changed

+63
-98
lines changed

8 files changed

+63
-98
lines changed

src/sbvr-api/sbvr-utils.ts

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export interface ApiKey extends Actor {
143143

144144
export interface Response {
145145
id?: string;
146-
status: number;
146+
statusCode: number;
147147
headers?:
148148
| {
149149
[headerName: string]: any;
@@ -1060,15 +1060,15 @@ export const runURI = async (
10601060
throw response;
10611061
}
10621062

1063-
const { body: responseBody, status, headers } = response as Response;
1063+
const { body: responseBody, statusCode, headers } = response as Response;
10641064

1065-
if (status != null && status >= 400) {
1065+
if (statusCode != null && statusCode >= 400) {
10661066
const ErrorClass =
1067-
statusCodeToError[status as keyof typeof statusCodeToError];
1067+
statusCodeToError[statusCode as keyof typeof statusCodeToError];
10681068
if (ErrorClass != null) {
10691069
throw new ErrorClass(undefined, responseBody, headers);
10701070
}
1071-
throw new HttpError(status, undefined, responseBody, headers);
1071+
throw new HttpError(statusCode, undefined, responseBody, headers);
10721072
}
10731073

10741074
return responseBody as AnyObject | undefined;
@@ -1269,7 +1269,7 @@ const validateBatch = (req: Express.Request) => {
12691269
if (urls.has(undefined)) {
12701270
throw new BadRequestError('Requests of a batch request must have a "url"');
12711271
}
1272-
if (urls.has('/university/$batch')) {
1272+
if (urls.has('/$batch')) {
12731273
throw new BadRequestError('Batch requests cannot contain batch requests');
12741274
}
12751275
const urlModels = new Set(
@@ -1467,7 +1467,7 @@ const runODataRequest = (req: Express.Request, vocabulary: string) => {
14671467
if (
14681468
!Array.isArray(result) &&
14691469
result.body == null &&
1470-
result.status == null
1470+
result.statusCode == null
14711471
) {
14721472
console.error('No status or body set', req.url, responses);
14731473
return new InternalRequestError();
@@ -1555,9 +1555,9 @@ export const handleHttpErrors = (
15551555
return false;
15561556
};
15571557
const handleResponse = (res: Express.Response, response: Response): void => {
1558-
const { body, headers, status } = response as Response;
1558+
const { body, headers, statusCode } = response as Response;
15591559
res.set(headers);
1560-
res.status(status);
1560+
res.status(statusCode);
15611561
if (!body) {
15621562
res.end();
15631563
} else {
@@ -1568,10 +1568,10 @@ const handleResponse = (res: Express.Response, response: Response): void => {
15681568
const httpErrorToResponse = (
15691569
err: HttpError,
15701570
req?: Express.Request,
1571-
): RequiredField<Response, 'status'> => {
1571+
): RequiredField<Response, 'statusCode'> => {
15721572
const message = err.getResponseBody();
15731573
return {
1574-
status: err.status,
1574+
statusCode: err.status,
15751575
body: req != null && 'batch' in req ? { responses: [], message } : message,
15761576
headers: err.headers,
15771577
};
@@ -1748,7 +1748,10 @@ const prepareResponse = async (
17481748
default:
17491749
throw new MethodNotAllowedError();
17501750
}
1751-
return { ...response, id: request.batchRequestId };
1751+
if (request.batchRequestId != null) {
1752+
response['id'] = request.batchRequestId;
1753+
}
1754+
return response;
17521755
};
17531756

17541757
const checkReadOnlyRequests = (request: uriParser.ODataRequest) => {
@@ -1871,7 +1874,7 @@ const respondGet = async (
18711874
);
18721875

18731876
const response = {
1874-
status: 200,
1877+
statusCode: 200,
18751878
body: { d },
18761879
headers: { 'content-type': 'application/json' },
18771880
};
@@ -1886,14 +1889,14 @@ const respondGet = async (
18861889
} else {
18871890
if (request.resourceName === '$metadata') {
18881891
return {
1889-
status: 200,
1892+
statusCode: 200,
18901893
body: models[vocab].odataMetadata,
18911894
headers: { 'content-type': 'xml' },
18921895
};
18931896
} else {
18941897
// TODO: request.resourceName can be '$serviceroot' or a resource and we should return an odata xml document based on that
18951898
return {
1896-
status: 404,
1899+
statusCode: 404,
18971900
};
18981901
}
18991902
}
@@ -1949,7 +1952,7 @@ const respondPost = async (
19491952
}
19501953

19511954
const response = {
1952-
status: 201,
1955+
statusCode: 201,
19531956
body: result.d[0],
19541957
headers: {
19551958
'content-type': 'application/json',
@@ -1997,7 +2000,7 @@ const respondPut = async (
19972000
tx: Db.Tx,
19982001
): Promise<Response> => {
19992002
const response = {
2000-
status: 200,
2003+
statusCode: 200,
20012004
};
20022005
await runHooks('PRERESPOND', request.hooks, {
20032006
req,
Lines changed: 43 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
1-
const configPath = __dirname + '/fixtures/06-batch/config';
2-
const hooksPath = __dirname + '/fixtures/06-batch/translations/hooks';
1+
const configPath = __dirname + '/fixtures/07-batch/config';
2+
const hooksPath = __dirname + '/fixtures/07-batch/translations/hooks';
33
import { testInit, testDeInit, testLocalServer } from './lib/test-init';
44
import { faker } from '@faker-js/faker';
55
import { expect } from 'chai';
66
import * as supertest from 'supertest';
77

88
const validBatchMethods = ['PUT', 'POST', 'PATCH', 'DELETE', 'GET'];
99

10+
const validBatchPostRequest = {
11+
id: '1',
12+
method: 'POST',
13+
url: '/university/student',
14+
body: {
15+
matrix_number: 100004,
16+
name: faker.name.firstName(),
17+
last_name: faker.name.lastName(),
18+
studies_at__campus: 'bar',
19+
},
20+
};
21+
1022
// TODO: figure out how to not persist the results across describes
11-
describe('06 batch tests', function () {
23+
describe('07 batch tests', function () {
1224
let pineServer: Awaited<ReturnType<typeof testInit>>;
1325
before(async () => {
1426
pineServer = await testInit({
@@ -24,12 +36,6 @@ describe('06 batch tests', function () {
2436
testDeInit(pineServer);
2537
});
2638

27-
describe('Basic', () => {
28-
it('check /ping route is OK', async () => {
29-
await supertest(testLocalServer).get('/ping').expect(200, 'OK');
30-
});
31-
});
32-
3339
describe('test non-atomic batch requests', () => {
3440
it('should create two students', async () => {
3541
await supertest(testLocalServer)
@@ -95,7 +101,30 @@ describe('06 batch tests', function () {
95101
.that.has.ownProperty('d')
96102
.to.be.an('array')
97103
.of.length(2);
104+
});
105+
106+
it("ids of responses in a successful request should match the original requests' ids", async () => {
107+
const id = Math.random().toString();
108+
const id2 = id + 'test';
109+
const res = await supertest(testLocalServer)
110+
.post('/university/$batch')
111+
.send({
112+
requests: [
113+
{
114+
id,
115+
method: 'GET',
116+
url: '/university/student',
117+
},
118+
{
119+
id2,
120+
method: 'GET',
121+
url: '/university/student?$filter=matrix_number eq 100000',
122+
},
123+
],
124+
})
125+
.expect(200);
98126
expect(res.body.responses[0].id).to.equal(id);
127+
expect(res.body.responses[1].id).to.equal(id2);
99128
});
100129

101130
it('should fail if the body does not have a valid "requests" property', async () => {
@@ -115,7 +144,6 @@ describe('06 batch tests', function () {
115144
);
116145
});
117146

118-
// TODO: Seems we have default `continue-on-error` = `false`, but the docs specify `true`. Do we want to continue like this?
119147
it('should not complete following requests if an earlier request fails', async () => {
120148
await supertest(testLocalServer)
121149
.post('/university/$batch')
@@ -273,17 +301,7 @@ describe('06 batch tests', function () {
273301
studies_at__campus: 'foo',
274302
},
275303
},
276-
{
277-
id: '1',
278-
method: 'POST',
279-
url: '/university/student',
280-
body: {
281-
matrix_number: 100004,
282-
name: faker.name.firstName(),
283-
last_name: faker.name.lastName(),
284-
studies_at__campus: 'bar',
285-
},
286-
},
304+
validBatchPostRequest,
287305
],
288306
})
289307
.expect(400, '"Batch requests cannot contain batch requests"');
@@ -304,17 +322,7 @@ describe('06 batch tests', function () {
304322
studies_at__campus: 'foo',
305323
},
306324
},
307-
{
308-
id: '1',
309-
method: 'POST',
310-
url: '/university/student',
311-
body: {
312-
matrix_number: 100004,
313-
name: faker.name.firstName(),
314-
last_name: faker.name.lastName(),
315-
studies_at__campus: 'bar',
316-
},
317-
},
325+
validBatchPostRequest,
318326
],
319327
})
320328
.expect(400, '"Requests of a batch request must have a \\"url\\""');
@@ -335,17 +343,7 @@ describe('06 batch tests', function () {
335343
studies_at__campus: 'foo',
336344
},
337345
},
338-
{
339-
id: '1',
340-
method: 'POST',
341-
url: '/university/student',
342-
body: {
343-
matrix_number: 100004,
344-
name: faker.name.firstName(),
345-
last_name: faker.name.lastName(),
346-
studies_at__campus: 'bar',
347-
},
348-
},
346+
validBatchPostRequest,
349347
],
350348
})
351349
.expect(400, '"Requests of a batch request must have a \\"method\\""');
@@ -364,17 +362,7 @@ describe('06 batch tests', function () {
364362
studies_at__campus: 'foo',
365363
},
366364
},
367-
{
368-
id: '1',
369-
method: 'POST',
370-
url: '/university/student',
371-
body: {
372-
matrix_number: 100004,
373-
name: faker.name.firstName(),
374-
last_name: faker.name.lastName(),
375-
studies_at__campus: 'bar',
376-
},
377-
},
365+
validBatchPostRequest,
378366
],
379367
})
380368
.expect(
@@ -468,17 +456,7 @@ describe('06 batch tests', function () {
468456
studies_at__campus: 'foo',
469457
},
470458
},
471-
{
472-
id: '1',
473-
method: 'POST',
474-
url: '/university/student',
475-
body: {
476-
matrix_number: 100004,
477-
name: faker.name.firstName(),
478-
last_name: faker.name.lastName(),
479-
studies_at__campus: 'bar',
480-
},
481-
},
459+
validBatchPostRequest,
482460
],
483461
})
484462
.expect(
Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { AbstractSqlQuery } from '@balena/abstract-sql-compiler';
21
import { getAbstractSqlModelFromFile } from '../../../src/bin/utils';
32
import type { ConfigLoader } from '../../../src/server-glue/module';
43

@@ -10,13 +9,6 @@ import { v1AbstractSqlModel, v1Translations } from './translations/v1';
109

1110
export const abstractSql = getAbstractSqlModelFromFile(modelFile);
1211

13-
abstractSql.tables['student'].fields.push({
14-
fieldName: 'computed field',
15-
dataType: 'Text',
16-
required: false,
17-
computed: ['EmbeddedText', 'latest_computed_field'] as AbstractSqlQuery,
18-
});
19-
2012
export default {
2113
models: [
2214
{
File renamed without changes.
File renamed without changes.

test/fixtures/06-batch/translations/v1/index.ts renamed to test/fixtures/07-batch/translations/v1/index.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,12 @@
11
import { ConfigLoader } from '../../../../../src/server-glue/module';
22
import { getAbstractSqlModelFromFile } from '../../../../../src/bin/utils';
3-
import { AbstractSqlQuery } from '@balena/abstract-sql-compiler';
43

54
export const toVersion = 'university';
65

76
export const v1AbstractSqlModel = getAbstractSqlModelFromFile(
87
__dirname + '/university.sbvr',
98
);
109

11-
v1AbstractSqlModel.tables['student'].fields.push({
12-
fieldName: 'computed field',
13-
dataType: 'Text',
14-
required: false,
15-
computed: ['EmbeddedText', 'v1_computed_field'] as AbstractSqlQuery,
16-
});
17-
1810
v1AbstractSqlModel.relationships['version'] = { v1: {} };
1911

2012
export const v1Translations: ConfigLoader.Model['translations'] = {

test/fixtures/06-batch/translations/v1/university.sbvr renamed to test/fixtures/07-batch/translations/v1/university.sbvr

File renamed without changes.

0 commit comments

Comments
 (0)