feat!: expose a version agnostic event emitter (#141)
* feat!: expose a version agnostic event emitter This is a breaking change. This commit exposes an HTTP based event emitter that simplifes the API. To use it, simply import the SDK and start emitting. The default spec version is 1.0, but you can use 0.3 by supplying that to the constructor. By default, CloudEvents are emitted in binary mode, but this can be changed by providing the "structured" parameter to the `send()` function. This commit also eliminates the version specific emitters and receivers from the `v1` and `v03` exports, and eliminates the explicit usage of versioned emitters from `lib/bindings/http`. Finally, the CE headers can be retrieved from the emitter for a given event by passing the event to the `headers()` function. Fixes: https://github.com/cloudevents/sdk-javascript/issues/124 Fixes: https://github.com/cloudevents/sdk-javascript/issues/149 Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
76659697aa
commit
250a0a144c
57
README.md
57
README.md
|
@ -62,25 +62,60 @@ console.log(receivedEvent.format());
|
|||
|
||||
#### Emitting Events
|
||||
|
||||
Currently, to emit events, you'll need to decide whether the event is in
|
||||
To emit events, you'll need to decide whether the event should be sent in
|
||||
binary or structured format, and determine what version of the CloudEvents
|
||||
specification you want to send the event as.
|
||||
|
||||
By default, the `HTTPEmitter` will emit events over HTTP POST using the
|
||||
1.0 specification, in binary mode. You can emit 0.3 events by providing
|
||||
the specication version in the constructor to `HTTPEmitter`. To send
|
||||
structured events, add that string as a parameter to `emitter.sent()`.
|
||||
|
||||
```js
|
||||
const { CloudEvent } = require("cloudevents-sdk");
|
||||
const { StructuredHTTPEmitter } = require("cloudevents-sdk/v1");
|
||||
const { CloudEvent, HTTPEmitter } = require("cloudevents-sdk");
|
||||
|
||||
const myevent = new CloudEvent()
|
||||
.type("com.github.pull.create")
|
||||
.source("urn:event:from:myapi/resource/123");
|
||||
// With only an endpoint URL, this creates a v1 emitter
|
||||
const v1Emitter = new HTTPEmitter({
|
||||
url: "https://cloudevents.io/example"
|
||||
});
|
||||
const event = new CloudEvent()
|
||||
.type(type)
|
||||
.source(source)
|
||||
.time(new Date())
|
||||
.data(data)
|
||||
|
||||
const emitter = new StructuredHTTPEmitter({
|
||||
method: "POST",
|
||||
url : "https://myserver.com"
|
||||
// By default, the emitter will send binary events
|
||||
v1Emitter.send(event).then((response) => {
|
||||
// handle the response
|
||||
}).catch(console.error);
|
||||
|
||||
// To send a structured event, just add that as an option
|
||||
v1Emitter.send(event, { mode: "structured" })
|
||||
.then((response) => {
|
||||
// handle the response
|
||||
}).catch(console.error);
|
||||
|
||||
// To send an event to an alternate URL, add that as an option
|
||||
v1Emitter.send(event, { url: "https://alternate.com/api" })
|
||||
.then((response) => {
|
||||
// handle the response
|
||||
}).catch(console.error);
|
||||
|
||||
// Sending a v0.3 event works the same, just let the emitter know when
|
||||
// you create it that you are working with the 0.3 spec
|
||||
const v03Emitter = new HTTPEmitter({
|
||||
url: "https://cloudevents.io/example",
|
||||
version: "0.3"
|
||||
});
|
||||
|
||||
// Emit the event
|
||||
emitter.emit(myevent)
|
||||
// Again, the default is to send binary events
|
||||
// To send a structured event or to an alternate URL, provide those
|
||||
// as parameters in a options object as above
|
||||
v3Emitter.send(event)
|
||||
.then((response) => {
|
||||
// handle the response
|
||||
}).catch(console.error);
|
||||
|
||||
```
|
||||
|
||||
## Supported specification features
|
||||
|
|
4
index.js
4
index.js
|
@ -1,7 +1,9 @@
|
|||
const CloudEvent = require("./lib/cloudevent.js");
|
||||
const HTTPReceiver = require("./lib/bindings/http/http_receiver.js");
|
||||
const HTTPEmitter = require("./lib/bindings/http/http_emitter.js");
|
||||
|
||||
module.exports = {
|
||||
CloudEvent,
|
||||
HTTPReceiver
|
||||
HTTPReceiver,
|
||||
HTTPEmitter
|
||||
};
|
||||
|
|
|
@ -1,49 +1,85 @@
|
|||
const axios = require("axios");
|
||||
|
||||
const Constants = require("./constants.js");
|
||||
const defaults = {};
|
||||
defaults[Constants.HEADERS] = {};
|
||||
defaults[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE] =
|
||||
Constants.DEFAULT_CONTENT_TYPE;
|
||||
const {
|
||||
HEADERS,
|
||||
BINARY_HEADERS_03,
|
||||
BINARY_HEADERS_1,
|
||||
HEADER_CONTENT_TYPE,
|
||||
DEFAULT_CONTENT_TYPE,
|
||||
DATA_ATTRIBUTE,
|
||||
SPEC_V1,
|
||||
SPEC_V03
|
||||
} = require("./constants.js");
|
||||
|
||||
function BinaryHTTPEmitter(config, headerByGetter, extensionPrefix) {
|
||||
this.config = Object.assign({}, defaults, config);
|
||||
this.headerByGetter = headerByGetter;
|
||||
this.extensionPrefix = extensionPrefix;
|
||||
}
|
||||
|
||||
BinaryHTTPEmitter.prototype.emit = function(cloudevent) {
|
||||
const config = Object.assign({}, this.config);
|
||||
const headers = Object.assign({}, this.config[Constants.HEADERS]);
|
||||
|
||||
Object.keys(this.headerByGetter)
|
||||
.filter((getter) => cloudevent[getter]())
|
||||
.forEach((getter) => {
|
||||
const header = this.headerByGetter[getter];
|
||||
headers[header.name] =
|
||||
header.parser(
|
||||
cloudevent[getter]()
|
||||
);
|
||||
});
|
||||
|
||||
// Set the cloudevent payload
|
||||
const formatted = cloudevent.format();
|
||||
let data = formatted.data;
|
||||
data = (formatted.data_base64 ? formatted.data_base64 : data);
|
||||
|
||||
// Have extensions?
|
||||
const exts = cloudevent.getExtensions();
|
||||
Object.keys(exts)
|
||||
.filter((ext) => Object.hasOwnProperty.call(exts, ext))
|
||||
.forEach((ext) => {
|
||||
headers[this.extensionPrefix + ext] = exts[ext];
|
||||
});
|
||||
|
||||
config[Constants.DATA_ATTRIBUTE] = data;
|
||||
config.headers = headers;
|
||||
|
||||
// Return the Promise
|
||||
return axios.request(config);
|
||||
const defaults = {
|
||||
[HEADERS]: {
|
||||
[HEADER_CONTENT_TYPE]: DEFAULT_CONTENT_TYPE
|
||||
},
|
||||
method: "POST"
|
||||
};
|
||||
|
||||
/**
|
||||
* A class to emit binary CloudEvents over HTTP.
|
||||
*/
|
||||
class BinaryHTTPEmitter {
|
||||
/**
|
||||
* Create a new {BinaryHTTPEmitter} for the provided CloudEvent specification version.
|
||||
* Once an instance is created for a given spec version, it may only be used to send
|
||||
* events for that version.
|
||||
* Default version is 1.0
|
||||
* @param {string} version - the CloudEvent HTTP specification version.
|
||||
* Default: 1.0
|
||||
*/
|
||||
constructor(version) {
|
||||
if (version === SPEC_V1) {
|
||||
this.headerByGetter = require("./emitter_binary_1.js");
|
||||
this.extensionPrefix = BINARY_HEADERS_1.EXTENSIONS_PREFIX;
|
||||
} else if (version === SPEC_V03) {
|
||||
this.headerByGetter = require("./emitter_binary_0_3.js");
|
||||
this.extensionPrefix = BINARY_HEADERS_03.EXTENSIONS_PREFIX;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends this cloud event to a receiver over HTTP.
|
||||
*
|
||||
* @param {Object} options The configuration options for this event. Options
|
||||
* provided other than `url` will be passed along to Node.js `http.request`.
|
||||
* https://nodejs.org/api/http.html#http_http_request_options_callback
|
||||
* @param {URL} options.url The HTTP/S url that should receive this event
|
||||
* @param {Object} cloudevent the CloudEvent to be sent
|
||||
* @returns {Promise} Promise with an eventual response from the receiver
|
||||
*/
|
||||
async emit(options, cloudevent) {
|
||||
const config = { ...options, ...defaults };
|
||||
const headers = config[HEADERS];
|
||||
|
||||
Object.keys(this.headerByGetter)
|
||||
.filter((getter) => cloudevent[getter]())
|
||||
.forEach((getter) => {
|
||||
const header = this.headerByGetter[getter];
|
||||
headers[header.name] = header.parser(cloudevent[getter]());
|
||||
});
|
||||
|
||||
// Set the cloudevent payload
|
||||
const formatted = cloudevent.format();
|
||||
let data = formatted.data;
|
||||
data = (formatted.data_base64 ? formatted.data_base64 : data);
|
||||
|
||||
// Have extensions?
|
||||
const exts = cloudevent.getExtensions();
|
||||
Object.keys(exts)
|
||||
.filter((ext) => Object.hasOwnProperty.call(exts, ext))
|
||||
.forEach((ext) => {
|
||||
headers[this.extensionPrefix + ext] = exts[ext];
|
||||
});
|
||||
|
||||
config[DATA_ATTRIBUTE] = data;
|
||||
config.headers = headers;
|
||||
|
||||
// Return the Promise
|
||||
return axios.request(config);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BinaryHTTPEmitter;
|
||||
|
|
|
@ -1,64 +1,53 @@
|
|||
const BinaryHTTPEmitter = require("./emitter_binary.js");
|
||||
|
||||
const Constants = require("./constants.js");
|
||||
const {
|
||||
HEADER_CONTENT_TYPE,
|
||||
BINARY_HEADERS_03
|
||||
} = require("./constants.js");
|
||||
|
||||
const headerByGetter = {};
|
||||
|
||||
headerByGetter.getDataContentType = {
|
||||
name: Constants.HEADER_CONTENT_TYPE,
|
||||
name: HEADER_CONTENT_TYPE,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getDataContentEncoding = {
|
||||
name: Constants.BINARY_HEADERS_03.CONTENT_ENCONDING,
|
||||
name: BINARY_HEADERS_03.CONTENT_ENCONDING,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getSubject = {
|
||||
name: Constants.BINARY_HEADERS_03.SUBJECT,
|
||||
name: BINARY_HEADERS_03.SUBJECT,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getType = {
|
||||
name: Constants.BINARY_HEADERS_03.TYPE,
|
||||
name: BINARY_HEADERS_03.TYPE,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getSpecversion = {
|
||||
name: Constants.BINARY_HEADERS_03.SPEC_VERSION,
|
||||
name: BINARY_HEADERS_03.SPEC_VERSION,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getSource = {
|
||||
name: Constants.BINARY_HEADERS_03.SOURCE,
|
||||
name: BINARY_HEADERS_03.SOURCE,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getId = {
|
||||
name: Constants.BINARY_HEADERS_03.ID,
|
||||
name: BINARY_HEADERS_03.ID,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getTime = {
|
||||
name: Constants.BINARY_HEADERS_03.TIME,
|
||||
name: BINARY_HEADERS_03.TIME,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getSchemaurl = {
|
||||
name: Constants.BINARY_HEADERS_03.SCHEMA_URL,
|
||||
name: BINARY_HEADERS_03.SCHEMA_URL,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
function HTTPBinary(configuration) {
|
||||
this.emitter = new BinaryHTTPEmitter(
|
||||
configuration,
|
||||
headerByGetter,
|
||||
Constants.BINARY_HEADERS_03.EXTENSIONS_PREFIX
|
||||
);
|
||||
}
|
||||
|
||||
HTTPBinary.prototype.emit = function(cloudevent) {
|
||||
return this.emitter.emit(cloudevent);
|
||||
};
|
||||
|
||||
module.exports = HTTPBinary;
|
||||
module.exports = headerByGetter;
|
||||
|
|
|
@ -1,59 +1,48 @@
|
|||
const BinaryHTTPEmitter = require("./emitter_binary.js");
|
||||
|
||||
const Constants = require("./constants.js");
|
||||
const {
|
||||
HEADER_CONTENT_TYPE,
|
||||
BINARY_HEADERS_1
|
||||
} = require("./constants.js");
|
||||
|
||||
const headerByGetter = {};
|
||||
|
||||
headerByGetter.getDataContentType = {
|
||||
name: Constants.HEADER_CONTENT_TYPE,
|
||||
name: HEADER_CONTENT_TYPE,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getSubject = {
|
||||
name: Constants.BINARY_HEADERS_1.SUBJECT,
|
||||
name: BINARY_HEADERS_1.SUBJECT,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getType = {
|
||||
name: Constants.BINARY_HEADERS_1.TYPE,
|
||||
name: BINARY_HEADERS_1.TYPE,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getSpecversion = {
|
||||
name: Constants.BINARY_HEADERS_1.SPEC_VERSION,
|
||||
name: BINARY_HEADERS_1.SPEC_VERSION,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getSource = {
|
||||
name: Constants.BINARY_HEADERS_1.SOURCE,
|
||||
name: BINARY_HEADERS_1.SOURCE,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getId = {
|
||||
name: Constants.BINARY_HEADERS_1.ID,
|
||||
name: BINARY_HEADERS_1.ID,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getTime = {
|
||||
name: Constants.BINARY_HEADERS_1.TIME,
|
||||
name: BINARY_HEADERS_1.TIME,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
headerByGetter.getDataschema = {
|
||||
name: Constants.BINARY_HEADERS_1.DATA_SCHEMA,
|
||||
name: BINARY_HEADERS_1.DATA_SCHEMA,
|
||||
parser: (v) => v
|
||||
};
|
||||
|
||||
function HTTPBinary(configuration) {
|
||||
this.emitter = new BinaryHTTPEmitter(
|
||||
configuration,
|
||||
headerByGetter,
|
||||
Constants.BINARY_HEADERS_1.EXTENSIONS_PREFIX
|
||||
);
|
||||
}
|
||||
|
||||
HTTPBinary.prototype.emit = function(cloudevent) {
|
||||
return this.emitter.emit(cloudevent);
|
||||
};
|
||||
|
||||
module.exports = HTTPBinary;
|
||||
module.exports = headerByGetter;
|
||||
|
|
|
@ -1,24 +1,38 @@
|
|||
const axios = require("axios");
|
||||
const {
|
||||
DATA_ATTRIBUTE,
|
||||
DEFAULT_CE_CONTENT_TYPE,
|
||||
HEADERS,
|
||||
HEADER_CONTENT_TYPE
|
||||
} = require("./constants.js");
|
||||
|
||||
const Constants = require("./constants.js");
|
||||
const defaults = {};
|
||||
defaults[Constants.HEADERS] = {};
|
||||
defaults[Constants.HEADERS][Constants.HEADER_CONTENT_TYPE] =
|
||||
Constants.DEFAULT_CE_CONTENT_TYPE;
|
||||
|
||||
function StructuredHTTPEmitter(configuration) {
|
||||
this.config = Object.assign({}, defaults, configuration);
|
||||
}
|
||||
|
||||
StructuredHTTPEmitter.prototype.emit = function(cloudevent) {
|
||||
// Set the cloudevent payload
|
||||
this.config[Constants.DATA_ATTRIBUTE] = cloudevent.format();
|
||||
|
||||
// Return the Promise
|
||||
return axios.request(this.config).then((response) => {
|
||||
delete this.config[Constants.DATA_ATTRIBUTE];
|
||||
return response;
|
||||
});
|
||||
const defaults = {
|
||||
[HEADERS]: {
|
||||
[HEADER_CONTENT_TYPE]: DEFAULT_CE_CONTENT_TYPE
|
||||
},
|
||||
method: "POST"
|
||||
};
|
||||
|
||||
/**
|
||||
* A class for sending {CloudEvent} instances over HTTP.
|
||||
*/
|
||||
class StructuredHTTPEmitter {
|
||||
// TODO: Do we really need a class here? There is no state maintenance
|
||||
|
||||
/**
|
||||
* Sends the event over HTTP
|
||||
* @param {Object} options The configuration options for this event. Options
|
||||
* provided will be passed along to Node.js `http.request()`.
|
||||
* https://nodejs.org/api/http.html#http_http_request_options_callback
|
||||
* @param {URL} options.url The HTTP/S url that should receive this event
|
||||
* @param {CloudEvent} cloudevent The CloudEvent to be sent
|
||||
* @returns {Promise} Promise with an eventual response from the receiver
|
||||
*/
|
||||
async emit(options, cloudevent) {
|
||||
const config = { ...defaults, ...options };
|
||||
config[DATA_ATTRIBUTE] = cloudevent.format();
|
||||
return axios.request(config);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StructuredHTTPEmitter;
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
const BinaryHTTPEmitter = require("./emitter_binary.js");
|
||||
const StructuredEmitter = require("./emitter_structured.js");
|
||||
|
||||
const {
|
||||
SPEC_V03,
|
||||
SPEC_V1
|
||||
} = require("./constants");
|
||||
|
||||
/**
|
||||
* A class which is capable of sending binary and structured events using
|
||||
* the CloudEvents HTTP Protocol Binding specification.
|
||||
*
|
||||
* @see https://github.com/cloudevents/spec/blob/v1.0/http-protocol-binding.md
|
||||
* @see https://github.com/cloudevents/spec/blob/v1.0/http-protocol-binding.md#13-content-modes
|
||||
*/
|
||||
class HTTPEmitter {
|
||||
/**
|
||||
* Creates a new instance of {HTTPEmitter}. The default emitter uses the 1.0
|
||||
* protocol specification in binary mode.
|
||||
*
|
||||
* @param {Object} [options] The configuration options for this event emitter
|
||||
* @param {URL} options.url The endpoint that will receive the sent events.
|
||||
* @param {string} [options.version] The HTTP binding specification version. Default: "1.0"
|
||||
* @throws {TypeError} if no options.url is provided or an unknown specification version is provided.
|
||||
*/
|
||||
constructor({ url, version = SPEC_V1 } = {}) {
|
||||
if (version !== SPEC_V03 && version !== SPEC_V1) {
|
||||
throw new TypeError(
|
||||
`Unknown CloudEvent specification version: ${version}`);
|
||||
}
|
||||
if (!url) {
|
||||
throw new TypeError("A default endpoint URL is required for a CloudEvent emitter");
|
||||
}
|
||||
this.binary = new BinaryHTTPEmitter(version);
|
||||
this.structured = new StructuredEmitter();
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the {CloudEvent} to an event receiver over HTTP POST
|
||||
*
|
||||
* @param {CloudEvent} event the CloudEvent to be sent
|
||||
* @param {Object} [options] The configuration options for this event. Options
|
||||
* provided will be passed along to Node.js `http.request()`.
|
||||
* https://nodejs.org/api/http.html#http_http_request_options_callback
|
||||
* @param {URL} [options.url] The HTTP/S url that should receive this event.
|
||||
* The URL is optional if one was provided when this emitter was constructed.
|
||||
* In that case, it will be used as the recipient endpoint. The endpoint can
|
||||
* be overridden by providing a URL here.
|
||||
* @param {string} [options.mode] the message mode for sending this event.
|
||||
* Possible values are "binary" and "structured". Default: structured
|
||||
* @returns {Promise} Promise with an eventual response from the receiver
|
||||
*/
|
||||
send(event, { url, mode = "binary", ...httpOpts } = {}) {
|
||||
if (!url) { url = this.url; }
|
||||
httpOpts.url = url;
|
||||
if (mode === "binary") {
|
||||
return this.binary.emit(httpOpts, event);
|
||||
} else if (mode === "structured") {
|
||||
return this.structured.emit(httpOpts, event);
|
||||
}
|
||||
throw new TypeError(`Unknown transport mode ${mode}.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the HTTP headers that will be sent for this event when the HTTP transmission
|
||||
* mode is "binary". Events sent over HTTP in structured mode only have a single CE header
|
||||
* and that is "ce-id", corresponding to the event ID.
|
||||
* @param {CloudEvent} event a CloudEvent
|
||||
* @returns {Object} the headers that will be sent for the event
|
||||
*/
|
||||
headers(event) {
|
||||
const headers = {};
|
||||
|
||||
Object.keys(this.binary.headerByGetter)
|
||||
.filter((getter) => event[getter]())
|
||||
.forEach((getter) => {
|
||||
const header = this.binary.headerByGetter[getter];
|
||||
headers[header.name] = header.parser(event[getter]());
|
||||
});
|
||||
|
||||
return headers;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HTTPEmitter;
|
|
@ -0,0 +1,189 @@
|
|||
const { expect } = require("chai");
|
||||
const nock = require("nock");
|
||||
|
||||
const {
|
||||
SPEC_V1,
|
||||
SPEC_V03,
|
||||
DEFAULT_CE_CONTENT_TYPE,
|
||||
BINARY_HEADERS_03,
|
||||
BINARY_HEADERS_1
|
||||
} = require("../../../lib/bindings/http/constants.js");
|
||||
|
||||
const { CloudEvent, HTTPEmitter } = require("../../../");
|
||||
|
||||
const V1Spec = require("../../../v1").Spec;
|
||||
const V03Spec = require("../../../v03").Spec;
|
||||
|
||||
const receiver = "https://cloudevents.io/";
|
||||
const type = "com.example.test";
|
||||
const source = "urn:event:from:myapi/resource/123";
|
||||
const ext1Name = "lunch";
|
||||
const ext1Value = "tacos";
|
||||
const ext2Name = "supper";
|
||||
const ext2Value = "sushi";
|
||||
|
||||
const data = {
|
||||
lunchBreak: "noon"
|
||||
};
|
||||
|
||||
describe("HTTP Transport Binding Emitter for CloudEvents", () => {
|
||||
beforeEach(() => {
|
||||
nock(receiver)
|
||||
.post("/")
|
||||
.reply(function(uri, requestBody) {
|
||||
// return the request body and the headers so they can be
|
||||
// examined in the test
|
||||
if (typeof requestBody === "string") {
|
||||
requestBody = JSON.parse(requestBody);
|
||||
}
|
||||
const returnBody = { ...requestBody, ...this.req.headers };
|
||||
return [
|
||||
201,
|
||||
returnBody
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
describe("V1", () => {
|
||||
const emitter = new HTTPEmitter({ url: receiver });
|
||||
const event = new CloudEvent(V1Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.time(new Date())
|
||||
.data(data)
|
||||
.addExtension(ext1Name, ext1Value)
|
||||
.addExtension(ext2Name, ext2Value);
|
||||
|
||||
it("Sends a binary 1.0 CloudEvent by default", () => {
|
||||
emitter.send(event)
|
||||
.then((response) => {
|
||||
// A binary message will have a ce-id header
|
||||
expect(response.data[BINARY_HEADERS_1.ID]).to.equal(event.getId());
|
||||
expect(response.data[BINARY_HEADERS_1.SPEC_VERSION]).to.equal(SPEC_V1);
|
||||
// A binary message will have a request body for the data
|
||||
expect(response.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
}).catch(expect.fail);
|
||||
});
|
||||
|
||||
it("Provides the HTTP headers for a binary event", () => {
|
||||
const headers = emitter.headers(event);
|
||||
expect(headers[BINARY_HEADERS_1.TYPE]).to.equal(event.getType());
|
||||
expect(headers[BINARY_HEADERS_1.SPEC_VERSION]).to.equal(event.getSpecversion());
|
||||
expect(headers[BINARY_HEADERS_1.SOURCE]).to.equal(event.getSource());
|
||||
expect(headers[BINARY_HEADERS_1.ID]).to.equal(event.getId());
|
||||
expect(headers[BINARY_HEADERS_1.TIME]).to.equal(event.getTime());
|
||||
});
|
||||
|
||||
it("Sends a structured 1.0 CloudEvent if specified", () => {
|
||||
emitter.send(event, { mode: "structured" })
|
||||
.then((response) => {
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[BINARY_HEADERS_1.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(SPEC_V1);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
}).catch(expect.fail);
|
||||
});
|
||||
|
||||
it("Sends to an alternate URL if specified", () => {
|
||||
nock(receiver)
|
||||
.post("/alternate")
|
||||
.reply(function(uri, requestBody) {
|
||||
// return the request body and the headers so they can be
|
||||
// examined in the test
|
||||
if (typeof requestBody === "string") {
|
||||
requestBody = JSON.parse(requestBody);
|
||||
}
|
||||
const returnBody = { ...requestBody, ...this.req.headers };
|
||||
return [
|
||||
201,
|
||||
returnBody
|
||||
];
|
||||
});
|
||||
|
||||
emitter.send(event, { mode: "structured", url: `${receiver}alternate` })
|
||||
.then((response) => {
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[BINARY_HEADERS_1.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(SPEC_V1);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
}).catch(expect.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe("V03", () => {
|
||||
const emitter = new HTTPEmitter({ url: receiver, version: SPEC_V03 });
|
||||
const event = new CloudEvent(V03Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.time(new Date())
|
||||
.data(data)
|
||||
.addExtension(ext1Name, ext1Value)
|
||||
.addExtension(ext2Name, ext2Value);
|
||||
|
||||
it("Sends a binary 0.3 CloudEvent", () => {
|
||||
emitter.send(event)
|
||||
.then((response) => {
|
||||
// A binary message will have a ce-id header
|
||||
expect(response.data[BINARY_HEADERS_03.ID]).to.equal(event.getId());
|
||||
expect(response.data[BINARY_HEADERS_03.SPEC_VERSION]).to.equal(SPEC_V03);
|
||||
// A binary message will have a request body for the data
|
||||
expect(response.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
}).catch(expect.fail);
|
||||
});
|
||||
|
||||
it("Provides the HTTP headers for a binary event", () => {
|
||||
const headers = emitter.headers(event);
|
||||
expect(headers[BINARY_HEADERS_03.TYPE]).to.equal(event.getType());
|
||||
expect(headers[BINARY_HEADERS_03.SPEC_VERSION]).to.equal(event.getSpecversion());
|
||||
expect(headers[BINARY_HEADERS_03.SOURCE]).to.equal(event.getSource());
|
||||
expect(headers[BINARY_HEADERS_03.ID]).to.equal(event.getId());
|
||||
expect(headers[BINARY_HEADERS_03.TIME]).to.equal(event.getTime());
|
||||
});
|
||||
|
||||
it("Sends a structured 0.3 CloudEvent if specified", () => {
|
||||
emitter.send(event, { mode: "structured", foo: "bar" })
|
||||
.then((response) => {
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[BINARY_HEADERS_03.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(SPEC_V03);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
}).catch(expect.fail);
|
||||
});
|
||||
it("Sends to an alternate URL if specified", () => {
|
||||
nock(receiver)
|
||||
.post("/alternate")
|
||||
.reply(function(uri, requestBody) {
|
||||
// return the request body and the headers so they can be
|
||||
// examined in the test
|
||||
if (typeof requestBody === "string") {
|
||||
requestBody = JSON.parse(requestBody);
|
||||
}
|
||||
const returnBody = { ...requestBody, ...this.req.headers };
|
||||
return [
|
||||
201,
|
||||
returnBody
|
||||
];
|
||||
});
|
||||
|
||||
emitter.send(event, { mode: "structured", url: `${receiver}alternate` })
|
||||
.then((response) => {
|
||||
// A structured message will have a cloud event content type
|
||||
expect(response.data["content-type"]).to.equal(DEFAULT_CE_CONTENT_TYPE);
|
||||
// Ensure other CE headers don't exist - just testing for ID
|
||||
expect(response.data[BINARY_HEADERS_03.ID]).to.equal(undefined);
|
||||
// The spec version would have been specified in the body
|
||||
expect(response.data.specversion).to.equal(SPEC_V03);
|
||||
expect(response.data.data.lunchBreak).to.equal(data.lunchBreak);
|
||||
}).catch(expect.fail);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,7 +1,8 @@
|
|||
const expect = require("chai").expect;
|
||||
const v03 = require("../../../v03/index.js");
|
||||
const ValidationError = require("../../../lib/validation_error.js");
|
||||
const HTTPStructuredReceiver = require("../../../lib/bindings/http/receiver_structured_0_3.js");
|
||||
const CloudEvent = require("../../../lib/cloudevent.js");
|
||||
const { Spec } = require("../../../v03/index.js");
|
||||
|
||||
const receiver = new HTTPStructuredReceiver();
|
||||
|
||||
|
@ -68,7 +69,7 @@ describe("HTTP Transport Binding Structured Receiver CloudEvents v0.3", () => {
|
|||
it("Throw error data content encoding is base64, but 'data' is not",
|
||||
() => {
|
||||
// setup
|
||||
const payload = v03.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType("text/plain")
|
||||
|
@ -119,14 +120,13 @@ describe("HTTP Transport Binding Structured Receiver CloudEvents v0.3", () => {
|
|||
describe("Parse", () => {
|
||||
it("Throw error when the event does not follow the spec", () => {
|
||||
// setup
|
||||
const payload =
|
||||
v03.event()
|
||||
.type(type)
|
||||
.source(source)
|
||||
.time(now)
|
||||
.schemaurl(schemaurl)
|
||||
.data(data)
|
||||
.toString();
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.time(now)
|
||||
.schemaurl(schemaurl)
|
||||
.data(data)
|
||||
.toString();
|
||||
|
||||
const headers = {
|
||||
"Content-Type": "application/cloudevents+xml"
|
||||
|
@ -140,7 +140,7 @@ describe("HTTP Transport Binding Structured Receiver CloudEvents v0.3", () => {
|
|||
it("Should accept event that follows the spec", () => {
|
||||
// setup
|
||||
const id = "id-x0dk";
|
||||
const payload = v03.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.id(id)
|
||||
|
@ -170,7 +170,7 @@ describe("HTTP Transport Binding Structured Receiver CloudEvents v0.3", () => {
|
|||
it("Should accept 'extension1'", () => {
|
||||
// setup
|
||||
const extension1 = "mycuston-ext1";
|
||||
const payload = v03.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType(ceContentType)
|
||||
|
@ -195,7 +195,7 @@ describe("HTTP Transport Binding Structured Receiver CloudEvents v0.3", () => {
|
|||
|
||||
it("Should parse 'data' stringfied json to json object", () => {
|
||||
// setup
|
||||
const payload = v03.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType(ceContentType)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
const expect = require("chai").expect;
|
||||
const v1 = require("../../../v1/index.js");
|
||||
const { Spec } = require("../../../v1/index.js");
|
||||
const { CloudEvent } = require("../../../index.js");
|
||||
const { asBase64 } = require("../../../lib/utils/fun.js");
|
||||
const ValidationError = require("../../../lib/validation_error.js");
|
||||
|
@ -99,7 +99,7 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0",
|
|||
it("Should accept event that follows the spec", () => {
|
||||
// setup
|
||||
const id = "id-x0dk";
|
||||
const payload = v1.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.id(id)
|
||||
|
@ -129,7 +129,7 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0",
|
|||
it("Should accept 'extension1'", () => {
|
||||
// setup
|
||||
const extension1 = "mycustom-ext1";
|
||||
const payload = v1.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType(ceContentType)
|
||||
|
@ -154,7 +154,7 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0",
|
|||
|
||||
it("Should parse 'data' stringified json to json object", () => {
|
||||
// setup
|
||||
const payload = v1.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType(ceContentType)
|
||||
|
@ -179,7 +179,7 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0",
|
|||
const bindata = Uint32Array
|
||||
.from(JSON.stringify(data), (c) => c.codePointAt(0));
|
||||
const expected = asBase64(bindata);
|
||||
const payload = v1.event()
|
||||
const payload = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType(ceContentType)
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
const expect = require("chai").expect;
|
||||
const nock = require("nock");
|
||||
const BinaryHTTPEmitter =
|
||||
require("../lib/bindings/http/emitter_binary_0_3.js");
|
||||
const BinaryHTTPEmitter = require("../lib/bindings/http/emitter_binary.js");
|
||||
const StructuredHTTPEmitter = require("../lib/bindings/http/emitter_structured.js");
|
||||
const CloudEvent = require("../lib/cloudevent.js");
|
||||
const v03 = require("../v03/index.js");
|
||||
const {
|
||||
SPEC_V03
|
||||
} = require("../lib/bindings/http/constants.js");
|
||||
|
||||
const type = "com.github.pull.create";
|
||||
const source = "urn:event:from:myapi/resourse/123";
|
||||
|
@ -54,8 +57,8 @@ const httpcfg = {
|
|||
url: `${webhook}/json`
|
||||
};
|
||||
|
||||
const binary = new BinaryHTTPEmitter(httpcfg);
|
||||
const structured = new v03.StructuredHTTPEmitter(httpcfg);
|
||||
const binary = new BinaryHTTPEmitter(SPEC_V03);
|
||||
const structured = new StructuredHTTPEmitter();
|
||||
|
||||
describe("HTTP Transport Binding - Version 0.3", () => {
|
||||
beforeEach(() => {
|
||||
|
@ -68,14 +71,14 @@ describe("HTTP Transport Binding - Version 0.3", () => {
|
|||
describe("Structured", () => {
|
||||
describe("JSON Format", () => {
|
||||
it(`requires '${contentType}' Content-Type in the header`,
|
||||
() => structured.emit(cloudevent)
|
||||
() => structured.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers["Content-Type"])
|
||||
.to.equal(contentType);
|
||||
}));
|
||||
|
||||
it("the request payload should be correct",
|
||||
() => structured.emit(cloudevent)
|
||||
() => structured.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(JSON.parse(response.config.data))
|
||||
.to.deep.equal(cloudevent.format());
|
||||
|
@ -83,7 +86,7 @@ describe("HTTP Transport Binding - Version 0.3", () => {
|
|||
|
||||
describe("'data' attribute with 'base64' encoding", () => {
|
||||
it("the request payload should be correct",
|
||||
() => structured.emit(cebase64)
|
||||
() => structured.emit(httpcfg, cebase64)
|
||||
.then((response) => {
|
||||
expect(JSON.parse(response.config.data).data)
|
||||
.to.equal(cebase64.format().data);
|
||||
|
@ -95,127 +98,127 @@ describe("HTTP Transport Binding - Version 0.3", () => {
|
|||
describe("Binary", () => {
|
||||
describe("JSON Format", () => {
|
||||
it(`requires ${cloudevent.getDataContentType()} in the header`,
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers["Content-Type"])
|
||||
.to.equal(cloudevent.getDataContentType());
|
||||
}));
|
||||
|
||||
it("the request payload should be correct", () => binary.emit(cloudevent)
|
||||
it("the request payload should be correct", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(JSON.parse(response.config.data))
|
||||
.to.deep.equal(cloudevent.getData());
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-type'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-type'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-type");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-specversion'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-specversion'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-specversion");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-source'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-source'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-source");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-id'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-id'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-id");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-time'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-time'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-time");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-schemaurl'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-schemaurl'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-schemaurl");
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext1Name}'`, () => binary.emit(cloudevent)
|
||||
it(`HTTP Header contains 'ce-${ext1Name}'`, () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property(`ce-${ext1Name}`);
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext2Name}'`, () => binary.emit(cloudevent)
|
||||
it(`HTTP Header contains 'ce-${ext2Name}'`, () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property(`ce-${ext2Name}`);
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-subject'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-subject'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-subject");
|
||||
}));
|
||||
|
||||
it("should 'ce-type' have the right value", () => binary.emit(cloudevent)
|
||||
it("should 'ce-type' have the right value", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getType())
|
||||
.to.equal(response.config.headers["ce-type"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-specversion' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getSpecversion())
|
||||
.to.equal(response.config.headers["ce-specversion"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-source' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getSource())
|
||||
.to.equal(response.config.headers["ce-source"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-id' have the right value", () => binary.emit(cloudevent)
|
||||
it("should 'ce-id' have the right value", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getId())
|
||||
.to.equal(response.config.headers["ce-id"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-time' have the right value", () => binary.emit(cloudevent)
|
||||
it("should 'ce-time' have the right value", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getTime())
|
||||
.to.equal(response.config.headers["ce-time"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-schemaurl' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getSchemaurl())
|
||||
.to.equal(response.config.headers["ce-schemaurl"]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext1Name}' have the right value`,
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getExtensions()[ext1Name])
|
||||
.to.equal(response.config.headers[`ce-${ext1Name}`]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext2Name}' have the right value`,
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getExtensions()[ext2Name])
|
||||
.to.equal(response.config.headers[`ce-${ext2Name}`]);
|
||||
}));
|
||||
|
||||
it("should 'ce-subject' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getSubject())
|
||||
.to.equal(response.config.headers["ce-subject"]);
|
||||
|
@ -223,16 +226,16 @@ describe("HTTP Transport Binding - Version 0.3", () => {
|
|||
|
||||
describe("'data' attribute with 'base64' encoding", () => {
|
||||
it("HTTP Header contains 'ce-datacontentencoding'",
|
||||
() => binary.emit(cebase64)
|
||||
() => binary.emit(httpcfg, cebase64)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-datacontentencoding");
|
||||
}));
|
||||
|
||||
it("should 'ce-datacontentencoding' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cebase64)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getDataContentEncoding())
|
||||
expect(cebase64.getDataContentEncoding())
|
||||
.to.equal(response.config.headers["ce-datacontentencoding"]);
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -2,14 +2,14 @@ const expect = require("chai").expect;
|
|||
const nock = require("nock");
|
||||
const https = require("https");
|
||||
const { asBase64 } = require("../lib/utils/fun.js");
|
||||
|
||||
const {
|
||||
Spec,
|
||||
BinaryHTTPEmitter,
|
||||
StructuredHTTPEmitter,
|
||||
CloudEvent
|
||||
} = require("../v1/index.js");
|
||||
SPEC_V1
|
||||
} = require("../lib/bindings/http/constants.js");
|
||||
|
||||
const { Spec } = require("../v1/index.js");
|
||||
const CloudEvent = require("../lib/cloudevent.js");
|
||||
const BinaryHTTPEmitter = require("../lib/bindings/http/emitter_binary.js");
|
||||
const StructuredHTTPEmitter = require("../lib/bindings/http/emitter_structured.js");
|
||||
const type = "com.github.pull.create";
|
||||
const source = "urn:event:from:myapi/resource/123";
|
||||
const contentType = "application/cloudevents+json; charset=utf-8";
|
||||
|
@ -27,17 +27,16 @@ const ext1Value = "foobar";
|
|||
const ext2Name = "extension2";
|
||||
const ext2Value = "acme";
|
||||
|
||||
const cloudevent =
|
||||
new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType(ceContentType)
|
||||
.subject("subject.ext")
|
||||
.time(now)
|
||||
.dataschema(dataschema)
|
||||
.data(data)
|
||||
.addExtension(ext1Name, ext1Value)
|
||||
.addExtension(ext2Name, ext2Value);
|
||||
const cloudevent = new CloudEvent(Spec)
|
||||
.type(type)
|
||||
.source(source)
|
||||
.dataContentType(ceContentType)
|
||||
.subject("subject.ext")
|
||||
.time(now)
|
||||
.dataschema(dataschema)
|
||||
.data(data)
|
||||
.addExtension(ext1Name, ext1Value)
|
||||
.addExtension(ext2Name, ext2Value);
|
||||
|
||||
const dataString = ")(*~^my data for ce#@#$%";
|
||||
|
||||
|
@ -47,8 +46,8 @@ const httpcfg = {
|
|||
url: `${webhook}/json`
|
||||
};
|
||||
|
||||
const binary = new BinaryHTTPEmitter(httpcfg);
|
||||
const structured = new StructuredHTTPEmitter(httpcfg);
|
||||
const binary = new BinaryHTTPEmitter(SPEC_V1);
|
||||
const structured = new StructuredHTTPEmitter();
|
||||
|
||||
describe("HTTP Transport Binding - Version 1.0", () => {
|
||||
beforeEach(() => {
|
||||
|
@ -68,7 +67,7 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
|||
key: "other value"
|
||||
})
|
||||
});
|
||||
return event.emit(cloudevent).then((response) => {
|
||||
return event.emit(httpcfg, cloudevent).then((response) => {
|
||||
expect(response.config.headers["Content-Type"])
|
||||
.to.equal(contentType);
|
||||
});
|
||||
|
@ -76,14 +75,14 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
|||
|
||||
describe("JSON Format", () => {
|
||||
it(`requires '${contentType}' Content-Type in the header`,
|
||||
() => structured.emit(cloudevent)
|
||||
() => structured.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers["Content-Type"])
|
||||
.to.equal(contentType);
|
||||
}));
|
||||
|
||||
it("the request payload should be correct",
|
||||
() => structured.emit(cloudevent)
|
||||
() => structured.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(JSON.parse(response.config.data))
|
||||
.to.deep.equal(cloudevent.format());
|
||||
|
@ -102,7 +101,7 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
|||
.addExtension(ext1Name, ext1Value)
|
||||
.addExtension(ext2Name, ext2Value);
|
||||
|
||||
return structured.emit(binevent)
|
||||
return structured.emit(httpcfg, binevent)
|
||||
.then((response) => {
|
||||
expect(JSON.parse(response.config.data).data_base64)
|
||||
.to.equal(expected);
|
||||
|
@ -119,7 +118,7 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
|||
.addExtension(ext1Name, ext1Value)
|
||||
.addExtension(ext2Name, ext2Value);
|
||||
|
||||
return structured.emit(binevent)
|
||||
return structured.emit(httpcfg, binevent)
|
||||
.then((response) => {
|
||||
expect(JSON.parse(response.config.data))
|
||||
.to.have.property("data_base64");
|
||||
|
@ -130,30 +129,29 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
|||
});
|
||||
|
||||
describe("Binary", () => {
|
||||
it("works with mTLS authentication", () => {
|
||||
const event = new BinaryHTTPEmitter({
|
||||
it("works with mTLS authentication", () =>
|
||||
binary.emit({
|
||||
method: "POST",
|
||||
url: `${webhook}/json`,
|
||||
httpsAgent: new https.Agent({
|
||||
cert: "some value",
|
||||
key: "other value"
|
||||
})
|
||||
});
|
||||
return event.emit(cloudevent).then((response) => {
|
||||
}, cloudevent).then((response) => {
|
||||
expect(response.config.headers["Content-Type"])
|
||||
.to.equal(cloudevent.getDataContentType());
|
||||
});
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
describe("JSON Format", () => {
|
||||
it(`requires '${cloudevent.getDataContentType()}' in the header`,
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers["Content-Type"])
|
||||
.to.equal(cloudevent.getDataContentType());
|
||||
}));
|
||||
|
||||
it("the request payload should be correct", () => binary.emit(cloudevent)
|
||||
it("the request payload should be correct", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(JSON.parse(response.config.data))
|
||||
.to.deep.equal(cloudevent.getData());
|
||||
|
@ -172,122 +170,122 @@ describe("HTTP Transport Binding - Version 1.0", () => {
|
|||
.addExtension(ext1Name, ext1Value)
|
||||
.addExtension(ext2Name, ext2Value);
|
||||
|
||||
return binary.emit(binevent)
|
||||
return binary.emit(httpcfg, binevent)
|
||||
.then((response) => {
|
||||
expect(response.config.data)
|
||||
.to.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
it("HTTP Header contains 'ce-type'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-type'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-type");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-specversion'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-specversion'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-specversion");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-source'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-source'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-source");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-id'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-id'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-id");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-time'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-time'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-time");
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-dataschema'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-dataschema'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-dataschema");
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext1Name}'`, () => binary.emit(cloudevent)
|
||||
it(`HTTP Header contains 'ce-${ext1Name}'`, () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property(`ce-${ext1Name}`);
|
||||
}));
|
||||
|
||||
it(`HTTP Header contains 'ce-${ext2Name}'`, () => binary.emit(cloudevent)
|
||||
it(`HTTP Header contains 'ce-${ext2Name}'`, () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property(`ce-${ext2Name}`);
|
||||
}));
|
||||
|
||||
it("HTTP Header contains 'ce-subject'", () => binary.emit(cloudevent)
|
||||
it("HTTP Header contains 'ce-subject'", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(response.config.headers)
|
||||
.to.have.property("ce-subject");
|
||||
}));
|
||||
|
||||
it("should 'ce-type' have the right value", () => binary.emit(cloudevent)
|
||||
it("should 'ce-type' have the right value", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getType())
|
||||
.to.equal(response.config.headers["ce-type"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-specversion' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getSpecversion())
|
||||
.to.equal(response.config.headers["ce-specversion"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-source' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getSource())
|
||||
.to.equal(response.config.headers["ce-source"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-id' have the right value", () => binary.emit(cloudevent)
|
||||
it("should 'ce-id' have the right value", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getId())
|
||||
.to.equal(response.config.headers["ce-id"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-time' have the right value", () => binary.emit(cloudevent)
|
||||
it("should 'ce-time' have the right value", () => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getTime())
|
||||
.to.equal(response.config.headers["ce-time"]);
|
||||
}));
|
||||
|
||||
it("should 'ce-dataschema' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getDataschema())
|
||||
.to.equal(response.config.headers["ce-dataschema"]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext1Name}' have the right value`,
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getExtensions()[ext1Name])
|
||||
.to.equal(response.config.headers[`ce-${ext1Name}`]);
|
||||
}));
|
||||
|
||||
it(`should 'ce-${ext2Name}' have the right value`,
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getExtensions()[ext2Name])
|
||||
.to.equal(response.config.headers[`ce-${ext2Name}`]);
|
||||
}));
|
||||
|
||||
it("should 'ce-subject' have the right value",
|
||||
() => binary.emit(cloudevent)
|
||||
() => binary.emit(httpcfg, cloudevent)
|
||||
.then((response) => {
|
||||
expect(cloudevent.getSubject())
|
||||
.to.equal(response.config.headers["ce-subject"]);
|
||||
|
|
|
@ -1,69 +1,39 @@
|
|||
const expect = require("chai").expect;
|
||||
const v03 = require("../v03/index.js");
|
||||
const v1 = require("../v1/index.js");
|
||||
const { CloudEvent, HTTPReceiver, HTTPEmitter } = require("../");
|
||||
const SpecV03 = require("../v03").Spec;
|
||||
const SpecV1 = require("../v1").Spec;
|
||||
const {
|
||||
SPEC_V03,
|
||||
SPEC_V1
|
||||
} = require("../lib/bindings/http/constants.js");
|
||||
|
||||
describe("The SDK Requirements", () => {
|
||||
it("should expose a CloudEvent type", () => {
|
||||
const event = new CloudEvent();
|
||||
expect(event instanceof CloudEvent).to.equal(true);
|
||||
});
|
||||
|
||||
it("should expose an HTTPReceiver type", () => {
|
||||
const receiver = new HTTPReceiver();
|
||||
expect(receiver instanceof HTTPReceiver).to.equal(true);
|
||||
});
|
||||
|
||||
it("should expose an HTTPEmitter type", () => {
|
||||
const emitter = new HTTPEmitter({
|
||||
url: "http://example.com"
|
||||
});
|
||||
expect(emitter instanceof HTTPEmitter).to.equal(true);
|
||||
});
|
||||
|
||||
describe("v0.3", () => {
|
||||
it("should create an event using the right spec version", () => {
|
||||
expect(v03.event().spec.payload.specversion).to.equal("0.3");
|
||||
});
|
||||
|
||||
it("should exports 'Spec'", () => {
|
||||
expect(v03).to.have.property("Spec");
|
||||
});
|
||||
|
||||
it("should exports 'StructuredHTTPEmitter'", () => {
|
||||
expect(v03).to.have.property("StructuredHTTPEmitter");
|
||||
});
|
||||
|
||||
it("should exports 'StructuredHTTPReceiver'", () => {
|
||||
expect(v03).to.have.property("StructuredHTTPReceiver");
|
||||
});
|
||||
|
||||
it("should exports 'BinaryHTTPEmitter'", () => {
|
||||
expect(v03).to.have.property("BinaryHTTPEmitter");
|
||||
});
|
||||
|
||||
it("should exports 'BinaryHTTPReceiver'", () => {
|
||||
expect(v03).to.have.property("BinaryHTTPReceiver");
|
||||
});
|
||||
|
||||
it("should exports 'HTTPUnmarshaller'", () => {
|
||||
expect(v03).to.have.property("HTTPUnmarshaller");
|
||||
});
|
||||
|
||||
it("should exports 'event'", () => {
|
||||
expect(v03).to.have.property("event");
|
||||
expect(new CloudEvent(SpecV03).spec.payload.specversion).to.equal(SPEC_V03);
|
||||
});
|
||||
});
|
||||
|
||||
describe("v1.0", () => {
|
||||
it("should create an event using the right spec version", () => {
|
||||
expect(v1.event().spec.payload.specversion).to.equal("1.0");
|
||||
});
|
||||
|
||||
it("should exports 'Spec'", () => {
|
||||
expect(v1).to.have.property("Spec");
|
||||
});
|
||||
|
||||
it("should exports 'StructuredHTTPEmitter'", () => {
|
||||
expect(v1).to.have.property("StructuredHTTPEmitter");
|
||||
});
|
||||
|
||||
it("should exports 'StructuredHTTPReceiver'", () => {
|
||||
expect(v1).to.have.property("StructuredHTTPReceiver");
|
||||
});
|
||||
|
||||
it("should exports 'BinaryHTTPEmitter'", () => {
|
||||
expect(v1).to.have.property("BinaryHTTPEmitter");
|
||||
});
|
||||
|
||||
it("should exports 'BinaryHTTPReceiver'", () => {
|
||||
expect(v1).to.have.property("BinaryHTTPReceiver");
|
||||
});
|
||||
|
||||
it("should exports 'event'", () => {
|
||||
expect(v1).to.have.property("event");
|
||||
expect(new CloudEvent(SpecV1).spec.payload.specversion).to.equal(SPEC_V1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
25
v03/index.js
25
v03/index.js
|
@ -1,28 +1,5 @@
|
|||
const CloudEvent = require("../lib/cloudevent.js");
|
||||
const Spec = require("../lib/specs/spec_0_3.js");
|
||||
const StructuredHTTPEmitter =
|
||||
require("../lib/bindings/http/emitter_structured.js");
|
||||
const BinaryHTTPEmitter = require("../lib/bindings/http/emitter_binary_0_3.js");
|
||||
|
||||
const StructuredHTTPReceiver =
|
||||
require("../lib/bindings/http/receiver_structured_0_3.js");
|
||||
|
||||
const BinaryHTTPReceiver =
|
||||
require("../lib/bindings/http/receiver_binary_0_3.js");
|
||||
|
||||
const HTTPUnmarshaller = require("../lib/bindings/http/unmarshaller_0_3.js");
|
||||
|
||||
function newEvent() {
|
||||
return new CloudEvent(Spec);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Spec,
|
||||
StructuredHTTPEmitter,
|
||||
StructuredHTTPReceiver,
|
||||
BinaryHTTPEmitter,
|
||||
BinaryHTTPReceiver,
|
||||
HTTPUnmarshaller,
|
||||
CloudEvent: newEvent,
|
||||
event: newEvent
|
||||
Spec
|
||||
};
|
||||
|
|
24
v1/index.js
24
v1/index.js
|
@ -1,27 +1,5 @@
|
|||
const CloudEvent = require("../lib/cloudevent.js");
|
||||
const Spec = require("../lib/specs/spec_1.js");
|
||||
|
||||
const StructuredHTTPEmitter =
|
||||
require("../lib/bindings/http/emitter_structured.js");
|
||||
|
||||
const BinaryHTTPEmitter = require("../lib/bindings/http/emitter_binary_1.js");
|
||||
|
||||
const StructuredHTTPReceiver =
|
||||
require("../lib/bindings/http/receiver_structured_1.js");
|
||||
|
||||
const BinaryHTTPReceiver =
|
||||
require("../lib/bindings/http/receiver_binary_1.js");
|
||||
|
||||
function newEvent() {
|
||||
return new CloudEvent(Spec);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Spec,
|
||||
StructuredHTTPEmitter,
|
||||
BinaryHTTPEmitter,
|
||||
StructuredHTTPReceiver,
|
||||
BinaryHTTPReceiver,
|
||||
CloudEvent: newEvent,
|
||||
event: newEvent
|
||||
Spec
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue