api-core
Version:
Model-based dynamic multi-level APIs for any provider, plus multiple consumption channels
411 lines • 17 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const ApiEdgeError_1 = require("../src/query/ApiEdgeError");
const tap = require('tap');
const Api_1 = require("../src/Api");
const builder = require("../src/query/ApiQueryBuilder");
const OneToOneRelation_1 = require("../src/relations/OneToOneRelation");
const OneToManyRelation_1 = require("../src/relations/OneToManyRelation");
const StudentEdge_1 = require("./env/edges/StudentEdge");
const ClassEdge_1 = require("./env/edges/ClassEdge");
const CourseEdge_1 = require("./env/edges/CourseEdge");
const CourseTypeEdge_1 = require("./env/edges/CourseTypeEdge");
const SchoolEdge_1 = require("./env/edges/SchoolEdge");
const ApiRequest_1 = require("../src/request/ApiRequest");
const studentEdge = new StudentEdge_1.StudentEdge, classEdge = new ClassEdge_1.ClassEdge, courseEdge = new CourseEdge_1.CourseEdge, courseTypeEdge = new CourseTypeEdge_1.CourseTypeEdge, schoolEdge = new SchoolEdge_1.SchoolEdge;
var api;
tap.test('creating the API should work', (t) => {
api = new Api_1.Api({ name: 'test-service', version: '1.0' })
.edge(studentEdge)
.edge(classEdge)
.edge(courseEdge)
.edge(courseTypeEdge)
.edge(schoolEdge)
.relation(new OneToOneRelation_1.OneToOneRelation(courseEdge, courseTypeEdge))
.relation(new OneToManyRelation_1.OneToManyRelation(courseTypeEdge, courseEdge))
.relation(new OneToManyRelation_1.OneToManyRelation(studentEdge, courseEdge))
.relation(new OneToOneRelation_1.OneToOneRelation(studentEdge, classEdge))
.relation(new OneToOneRelation_1.OneToOneRelation(classEdge, schoolEdge))
.relation(new OneToOneRelation_1.OneToOneRelation(courseEdge, classEdge))
.relation(new OneToManyRelation_1.OneToManyRelation(classEdge, studentEdge))
.relation(new OneToManyRelation_1.OneToManyRelation(classEdge, courseEdge))
.relation(new OneToManyRelation_1.OneToManyRelation(schoolEdge, studentEdge))
.relation(new OneToManyRelation_1.OneToManyRelation(schoolEdge, classEdge));
t.end();
});
tap.test('Any type queries should fail', (t) => {
try {
let request = new ApiRequest_1.ApiRequest(api);
request.type = ApiRequest_1.ApiRequestType.Any;
api.buildQuery(request);
t.ok(false, 'an invalid query should not succeed');
}
catch (e) {
t.ok(e instanceof ApiEdgeError_1.ApiEdgeError);
t.equal(e.message, 'Unsupported Query Type');
t.equal(e.status, 400);
}
t.end();
});
tap.test('Change type queries should fail', (t) => {
try {
let request = new ApiRequest_1.ApiRequest(api);
request.type = ApiRequest_1.ApiRequestType.Change;
api.buildQuery(request);
t.ok(false, 'an invalid query should not succeed');
}
catch (e) {
t.ok(e instanceof ApiEdgeError_1.ApiEdgeError);
t.equal(e.message, 'Unsupported Query Type');
t.equal(e.status, 400);
}
t.end();
});
tap.test('/schools', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools']), query = api.buildQuery(request);
t.equal(query.steps.length, 2, 'should build a 2 step query');
t.ok(query.steps[0] instanceof builder.ExtendContextQueryStep);
t.ok(query.steps[1] instanceof builder.QueryEdgeQueryStep);
return query.execute()
.then(resp => {
t.same(resp.data, [
{
address: "16, Test street, North Pole, HA23535",
id: "s1",
name: "First School",
phone: "435234523"
},
{
address: "12, Test street, North Pole, HA23535",
id: "s2",
name: "Second School",
phone: "456345283"
}
]);
t.equal(resp.metadata, null);
t.end();
})
.catch((e) => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('/schools/s2', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's2']), query = api.buildQuery(request);
t.equal(query.steps.length, 3, 'should build a 3 step query');
t.ok(query.steps[0] instanceof builder.ExtendContextLiveQueryStep);
t.ok(query.steps[1] instanceof builder.ExtendContextQueryStep);
t.ok(query.steps[2] instanceof builder.QueryEdgeQueryStep);
return query.execute()
.then(resp => {
t.same(resp.data, {
address: "12, Test street, North Pole, HA23535",
id: "s2",
name: "Second School",
phone: "456345283"
});
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('/schools/s5', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's5']), query = api.buildQuery(request);
return query.execute()
.then(() => {
t.ok(false, "an invalid query should not succeed");
t.end();
})
.catch(e => {
t.ok(e instanceof ApiEdgeError_1.ApiEdgeError);
t.equal(e.status, 404);
t.equal(e.message, 'Not Found');
t.end();
});
}));
tap.test('/schools/s1/classes', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's1', 'classes']), query = api.buildQuery(request);
t.equal(query.steps.length, 5, 'should build a 5 step query');
t.ok(query.steps[0] instanceof builder.ExtendContextLiveQueryStep, 'EXTEND');
t.ok(query.steps[1] instanceof builder.QueryEdgeQueryStep, 'QUERY /schools');
t.ok(query.steps[2] instanceof builder.RelateQueryStep, 'RELATE schoolId');
t.ok(query.steps[3] instanceof builder.ExtendContextQueryStep, 'APPLY PARAMS');
t.ok(query.steps[4] instanceof builder.QueryEdgeQueryStep, 'QUERY /classes');
return query.execute()
.then(resp => {
t.same(resp.data, [
{
id: "c1",
name: "A",
year: 1,
room: "Room 1",
schoolId: "s1"
}
]);
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('/schools/s1/classes/c1', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's1', 'classes', 'c1']), query = api.buildQuery(request);
t.equal(query.steps.length, 6, 'should build a 6 step query');
t.ok(query.steps[0] instanceof builder.ExtendContextLiveQueryStep, 'EXTEND');
t.ok(query.steps[1] instanceof builder.QueryEdgeQueryStep, 'QUERY /schools');
t.ok(query.steps[2] instanceof builder.RelateQueryStep, 'RELATE schoolId');
t.ok(query.steps[3] instanceof builder.ExtendContextLiveQueryStep, 'EXTEND');
t.ok(query.steps[4] instanceof builder.ExtendContextQueryStep, 'APPLY PARAMS');
t.ok(query.steps[5] instanceof builder.QueryEdgeQueryStep, 'QUERY /classes');
return query.execute()
.then(resp => {
t.same(resp.data, {
id: "c1",
name: "A",
year: 1,
room: "Room 1",
schoolId: "s1"
});
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('/students/s2/class', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['students', 's2', 'class']), query = api.buildQuery(request);
t.equal(query.steps.length, 5, 'should build a 5 step query');
t.ok(query.steps[0] instanceof builder.ExtendContextLiveQueryStep, 'EXTEND');
t.ok(query.steps[1] instanceof builder.QueryEdgeQueryStep, 'QUERY /students');
t.ok(query.steps[2] instanceof builder.ProvideIdQueryStep, 'PROVIDE ID: classId');
t.ok(query.steps[3] instanceof builder.ExtendContextQueryStep, 'APPLY PARAMS');
t.ok(query.steps[4] instanceof builder.QueryEdgeQueryStep, 'QUERY /classes');
return query.execute()
.then(resp => {
t.same(resp.data, {
id: "c1",
name: "A",
year: 1,
room: "Room 1",
schoolId: "s1"
});
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('/schools/s1/classes/c2', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's1', 'classes', 'c2']), query = api.buildQuery(request);
return query.execute()
.then(() => {
t.ok(false, "an invalid query should not succeed");
t.end();
})
.catch(e => {
t.ok(e instanceof ApiEdgeError_1.ApiEdgeError);
t.equal(e.status, 404);
t.equal(e.message, 'Not Found');
t.end();
});
}));
tap.test('POST /schools', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools']);
request.type = ApiRequest_1.ApiRequestType.Create;
const body = request.body = {
address: "12, Test street, North Pole, HA23535",
id: "s3",
name: "Third School",
phone: "456345283"
};
const query = api.buildQuery(request);
t.equal(query.steps.length, 2, 'should build a 2 step query');
t.ok(query.steps[0] instanceof builder.SetBodyQueryStep);
t.ok(query.steps[1] instanceof builder.QueryEdgeQueryStep);
return query.execute()
.then(resp => {
t.same(resp.data, body);
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('DELETE /schools/s3', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's3']);
request.type = ApiRequest_1.ApiRequestType.Delete;
const query = api.buildQuery(request);
t.equal(query.steps.length, 3, 'should build a 3 step query');
t.ok(query.steps[0] instanceof builder.ExtendContextLiveQueryStep);
t.ok(query.steps[1] instanceof builder.ExtendContextQueryStep);
t.ok(query.steps[2] instanceof builder.QueryEdgeQueryStep);
return query.execute()
.then(resp => {
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('DELETE /students/s2/class', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['students', 's2', 'class']);
request.type = ApiRequest_1.ApiRequestType.Delete;
try {
api.buildQuery(request);
t.ok(false, "an invalid query should not succeed");
t.end();
}
catch (e) {
t.ok(e instanceof ApiEdgeError_1.ApiEdgeError);
t.equal(e.status, 400);
t.equal(e.message, 'Invalid Delete Query');
t.end();
}
}));
tap.test('PATCH /schools/s2', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's2']);
request.type = ApiRequest_1.ApiRequestType.Patch;
request.body = {
name: "Cool School"
};
const query = api.buildQuery(request);
t.equal(query.steps.length, 4, 'should build a 4 step query');
t.ok(query.steps[0] instanceof builder.SetBodyQueryStep, 'SET BODY');
t.ok(query.steps[1] instanceof builder.ExtendContextLiveQueryStep, 'EXTEND');
t.ok(query.steps[2] instanceof builder.ExtendContextQueryStep, 'APPLY PARAMS');
t.ok(query.steps[3] instanceof builder.QueryEdgeQueryStep, 'QUERY');
return query.execute()
.then(resp => {
t.same(resp.data, {
address: "12, Test street, North Pole, HA23535",
id: "s2",
name: "Cool School",
phone: "456345283"
});
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('PUT /schools/s2', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['schools', 's2']);
request.type = ApiRequest_1.ApiRequestType.Update;
request.body = {
name: "Cool School"
};
const query = api.buildQuery(request);
t.equal(query.steps.length, 4, 'should build a 4 step query');
t.ok(query.steps[0] instanceof builder.SetBodyQueryStep, 'SET BODY');
t.ok(query.steps[1] instanceof builder.ExtendContextLiveQueryStep, 'EXTEND');
t.ok(query.steps[2] instanceof builder.ExtendContextQueryStep, 'APPLY PARAMS');
t.ok(query.steps[3] instanceof builder.QueryEdgeQueryStep, 'QUERY');
return query.execute()
.then(resp => {
t.same(resp.data, {
id: "s2",
name: "Cool School",
address: null,
phone: null
});
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('GET /students/s2/rename', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['students', 's2', 'rename']);
request.type = ApiRequest_1.ApiRequestType.Read;
try {
api.buildQuery(request);
t.ok(false, 'an invalid query should not succeed');
}
catch (e) {
t.ok(e instanceof ApiEdgeError_1.ApiEdgeError);
t.equal(e.message, 'Method Not Allowed');
t.equal(e.status, 405);
}
t.end();
}));
tap.test('/students/s2/withHungarianName', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['students', 's2', 'withHungarianName']), query = api.buildQuery(request);
t.equal(query.steps.length, 5, 'should build an 5 step query');
t.ok(query.steps[0] instanceof builder.ExtendContextLiveQueryStep, 'EXTEND');
t.ok(query.steps[1] instanceof builder.QueryEdgeQueryStep, 'QUERY /students');
t.ok(query.steps[2] instanceof builder.ExtendContextQueryStep, 'APPLY PARAMS');
t.ok(query.steps[3] instanceof builder.ProvideIdQueryStep, 'PROVIDE ID');
t.ok(query.steps[4] instanceof builder.CallMethodQueryStep, 'call{withHungarianName}');
return query.execute()
.then(resp => {
t.same(resp.data, {
id: "s2",
fullName: "Dave Test",
hungarianName: "Test Dave",
email: "dave.test@gmail.com",
schoolId: "s1",
classId: "c1"
});
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
tap.test('POST /students/s2/rename', (t) => __awaiter(void 0, void 0, void 0, function* () {
const request = yield api.parseRequest(['students', 's2', 'rename']);
request.type = ApiRequest_1.ApiRequestType.Update;
request.body = { name: "Test David" };
const query = api.buildQuery(request);
t.equal(query.steps.length, 5, 'should build a 4 step query');
t.ok(query.steps[0] instanceof builder.SetBodyQueryStep, 'SET BODY');
t.ok(query.steps[1] instanceof builder.SetResponseQueryStep, 'SET RESPONSE');
t.ok(query.steps[2] instanceof builder.ExtendContextQueryStep, 'APPLY PARAMS');
t.ok(query.steps[3] instanceof builder.ProvideIdQueryStep, 'PROVIDE ID');
t.ok(query.steps[4] instanceof builder.CallMethodQueryStep, 'call{rename}');
return query.execute()
.then(resp => {
t.same(resp.data, {
id: "s2",
fullName: "David Test",
email: "dave.test@gmail.com",
schoolId: "s1",
classId: "c1"
});
t.equal(resp.metadata, null);
t.end();
})
.catch(() => {
t.ok(false, "a valid query should not fail");
t.end();
});
}));
//# sourceMappingURL=query-builder.js.map