@signaltree/events 7.3.6 → 7.4.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.
- package/dist/angular/handlers.cjs +38 -0
- package/dist/angular/handlers.js +35 -0
- package/dist/angular/index.cjs +15 -0
- package/dist/angular/index.js +3 -0
- package/dist/angular/optimistic-updates.cjs +161 -0
- package/dist/angular/optimistic-updates.js +159 -0
- package/{angular.cjs.js → dist/angular/websocket.service.cjs} +0 -194
- package/{angular.esm.js → dist/angular/websocket.service.js} +1 -191
- package/dist/core/error-classification.cjs +282 -0
- package/dist/core/error-classification.js +276 -0
- package/{factory.cjs.js → dist/core/factory.cjs} +3 -40
- package/{factory.esm.js → dist/core/factory.js} +2 -37
- package/dist/core/idempotency.cjs +252 -0
- package/dist/core/idempotency.js +247 -0
- package/dist/core/registry.cjs +183 -0
- package/dist/core/registry.js +180 -0
- package/dist/core/types.cjs +41 -0
- package/dist/core/types.js +38 -0
- package/{index.cjs.js → dist/core/validation.cjs} +1 -23
- package/{index.esm.js → dist/core/validation.js} +1 -4
- package/dist/index.cjs +43 -0
- package/dist/index.js +7 -0
- package/dist/nestjs/base.subscriber.cjs +287 -0
- package/dist/nestjs/base.subscriber.js +287 -0
- package/dist/nestjs/decorators.cjs +35 -0
- package/dist/nestjs/decorators.js +32 -0
- package/dist/nestjs/dlq.service.cjs +249 -0
- package/dist/nestjs/dlq.service.js +249 -0
- package/dist/nestjs/event-bus.module.cjs +152 -0
- package/dist/nestjs/event-bus.module.js +152 -0
- package/dist/nestjs/event-bus.service.cjs +243 -0
- package/dist/nestjs/event-bus.service.js +243 -0
- package/dist/nestjs/index.cjs +33 -0
- package/dist/nestjs/index.js +6 -0
- package/dist/nestjs/tokens.cjs +14 -0
- package/dist/nestjs/tokens.js +9 -0
- package/dist/testing/assertions.cjs +172 -0
- package/dist/testing/assertions.js +169 -0
- package/dist/testing/factories.cjs +122 -0
- package/dist/testing/factories.js +119 -0
- package/dist/testing/helpers.cjs +233 -0
- package/dist/testing/helpers.js +227 -0
- package/dist/testing/index.cjs +20 -0
- package/dist/testing/index.js +4 -0
- package/dist/testing/mock-event-bus.cjs +237 -0
- package/dist/testing/mock-event-bus.js +234 -0
- package/package.json +35 -23
- package/angular.d.ts +0 -1
- package/idempotency.cjs.js +0 -713
- package/idempotency.esm.js +0 -701
- package/index.d.ts +0 -1
- package/nestjs.cjs.js +0 -951
- package/nestjs.d.ts +0 -1
- package/nestjs.esm.js +0 -944
- package/testing.cjs.js +0 -755
- package/testing.d.ts +0 -1
- package/testing.esm.js +0 -743
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Event assertions class
|
|
5
|
+
*/
|
|
6
|
+
class EventAssertions {
|
|
7
|
+
publishedEvents;
|
|
8
|
+
constructor(events) {
|
|
9
|
+
this.publishedEvents = events;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Assert that an event was published
|
|
13
|
+
*/
|
|
14
|
+
toHavePublished(eventType) {
|
|
15
|
+
const found = this.publishedEvents.some(p => p.event.type === eventType);
|
|
16
|
+
return {
|
|
17
|
+
passed: found,
|
|
18
|
+
message: found ? `Event "${eventType}" was published` : `Expected event "${eventType}" to be published, but it was not`,
|
|
19
|
+
expected: eventType,
|
|
20
|
+
actual: this.publishedEvents.map(p => p.event.type)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Assert that an event was NOT published
|
|
25
|
+
*/
|
|
26
|
+
toNotHavePublished(eventType) {
|
|
27
|
+
const found = this.publishedEvents.some(p => p.event.type === eventType);
|
|
28
|
+
return {
|
|
29
|
+
passed: !found,
|
|
30
|
+
message: !found ? `Event "${eventType}" was not published` : `Expected event "${eventType}" to NOT be published, but it was`,
|
|
31
|
+
expected: `NOT ${eventType}`,
|
|
32
|
+
actual: this.publishedEvents.map(p => p.event.type)
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Assert the number of published events
|
|
37
|
+
*/
|
|
38
|
+
toHavePublishedCount(count, eventType) {
|
|
39
|
+
const events = eventType ? this.publishedEvents.filter(p => p.event.type === eventType) : this.publishedEvents;
|
|
40
|
+
const actual = events.length;
|
|
41
|
+
const passed = actual === count;
|
|
42
|
+
return {
|
|
43
|
+
passed,
|
|
44
|
+
message: passed ? `Published ${count} events${eventType ? ` of type "${eventType}"` : ''}` : `Expected ${count} events${eventType ? ` of type "${eventType}"` : ''}, got ${actual}`,
|
|
45
|
+
expected: count,
|
|
46
|
+
actual
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Assert event was published with specific data
|
|
51
|
+
*/
|
|
52
|
+
toHavePublishedWith(eventType, predicate) {
|
|
53
|
+
const matching = this.publishedEvents.find(p => p.event.type === eventType && predicate(p.event));
|
|
54
|
+
return {
|
|
55
|
+
passed: !!matching,
|
|
56
|
+
message: matching ? `Found event "${eventType}" matching predicate` : `Expected to find event "${eventType}" matching predicate`,
|
|
57
|
+
expected: eventType,
|
|
58
|
+
actual: matching?.event
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Assert events were published in order
|
|
63
|
+
*/
|
|
64
|
+
toHavePublishedInOrder(eventTypes) {
|
|
65
|
+
const publishedTypes = this.publishedEvents.map(p => p.event.type);
|
|
66
|
+
let typeIndex = 0;
|
|
67
|
+
for (const publishedType of publishedTypes) {
|
|
68
|
+
if (publishedType === eventTypes[typeIndex]) {
|
|
69
|
+
typeIndex++;
|
|
70
|
+
if (typeIndex === eventTypes.length) break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const passed = typeIndex === eventTypes.length;
|
|
74
|
+
return {
|
|
75
|
+
passed,
|
|
76
|
+
message: passed ? `Events published in expected order` : `Expected events in order: [${eventTypes.join(', ')}], got: [${publishedTypes.join(', ')}]`,
|
|
77
|
+
expected: eventTypes,
|
|
78
|
+
actual: publishedTypes
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Assert event has valid structure
|
|
83
|
+
*/
|
|
84
|
+
toBeValidEvent(event) {
|
|
85
|
+
const issues = [];
|
|
86
|
+
if (!event.id) issues.push('Missing id');
|
|
87
|
+
if (!event.type) issues.push('Missing type');
|
|
88
|
+
if (!event.timestamp) issues.push('Missing timestamp');
|
|
89
|
+
if (!event.correlationId) issues.push('Missing correlationId');
|
|
90
|
+
if (!event.version) issues.push('Missing version');
|
|
91
|
+
if (!event.actor) issues.push('Missing actor');
|
|
92
|
+
if (!event.metadata) issues.push('Missing metadata');
|
|
93
|
+
if (event.actor) {
|
|
94
|
+
if (!event.actor.id) issues.push('Missing actor.id');
|
|
95
|
+
if (!event.actor.type) issues.push('Missing actor.type');
|
|
96
|
+
}
|
|
97
|
+
if (event.metadata) {
|
|
98
|
+
if (!event.metadata.source) issues.push('Missing metadata.source');
|
|
99
|
+
}
|
|
100
|
+
const passed = issues.length === 0;
|
|
101
|
+
return {
|
|
102
|
+
passed,
|
|
103
|
+
message: passed ? 'Event has valid structure' : `Event has invalid structure: ${issues.join(', ')}`,
|
|
104
|
+
expected: 'Valid event structure',
|
|
105
|
+
actual: issues
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Assert all events have same correlation ID
|
|
110
|
+
*/
|
|
111
|
+
toHaveSameCorrelationId() {
|
|
112
|
+
if (this.publishedEvents.length === 0) {
|
|
113
|
+
return {
|
|
114
|
+
passed: true,
|
|
115
|
+
message: 'No events to check'
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
const correlationId = this.publishedEvents[0].event.correlationId;
|
|
119
|
+
const allMatch = this.publishedEvents.every(p => p.event.correlationId === correlationId);
|
|
120
|
+
return {
|
|
121
|
+
passed: allMatch,
|
|
122
|
+
message: allMatch ? `All events have correlation ID: ${correlationId}` : 'Events have different correlation IDs',
|
|
123
|
+
expected: correlationId,
|
|
124
|
+
actual: this.publishedEvents.map(p => p.event.correlationId)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Assert event was published to specific queue
|
|
129
|
+
*/
|
|
130
|
+
toHavePublishedToQueue(eventType, queue) {
|
|
131
|
+
const matching = this.publishedEvents.find(p => p.event.type === eventType && p.queue === queue);
|
|
132
|
+
return {
|
|
133
|
+
passed: !!matching,
|
|
134
|
+
message: matching ? `Event "${eventType}" was published to queue "${queue}"` : `Expected event "${eventType}" to be published to queue "${queue}"`,
|
|
135
|
+
expected: {
|
|
136
|
+
eventType,
|
|
137
|
+
queue
|
|
138
|
+
},
|
|
139
|
+
actual: this.publishedEvents.filter(p => p.event.type === eventType).map(p => ({
|
|
140
|
+
type: p.event.type,
|
|
141
|
+
queue: p.queue
|
|
142
|
+
}))
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get all assertions as an array
|
|
147
|
+
*/
|
|
148
|
+
getAllResults() {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create event assertions helper
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const eventBus = createMockEventBus();
|
|
158
|
+
* // ... publish events ...
|
|
159
|
+
*
|
|
160
|
+
* const assertions = createEventAssertions(eventBus.getPublishedEvents());
|
|
161
|
+
*
|
|
162
|
+
* expect(assertions.toHavePublished('TradeCreated').passed).toBe(true);
|
|
163
|
+
* expect(assertions.toHavePublishedCount(3).passed).toBe(true);
|
|
164
|
+
* expect(assertions.toHavePublishedInOrder(['TradeCreated', 'TradeAccepted']).passed).toBe(true);
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
function createEventAssertions(events) {
|
|
168
|
+
return new EventAssertions(events);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
exports.EventAssertions = EventAssertions;
|
|
172
|
+
exports.createEventAssertions = createEventAssertions;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event assertions class
|
|
3
|
+
*/
|
|
4
|
+
class EventAssertions {
|
|
5
|
+
publishedEvents;
|
|
6
|
+
constructor(events) {
|
|
7
|
+
this.publishedEvents = events;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Assert that an event was published
|
|
11
|
+
*/
|
|
12
|
+
toHavePublished(eventType) {
|
|
13
|
+
const found = this.publishedEvents.some(p => p.event.type === eventType);
|
|
14
|
+
return {
|
|
15
|
+
passed: found,
|
|
16
|
+
message: found ? `Event "${eventType}" was published` : `Expected event "${eventType}" to be published, but it was not`,
|
|
17
|
+
expected: eventType,
|
|
18
|
+
actual: this.publishedEvents.map(p => p.event.type)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Assert that an event was NOT published
|
|
23
|
+
*/
|
|
24
|
+
toNotHavePublished(eventType) {
|
|
25
|
+
const found = this.publishedEvents.some(p => p.event.type === eventType);
|
|
26
|
+
return {
|
|
27
|
+
passed: !found,
|
|
28
|
+
message: !found ? `Event "${eventType}" was not published` : `Expected event "${eventType}" to NOT be published, but it was`,
|
|
29
|
+
expected: `NOT ${eventType}`,
|
|
30
|
+
actual: this.publishedEvents.map(p => p.event.type)
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Assert the number of published events
|
|
35
|
+
*/
|
|
36
|
+
toHavePublishedCount(count, eventType) {
|
|
37
|
+
const events = eventType ? this.publishedEvents.filter(p => p.event.type === eventType) : this.publishedEvents;
|
|
38
|
+
const actual = events.length;
|
|
39
|
+
const passed = actual === count;
|
|
40
|
+
return {
|
|
41
|
+
passed,
|
|
42
|
+
message: passed ? `Published ${count} events${eventType ? ` of type "${eventType}"` : ''}` : `Expected ${count} events${eventType ? ` of type "${eventType}"` : ''}, got ${actual}`,
|
|
43
|
+
expected: count,
|
|
44
|
+
actual
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Assert event was published with specific data
|
|
49
|
+
*/
|
|
50
|
+
toHavePublishedWith(eventType, predicate) {
|
|
51
|
+
const matching = this.publishedEvents.find(p => p.event.type === eventType && predicate(p.event));
|
|
52
|
+
return {
|
|
53
|
+
passed: !!matching,
|
|
54
|
+
message: matching ? `Found event "${eventType}" matching predicate` : `Expected to find event "${eventType}" matching predicate`,
|
|
55
|
+
expected: eventType,
|
|
56
|
+
actual: matching?.event
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Assert events were published in order
|
|
61
|
+
*/
|
|
62
|
+
toHavePublishedInOrder(eventTypes) {
|
|
63
|
+
const publishedTypes = this.publishedEvents.map(p => p.event.type);
|
|
64
|
+
let typeIndex = 0;
|
|
65
|
+
for (const publishedType of publishedTypes) {
|
|
66
|
+
if (publishedType === eventTypes[typeIndex]) {
|
|
67
|
+
typeIndex++;
|
|
68
|
+
if (typeIndex === eventTypes.length) break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const passed = typeIndex === eventTypes.length;
|
|
72
|
+
return {
|
|
73
|
+
passed,
|
|
74
|
+
message: passed ? `Events published in expected order` : `Expected events in order: [${eventTypes.join(', ')}], got: [${publishedTypes.join(', ')}]`,
|
|
75
|
+
expected: eventTypes,
|
|
76
|
+
actual: publishedTypes
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Assert event has valid structure
|
|
81
|
+
*/
|
|
82
|
+
toBeValidEvent(event) {
|
|
83
|
+
const issues = [];
|
|
84
|
+
if (!event.id) issues.push('Missing id');
|
|
85
|
+
if (!event.type) issues.push('Missing type');
|
|
86
|
+
if (!event.timestamp) issues.push('Missing timestamp');
|
|
87
|
+
if (!event.correlationId) issues.push('Missing correlationId');
|
|
88
|
+
if (!event.version) issues.push('Missing version');
|
|
89
|
+
if (!event.actor) issues.push('Missing actor');
|
|
90
|
+
if (!event.metadata) issues.push('Missing metadata');
|
|
91
|
+
if (event.actor) {
|
|
92
|
+
if (!event.actor.id) issues.push('Missing actor.id');
|
|
93
|
+
if (!event.actor.type) issues.push('Missing actor.type');
|
|
94
|
+
}
|
|
95
|
+
if (event.metadata) {
|
|
96
|
+
if (!event.metadata.source) issues.push('Missing metadata.source');
|
|
97
|
+
}
|
|
98
|
+
const passed = issues.length === 0;
|
|
99
|
+
return {
|
|
100
|
+
passed,
|
|
101
|
+
message: passed ? 'Event has valid structure' : `Event has invalid structure: ${issues.join(', ')}`,
|
|
102
|
+
expected: 'Valid event structure',
|
|
103
|
+
actual: issues
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Assert all events have same correlation ID
|
|
108
|
+
*/
|
|
109
|
+
toHaveSameCorrelationId() {
|
|
110
|
+
if (this.publishedEvents.length === 0) {
|
|
111
|
+
return {
|
|
112
|
+
passed: true,
|
|
113
|
+
message: 'No events to check'
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
const correlationId = this.publishedEvents[0].event.correlationId;
|
|
117
|
+
const allMatch = this.publishedEvents.every(p => p.event.correlationId === correlationId);
|
|
118
|
+
return {
|
|
119
|
+
passed: allMatch,
|
|
120
|
+
message: allMatch ? `All events have correlation ID: ${correlationId}` : 'Events have different correlation IDs',
|
|
121
|
+
expected: correlationId,
|
|
122
|
+
actual: this.publishedEvents.map(p => p.event.correlationId)
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Assert event was published to specific queue
|
|
127
|
+
*/
|
|
128
|
+
toHavePublishedToQueue(eventType, queue) {
|
|
129
|
+
const matching = this.publishedEvents.find(p => p.event.type === eventType && p.queue === queue);
|
|
130
|
+
return {
|
|
131
|
+
passed: !!matching,
|
|
132
|
+
message: matching ? `Event "${eventType}" was published to queue "${queue}"` : `Expected event "${eventType}" to be published to queue "${queue}"`,
|
|
133
|
+
expected: {
|
|
134
|
+
eventType,
|
|
135
|
+
queue
|
|
136
|
+
},
|
|
137
|
+
actual: this.publishedEvents.filter(p => p.event.type === eventType).map(p => ({
|
|
138
|
+
type: p.event.type,
|
|
139
|
+
queue: p.queue
|
|
140
|
+
}))
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Get all assertions as an array
|
|
145
|
+
*/
|
|
146
|
+
getAllResults() {
|
|
147
|
+
return [];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create event assertions helper
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* ```typescript
|
|
155
|
+
* const eventBus = createMockEventBus();
|
|
156
|
+
* // ... publish events ...
|
|
157
|
+
*
|
|
158
|
+
* const assertions = createEventAssertions(eventBus.getPublishedEvents());
|
|
159
|
+
*
|
|
160
|
+
* expect(assertions.toHavePublished('TradeCreated').passed).toBe(true);
|
|
161
|
+
* expect(assertions.toHavePublishedCount(3).passed).toBe(true);
|
|
162
|
+
* expect(assertions.toHavePublishedInOrder(['TradeCreated', 'TradeAccepted']).passed).toBe(true);
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
function createEventAssertions(events) {
|
|
166
|
+
return new EventAssertions(events);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export { EventAssertions, createEventAssertions };
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var factory = require('../core/factory.cjs');
|
|
4
|
+
var types = require('../core/types.cjs');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Default test actor
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_TEST_ACTOR = {
|
|
10
|
+
id: 'test-user-1',
|
|
11
|
+
type: 'user',
|
|
12
|
+
name: 'Test User'
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Default test metadata
|
|
16
|
+
*/
|
|
17
|
+
const DEFAULT_TEST_METADATA = {
|
|
18
|
+
source: 'test',
|
|
19
|
+
environment: 'test'
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Create a test event
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const event = createTestEvent('TradeProposalCreated', {
|
|
27
|
+
* tradeId: '123',
|
|
28
|
+
* initiatorId: 'user-1',
|
|
29
|
+
* recipientId: 'user-2',
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
function createTestEvent(type, data, options = {}) {
|
|
34
|
+
return {
|
|
35
|
+
id: options.id ?? factory.generateEventId(),
|
|
36
|
+
type,
|
|
37
|
+
version: options.version ?? types.DEFAULT_EVENT_VERSION,
|
|
38
|
+
timestamp: options.timestamp ?? new Date().toISOString(),
|
|
39
|
+
correlationId: options.correlationId ?? factory.generateCorrelationId(),
|
|
40
|
+
causationId: options.causationId,
|
|
41
|
+
actor: {
|
|
42
|
+
...DEFAULT_TEST_ACTOR,
|
|
43
|
+
...options.actor
|
|
44
|
+
},
|
|
45
|
+
metadata: {
|
|
46
|
+
...DEFAULT_TEST_METADATA,
|
|
47
|
+
...options.metadata
|
|
48
|
+
},
|
|
49
|
+
data,
|
|
50
|
+
priority: options.priority,
|
|
51
|
+
aggregate: options.aggregate
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Create a test event factory
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* const factory = createTestEventFactory({
|
|
60
|
+
* defaultActor: { id: 'test-user', type: 'user' },
|
|
61
|
+
* defaultMetadata: { source: 'test-service' },
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* const event = factory.create('TradeProposalCreated', {
|
|
65
|
+
* tradeId: '123',
|
|
66
|
+
* });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
function createTestEventFactory(config) {
|
|
70
|
+
const defaultActor = {
|
|
71
|
+
...DEFAULT_TEST_ACTOR,
|
|
72
|
+
...config?.defaultActor
|
|
73
|
+
};
|
|
74
|
+
const defaultMetadata = {
|
|
75
|
+
...DEFAULT_TEST_METADATA,
|
|
76
|
+
...config?.defaultMetadata
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
create(type, data, options = {}) {
|
|
80
|
+
return {
|
|
81
|
+
id: options.id ?? factory.generateEventId(),
|
|
82
|
+
type,
|
|
83
|
+
version: options.version ?? types.DEFAULT_EVENT_VERSION,
|
|
84
|
+
timestamp: options.timestamp ?? new Date().toISOString(),
|
|
85
|
+
correlationId: options.correlationId ?? factory.generateCorrelationId(),
|
|
86
|
+
causationId: options.causationId,
|
|
87
|
+
actor: {
|
|
88
|
+
...defaultActor,
|
|
89
|
+
...options.actor
|
|
90
|
+
},
|
|
91
|
+
metadata: {
|
|
92
|
+
...defaultMetadata,
|
|
93
|
+
...options.metadata
|
|
94
|
+
},
|
|
95
|
+
data,
|
|
96
|
+
priority: options.priority,
|
|
97
|
+
aggregate: options.aggregate
|
|
98
|
+
};
|
|
99
|
+
},
|
|
100
|
+
createMany(type, dataArray, options = {}) {
|
|
101
|
+
const correlationId = options.correlationId ?? factory.generateCorrelationId();
|
|
102
|
+
return dataArray.map((data, index) => this.create(type, data, {
|
|
103
|
+
...options,
|
|
104
|
+
correlationId,
|
|
105
|
+
causationId: index > 0 ? undefined : options.causationId
|
|
106
|
+
}));
|
|
107
|
+
},
|
|
108
|
+
createRandom(type, overrides = {}, options = {}) {
|
|
109
|
+
// Get random generator for this type if available
|
|
110
|
+
const generator = config?.randomGenerators?.[type];
|
|
111
|
+
const randomData = generator ? generator() : {};
|
|
112
|
+
const overrideData = overrides ? overrides : {};
|
|
113
|
+
return this.create(type, {
|
|
114
|
+
...randomData,
|
|
115
|
+
...overrideData
|
|
116
|
+
}, options);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
exports.createTestEvent = createTestEvent;
|
|
122
|
+
exports.createTestEventFactory = createTestEventFactory;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { generateCorrelationId, generateEventId } from '../core/factory.js';
|
|
2
|
+
import { DEFAULT_EVENT_VERSION } from '../core/types.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Default test actor
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_TEST_ACTOR = {
|
|
8
|
+
id: 'test-user-1',
|
|
9
|
+
type: 'user',
|
|
10
|
+
name: 'Test User'
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Default test metadata
|
|
14
|
+
*/
|
|
15
|
+
const DEFAULT_TEST_METADATA = {
|
|
16
|
+
source: 'test',
|
|
17
|
+
environment: 'test'
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Create a test event
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* const event = createTestEvent('TradeProposalCreated', {
|
|
25
|
+
* tradeId: '123',
|
|
26
|
+
* initiatorId: 'user-1',
|
|
27
|
+
* recipientId: 'user-2',
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
function createTestEvent(type, data, options = {}) {
|
|
32
|
+
return {
|
|
33
|
+
id: options.id ?? generateEventId(),
|
|
34
|
+
type,
|
|
35
|
+
version: options.version ?? DEFAULT_EVENT_VERSION,
|
|
36
|
+
timestamp: options.timestamp ?? new Date().toISOString(),
|
|
37
|
+
correlationId: options.correlationId ?? generateCorrelationId(),
|
|
38
|
+
causationId: options.causationId,
|
|
39
|
+
actor: {
|
|
40
|
+
...DEFAULT_TEST_ACTOR,
|
|
41
|
+
...options.actor
|
|
42
|
+
},
|
|
43
|
+
metadata: {
|
|
44
|
+
...DEFAULT_TEST_METADATA,
|
|
45
|
+
...options.metadata
|
|
46
|
+
},
|
|
47
|
+
data,
|
|
48
|
+
priority: options.priority,
|
|
49
|
+
aggregate: options.aggregate
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Create a test event factory
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const factory = createTestEventFactory({
|
|
58
|
+
* defaultActor: { id: 'test-user', type: 'user' },
|
|
59
|
+
* defaultMetadata: { source: 'test-service' },
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* const event = factory.create('TradeProposalCreated', {
|
|
63
|
+
* tradeId: '123',
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
function createTestEventFactory(config) {
|
|
68
|
+
const defaultActor = {
|
|
69
|
+
...DEFAULT_TEST_ACTOR,
|
|
70
|
+
...config?.defaultActor
|
|
71
|
+
};
|
|
72
|
+
const defaultMetadata = {
|
|
73
|
+
...DEFAULT_TEST_METADATA,
|
|
74
|
+
...config?.defaultMetadata
|
|
75
|
+
};
|
|
76
|
+
return {
|
|
77
|
+
create(type, data, options = {}) {
|
|
78
|
+
return {
|
|
79
|
+
id: options.id ?? generateEventId(),
|
|
80
|
+
type,
|
|
81
|
+
version: options.version ?? DEFAULT_EVENT_VERSION,
|
|
82
|
+
timestamp: options.timestamp ?? new Date().toISOString(),
|
|
83
|
+
correlationId: options.correlationId ?? generateCorrelationId(),
|
|
84
|
+
causationId: options.causationId,
|
|
85
|
+
actor: {
|
|
86
|
+
...defaultActor,
|
|
87
|
+
...options.actor
|
|
88
|
+
},
|
|
89
|
+
metadata: {
|
|
90
|
+
...defaultMetadata,
|
|
91
|
+
...options.metadata
|
|
92
|
+
},
|
|
93
|
+
data,
|
|
94
|
+
priority: options.priority,
|
|
95
|
+
aggregate: options.aggregate
|
|
96
|
+
};
|
|
97
|
+
},
|
|
98
|
+
createMany(type, dataArray, options = {}) {
|
|
99
|
+
const correlationId = options.correlationId ?? generateCorrelationId();
|
|
100
|
+
return dataArray.map((data, index) => this.create(type, data, {
|
|
101
|
+
...options,
|
|
102
|
+
correlationId,
|
|
103
|
+
causationId: index > 0 ? undefined : options.causationId
|
|
104
|
+
}));
|
|
105
|
+
},
|
|
106
|
+
createRandom(type, overrides = {}, options = {}) {
|
|
107
|
+
// Get random generator for this type if available
|
|
108
|
+
const generator = config?.randomGenerators?.[type];
|
|
109
|
+
const randomData = generator ? generator() : {};
|
|
110
|
+
const overrideData = overrides ? overrides : {};
|
|
111
|
+
return this.create(type, {
|
|
112
|
+
...randomData,
|
|
113
|
+
...overrideData
|
|
114
|
+
}, options);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { createTestEvent, createTestEventFactory };
|