UNPKG

api-core

Version:

Model-based dynamic multi-level APIs for any provider, plus multiple consumption channels

411 lines 17 kB
"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