feat(unmarshaller)!: remove asynchronous 0.3 unmarshaller API (#126)

This commit removes the unnecessary use of Promises in the 0.3 unmarshaller.
There was actually no asynchronous activity happening in that function, so
there was no need to deal with Promises, and as a result testing was made
much more difficult.

Fixes: https://github.com/cloudevents/sdk-javascript/pull/95

Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
Lance Ball 2020-05-06 20:05:10 -04:00 committed by GitHub
parent 106b943ee2
commit 63ae1ad527
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 137 deletions

View File

@ -45,27 +45,25 @@ class Unmarshaller {
} }
unmarshall(payload, headers) { unmarshall(payload, headers) {
return new Promise((resolve, reject) => { if (!payload) {
if (!payload) { throw new TypeError("payload is null or undefined");
return reject(new TypeError("payload is null or undefined")); }
} if (!headers) {
if (!headers) { throw new TypeError("headers is null or undefined");
return reject(new TypeError("headers is null or undefined")); }
}
// Validation level 1 // Validation level 1
const sanityHeaders = Commons.sanityAndClone(headers); const sanityHeaders = Commons.sanityAndClone(headers);
if (!sanityHeaders[Constants.HEADER_CONTENT_TYPE]) { if (!sanityHeaders[Constants.HEADER_CONTENT_TYPE]) {
throw new TypeError("content-type header not found"); throw new TypeError("content-type header not found");
} }
// Resolve the binding // Resolve the binding
const bindingName = resolveBindingName(payload, sanityHeaders); const bindingName = resolveBindingName(payload, sanityHeaders);
const cloudevent = this.receiverByBinding[bindingName] const cloudevent = this.receiverByBinding[bindingName]
.parse(payload, sanityHeaders); .parse(payload, sanityHeaders);
resolve(cloudevent); return cloudevent;
});
} }
} }

View File

