@1mill/cloudevents 4.0.1 → 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#subject', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when #subject is not input', () => {
16
+ it('returns undefined', () => {
17
+ const { subject } = new Cloudevent(params)
18
+ expect(subject).to.be.undefined
19
+ })
20
+ })
21
+
22
+ describe('when #subject is not input', () => {
23
+ describe('when the input value is invalid', () => {
24
+ it('throws the proper error', () => {
25
+ const expected = 'Cloudevent "subject" must be of type STRING or UNDEFINED'
26
+ params.subject = 1234
27
+ expect(() => new Cloudevent(params)).to.throw(expected)
28
+ })
29
+ })
30
+
31
+ describe('when the input value is valid', () => {
32
+ it('sets cloudevent#subject to the input value', () => {
33
+ params.subject = 'some-string'
34
+ const { subject } = new Cloudevent(params)
35
+ expect(subject).to.eq(params.subject)
36
+ })
37
+ })
38
+ })
39
+ })
@@ -0,0 +1,36 @@
1
+ import chai, { expect } from 'chai'
2
+ import chaiIso8601 from 'chai-iso8601'
3
+ import { Cloudevent } from '../index.js'
4
+ import { useFakeTimers } from 'sinon'
5
+
6
+ chai.use(chaiIso8601())
7
+
8
+ describe('cloudevent#time', () => {
9
+ let params
10
+
11
+ beforeEach(() => {
12
+ params = {
13
+ // * Required base defaults
14
+ source: 'some-source',
15
+ type: 'some-type',
16
+ }
17
+ })
18
+
19
+ it('returns a string', () => {
20
+ const { time } = new Cloudevent(params)
21
+ expect(time).to.be.a('string')
22
+ })
23
+
24
+ it('returns the current time formatted in ISO8601', () => {
25
+ const clock = useFakeTimers()
26
+
27
+ clock.tick(987654321) // * Jump into the future
28
+ const expected = new Date().toISOString()
29
+ const { time } = new Cloudevent(params)
30
+
31
+ clock.tick(123456789) // * Jump into the future
32
+ expect(time).to.be.iso8601('eq', expected)
33
+
34
+ clock.restore()
35
+ })
36
+ })
@@ -0,0 +1,39 @@
1
+ import { Cloudevent } from '../index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('cloudevent#type', () => {
5
+ let params
6
+
7
+ beforeEach(() => {
8
+ params = {
9
+ // * Required base defaults
10
+ source: 'some-source',
11
+ type: 'some-type',
12
+ }
13
+ })
14
+
15
+ describe('when a #type value is not input', () => {
16
+ it('throws the proper error', () => {
17
+ const expected = 'Cloudevent "type" must be of type STRING'
18
+ params.type = null
19
+ expect(() => new Cloudevent(params)).to.throw(expected)
20
+ })
21
+ })
22
+
23
+ describe('when a #type value is input', () => {
24
+ describe('when the input value is not a string', () => {
25
+ it('throws the proper error', () => {
26
+ const expected = 'Cloudevent "type" must be of type STRING'
27
+ params.type = 1234
28
+ expect(() => new Cloudevent(params)).to.throw(expected)
29
+ })
30
+ })
31
+
32
+ describe('when the input value is a string', () => {
33
+ it('returns the input value', () => {
34
+ const { type } = new Cloudevent(params)
35
+ expect(type).to.eq(params.type)
36
+ })
37
+ })
38
+ })
39
+ })
@@ -0,0 +1,92 @@
1
+ import chai, { expect } from 'chai'
2
+ import chaiIso8601 from 'chai-iso8601'
3
+ import chaiSubset from 'chai-subset'
4
+ import { Cloudevent } from '../dist/index.cjs'
5
+ import { useFakeTimers } from 'sinon'
6
+
7
+ chai.use(chaiIso8601)
8
+ chai.use(chaiSubset)
9
+
10
+ describe('new Cloudevent', () => {
11
+ let clock
12
+
13
+ beforeEach(() => {
14
+ clock = useFakeTimers()
15
+ })
16
+
17
+ afterEach(() => {
18
+ clock.restore()
19
+ })
20
+
21
+ describe('when the cloudevent is not enriched', () => {
22
+ it('returns the expected cloudevent', () => {
23
+ clock.tick(987654321) // * Jump into the future
24
+
25
+ const data = JSON.stringify({ some: 'data' })
26
+ const source = 'some-source'
27
+ const time = new Date().toISOString()
28
+ const type = 'some-type'
29
+
30
+ const cloudevent = new Cloudevent({ data, source, type })
31
+
32
+ clock.tick(123456789) // * Jump into the future
33
+
34
+ expect(cloudevent).to.containSubset({
35
+ data,
36
+ datacontenttype: 'application/json',
37
+ originsource: source,
38
+ origintime: time,
39
+ origintype: type,
40
+ source,
41
+ specversion: '1.0',
42
+ time,
43
+ type,
44
+ })
45
+ })
46
+ })
47
+
48
+ describe('when the cloudevent is enriched', () => {
49
+ it('returns the expected cloudevent', () => {
50
+ clock.tick(987654321) // * Jump into the future
51
+
52
+ const originCloudevent = new Cloudevent({
53
+ data: JSON.stringify({ some: 'data' }),
54
+ source: 'some-origin-source',
55
+ type: 'some-origin-type',
56
+ })
57
+
58
+ clock.tick(123456789) // * Jump into the future
59
+
60
+ const data = undefined
61
+ const datacontenttype = undefined
62
+ const source = 'some-enrichment-source'
63
+ const time = new Date().toISOString()
64
+ const type = 'some-enrichment-type'
65
+
66
+ const cloudevent = new Cloudevent({
67
+ ...originCloudevent,
68
+ data,
69
+ datacontenttype,
70
+ source,
71
+ type,
72
+
73
+ })
74
+
75
+ clock.tick(987654321) // * Jump into the future
76
+ expect(cloudevent).to.containSubset({
77
+ data,
78
+ datacontenttype: undefined,
79
+ dataschema: undefined,
80
+ originid: originCloudevent.id,
81
+ originsource: originCloudevent.source,
82
+ origintime: originCloudevent.time,
83
+ origintype: originCloudevent.type,
84
+ source,
85
+ specversion: '1.0',
86
+ subject: undefined,
87
+ time,
88
+ type,
89
+ })
90
+ })
91
+ })
92
+ })
@@ -0,0 +1,4 @@
1
+ export const fetchNodeEnv = (name, fallbackValue) => {
2
+ if (typeof process === 'undefined') { return }
3
+ return process.env[name] || fallbackValue
4
+ }
@@ -0,0 +1,55 @@
1
+ import { createSandbox } from 'sinon'
2
+ import { expect } from 'chai'
3
+ import { fetchNodeEnv } from './index.js'
4
+
5
+ describe('fetchNodeEnv', () => {
6
+ const name = 'SOME_NAME'
7
+ const sandbox = createSandbox()
8
+
9
+ afterEach(() => {
10
+ sandbox.restore()
11
+ })
12
+
13
+ describe('when the node global.process is not defined', () => {
14
+ it('returns undefined', () => {
15
+ sandbox.stub(global, 'process').value(undefined)
16
+ const result = fetchNodeEnv(name)
17
+ expect(result).to.be.undefined
18
+ })
19
+ })
20
+
21
+ describe('when the node global.process is defined', () => {
22
+ describe('when the input name does not exist as an environmental variable', () => {
23
+ describe('when a fallback value is not input', () => {
24
+ it ('returns undefined', () => {
25
+ sandbox.stub(process, 'env').value({})
26
+ const result = fetchNodeEnv(name)
27
+ expect(result).to.be.undefined
28
+ })
29
+ })
30
+
31
+ describe('when a fallback value is input', () => {
32
+ it ('returns the input fallback value', () => {
33
+ const fallbackValue = 'some-fallback-value'
34
+
35
+ sandbox.stub(process, 'env').value({})
36
+
37
+ const result = fetchNodeEnv(name, fallbackValue)
38
+ expect(result).to.eq(fallbackValue)
39
+ })
40
+ })
41
+ })
42
+
43
+ describe('when the input name exists as an environmental variable', () => {
44
+ it('returns the proper environmental variable', () => {
45
+ const expected = 'some-value'
46
+
47
+ const env = { [name]: expected }
48
+ sandbox.stub(process, 'env').value(env)
49
+
50
+ const result = fetchNodeEnv(name, 'some-fallback-value')
51
+ expect(result).to.eq(expected)
52
+ })
53
+ })
54
+ })
55
+ })
@@ -0,0 +1,7 @@
1
+ export const setAttribute = ({ cloudevent, name, types = [], value }) => {
2
+ if (types.length > 0 && !types.includes(typeof value)) {
3
+ const message = `Cloudevent "${name}" must be of type ${types.map(s => s.toUpperCase()).sort().join(' or ')}.`
4
+ throw new Error(message)
5
+ }
6
+ cloudevent[name] = value
7
+ }
@@ -0,0 +1,43 @@
1
+ import { setAttribute } from './index.js'
2
+ import { expect } from 'chai'
3
+
4
+ describe('setAttribute', () => {
5
+ const name = 'some-name'
6
+ let cloudevent
7
+
8
+ beforeEach(() => {
9
+ cloudevent = {}
10
+ })
11
+
12
+ describe('when #types is empty', () => {
13
+ [1234, '1234', undefined].forEach(value => {
14
+ it('sets cloudevent[#name] to the input #value', () => {
15
+ setAttribute({ cloudevent, name, value })
16
+ expect(cloudevent[name]).to.eq(value)
17
+ })
18
+ })
19
+ })
20
+
21
+ describe('when #types is not empty', () => {
22
+ describe('when the type of #value is not in #types', () => {
23
+ it('throws the proper error', () => {
24
+ const types = ['undefined', 'string']
25
+ const value = 1234
26
+
27
+ const expected = `Cloudevent "${name}" must be of type STRING or UNDEFINED`
28
+
29
+ expect(() => setAttribute({ cloudevent, name, types, value })).to.throw(expected)
30
+ })
31
+ })
32
+
33
+ describe('when the type of #value is in #types', () => {
34
+ [1234, undefined].forEach(value => {
35
+ it('sets cloudevent[#name] to the input #value', () => {
36
+ const types = ['number', 'undefined']
37
+ setAttribute({ cloudevent, name, types, value })
38
+ expect(cloudevent[name]).to.eq(value)
39
+ })
40
+ })
41
+ })
42
+ })
43
+ })