From 8fcbaecfcad941b21d979a903cd4ced195c1ac23 Mon Sep 17 00:00:00 2001 From: Lucas Holmquist Date: Tue, 14 Jul 2020 10:54:19 -0400 Subject: [PATCH 1/5] squash: valid types for ext values Signed-off-by: Lucas Holmquist --- src/event/cloudevent.ts | 9 ++++++++- test/integration/spec_1_tests.ts | 14 ++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/event/cloudevent.ts b/src/event/cloudevent.ts index 4cc7fcbb..32fc0d74 100644 --- a/src/event/cloudevent.ts +++ b/src/event/cloudevent.ts @@ -9,7 +9,7 @@ import { CloudEventV1OptionalAttributes, } from "./interfaces"; import { validateV1, validateV03 } from "./spec"; -import { ValidationError, isBinary, asBase64 } from "./validation"; +import { ValidationError, isBinary, asBase64, isValidType } from "./validation"; import CONSTANTS from "../constants"; import { isString } from "util"; @@ -108,6 +108,13 @@ export class CloudEvent implements CloudEventV1, CloudEventV03 { if (!key.match(/^[a-z0-9]{1,20}$/)) { throw new ValidationError("invalid extension name"); } + + // Value should be spec complient + // https://github.com/cloudevents/spec/blob/master/spec.md#type-system + if (!isValidType(value)) { + throw new ValidationError("invalid extension value"); + } + this[key] = value; } diff --git a/test/integration/spec_1_tests.ts b/test/integration/spec_1_tests.ts index d5802832..a2052dca 100644 --- a/test/integration/spec_1_tests.ts +++ b/test/integration/spec_1_tests.ts @@ -87,12 +87,14 @@ describe("CloudEvents Spec v1.0", () => { expect(cloudevent.cloneWith({ extdate: myDate }).validate()).to.equal(true); }); - // even though the spec doesn't allow object types for - // extensions, it could be JSON. And before a JS CE - // is transmitted across the wire, this value will be - // converted to JSON - it("should be ok when the type is an object", () => { - expect(cloudevent.cloneWith({ objectextension: { some: "object" } }).validate()).to.equal(true); + it("should fail when the type is an object", () => { + expect(() => { + cloudevent.cloneWith({ objectextension: { some: "object" } }); + }).to.throw(ValidationError, "invalid extension value"); + }); + + it("should be ok when the type is an string converted from an object", () => { + expect(cloudevent.cloneWith({ objectextension: JSON.stringify({ some: "object" }) }).validate()).to.equal(true); }); }); From 27095b3963090b429034f8bb97379f6240e29651 Mon Sep 17 00:00:00 2001 From: Lucas Holmquist Date: Fri, 24 Jul 2020 08:57:49 -0400 Subject: [PATCH 2/5] squash: fixing conflicts with the rebase Signed-off-by: Lucas Holmquist --- src/event/validation.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/validation.ts b/src/event/validation.ts index 56b97e5d..b0ed801b 100644 --- a/src/event/validation.ts +++ b/src/event/validation.ts @@ -81,5 +81,5 @@ export const asData = (data: unknown, contentType: string): string => { return isBinary(maybeJson) ? asBase64(maybeJson) : maybeJson; }; -export const isValidType = (v: boolean | number | string | Date | Uint32Array): boolean => +export const isValidType = (v: boolean | number | string | Date | Uint32Array | unknown): boolean => isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v); From 3a823898c06eaaf29b528d804a64b4736c4c2bd3 Mon Sep 17 00:00:00 2001 From: Lucas Holmquist Date: Fri, 24 Jul 2020 13:10:34 -0400 Subject: [PATCH 3/5] squash: nit Signed-off-by: Lucas Holmquist --- src/event/cloudevent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/cloudevent.ts b/src/event/cloudevent.ts index 32fc0d74..0cab0dad 100644 --- a/src/event/cloudevent.ts +++ b/src/event/cloudevent.ts @@ -109,7 +109,7 @@ export class CloudEvent implements CloudEventV1, CloudEventV03 { throw new ValidationError("invalid extension name"); } - // Value should be spec complient + // Value should be spec compliant // https://github.com/cloudevents/spec/blob/master/spec.md#type-system if (!isValidType(value)) { throw new ValidationError("invalid extension value"); From c3f8e92f2751b629b9a4c8d3dffbfa7610b5030f Mon Sep 17 00:00:00 2001 From: Lucas Holmquist Date: Fri, 24 Jul 2020 15:23:31 -0400 Subject: [PATCH 4/5] squash: can pass in an Object now Signed-off-by: Lucas Holmquist --- src/event/validation.ts | 2 +- test/integration/spec_1_tests.ts | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/event/validation.ts b/src/event/validation.ts index b0ed801b..6ca0258d 100644 --- a/src/event/validation.ts +++ b/src/event/validation.ts @@ -82,4 +82,4 @@ export const asData = (data: unknown, contentType: string): string => { }; export const isValidType = (v: boolean | number | string | Date | Uint32Array | unknown): boolean => - isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v); + isBoolean(v) || isInteger(v) || isString(v) || isDate(v) || isBinary(v) || isObject(v); diff --git a/test/integration/spec_1_tests.ts b/test/integration/spec_1_tests.ts index a2052dca..e39d3a56 100644 --- a/test/integration/spec_1_tests.ts +++ b/test/integration/spec_1_tests.ts @@ -87,10 +87,8 @@ describe("CloudEvents Spec v1.0", () => { expect(cloudevent.cloneWith({ extdate: myDate }).validate()).to.equal(true); }); - it("should fail when the type is an object", () => { - expect(() => { - cloudevent.cloneWith({ objectextension: { some: "object" } }); - }).to.throw(ValidationError, "invalid extension value"); + it("should be ok when the type is an object", () => { + expect(cloudevent.cloneWith({ objectextension: { some: "object" } }).validate()).to.equal(true); }); it("should be ok when the type is an string converted from an object", () => { From 4be9b6574ee4eb134eca0a15af086ac49111c12a Mon Sep 17 00:00:00 2001 From: Lucas Holmquist Date: Mon, 27 Jul 2020 11:36:37 -0400 Subject: [PATCH 5/5] squash: add an emitter test with the object based extension value Signed-off-by: Lucas Holmquist --- test/integration/http_emitter_test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/integration/http_emitter_test.ts b/test/integration/http_emitter_test.ts index 1644af9c..b5f211be 100644 --- a/test/integration/http_emitter_test.ts +++ b/test/integration/http_emitter_test.ts @@ -15,6 +15,8 @@ const ext1Name = "lunch"; const ext1Value = "tacos"; const ext2Name = "supper"; const ext2Value = "sushi"; +const ext3Name = "snack"; +const ext3Value = { value: "chips" }; const data = { lunchBreak: "noon", @@ -45,6 +47,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => { data, [ext1Name]: ext1Value, [ext2Name]: ext2Value, + [ext3Name]: ext3Value, }); it("Sends a binary 1.0 CloudEvent by default", () => { @@ -59,6 +62,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => { // Ensure extensions are handled properly expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext1Name}`]).to.equal(ext1Value); expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext2Name}`]).to.equal(ext2Value); + expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext3Name}`].value).to.equal(ext3Value.value); }) .catch(expect.fail); }); @@ -142,6 +146,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => { data, [ext1Name]: ext1Value, [ext2Name]: ext2Value, + [ext3Name]: ext3Value, }); it("Sends a binary 0.3 CloudEvent", () => { @@ -156,6 +161,7 @@ describe("HTTP Transport Binding Emitter for CloudEvents", () => { // Ensure extensions are handled properly expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext1Name}`]).to.equal(ext1Value); expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext2Name}`]).to.equal(ext2Value); + expect(response.data[`${CONSTANTS.EXTENSIONS_PREFIX}${ext3Name}`].value).to.equal(ext3Value.value); }) .catch(expect.fail); });