@ -19,128 +19,75 @@ const data = {
foo: "bar" foo: "bar"
}; };
const un = new Unmarshaller();
describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => { describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => {
it("Throw error when payload is null", () => { it("Throw error when payload is null", () => {
// setup expect(() => un.unmarshall(null)).to.throw("payload is null or undefined");
const payload = null;
const un = new Unmarshaller();
// act and assert
return un.unmarshall(payload)
.then(() => { throw new Error("failed"); })
.catch((err) =>
expect(err.message).to.equal("payload is null or undefined"));
}); });
it("Throw error when headers is null", () => { it("Throw error when headers is null", () => {
// setup expect(() => un.unmarshall({})).to.throw("headers is null or undefined");
const payload = {}; expect(() => un.unmarshall({}, null)).to
const headers = null; .throw("headers is null or undefined");
const un = new Unmarshaller();
// act and assert
return un.unmarshall(payload, headers)
.then(() => { throw new Error("failed"); })
.catch((err) =>
expect(err.message).to.equal("headers is null or undefined"));
}); });
it("Throw error when there is no content-type header", () => { it("Throw error when there is no content-type header", () => {
// setup expect(() => un.unmarshall({}, {})).to
const payload = {}; .throw("content-type header not found");
const headers = {};
const un = new Unmarshaller();
// act and assert
un.unmarshall(payload, headers)
.then(() => { throw new Error("failed"); })
.catch((err) =>
expect(err.message).to.equal("content-type header not found"));
}); });
it("Throw error when content-type is not allowed", () => { it("Throw error when content-type is not allowed", () => {
// setup
const payload = {};
const headers = { const headers = {
"content-type": "text/xml" "content-type": "text/xml"
}; };
const un = new Unmarshaller(); expect(() => un.unmarshall({}, headers)).to
.throw("content type not allowed");
// act and assert
un.unmarshall(payload, headers)
.then(() => { throw new Error("failed"); })
.catch((err) =>
expect(err.message).to.equal("content type not allowed"));
}); });
describe("Structured", () => { describe("Structured", () => {
it("Throw error when has not allowed mime", () => { it("Throw error when has not allowed mime", () => {
// setup // setup
const payload = {};
const headers = { const headers = {
"content-type": "application/cloudevents+zip" "content-type": "application/cloudevents+zip"
}; };
const un = new Unmarshaller();
// act and assert // act and assert
un.unmarshall(payload, headers) expect(() => un.unmarshall({}, headers)).to
.then(() => { throw new Error("failed"); }) .throw("structured+type not allowed");
.catch((err) =>
expect(err.message).to.equal("structured+type not allowed"));
}); });
it("Throw error when the event does not follow the spec 0.3", () => { it("Throw error when the event does not follow the spec 0.3", () => {
// setup
const payload = const payload =
new v03.CloudEvent(v03.Spec) new CloudEvent(v03.Spec)
.type(type)
.source(source)
.dataContentType(ceContentType)
.time(now) .time(now)
.schemaurl(schemaurl)
.data(data)
.toString(); .toString();
const headers = { const headers = {
"content-type": "application/cloudevents+json" "content-type": "application/cloudevents+json"
}; };
const un = new Unmarshaller(); expect(() => un.unmarshall(payload, headers)).to
.throw(TypeError);
// act and assert
un.unmarshall(payload, headers)
.then(() => { throw new Error("failed"); })
.catch((err) =>
expect(err.message).to.equal("invalid payload"));
}); });
it("Should accept event that follow the spec 0.3", () => { it("Should accept event that follow the spec 0.3", () => {
// setup
const payload = const payload =
new CloudEvent(v03.Spec) new CloudEvent(v03.Spec)
.type(type) .type(type)
.data(data)
.source(source) .source(source)
.dataContentType(ceContentType) .dataContentType(ceContentType)
.time(now) .time(now)
.schemaurl(schemaurl) .schemaurl(schemaurl)
.subject(subject) .subject(subject)
.data(data) .format();
.toString();
const headers = { const headers = {
"content-type": "application/cloudevents+json" "content-type": "application/cloudevents+json"
}; };
const event = un.unmarshall(payload, headers);
const un = new Unmarshaller(); expect(event instanceof CloudEvent).to.equal(true);
// act and assert
return un.unmarshall(payload, headers)
.then((actual) =>
expect(actual).to.be.an("object"))
.catch((err) => {
console.error(err);
throw err;
});
}); });
it("Should parse 'data' stringfied json to json object", () => { it("Should parse 'data' stringfied json to json object", () => {
@ -160,17 +107,8 @@ describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => {
"content-type": "application/cloudevents+json" "content-type": "application/cloudevents+json"
}; };
const un = new Unmarshaller(); const event = un.unmarshall(payload, headers);
expect(event.getData()).to.deep.equal(data);
// act and assert
return un.unmarshall(payload, headers)
.then((actual) => {
expect(actual.getData()).to.deep.equal(data);
})
.catch((err) => {
console.error(err);
throw err;
});
}); });
}); });
@ -190,13 +128,8 @@ describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => {
[HEADER_CONTENT_TYPE]: "text/html" [HEADER_CONTENT_TYPE]: "text/html"
}; };
const un = new Unmarshaller(); expect(() => un.unmarshall(payload, attributes)).to
.throw("content type not allowed");
// act and assert
un.unmarshall(payload, attributes)
.then(() => { throw new Error("failed"); })
.catch((err) =>
expect(err.message).to.equal("content type not allowed"));
}); });
it("Throw error when the event does not follow the spec 0.3", () => { it("Throw error when the event does not follow the spec 0.3", () => {
@ -214,13 +147,8 @@ describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => {
[HEADER_CONTENT_TYPE]: "application/json" [HEADER_CONTENT_TYPE]: "application/json"
}; };
const un = new Unmarshaller(); expect(() => un.unmarshall(payload, attributes)).to
.throw("header 'ce-specversion' not found");
// act and assert
un.unmarshall(payload, attributes)
.then(() => { throw new Error("failed"); })
.catch((err) =>
expect(err.message).to.not.empty);
}); });
it("No error when all attributes are in place", () => { it("No error when all attributes are in place", () => {
@ -238,11 +166,8 @@ describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => {
[HEADER_CONTENT_TYPE]: "application/json" [HEADER_CONTENT_TYPE]: "application/json"
}; };
const un = new Unmarshaller(); const event = un.unmarshall(payload, attributes);
expect(event instanceof CloudEvent).to.equal(true);
// act and assert
un.unmarshall(payload, attributes)
.then((actual) => expect(actual).to.be.an("object"));
}); });
it("Throw error when 'ce-datacontentencoding' is not allowed", () => { it("Throw error when 'ce-datacontentencoding' is not allowed", () => {
@ -260,14 +185,8 @@ describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => {
[BINARY_HEADERS_03.CONTENT_ENCONDING]: "binary" [BINARY_HEADERS_03.CONTENT_ENCONDING]: "binary"
}; };
const un = new Unmarshaller(); expect(() => un.unmarshall(payload, attributes)).to
.throw("unsupported datacontentencoding");
// act and assert
return un.unmarshall(payload, attributes)
.then(() => { throw new Error("failed"); })
.catch((err) => {
expect(err.message).to.equal("unsupported datacontentencoding");
});
}); });
it("No error when 'ce-datacontentencoding' is base64", () => { it("No error when 'ce-datacontentencoding' is base64", () => {
@ -288,15 +207,8 @@ describe("HTTP Transport Binding Unmarshaller for CloudEvents v0.3", () => {
[BINARY_HEADERS_03.CONTENT_ENCONDING]: "base64" [BINARY_HEADERS_03.CONTENT_ENCONDING]: "base64"
}; };
const un = new Unmarshaller(); const event = un.unmarshall(payload, attributes);
expect(event.getData()).to.deep.equal(expected);
// act and assert
return un.unmarshall(payload, attributes)
.then((actual) => expect(actual.getData()).to.deep.equal(expected))
.catch((err) => {
console.error(err);
throw err;
});
}); });
}); });
}); });