@bsv/overlay 0.1.13 → 0.1.15
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/cjs/package.json +1 -1
- package/dist/cjs/src/Engine.js +51 -5
- package/dist/cjs/src/Engine.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/Engine.js +51 -5
- package/dist/esm/src/Engine.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/Engine.d.ts +11 -0
- package/dist/types/src/Engine.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/Engine.ts +58 -6
- package/src/__tests/Engine.test.ts +95 -1
|
@@ -7,6 +7,8 @@ import { Storage } from '../storage/Storage'
|
|
|
7
7
|
import { Transaction, Utils } from '@bsv/sdk'
|
|
8
8
|
import { Output } from '../Output'
|
|
9
9
|
import { SyncConfiguration } from '../SyncConfiguration'
|
|
10
|
+
import { TaggedBEEF } from '../TaggedBEEF.js'
|
|
11
|
+
import { Advertiser } from '../Advertiser.js'
|
|
10
12
|
|
|
11
13
|
const mockChainTracker = {
|
|
12
14
|
isValidRootForHeight: jest.fn(async () => true)
|
|
@@ -24,13 +26,37 @@ const mockOutput: Output = {
|
|
|
24
26
|
outputIndex: 0,
|
|
25
27
|
outputScript: exampleTX.outputs[0].lockingScript.toBinary(),
|
|
26
28
|
topic: 'hello',
|
|
27
|
-
satoshis: exampleTX.outputs[0].satoshis,
|
|
29
|
+
satoshis: exampleTX.outputs[0].satoshis as number,
|
|
28
30
|
beef: exampleBeef,
|
|
29
31
|
spent: false,
|
|
30
32
|
outputsConsumed: [],
|
|
31
33
|
consumedBy: []
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
const invalidHostingUrls = [
|
|
37
|
+
"http://example.com", // Invalid: http
|
|
38
|
+
"https://localhost:3000", // Invalid: localhost
|
|
39
|
+
"https://192.168.1.1", // Invalid: internal private IP
|
|
40
|
+
"https://127.0.0.1", // Invalid: loopback IP
|
|
41
|
+
"https://0.0.0.0", // Invalid: non-routable IP
|
|
42
|
+
"http://172.16.0.1", // Invalid: private IP
|
|
43
|
+
"[::1]"
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
const validHostingUrls = [
|
|
48
|
+
"https://example.com", // Valid: public URL
|
|
49
|
+
"https://8.8.8.8", // Valid: public routable IP
|
|
50
|
+
"https://255.255.255.255", // Valid: public routable IP
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
const mockAdvertiser: Advertiser = {
|
|
54
|
+
createAdvertisements: jest.fn(async (): Promise<TaggedBEEF> => ({ beef: [0, 1, 2], topics: [] })),
|
|
55
|
+
revokeAdvertisements: jest.fn(async (): Promise<TaggedBEEF> => ({ beef: [0, 1, 2], topics: [] })),
|
|
56
|
+
findAllAdvertisements: jest.fn(async () => []),
|
|
57
|
+
parseAdvertisement: jest.fn()
|
|
58
|
+
}
|
|
59
|
+
|
|
34
60
|
describe('BSV Overlay Services Engine', () => {
|
|
35
61
|
beforeEach(() => {
|
|
36
62
|
jest.clearAllMocks()
|
|
@@ -66,6 +92,74 @@ describe('BSV Overlay Services Engine', () => {
|
|
|
66
92
|
findUTXOsForTopic: jest.fn()
|
|
67
93
|
}
|
|
68
94
|
})
|
|
95
|
+
|
|
96
|
+
it('engine.syncAdvertisements should return void when invalid hostingURL is provided', async () => {
|
|
97
|
+
for (const url of invalidHostingUrls) {
|
|
98
|
+
const engine = new Engine(
|
|
99
|
+
{ tm_helloworld: mockTopicManager },
|
|
100
|
+
{ ls_helloworld: mockLookupService },
|
|
101
|
+
mockStorageEngine,
|
|
102
|
+
mockChainTracker,
|
|
103
|
+
url, // Invalid hostingURL
|
|
104
|
+
['tracker1'], // shipTrackers
|
|
105
|
+
['tracker2'], // slapTrackers
|
|
106
|
+
undefined,
|
|
107
|
+
mockAdvertiser,
|
|
108
|
+
undefined
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
engine.submit = jest.fn(async (taggedBEEF: TaggedBEEF, onSteakReady: any, mode?: string) => ({ outputsToAdmit: [] }))
|
|
112
|
+
|
|
113
|
+
// Call the method that would normally trigger syncAdvertisements
|
|
114
|
+
const result = await engine.syncAdvertisements()
|
|
115
|
+
|
|
116
|
+
expect(result).toBeUndefined()
|
|
117
|
+
|
|
118
|
+
// Verify that Advertiser methods are NOT called
|
|
119
|
+
expect(mockAdvertiser.createAdvertisements).not.toHaveBeenCalled()
|
|
120
|
+
expect(mockAdvertiser.findAllAdvertisements).not.toHaveBeenCalledWith('SHIP') // Assuming 'SHIP' is expected
|
|
121
|
+
|
|
122
|
+
console.log('Got past', url)
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
it('should allow engine.syncAdvertisements to proceed with valid hostingURLs', async () => {
|
|
127
|
+
const mockAdvertiser: Advertiser = {
|
|
128
|
+
createAdvertisements: jest.fn().mockResolvedValue({ tag: 'MOCK_TAG', data: Buffer.from('mock data') }),
|
|
129
|
+
findAllAdvertisements: jest.fn().mockResolvedValue([]),
|
|
130
|
+
revokeAdvertisements: jest.fn().mockResolvedValue({ tag: 'MOCK_REVOKE_TAG', data: Buffer.from('revocation data') }),
|
|
131
|
+
parseAdvertisement: jest.fn().mockReturnValue({
|
|
132
|
+
protocol: 'SHIP',
|
|
133
|
+
topicOrServiceName: 'mock-topic',
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
}),
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
for (const url of validHostingUrls) {
|
|
139
|
+
const engine = new Engine(
|
|
140
|
+
{ tm_helloworld: mockTopicManager },
|
|
141
|
+
{ ls_helloworld: mockLookupService },
|
|
142
|
+
mockStorageEngine,
|
|
143
|
+
mockChainTracker,
|
|
144
|
+
url, // Valid hostingURL
|
|
145
|
+
['tracker1'], // shipTrackers
|
|
146
|
+
['tracker2'], // slapTrackers
|
|
147
|
+
undefined,
|
|
148
|
+
mockAdvertiser, // Pass the mock Advertiser
|
|
149
|
+
undefined
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
// Call the method that would normally trigger syncAdvertisements
|
|
153
|
+
engine.submit = jest.fn(async (taggedBEEF: TaggedBEEF, onSteakReady: any, mode?: string) => ({ outputsToAdmit: [] }))
|
|
154
|
+
const result = await engine.syncAdvertisements()
|
|
155
|
+
expect(engine.submit).toHaveBeenCalled()
|
|
156
|
+
|
|
157
|
+
// Verify that Advertiser methods are called
|
|
158
|
+
expect(mockAdvertiser.createAdvertisements).toHaveBeenCalled()
|
|
159
|
+
expect(mockAdvertiser.findAllAdvertisements).toHaveBeenCalledWith('SHIP') // Assuming 'SHIP' is expected
|
|
160
|
+
}
|
|
161
|
+
})
|
|
162
|
+
|
|
69
163
|
it('Uses SHIP sync configuration by default if no syncConfiguration was provided', () => {
|
|
70
164
|
const engine = new Engine(
|
|
71
165
|
{ tm_helloworld: mockTopicManager },
|