Skip to content

Commit 615ab02

Browse files
committed
squash: add ext name validation
Signed-off-by: Lucas Holmquist <[email protected]>
1 parent 3116ffc commit 615ab02

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

src/event/cloudevent.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@ export class CloudEvent implements CloudEventV1, CloudEventV03 {
9696

9797
// finally process any remaining properties - these are extensions
9898
for (const [key, value] of Object.entries(properties)) {
99+
// Extension names should only allow lowercase a-z and 0-9 in the name
100+
// names should not exceed 20 characters in length
101+
if (!key.match(/^[a-z0-9]{1,20}$/)) {
102+
throw new ValidationError("invalid extension name");
103+
}
99104
this[key] = value;
100105
}
101106

test/cloud_event_test.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@ describe("A CloudEvent", () => {
2525
const ce = new CloudEvent(fixture);
2626
expect(ce.toString()).to.deep.equal(JSON.stringify(ce));
2727
});
28+
29+
it("Throw a validation error for invalid extension names", () => {
30+
expect(() => {
31+
new CloudEvent({ "ext-1": "extension1", ...fixture });
32+
}).throw("invalid extension name");
33+
});
34+
35+
it("Throw a validation error for invalid extension names, more than 20 chars", () => {
36+
expect(() => {
37+
new CloudEvent({ "123456789012345678901": "extension1", ...fixture });
38+
}).throw("invalid extension name");
39+
});
2840
});
2941

3042
describe("A 1.0 CloudEvent", () => {
@@ -92,13 +104,13 @@ describe("A 1.0 CloudEvent", () => {
92104

93105
it("can be constructed with extensions", () => {
94106
const extensions = {
95-
"extension-key": "extension-value",
107+
extensionkey: "extension-value",
96108
};
97109
const ce = new CloudEvent({
98110
...extensions,
99111
...fixture,
100112
});
101-
expect(ce["extension-key"]).to.equal(extensions["extension-key"]);
113+
expect(ce["extensionkey"]).to.equal(extensions["extensionkey"]);
102114
});
103115

104116
it("throws ValidationError if the CloudEvent does not conform to the schema");

test/receiver_structured_1_test.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ const source = "urn:event:from:myapi/resourse/123";
1111
const time = new Date();
1212
const dataschema = "http://cloudevents.io/schema.json";
1313

14-
const ceContentType = "application/json";
15-
1614
const data = {
1715
foo: "bar",
1816
};
@@ -108,7 +106,6 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0", () =
108106
time,
109107
data,
110108
dataschema,
111-
dataContentType: ceContentType,
112109
};
113110
const headers = {
114111
"content-type": "application/cloudevents+json",
@@ -124,14 +121,13 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0", () =
124121

125122
it("Should accept 'extension1'", () => {
126123
// setup
127-
const extension1 = "mycustom-ext1";
124+
const extension1 = "mycustomext1";
128125
const event = {
129126
type,
130127
source,
131128
time,
132129
data,
133130
dataschema,
134-
dataContentType: ceContentType,
135131
extension1,
136132
};
137133

@@ -152,7 +148,6 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0", () =
152148
time,
153149
dataschema,
154150
data: data,
155-
dataContentType: ceContentType,
156151
};
157152

158153
const headers = {
@@ -173,7 +168,6 @@ describe("HTTP Transport Binding Structured Receiver for CloudEvents v1.0", () =
173168
type,
174169
source,
175170
data: bindata,
176-
dataContentType: ceContentType,
177171
};
178172

179173
const headers = {

test/spec_1_tests.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,30 +65,30 @@ describe("CloudEvents Spec v1.0", () => {
6565

6666
describe("Extensions Constraints", () => {
6767
it("should be ok when type is 'boolean'", () => {
68-
cloudevent = cloudevent.cloneWith({ "ext-boolean": true });
68+
cloudevent = cloudevent.cloneWith({ extboolean: true });
6969
expect(cloudevent.validate()).to.equal(true);
7070
});
7171

7272
it("should be ok when type is 'integer'", () => {
73-
cloudevent = cloudevent.cloneWith({ "ext-integer": 2019 });
73+
cloudevent = cloudevent.cloneWith({ extinteger: 2019 });
7474
expect(cloudevent.validate()).to.equal(true);
7575
});
7676

7777
it("should be ok when type is 'string'", () => {
78-
cloudevent = cloudevent.cloneWith({ "ext-string": "an-string" });
78+
cloudevent = cloudevent.cloneWith({ extstring: "an-string" });
7979
expect(cloudevent.validate()).to.equal(true);
8080
});
8181

8282
it("should be ok when type is 'Uint32Array' for 'Binary'", () => {
8383
const myBinary = new Uint32Array(2019);
84-
cloudevent = cloudevent.cloneWith({ "ext-binary": myBinary });
84+
cloudevent = cloudevent.cloneWith({ extbinary: myBinary });
8585
expect(cloudevent.validate()).to.equal(true);
8686
});
8787

8888
// URI
8989
it("should be ok when type is 'Date' for 'Timestamp'", () => {
9090
const myDate = new Date();
91-
cloudevent = cloudevent.cloneWith({ "ext-date": myDate });
91+
cloudevent = cloudevent.cloneWith({ extdate: myDate });
9292
expect(cloudevent.validate()).to.equal(true);
9393
});
9494

@@ -97,7 +97,7 @@ describe("CloudEvents Spec v1.0", () => {
9797
// is transmitted across the wire, this value will be
9898
// converted to JSON
9999
it("should be ok when the type is an object", () => {
100-
cloudevent = cloudevent.cloneWith({ "object-extension": { some: "object" } });
100+
cloudevent = cloudevent.cloneWith({ objectextension: { some: "object" } });
101101
expect(cloudevent.validate()).to.equal(true);
102102
});
103103
});

0 commit comments

Comments
 (0)