diff --git a/src/steps/pre-query/parse-request-primary.js b/src/steps/pre-query/parse-request-primary.js index 9ead5de0..0f84e8de 100644 --- a/src/steps/pre-query/parse-request-primary.js +++ b/src/steps/pre-query/parse-request-primary.js @@ -22,14 +22,24 @@ export default function(data, parseAsLinkage) { } catch (error) { - const title = "The resources you provided could not be parsed."; - const details = `The precise error was: "${error.message}".`; - reject(new APIError(400, undefined, title, details)); + if (error instanceof APIError) { + reject(error); + } + + else { + const title = "The resources you provided could not be parsed."; + const details = `The precise error was: "${error.message}".`; + reject(new APIError(400, undefined, title, details)); + } } }); } function relationshipObjectFromJSON(json) { + if (typeof json.data === "undefined") { + throw new APIError(400, undefined, `Missing relationship linkage.`); + } + return new RelationshipObject(linkageFromJSON(json.data)); } @@ -41,8 +51,15 @@ function resourceFromJSON(json) { let relationships = json.relationships || {}; //build RelationshipObjects - for(let key in relationships) { - relationships[key] = relationshipObjectFromJSON(relationships[key]); + let key; + try { + for(key in relationships) { + relationships[key] = relationshipObjectFromJSON(relationships[key], key); + } + } + catch (e) { + e.details = `No data was found for the ${key} relationship.`; + throw e; } return new Resource(json.type, json.id, json.attributes, relationships, json.meta); diff --git a/test/integration/create-resource/index.js b/test/integration/create-resource/index.js index 3ac9aec5..df693ab6 100644 --- a/test/integration/create-resource/index.js +++ b/test/integration/create-resource/index.js @@ -3,7 +3,8 @@ import AgentPromise from "../../app/agent"; import { ORG_RESOURCE_CLIENT_ID, VALID_ORG_RESOURCE_NO_ID_EXTRA_MEMBER, - VALID_SCHOOL_RESOURCE_NO_ID + VALID_SCHOOL_RESOURCE_NO_ID, + INVALID_ORG_RESOURCE_NO_DATA_IN_RELATIONSHIP } from "../fixtures/creation"; describe("", () => { @@ -106,6 +107,40 @@ describe("", () => { }).done(); }); +describe("", () => { + AgentPromise.then((Agent) => { + Agent.request("POST", "/organizations") + .type("application/vnd.api+json") + .send({"data": INVALID_ORG_RESOURCE_NO_DATA_IN_RELATIONSHIP}) + .promise() + .then(() => { throw new Error("Should not run!"); }, (err) => { + describe("Creating a Resource With a Missing Relationship Data Key", () => { + describe("HTTP", () => { + it("should return 400", () => { + expect(err.response.status).to.equal(400); + }); + }); + + describe("Document Structure", () => { + it("should contain an error", () => { + expect(err.response.body.errors).to.be.an("array"); + }); + }); + + describe("Error", () => { + it("should have the correct title", () => { + expect(err.response.body.errors[0].title).to.be.equal("Missing relationship linkage."); + }); + + it("should have the correct details", () => { + expect(err.response.body.errors[0].details).to.be.equal("No data was found for the liaisons relationship."); + }); + }); + }); + }).done(); + }).done(); +}); + // "[S]erver implementations MUST ignore // [members] not recognized by this specification." /*it("must ignore unrecognized request object members", (done) => { diff --git a/test/integration/fixtures/creation.js b/test/integration/fixtures/creation.js index b43ffccf..8231c14d 100644 --- a/test/integration/fixtures/creation.js +++ b/test/integration/fixtures/creation.js @@ -24,3 +24,12 @@ export const VALID_SCHOOL_RESOURCE_NO_ID = { "name": "Test School" } }; + +export const INVALID_ORG_RESOURCE_NO_DATA_IN_RELATIONSHIP = { + "type": "organizations", + "relationships": { + "liaisons": { + "type": "people", "id": "53f54dd98d1e62ff12539db3" + } + } +};