src!: remove support for 0.3 events (#425)
It has been nearly two years since 1.0 became final. This change removes support for 0.3 events in the interest of simplifying the project a little. Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
36f5e2b5f8
commit
2bd9a5a1e4
|
@ -7159,9 +7159,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"path-type": {
|
||||
|
|
|
@ -6,14 +6,7 @@
|
|||
import { v4 as uuidv4 } from "uuid";
|
||||
import { Emitter } from "..";
|
||||
|
||||
import {
|
||||
CloudEventV03,
|
||||
CloudEventV03Attributes,
|
||||
CloudEventV03OptionalAttributes,
|
||||
CloudEventV1,
|
||||
CloudEventV1Attributes,
|
||||
CloudEventV1OptionalAttributes,
|
||||
} from "./interfaces";
|
||||
import { CloudEventV1, CloudEventV1Attributes, CloudEventV1OptionalAttributes } from "./interfaces";
|
||||
import { validateCloudEvent } from "./spec";
|
||||
import { ValidationError, isBinary, asBase64, isValidType } from "./validation";
|
||||
|
||||
|
@ -30,7 +23,7 @@ export const enum Version {
|
|||
* interoperability across services, platforms and systems.
|
||||
* @see https://github.com/cloudevents/spec/blob/v1.0/spec.md
|
||||
*/
|
||||
export class CloudEvent implements CloudEventV1, CloudEventV03 {
|
||||
export class CloudEvent implements CloudEventV1 {
|
||||
id: string;
|
||||
type: string;
|
||||
source: string;
|
||||
|
@ -58,7 +51,7 @@ export class CloudEvent implements CloudEventV1, CloudEventV03 {
|
|||
* @param {object} event the event properties
|
||||
* @param {boolean?} strict whether to perform event validation when creating the object - default: true
|
||||
*/
|
||||
constructor(event: CloudEventV1 | CloudEventV1Attributes | CloudEventV03 | CloudEventV03Attributes, strict = true) {
|
||||
constructor(event: CloudEventV1 | CloudEventV1Attributes, strict = true) {
|
||||
// copy the incoming event so that we can delete properties as we go
|
||||
// everything left after we have deleted know properties becomes an extension
|
||||
const properties = { ...event };
|
||||
|
@ -197,13 +190,7 @@ See: https://github.com/cloudevents/spec/blob/v1.0/spec.md#type-system`);
|
|||
* @return {CloudEvent} returns a new CloudEvent
|
||||
*/
|
||||
public cloneWith(
|
||||
options:
|
||||
| CloudEventV1
|
||||
| CloudEventV1Attributes
|
||||
| CloudEventV1OptionalAttributes
|
||||
| CloudEventV03
|
||||
| CloudEventV03Attributes
|
||||
| CloudEventV03OptionalAttributes,
|
||||
options: CloudEventV1 | CloudEventV1Attributes | CloudEventV1OptionalAttributes,
|
||||
strict = true,
|
||||
): CloudEvent {
|
||||
return new CloudEvent(Object.assign({}, this.toJSON(), options) as CloudEvent, strict);
|
||||
|
|
|
@ -140,139 +140,3 @@ export interface CloudEventV1OptionalAttributes {
|
|||
*/
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* The object interface for CloudEvents 0.3.
|
||||
* @see https://github.com/cloudevents/spec/blob/v0.3/spec.md
|
||||
*/
|
||||
|
||||
export interface CloudEventV03 extends CloudEventV03Attributes {
|
||||
// REQUIRED Attributes
|
||||
/**
|
||||
* [REQUIRED] Identifies the event. Producers MUST ensure that `source` + `id`
|
||||
* is unique for each distinct event. If a duplicate event is re-sent (e.g. due
|
||||
* to a network error) it MAY have the same `id`. Consumers MAY assume that
|
||||
* Events with identical `source` and `id` are duplicates.
|
||||
* @required Non-empty string. Unique within producer.
|
||||
* @example An event counter maintained by the producer
|
||||
* @example A UUID
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* [REQUIRED] The version of the CloudEvents specification which the event
|
||||
* uses. This enables the interpretation of the context. Compliant event
|
||||
* producers MUST use a value of `1.0` when referring to this version of the
|
||||
* specification.
|
||||
* @required MUST be a non-empty string.
|
||||
*/
|
||||
specversion: string;
|
||||
}
|
||||
|
||||
export interface CloudEventV03Attributes extends CloudEventV03OptionalAttributes {
|
||||
/**
|
||||
* [REQUIRED] Identifies the context in which an event happened. Often this
|
||||
* will include information such as the type of the event source, the
|
||||
* organization publishing the event or the process that produced the event. The
|
||||
* exact syntax and semantics behind the data encoded in the URI is defined by
|
||||
* the event producer.
|
||||
* Producers MUST ensure that `source` + `id` is unique for each distinct event.
|
||||
* An application MAY assign a unique `source` to each distinct producer, which
|
||||
* makes it easy to produce unique IDs since no other producer will have the same
|
||||
* source. The application MAY use UUIDs, URNs, DNS authorities or an
|
||||
* application-specific scheme to create unique `source` identifiers.
|
||||
* A source MAY include more than one producer. In that case the producers MUST
|
||||
* collaborate to ensure that `source` + `id` is unique for each distinct event.
|
||||
* @required Non-empty URI-reference
|
||||
*/
|
||||
source: string;
|
||||
/**
|
||||
* [REQUIRED] This attribute contains a value describing the type of event
|
||||
* related to the originating occurrence. Often this attribute is used for
|
||||
* routing, observability, policy enforcement, etc. The format of this is
|
||||
* producer defined and might include information such as the version of the
|
||||
* `type` - see
|
||||
* [Versioning of Attributes in the Primer](primer.md#versioning-of-attributes)
|
||||
* for more information.
|
||||
* @required MUST be a non-empty string
|
||||
* @should SHOULD be prefixed with a reverse-DNS name. The prefixed domain dictates the
|
||||
* organization which defines the semantics of this event type.
|
||||
* @example com.github.pull.create
|
||||
* @example com.example.object.delete.v2
|
||||
*/
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface CloudEventV03OptionalAttributes {
|
||||
/**
|
||||
* The following fields are optional.
|
||||
*/
|
||||
|
||||
/**
|
||||
* [OPTIONAL] Describes the content encoding for the data attribute for when the
|
||||
* data field MUST be encoded as a string, like with structured transport binding
|
||||
* modes using the JSON event format, but the datacontenttype indicates a non-string
|
||||
* media type. When the data field's effective data type is not String, this attribute
|
||||
* MUST NOT be set and MUST be ignored when set.
|
||||
*/
|
||||
datacontentencoding?: string;
|
||||
|
||||
/**
|
||||
* [OPTIONAL] Content type of `data` value. This attribute enables `data` to
|
||||
* carry any type of content, whereby format and encoding might differ from that
|
||||
* of the chosen event format. For example, an event rendered using the
|
||||
* [JSON envelope](./json-format.md#3-envelope) format might carry an XML payload
|
||||
* in `data`, and the consumer is informed by this attribute being set to
|
||||
* "application/xml". The rules for how `data` content is rendered for different
|
||||
* `datacontenttype` values are defined in the event format specifications; for
|
||||
* example, the JSON event format defines the relationship in
|
||||
* [section 3.1](./json-format.md#31-handling-of-data).
|
||||
*/
|
||||
datacontenttype?: string;
|
||||
/**
|
||||
* [OPTIONAL] A link to the schema that the data attribute adheres to.
|
||||
* Incompatible changes to the schema SHOULD be reflected by a different URL.
|
||||
* If present, MUST be a non-empty URI.
|
||||
*/
|
||||
schemaurl?: string;
|
||||
/**
|
||||
* [OPTIONAL] This describes the subject of the event in the context of the
|
||||
* event producer (identified by `source`). In publish-subscribe scenarios, a
|
||||
* subscriber will typically subscribe to events emitted by a `source`, but the
|
||||
* `source` identifier alone might not be sufficient as a qualifier for any
|
||||
* specific event if the `source` context has internal sub-structure.
|
||||
*
|
||||
* Identifying the subject of the event in context metadata (opposed to only in
|
||||
* the `data` payload) is particularly helpful in generic subscription filtering
|
||||
* scenarios where middleware is unable to interpret the `data` content. In the
|
||||
* above example, the subscriber might only be interested in blobs with names
|
||||
* ending with '.jpg' or '.jpeg' and the `subject` attribute allows for
|
||||
* constructing a simple and efficient string-suffix filter for that subset of
|
||||
* events.
|
||||
*
|
||||
* If present, MUST be a non-empty string.
|
||||
* @example "https://example.com/storage/tenant/container"
|
||||
* @example "mynewfile.jpg"
|
||||
*/
|
||||
subject?: string;
|
||||
/**
|
||||
* [OPTIONAL] Timestamp of when the occurrence happened. If the time of the
|
||||
* occurrence cannot be determined then this attribute MAY be set to some other
|
||||
* time (such as the current time) by the CloudEvents producer, however all
|
||||
* producers for the same `source` MUST be consistent in this respect. In other
|
||||
* words, either they all use the actual time of the occurrence or they all use
|
||||
* the same algorithm to determine the value used.
|
||||
* @example "2020-08-08T14:48:09.769Z"
|
||||
*/
|
||||
time?: string;
|
||||
/**
|
||||
* [OPTIONAL] The event payload. This specification does not place any restriction
|
||||
* on the type of this information. It is encoded into a media format which is
|
||||
* specified by the datacontenttype attribute (e.g. application/json), and adheres
|
||||
* to the dataschema format when those respective attributes are present.
|
||||
*/
|
||||
data?: Record<string, unknown | string | number | boolean> | string | number | boolean | null | unknown;
|
||||
/**
|
||||
* [OPTIONAL] CloudEvents extension attributes.
|
||||
*/
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
|
|
@ -83,76 +83,3 @@ export const schemaV1 = {
|
|||
},
|
||||
type: "object",
|
||||
};
|
||||
|
||||
export const schemaV03 = {
|
||||
$ref: "#/definitions/event",
|
||||
definitions: {
|
||||
specversion: {
|
||||
const: "0.3",
|
||||
},
|
||||
datacontenttype: {
|
||||
type: "string",
|
||||
},
|
||||
data: {
|
||||
type: ["object", "string", "array", "number", "boolean", "null"],
|
||||
},
|
||||
event: {
|
||||
properties: {
|
||||
specversion: {
|
||||
$ref: "#/definitions/specversion",
|
||||
},
|
||||
datacontenttype: {
|
||||
$ref: "#/definitions/datacontenttype",
|
||||
},
|
||||
data: {
|
||||
$ref: "#/definitions/data",
|
||||
},
|
||||
id: {
|
||||
$ref: "#/definitions/id",
|
||||
},
|
||||
time: {
|
||||
$ref: "#/definitions/time",
|
||||
},
|
||||
schemaurl: {
|
||||
$ref: "#/definitions/schemaurl",
|
||||
},
|
||||
subject: {
|
||||
$ref: "#/definitions/subject",
|
||||
},
|
||||
type: {
|
||||
$ref: "#/definitions/type",
|
||||
},
|
||||
source: {
|
||||
$ref: "#/definitions/source",
|
||||
},
|
||||
},
|
||||
required: ["specversion", "id", "type", "source"],
|
||||
type: "object",
|
||||
},
|
||||
id: {
|
||||
type: "string",
|
||||
minLength: 1,
|
||||
},
|
||||
time: {
|
||||
format: "js-date-time",
|
||||
type: "string",
|
||||
},
|
||||
schemaurl: {
|
||||
type: "string",
|
||||
format: "uri-reference",
|
||||
},
|
||||
subject: {
|
||||
type: "string",
|
||||
minLength: 1,
|
||||
},
|
||||
type: {
|
||||
type: "string",
|
||||
minLength: 1,
|
||||
},
|
||||
source: {
|
||||
format: "uri-reference",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
};
|
||||
|
|
|
@ -3,15 +3,14 @@
|
|||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import Ajv from "ajv";
|
||||
import { ValidationError, isBase64 } from "./validation";
|
||||
import Ajv, { Options } from "ajv";
|
||||
import { ValidationError } from "./validation";
|
||||
|
||||
import { CloudEventV1, CloudEventV03 } from "./interfaces";
|
||||
import { schemaV03, schemaV1 } from "./schemas";
|
||||
import { CloudEventV1 } from "./interfaces";
|
||||
import { schemaV1 } from "./schemas";
|
||||
import { Version } from "./cloudevent";
|
||||
import CONSTANTS from "../constants";
|
||||
|
||||
const ajv = new Ajv({ extendRefs: true });
|
||||
const ajv = new Ajv({ extendRefs: true } as Options);
|
||||
|
||||
// handle date-time format specially because a user could pass
|
||||
// Date().toString(), which is not spec compliant date-time format
|
||||
|
@ -21,18 +20,12 @@ ajv.addFormat("js-date-time", function (dateTimeString) {
|
|||
});
|
||||
|
||||
const isValidAgainstSchemaV1 = ajv.compile(schemaV1);
|
||||
const isValidAgainstSchemaV03 = ajv.compile(schemaV03);
|
||||
|
||||
export function validateCloudEvent(event: CloudEventV03 | CloudEventV1): boolean {
|
||||
export function validateCloudEvent(event: CloudEventV1): boolean {
|
||||
if (event.specversion === Version.V1) {
|
||||
if (!isValidAgainstSchemaV1(event)) {
|
||||
throw new ValidationError("invalid payload", isValidAgainstSchemaV1.errors);
|
||||
}
|
||||
} else if (event.specversion === Version.V03) {
|
||||
if (!isValidAgainstSchemaV03(event)) {
|
||||
throw new ValidationError("invalid payload", isValidAgainstSchemaV03.errors);
|
||||
}
|
||||
checkDataContentEncoding(event);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -44,18 +37,3 @@ export function validateCloudEvent(event: CloudEventV03 | CloudEventV1): boolean
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function checkDataContentEncoding(event: CloudEventV03): boolean {
|
||||
if (event.datacontentencoding) {
|
||||
// we only support base64
|
||||
const encoding = event.datacontentencoding.toLocaleLowerCase();
|
||||
if (encoding !== CONSTANTS.ENCODING_BASE64) {
|
||||
throw new ValidationError("invalid payload", [`Unsupported content encoding: ${encoding}`]);
|
||||
} else {
|
||||
if (!isBase64(event.data)) {
|
||||
throw new ValidationError("invalid payload", [`Invalid content encoding of data: ${event.data}`]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
import { CloudEvent, Version } from "./event/cloudevent";
|
||||
import { ValidationError } from "./event/validation";
|
||||
import { CloudEventV03, CloudEventV03Attributes, CloudEventV1, CloudEventV1Attributes } from "./event/interfaces";
|
||||
import { CloudEventV1, CloudEventV1Attributes } from "./event/interfaces";
|
||||
|
||||
import { Options, TransportFunction, EmitterFunction, emitterFor, Emitter } from "./transport/emitter";
|
||||
import { Headers, Mode, Binding, HTTP, Message, Serializer, Deserializer } from "./message";
|
||||
|
@ -15,8 +15,6 @@ import CONSTANTS from "./constants";
|
|||
export {
|
||||
// From event
|
||||
CloudEvent,
|
||||
CloudEventV03,
|
||||
CloudEventV03Attributes,
|
||||
CloudEventV1,
|
||||
CloudEventV1Attributes,
|
||||
Version,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { CloudEvent, CloudEventV03, CloudEventV1, CONSTANTS, Mode, Version } from "../..";
|
||||
import { CloudEvent, CloudEventV1, CONSTANTS, Mode, Version } from "../..";
|
||||
import { Message, Headers } from "..";
|
||||
|
||||
import {
|
||||
|
@ -187,7 +187,7 @@ function parseBinary(message: Message, version: Version): CloudEvent {
|
|||
delete eventObj.datacontentencoding;
|
||||
}
|
||||
|
||||
return new CloudEvent({ ...eventObj, data: body } as CloudEventV1 | CloudEventV03, false);
|
||||
return new CloudEvent({ ...eventObj, data: body } as CloudEventV1, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,5 +240,5 @@ function parseStructured(message: Message, version: Version): CloudEvent {
|
|||
delete eventObj.data_base64;
|
||||
delete eventObj.datacontentencoding;
|
||||
}
|
||||
return new CloudEvent(eventObj as CloudEventV1 | CloudEventV03, false);
|
||||
return new CloudEvent(eventObj as CloudEventV1, false);
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import fs from "fs";
|
|||
|
||||
import { expect } from "chai";
|
||||
import { CloudEvent, ValidationError, Version } from "../../src";
|
||||
import { CloudEventV03, CloudEventV1 } from "../../src/event/interfaces";
|
||||
import { CloudEventV1 } from "../../src/event/interfaces";
|
||||
import { asBase64 } from "../../src/event/validation";
|
||||
|
||||
const type = "org.cncf.cloudevents.example";
|
||||
|
@ -204,93 +204,9 @@ describe("A 1.0 CloudEvent", () => {
|
|||
it("correctly formats a CloudEvent as JSON", () => {
|
||||
const ce = new CloudEvent({ ...fixture });
|
||||
const json = ce.toString();
|
||||
const obj = JSON.parse((json as unknown) as string);
|
||||
const obj = JSON.parse(json as string);
|
||||
expect(obj.type).to.equal(type);
|
||||
expect(obj.source).to.equal(source);
|
||||
expect(obj.specversion).to.equal(Version.V1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("A 0.3 CloudEvent", () => {
|
||||
const v03fixture: CloudEventV03 = { ...fixture };
|
||||
v03fixture.specversion = Version.V03;
|
||||
|
||||
it("has retreivable source and type attributes", () => {
|
||||
const ce = new CloudEvent(v03fixture);
|
||||
expect(ce.source).to.equal("http://unit.test");
|
||||
expect(ce.type).to.equal("org.cncf.cloudevents.example");
|
||||
});
|
||||
|
||||
it("generates an ID if one is not provided in the constructor", () => {
|
||||
const ce = new CloudEvent({ source, type, specversion: Version.V03 });
|
||||
expect(ce.id).to.not.be.empty;
|
||||
expect(ce.specversion).to.equal(Version.V03);
|
||||
});
|
||||
|
||||
it("generates a timestamp by default", () => {
|
||||
const ce = new CloudEvent(v03fixture);
|
||||
expect(ce.time).to.not.be.empty;
|
||||
});
|
||||
|
||||
it("can be constructed with a timestamp", () => {
|
||||
const time = new Date().toISOString();
|
||||
const ce = new CloudEvent({ time, ...v03fixture });
|
||||
expect(ce.time).to.equal(time);
|
||||
});
|
||||
|
||||
it("can be constructed with a datacontenttype", () => {
|
||||
const ce = new CloudEvent({ datacontenttype: "application/json", ...v03fixture });
|
||||
expect(ce.datacontenttype).to.equal("application/json");
|
||||
});
|
||||
|
||||
it("can be constructed with a datacontentencoding", () => {
|
||||
const ce = new CloudEvent({ datacontentencoding: "Base64", ...v03fixture, data: "SSB3YXMgZnVubnkg8J+Ygg==" });
|
||||
expect(ce.datacontentencoding).to.equal("Base64");
|
||||
});
|
||||
|
||||
it("can be constructed with a schemaurl", () => {
|
||||
const ce = new CloudEvent({ schemaurl: "http://my.schema", ...v03fixture });
|
||||
expect(ce.schemaurl).to.equal("http://my.schema");
|
||||
});
|
||||
|
||||
it("can be constructed with a subject", () => {
|
||||
const ce = new CloudEvent({ subject: "science", ...v03fixture });
|
||||
expect(ce.subject).to.equal("science");
|
||||
});
|
||||
|
||||
// Handle 1.0 attribute - should this really throw?
|
||||
it("throws a TypeError when constructed with a dataschema", () => {
|
||||
expect(() => {
|
||||
new CloudEvent({ dataschema: "http://throw.com", ...v03fixture });
|
||||
}).to.throw(TypeError, "cannot set dataschema on version 0.3 event");
|
||||
});
|
||||
|
||||
it("can be constructed with data", () => {
|
||||
const ce = new CloudEvent({
|
||||
...v03fixture,
|
||||
data: { lunch: "tacos" },
|
||||
});
|
||||
expect(ce.data).to.deep.equal({ lunch: "tacos" });
|
||||
});
|
||||
|
||||
it("throws TypeError if the CloudEvent does not conform to the schema", () => {
|
||||
try {
|
||||
new CloudEvent({
|
||||
...v03fixture,
|
||||
source: (null as unknown) as string,
|
||||
});
|
||||
} catch (err) {
|
||||
expect(err).to.be.instanceOf(ValidationError);
|
||||
expect(err.message).to.include("invalid payload");
|
||||
}
|
||||
});
|
||||
|
||||
it("correctly formats a CloudEvent as JSON", () => {
|
||||
const ce = new CloudEvent({ ...v03fixture });
|
||||
const json = ce.toString();
|
||||
const obj = JSON.parse((json as unknown) as string);
|
||||
expect(obj.type).to.equal(type);
|
||||
expect(obj.source).to.equal(source);
|
||||
expect(obj.specversion).to.equal(Version.V03);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
Copyright 2021 The CloudEvents Authors
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import "mocha";
|
||||
import { expect } from "chai";
|
||||
import { CloudEvent, Version, ValidationError, Mode } from "../../src";
|
||||
import Constants from "../../src/constants";
|
||||
|
||||
const id = "97699ec2-a8d9-47c1-bfa0-ff7aa526f838";
|
||||
const type = "com.github.pull.create";
|
||||
const source = "urn:event:from:myapi/resourse/123";
|
||||
const time = new Date().toISOString();
|
||||
const schemaurl = "http://example.com/registry/myschema.json";
|
||||
const data = {
|
||||
much: "wow",
|
||||
};
|
||||
const subject = "subject-x0";
|
||||
|
||||
let cloudevent = new CloudEvent({
|
||||
specversion: Version.V03,
|
||||
id,
|
||||
source,
|
||||
type,
|
||||
subject,
|
||||
time,
|
||||
data,
|
||||
schemaurl,
|
||||
datacontenttype: Constants.MIME_JSON,
|
||||
});
|
||||
|
||||
describe("CloudEvents Spec v0.3", () => {
|
||||
describe("REQUIRED Attributes", () => {
|
||||
it("Should have 'id'", () => {
|
||||
expect(cloudevent.id).to.equal(id);
|
||||
});
|
||||
|
||||
it("Should have 'source'", () => {
|
||||
expect(cloudevent.source).to.equal(source);
|
||||
});
|
||||
|
||||
it("Should have 'specversion'", () => {
|
||||
expect(cloudevent.specversion).to.equal(Version.V03);
|
||||
});
|
||||
|
||||
it("Should have 'type'", () => {
|
||||
expect(cloudevent.type).to.equal(type);
|
||||
});
|
||||
});
|
||||
|
||||
describe("OPTIONAL Attributes", () => {
|
||||
it("Should have 'datacontentencoding'", () => {
|
||||
cloudevent = cloudevent.cloneWith({
|
||||
datacontentencoding: Constants.ENCODING_BASE64,
|
||||
data: "SSB3YXMgZnVubnkg8J+Ygg==",
|
||||
});
|
||||
expect(cloudevent.datacontentencoding).to.equal(Constants.ENCODING_BASE64);
|
||||
|
||||
cloudevent = cloudevent.cloneWith({ datacontentencoding: undefined, data: data });
|
||||
});
|
||||
|
||||
it("Should have 'datacontenttype'", () => {
|
||||
expect(cloudevent.datacontenttype).to.equal(Constants.MIME_JSON);
|
||||
});
|
||||
|
||||
it("Should have 'schemaurl'", () => {
|
||||
expect(cloudevent.schemaurl).to.equal(schemaurl);
|
||||
});
|
||||
|
||||
it("Should have 'subject'", () => {
|
||||
expect(cloudevent.subject).to.equal(subject);
|
||||
});
|
||||
|
||||
it("Should have 'time'", () => {
|
||||
expect(cloudevent.time).to.equal(time);
|
||||
});
|
||||
|
||||
it("Should have 'data'", () => {
|
||||
expect(cloudevent.data).to.deep.equal(data);
|
||||
});
|
||||
|
||||
it("Should have the 'extension1'", () => {
|
||||
cloudevent = cloudevent.cloneWith({ extension1: "value1" });
|
||||
expect(cloudevent.extension1).to.equal("value1");
|
||||
});
|
||||
});
|
||||
|
||||
describe("The Constraints check", () => {
|
||||
describe("'id'", () => {
|
||||
it("should throw an error when trying to remove", () => {
|
||||
expect(() => {
|
||||
delete (cloudevent as any).id;
|
||||
}).to.throw(TypeError);
|
||||
});
|
||||
|
||||
it("defaut ID create when an empty string", () => {
|
||||
cloudevent = cloudevent.cloneWith({ id: "" });
|
||||
expect(cloudevent.id.length).to.be.greaterThan(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("'source'", () => {
|
||||
it("should throw an error when trying to remove", () => {
|
||||
expect(() => {
|
||||
delete (cloudevent as any).source;
|
||||
}).to.throw(TypeError);
|
||||
});
|
||||
});
|
||||
|
||||
describe("'specversion'", () => {
|
||||
it("should throw an error when trying to remove", () => {
|
||||
expect(() => {
|
||||
delete (cloudevent as any).specversion;
|
||||
}).to.throw(TypeError);
|
||||
});
|
||||
});
|
||||
|
||||
describe("'type'", () => {
|
||||
it("should throw an error when trying to remove", () => {
|
||||
expect(() => {
|
||||
delete (cloudevent as any).type;
|
||||
}).to.throw(TypeError);
|
||||
});
|
||||
|
||||
it("should throw an error when is an empty string", () => {
|
||||
expect(() => {
|
||||
cloudevent.cloneWith({ type: "" });
|
||||
}).to.throw(ValidationError, "invalid payload");
|
||||
});
|
||||
|
||||
it("must be a non-empty string", () => {
|
||||
cloudevent.cloneWith({ type: type });
|
||||
expect(cloudevent.type).to.equal(type);
|
||||
});
|
||||
});
|
||||
|
||||
describe("'datacontentencoding'", () => {
|
||||
it("should throw an error when is a unsupported encoding", () => {
|
||||
expect(() => {
|
||||
cloudevent.cloneWith({ data: "Y2xvdWRldmVudHMK", datacontentencoding: Mode.BINARY });
|
||||
}).to.throw(ValidationError, "invalid payload");
|
||||
|
||||
cloudevent.cloneWith({ data: data, datacontentencoding: undefined });
|
||||
});
|
||||
|
||||
it("should throw an error when 'data' does not carry base64", () => {
|
||||
expect(() => {
|
||||
cloudevent.cloneWith({
|
||||
data: "no base 64 value",
|
||||
datacontentencoding: Constants.ENCODING_BASE64,
|
||||
datacontenttype: "text/plain",
|
||||
});
|
||||
}).to.throw(ValidationError, "invalid payload");
|
||||
|
||||
cloudevent.cloneWith({
|
||||
data: data,
|
||||
datacontentencoding: undefined,
|
||||
});
|
||||
});
|
||||
|
||||
it("should accept when 'data' is a string", () => {
|
||||
cloudevent.cloneWith({ data: "Y2xvdWRldmVudHMK", datacontentencoding: Constants.ENCODING_BASE64 });
|
||||
expect(cloudevent.validate()).to.be.true;
|
||||
cloudevent.cloneWith({ data: data, datacontentencoding: undefined });
|
||||
});
|
||||
});
|
||||
|
||||
describe("'data'", () => {
|
||||
it("should maintain the type of data when no data content type", () => {
|
||||
cloudevent = cloudevent.cloneWith({ datacontenttype: undefined });
|
||||
cloudevent.data = JSON.stringify(data);
|
||||
|
||||
expect(typeof cloudevent.data).to.equal("string");
|
||||
});
|
||||
});
|
||||
|
||||
describe("'subject'", () => {
|
||||
it("should throw an error when is an empty string", () => {
|
||||
expect(() => {
|
||||
cloudevent.cloneWith({ subject: "" });
|
||||
}).to.throw(ValidationError);
|
||||
});
|
||||
});
|
||||
|
||||
describe("'time'", () => {
|
||||
it("must adhere to the format specified in RFC 3339", () => {
|
||||
const d = new Date();
|
||||
cloudevent = cloudevent.cloneWith({ time: d.toString() });
|
||||
// ensure that we always get back the same thing we passed in
|
||||
expect(cloudevent.time).to.equal(d.toString());
|
||||
// ensure that when stringified, the timestamp is in RFC3339 format
|
||||
expect(JSON.parse(JSON.stringify(cloudevent)).time).to.equal(new Date(d.toString()).toISOString());
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue