From d836b06ffecd12baadffdf435967e33cb864dd74 Mon Sep 17 00:00:00 2001 From: Lance Ball Date: Mon, 18 May 2020 08:30:28 -0400 Subject: [PATCH] lib: expose constants as a top-level export (#161) This commit pulls the constants up from the lib/bindings/http/constants.js and exports them in the top level index.js. There are some elements of the API where we expect users to provide constant values, and this makes it easier for them to be sure the values they provide are what is expected. I've also added two new constants: `BINARY` and `STRUCTURED`. Signed-off-by: Lance Ball --- index.js | 4 +- lib/bindings/http/constants.js | 3 + lib/bindings/http/http_receiver.js | 8 +- lib/bindings/http/unmarshaller.js | 7 +- test/bindings/http/unmarshaller_0_3_tests.js | 5 +- test/constants_test.js | 191 +++++++++++++++++++ test/spec_0_3_tests.js | 5 +- 7 files changed, 211 insertions(+), 12 deletions(-) create mode 100644 test/constants_test.js diff --git a/index.js b/index.js index 11036a1..eb404ef 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,11 @@ const CloudEvent = require("./lib/cloudevent.js"); const HTTPReceiver = require("./lib/bindings/http/http_receiver.js"); const HTTPEmitter = require("./lib/bindings/http/http_emitter.js"); +const Constants = require("./lib/bindings/http/constants.js"); module.exports = { CloudEvent, HTTPReceiver, - HTTPEmitter + HTTPEmitter, + Constants }; diff --git a/lib/bindings/http/constants.js b/lib/bindings/http/constants.js index ab8fead..89542bc 100644 --- a/lib/bindings/http/constants.js +++ b/lib/bindings/http/constants.js @@ -3,6 +3,9 @@ module.exports = Object.freeze({ HEADERS: "headers", CHARSET_DEFAULT: "utf-8", + BINARY: "binary", + STRUCTURED: "structured", + SPEC_V03: "0.3", SPEC_V1: "1.0", diff --git a/lib/bindings/http/http_receiver.js b/lib/bindings/http/http_receiver.js index 803401d..78f5631 100644 --- a/lib/bindings/http/http_receiver.js +++ b/lib/bindings/http/http_receiver.js @@ -4,6 +4,8 @@ const V1Binary = require("./receiver_binary_1.js"); const V1Structured = require("./receiver_structured_1.js"); const ValidationError = require("../../validation_error.js"); const { + BINARY, + STRUCTURED, SPEC_V03, SPEC_V1, HEADER_CONTENT_TYPE, @@ -59,16 +61,16 @@ class HTTPReceiver { function getMode(headers) { const contentType = headers[HEADER_CONTENT_TYPE]; if (contentType && contentType.startsWith(MIME_CE)) { - return "structured"; + return STRUCTURED; } if (headers[BINARY_HEADERS_1.ID]) { - return "binary"; + return BINARY; } throw new ValidationError("no cloud event detected"); } function getVersion(mode, headers, body) { - if (mode === "binary") { + if (mode === BINARY) { // Check the headers for the version const versionHeader = headers[DEFAULT_SPEC_VERSION_HEADER]; if (versionHeader) { diff --git a/lib/bindings/http/unmarshaller.js b/lib/bindings/http/unmarshaller.js index dd071df..9bf97c2 100644 --- a/lib/bindings/http/unmarshaller.js +++ b/lib/bindings/http/unmarshaller.js @@ -3,14 +3,13 @@ const { MIME_CE, MIME_CE_JSON, MIME_JSON, - MIME_OCTET_STREAM + MIME_OCTET_STREAM, + BINARY, + STRUCTURED } = require("./constants.js"); const Commons = require("./commons.js"); const ValidationError = require("../../validation_error.js"); -const STRUCTURED = "structured"; -const BINARY = "binary"; - const allowedBinaryContentTypes = [ MIME_JSON, MIME_OCTET_STREAM diff --git a/test/bindings/http/unmarshaller_0_3_tests.js b/test/bindings/http/unmarshaller_0_3_tests.js index 55ff87e..77462e1 100644 --- a/test/bindings/http/unmarshaller_0_3_tests.js +++ b/test/bindings/http/unmarshaller_0_3_tests.js @@ -11,7 +11,8 @@ const schemaurl = "http://cloudevents.io/schema.json"; const subject = "subject.ext"; const { BINARY_HEADERS_03, - HEADER_CONTENT_TYPE + HEADER_CONTENT_TYPE, + BINARY } = require("../../../lib/bindings/http/constants.js"); const ceContentType = "application/json"; @@ -182,7 +183,7 @@ describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => { [BINARY_HEADERS_03.TIME]: "2019-06-16T11:42:00Z", [BINARY_HEADERS_03.SCHEMA_URL]: "http://schema.registry/v1", [HEADER_CONTENT_TYPE]: "application/json", - [BINARY_HEADERS_03.CONTENT_ENCONDING]: "binary" + [BINARY_HEADERS_03.CONTENT_ENCONDING]: BINARY }; expect(() => un.unmarshall(payload, attributes)).to diff --git a/test/constants_test.js b/test/constants_test.js new file mode 100644 index 0000000..55d2078 --- /dev/null +++ b/test/constants_test.js @@ -0,0 +1,191 @@ +const expect = require("chai").expect; + +const { + HEADERS, + CHARSET_DEFAULT, + BINARY, + STRUCTURED, + SPEC_V03, + SPEC_V1, + DEFAULT_SPEC_VERSION_HEADER, + ENCODING_BASE64, + DATA_ATTRIBUTE, + MIME_JSON, + MIME_OCTET_STREAM, + MIME_CE, + MIME_CE_JSON, + HEADER_CONTENT_TYPE, + DEFAULT_CONTENT_TYPE, + DEFAULT_CE_CONTENT_TYPE, + BINARY_HEADERS_03, + STRUCTURED_ATTRS_03, + BINARY_HEADERS_1, + STRUCTURED_ATTRS_1 +} = require("../").Constants; + +describe("Constants exposed by top level exports", () => { + it("Exports a HEADERS constant", () => { + expect(HEADERS).to.equal("headers"); + }); + it("Exports a CHARSET_DEFAULT constant", () => { + expect(CHARSET_DEFAULT).to.equal("utf-8"); + }); + it("Exports a BINARY constant", () => { + expect(BINARY).to.equal("binary"); + }); + it("Exports a STRUCTURED constant", () => { + expect(STRUCTURED).to.equal("structured"); + }); + it("Exports a SPEC_V03 constant", () => { + expect(SPEC_V03).to.equal("0.3"); + }); + it("Exports a SPEC_V1 constant", () => { + expect(SPEC_V1).to.equal("1.0"); + }); + it("Exports a DEFAULT_SPEC_VERSION_HEADER constant", () => { + expect(DEFAULT_SPEC_VERSION_HEADER).to.equal("ce-specversion"); + }); + it("Exports an ENCODING_BASE64 constant", () => { + expect(ENCODING_BASE64).to.equal("base64"); + }); + it("Exports a DATA_ATTRIBUTE constant", () => { + expect(DATA_ATTRIBUTE).to.equal("data"); + }); + it("Exports a MIME_JSON constant", () => { + expect(MIME_JSON).to.equal("application/json"); + }); + it("Exports a MIME_OCTET_STREAM constant", () => { + expect(MIME_OCTET_STREAM).to.equal("application/octet-stream"); + }); + it("Exports a MIME_CE constant", () => { + expect(MIME_CE).to.equal("application/cloudevents"); + }); + it("Exports a MIME_CE_JSON constant", () => { + expect(MIME_CE_JSON).to.equal("application/cloudevents+json"); + }); + it("Exports a HEADER_CONTENT_TYPE constant", () => { + expect(HEADER_CONTENT_TYPE).to.equal("content-type"); + }); + it("Exports a DEFAULT_CONTENT_TYPE constant", () => { + expect(DEFAULT_CONTENT_TYPE).to.equal(`${MIME_JSON}; charset=${CHARSET_DEFAULT}`); + }); + it("Exports a DEFAULT_CE_CONTENT_TYPE constant", () => { + expect(DEFAULT_CE_CONTENT_TYPE).to.equal(`${MIME_CE_JSON}; charset=${CHARSET_DEFAULT}`); + }); + describe("V0.3 binary headers constants", () => { + it("Provides a TYPE header", () => { + expect(BINARY_HEADERS_03.TYPE).to.equal("ce-type"); + }); + it("Provides a SPEC_VERSION header", () => { + expect(BINARY_HEADERS_03.SPEC_VERSION).to.equal("ce-specversion"); + }); + it("Provides a SOURCE header", () => { + expect(BINARY_HEADERS_03.SOURCE).to.equal("ce-source"); + }); + it("Provides an ID header", () => { + expect(BINARY_HEADERS_03.ID).to.equal("ce-id"); + }); + it("Provides a TIME header", () => { + expect(BINARY_HEADERS_03.TIME).to.equal("ce-time"); + }); + it("Provides a SCHEMA_URL header", () => { + expect(BINARY_HEADERS_03.SCHEMA_URL).to.equal("ce-schemaurl"); + }); + it("Provides a CONTENT_ENCODING header", () => { + expect(BINARY_HEADERS_03.CONTENT_ENCONDING).to.equal("ce-datacontentencoding"); + }); + it("Provides a SUBJECT header", () => { + expect(BINARY_HEADERS_03.SUBJECT).to.equal("ce-subject"); + }); + it("Provides an EXTENSIONS_PREFIX constant", () => { + expect(BINARY_HEADERS_03.EXTENSIONS_PREFIX).to.equal("ce-"); + }); + }); + describe("V0.3 structured attributes constants", () => { + it("Provides a TYPE attribute", () => { + expect(STRUCTURED_ATTRS_03.TYPE).to.equal("type"); + }); + it("Provides a SPEC_VERSION attribute", () => { + expect(STRUCTURED_ATTRS_03.SPEC_VERSION).to.equal("specversion"); + }); + it("Provides a SOURCE attribute", () => { + expect(STRUCTURED_ATTRS_03.SOURCE).to.equal("source"); + }); + it("Provides an ID attribute", () => { + expect(STRUCTURED_ATTRS_03.ID).to.equal("id"); + }); + it("Provides a TIME attribute", () => { + expect(STRUCTURED_ATTRS_03.TIME).to.equal("time"); + }); + it("Provides a SCHEMA_URL attribute", () => { + expect(STRUCTURED_ATTRS_03.SCHEMA_URL).to.equal("schemaurl"); + }); + it("Provides a CONTENT_ENCODING attribute", () => { + expect(STRUCTURED_ATTRS_03.CONTENT_ENCONDING).to.equal("datacontentencoding"); + }); + it("Provides a SUBJECT attribute", () => { + expect(STRUCTURED_ATTRS_03.SUBJECT).to.equal("subject"); + }); + it("Provides a DATA attribute", () => { + expect(STRUCTURED_ATTRS_03.DATA).to.equal("data"); + }); + }); + describe("V01 binary headers constants", () => { + it("Provides a TYPE header", () => { + expect(BINARY_HEADERS_1.TYPE).to.equal("ce-type"); + }); + it("Provides a SPEC_VERSION header", () => { + expect(BINARY_HEADERS_1.SPEC_VERSION).to.equal("ce-specversion"); + }); + it("Provides a SOURCE header", () => { + expect(BINARY_HEADERS_1.SOURCE).to.equal("ce-source"); + }); + it("Provides an ID header", () => { + expect(BINARY_HEADERS_1.ID).to.equal("ce-id"); + }); + it("Provides a TIME header", () => { + expect(BINARY_HEADERS_1.TIME).to.equal("ce-time"); + }); + it("Provides a DATA_SCHEMA header", () => { + expect(BINARY_HEADERS_1.DATA_SCHEMA).to.equal("ce-dataschema"); + }); + it("Provides a SUBJECT header", () => { + expect(BINARY_HEADERS_1.SUBJECT).to.equal("ce-subject"); + }); + it("Provides an EXTENSIONS_PREFIX constant", () => { + expect(BINARY_HEADERS_1.EXTENSIONS_PREFIX).to.equal("ce-"); + }); + }); + describe("V1 structured attributes constants", () => { + it("Provides a TYPE attribute", () => { + expect(STRUCTURED_ATTRS_1.TYPE).to.equal("type"); + }); + it("Provides a SPEC_VERSION attribute", () => { + expect(STRUCTURED_ATTRS_1.SPEC_VERSION).to.equal("specversion"); + }); + it("Provides a SOURCE attribute", () => { + expect(STRUCTURED_ATTRS_1.SOURCE).to.equal("source"); + }); + it("Provides an ID attribute", () => { + expect(STRUCTURED_ATTRS_1.ID).to.equal("id"); + }); + it("Provides a TIME attribute", () => { + expect(STRUCTURED_ATTRS_1.TIME).to.equal("time"); + }); + it("Provides a DATA_SCHEMA attribute", () => { + expect(STRUCTURED_ATTRS_1.DATA_SCHEMA).to.equal("dataschema"); + }); + it("Provides a CONTENT_TYPE attribute", () => { + expect(STRUCTURED_ATTRS_1.CONTENT_TYPE).to.equal("datacontenttype"); + }); + it("Provides a SUBJECT attribute", () => { + expect(STRUCTURED_ATTRS_1.SUBJECT).to.equal("subject"); + }); + it("Provides a DATA attribute", () => { + expect(STRUCTURED_ATTRS_1.DATA).to.equal("data"); + }); + it("Provides a DATA_BASE64 attribute", () => { + expect(STRUCTURED_ATTRS_1.DATA_BASE64).to.equal("data_base64"); + }); + }); +}); \ No newline at end of file diff --git a/test/spec_0_3_tests.js b/test/spec_0_3_tests.js index 4de79d6..6ab6a24 100644 --- a/test/spec_0_3_tests.js +++ b/test/spec_0_3_tests.js @@ -4,7 +4,8 @@ const { CloudEvent } = require("../index.js"); const { MIME_JSON, ENCODING_BASE64, - SPEC_V03 + SPEC_V03, + BINARY } = require("../lib/bindings/http/constants.js"); const ValidationError = require("../lib/validation_error.js"); @@ -155,7 +156,7 @@ describe("CloudEvents Spec v0.3", () => { it("should throw an error when is a unsupported encoding", () => { cloudevent .data("Y2xvdWRldmVudHMK") - .dataContentEncoding("binary"); + .dataContentEncoding(BINARY); expect(cloudevent.format.bind(cloudevent)) .to.throw(ValidationError, "invalid payload"); delete cloudevent.spec.payload.datacontentencoding;