@rosen-bridge/abstract-extractor 2.1.0 → 2.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.
Files changed (127) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/package.json +14 -7
  3. package/.eslintignore +0 -1
  4. package/dist/lib/abstractExtractor.d.ts +0 -25
  5. package/dist/lib/abstractExtractor.d.ts.map +0 -1
  6. package/dist/lib/abstractExtractor.js +0 -3
  7. package/dist/lib/constants.d.ts +0 -4
  8. package/dist/lib/constants.d.ts.map +0 -1
  9. package/dist/lib/constants.js +0 -4
  10. package/dist/lib/ergo/AbstractErgoExtractor.d.ts +0 -80
  11. package/dist/lib/ergo/AbstractErgoExtractor.d.ts.map +0 -1
  12. package/dist/lib/ergo/AbstractErgoExtractor.js +0 -142
  13. package/dist/lib/ergo/AbstractErgoExtractorAction.d.ts +0 -92
  14. package/dist/lib/ergo/AbstractErgoExtractorAction.d.ts.map +0 -1
  15. package/dist/lib/ergo/AbstractErgoExtractorAction.js +0 -222
  16. package/dist/lib/ergo/AbstractErgoExtractorEntity.d.ts +0 -11
  17. package/dist/lib/ergo/AbstractErgoExtractorEntity.d.ts.map +0 -1
  18. package/dist/lib/ergo/AbstractErgoExtractorEntity.js +0 -57
  19. package/dist/lib/ergo/index.d.ts +0 -10
  20. package/dist/lib/ergo/index.d.ts.map +0 -1
  21. package/dist/lib/ergo/index.js +0 -10
  22. package/dist/lib/ergo/initializable/AbstractInitializable.d.ts +0 -48
  23. package/dist/lib/ergo/initializable/AbstractInitializable.d.ts.map +0 -1
  24. package/dist/lib/ergo/initializable/AbstractInitializable.js +0 -163
  25. package/dist/lib/ergo/initializable/AbstractInitializableAction.d.ts +0 -14
  26. package/dist/lib/ergo/initializable/AbstractInitializableAction.d.ts.map +0 -1
  27. package/dist/lib/ergo/initializable/AbstractInitializableAction.js +0 -16
  28. package/dist/lib/ergo/initializable/index.d.ts +0 -3
  29. package/dist/lib/ergo/initializable/index.d.ts.map +0 -1
  30. package/dist/lib/ergo/initializable/index.js +0 -3
  31. package/dist/lib/ergo/interfaces.d.ts +0 -47
  32. package/dist/lib/ergo/interfaces.d.ts.map +0 -1
  33. package/dist/lib/ergo/interfaces.js +0 -8
  34. package/dist/lib/ergo/network/AbstractNetwork.d.ts +0 -26
  35. package/dist/lib/ergo/network/AbstractNetwork.d.ts.map +0 -1
  36. package/dist/lib/ergo/network/AbstractNetwork.js +0 -3
  37. package/dist/lib/ergo/network/ExplorerNetwork.d.ts +0 -74
  38. package/dist/lib/ergo/network/ExplorerNetwork.d.ts.map +0 -1
  39. package/dist/lib/ergo/network/ExplorerNetwork.js +0 -185
  40. package/dist/lib/ergo/network/NodeNetwork.d.ts +0 -60
  41. package/dist/lib/ergo/network/NodeNetwork.d.ts.map +0 -1
  42. package/dist/lib/ergo/network/NodeNetwork.js +0 -131
  43. package/dist/lib/ergo/utils.d.ts +0 -8
  44. package/dist/lib/ergo/utils.d.ts.map +0 -1
  45. package/dist/lib/ergo/utils.js +0 -16
  46. package/dist/lib/index.d.ts +0 -4
  47. package/dist/lib/index.d.ts.map +0 -1
  48. package/dist/lib/index.js +0 -4
  49. package/dist/tests/AbstractErgoExtractor.mock.d.ts +0 -11
  50. package/dist/tests/AbstractErgoExtractor.mock.d.ts.map +0 -1
  51. package/dist/tests/AbstractErgoExtractor.mock.js +0 -11
  52. package/dist/tests/AbstractErgoExtractor.spec.d.ts +0 -2
  53. package/dist/tests/AbstractErgoExtractor.spec.d.ts.map +0 -1
  54. package/dist/tests/AbstractErgoExtractor.spec.js +0 -240
  55. package/dist/tests/AbstractErgoExtractorAction.mock.d.ts +0 -15
  56. package/dist/tests/AbstractErgoExtractorAction.mock.d.ts.map +0 -1
  57. package/dist/tests/AbstractErgoExtractorAction.mock.js +0 -27
  58. package/dist/tests/AbstractErgoExtractorAction.spec.d.ts +0 -2
  59. package/dist/tests/AbstractErgoExtractorAction.spec.d.ts.map +0 -1
  60. package/dist/tests/AbstractErgoExtractorAction.spec.js +0 -221
  61. package/dist/tests/initializable/AbstractInitializable.mock.d.ts +0 -61
  62. package/dist/tests/initializable/AbstractInitializable.mock.d.ts.map +0 -1
  63. package/dist/tests/initializable/AbstractInitializable.mock.js +0 -18
  64. package/dist/tests/initializable/AbstractInitializable.spec.d.ts +0 -2
  65. package/dist/tests/initializable/AbstractInitializable.spec.d.ts.map +0 -1
  66. package/dist/tests/initializable/AbstractInitializable.spec.js +0 -299
  67. package/dist/tests/initializable/AbstractInitializableAction.mock.d.ts +0 -15
  68. package/dist/tests/initializable/AbstractInitializableAction.mock.d.ts.map +0 -1
  69. package/dist/tests/initializable/AbstractInitializableAction.mock.js +0 -27
  70. package/dist/tests/initializable/AbstractInitializableAction.spec.d.ts +0 -2
  71. package/dist/tests/initializable/AbstractInitializableAction.spec.d.ts.map +0 -1
  72. package/dist/tests/initializable/AbstractInitializableAction.spec.js +0 -54
  73. package/dist/tests/initializable/testData.d.ts +0 -94
  74. package/dist/tests/initializable/testData.d.ts.map +0 -1
  75. package/dist/tests/initializable/testData.js +0 -235
  76. package/dist/tests/network/ExplorerNetwork.spec.d.ts +0 -2
  77. package/dist/tests/network/ExplorerNetwork.spec.d.ts.map +0 -1
  78. package/dist/tests/network/ExplorerNetwork.spec.js +0 -61
  79. package/dist/tests/network/NodeNetwork.spec.d.ts +0 -2
  80. package/dist/tests/network/NodeNetwork.spec.d.ts.map +0 -1
  81. package/dist/tests/network/NodeNetwork.spec.js +0 -48
  82. package/dist/tests/network/testData.d.ts +0 -752
  83. package/dist/tests/network/testData.d.ts.map +0 -1
  84. package/dist/tests/network/testData.js +0 -1401
  85. package/dist/tests/testData.d.ts +0 -32
  86. package/dist/tests/testData.d.ts.map +0 -1
  87. package/dist/tests/testData.js +0 -121
  88. package/dist/tests/testUtils.d.ts +0 -9
  89. package/dist/tests/testUtils.d.ts.map +0 -1
  90. package/dist/tests/testUtils.js +0 -31
  91. package/dist/tsconfig.tsbuildinfo +0 -1
  92. package/dist/vitest.config.d.ts +0 -3
  93. package/dist/vitest.config.d.ts.map +0 -1
  94. package/dist/vitest.config.js +0 -18
  95. package/lib/abstractExtractor.ts +0 -31
  96. package/lib/constants.ts +0 -3
  97. package/lib/ergo/AbstractErgoExtractor.ts +0 -227
  98. package/lib/ergo/AbstractErgoExtractorAction.ts +0 -319
  99. package/lib/ergo/AbstractErgoExtractorEntity.ts +0 -32
  100. package/lib/ergo/index.ts +0 -9
  101. package/lib/ergo/initializable/AbstractInitializable.ts +0 -228
  102. package/lib/ergo/initializable/AbstractInitializableAction.ts +0 -33
  103. package/lib/ergo/initializable/index.ts +0 -2
  104. package/lib/ergo/interfaces.ts +0 -51
  105. package/lib/ergo/network/AbstractNetwork.ts +0 -29
  106. package/lib/ergo/network/ExplorerNetwork.ts +0 -237
  107. package/lib/ergo/network/NodeNetwork.ts +0 -169
  108. package/lib/ergo/utils.ts +0 -15
  109. package/lib/index.ts +0 -3
  110. package/tests/AbstractErgoExtractor.mock.ts +0 -33
  111. package/tests/AbstractErgoExtractor.spec.ts +0 -284
  112. package/tests/AbstractErgoExtractorAction.mock.ts +0 -45
  113. package/tests/AbstractErgoExtractorAction.spec.ts +0 -268
  114. package/tests/initializable/AbstractInitializable.mock.ts +0 -44
  115. package/tests/initializable/AbstractInitializable.spec.ts +0 -386
  116. package/tests/initializable/AbstractInitializableAction.mock.ts +0 -45
  117. package/tests/initializable/AbstractInitializableAction.spec.ts +0 -64
  118. package/tests/initializable/testData.ts +0 -283
  119. package/tests/network/ExplorerNetwork.spec.ts +0 -73
  120. package/tests/network/NodeNetwork.spec.ts +0 -56
  121. package/tests/network/testData.ts +0 -1708
  122. package/tests/testData.ts +0 -140
  123. package/tests/testUtils.ts +0 -22
  124. package/tsconfig.build.json +0 -9
  125. package/tsconfig.build.tsbuildinfo +0 -1
  126. package/tsconfig.json +0 -9
  127. package/vitest.config.ts +0 -18
@@ -1,169 +0,0 @@
1
- import ergoNodeClientFactory, {
2
- IndexedErgoBox,
3
- IndexedErgoTransaction,
4
- } from '@rosen-clients/ergo-node';
5
- import { BlockInfo } from '@rosen-bridge/scanner-interfaces';
6
-
7
- import { ErgoBox, ExtendedTransaction } from '../interfaces';
8
- import { AbstractNetwork } from './AbstractNetwork';
9
-
10
- export class NodeNetwork extends AbstractNetwork {
11
- private api;
12
-
13
- constructor(url: string) {
14
- super();
15
- this.api = ergoNodeClientFactory(url);
16
- }
17
-
18
- /**
19
- * convert node api boxes to ErgoBox interface
20
- * @param box
21
- * @returns ErgoBox
22
- */
23
- private convertBox = async (box: IndexedErgoBox): Promise<ErgoBox> => {
24
- const tx = await await this.api.getTxById(box.transactionId!);
25
- const spendInfo = box.spentTransactionId
26
- ? await this.getSpendingInfo(box.boxId!, box.spentTransactionId)
27
- : undefined;
28
- return {
29
- transactionId: box.transactionId || '',
30
- index: box.index || 0,
31
- value: box.value || 0n,
32
- ergoTree: box.ergoTree || '',
33
- creationHeight: box.creationHeight || 0,
34
- inclusionHeight: tx.inclusionHeight,
35
- assets: box.assets || [],
36
- additionalRegisters: box.additionalRegisters,
37
- boxId: box.boxId || '',
38
- blockId: tx.blockId,
39
- spentBlockId: spendInfo?.hash,
40
- spentHeight: spendInfo?.height,
41
- spentTransactionId: box.spentTransactionId,
42
- spentIndex: spendInfo?.spendIndex,
43
- };
44
- };
45
-
46
- /**
47
- * convert Node transaction to extractor transaction type
48
- * @param tx
49
- */
50
- private convertTransaction = (
51
- tx: IndexedErgoTransaction,
52
- ): ExtendedTransaction => {
53
- return {
54
- id: tx.id || '',
55
- inclusionHeight: tx.inclusionHeight,
56
- blockId: tx.blockId,
57
- outputs: tx.outputs.map((output) => ({
58
- transactionId: output.transactionId || '',
59
- index: output.index || 0,
60
- value: output.value || 0n,
61
- ergoTree: output.ergoTree || '',
62
- creationHeight: output.creationHeight || 0,
63
- assets: output.assets || [],
64
- additionalRegisters: output.additionalRegisters,
65
- boxId: output.boxId || '',
66
- })),
67
- // TODO: Add input extension local/ergo/rosen-bridge/scanner/-/issues/156
68
- inputs: tx.inputs.map((input) => ({ boxId: input.boxId! })) ?? [],
69
- dataInputs: tx.dataInputs,
70
- };
71
- };
72
-
73
- /**
74
- * return spending information of a specified box by having spendTxId
75
- * @param boxId
76
- * @param spendTxId
77
- */
78
- getSpendingInfo = async (
79
- boxId: string,
80
- spendTxId: string,
81
- ): Promise<BlockInfo & { spendIndex: number }> => {
82
- const tx = await this.api.getTxById(spendTxId);
83
- const spendIndex = tx.inputs?.findIndex((box) => box.boxId == boxId);
84
- if (spendIndex == undefined)
85
- throw Error(
86
- `Impossible behavior, the box [${boxId}] should have been spent in tx [${spendTxId}]`,
87
- );
88
- return {
89
- hash: tx.blockId,
90
- height: tx.inclusionHeight,
91
- spendIndex,
92
- };
93
- };
94
-
95
- /**
96
- * use node api to return related boxes by specified address
97
- * @param address
98
- * @param offset
99
- * @param limit
100
- * @returns related boxes
101
- */
102
- getBoxesByAddress = async (
103
- address: string,
104
- offset: number,
105
- limit: number,
106
- ): Promise<{ boxes: ErgoBox[]; hasNextBatch: boolean }> => {
107
- const boxes = await this.api.getBoxesByAddressUnspent(address, {
108
- offset: offset,
109
- limit: limit,
110
- sortDirection: 'desc',
111
- });
112
- if (!boxes)
113
- throw new Error('Ergo node BoxesByAddress api expected to have items');
114
- const ergoBoxes = await Promise.all(
115
- boxes.map(async (box) => await this.convertBox(box)),
116
- );
117
- return { boxes: ergoBoxes, hasNextBatch: boxes.length > 0 };
118
- };
119
-
120
- /**
121
- * use node api to return related boxes by specified token id
122
- * @param tokenId
123
- * @param offset
124
- * @param limit
125
- * @returns related boxes
126
- */
127
- getBoxesByTokenId = async (
128
- tokenId: string,
129
- offset: number,
130
- limit: number,
131
- ): Promise<{ boxes: ErgoBox[]; hasNextBatch: boolean }> => {
132
- const boxes = await this.api.getBoxesByTokenId(tokenId, {
133
- offset: offset,
134
- limit: limit,
135
- });
136
- if (!boxes.items)
137
- throw new Error('Ergo node BoxesByTokenId api expected to have items');
138
- const ergoBoxes = await Promise.all(
139
- boxes.items.map(async (box) => await this.convertBox(box)),
140
- );
141
- return { boxes: ergoBoxes, hasNextBatch: boxes.items.length > 0 };
142
- };
143
-
144
- /**
145
- * use node api to return related transactions of the specified address with limit offset
146
- * @param tokenId
147
- * @param offset
148
- * @param limit
149
- * @returns related transactions
150
- */
151
- getAddressTransactionsWithOffsetLimit = async (
152
- address: string,
153
- offset: number,
154
- limit: number,
155
- ): Promise<{ items: Array<ExtendedTransaction>; total: number }> => {
156
- const txs = await this.api.getTxsByAddress(address, {
157
- offset,
158
- limit,
159
- });
160
- if (!txs.items)
161
- throw new Error(
162
- 'Explorer AddressTransactions api expected to have items',
163
- );
164
- return {
165
- items: txs.items.map((tx) => this.convertTransaction(tx)),
166
- total: txs.total!,
167
- };
168
- };
169
- }
package/lib/ergo/utils.ts DELETED
@@ -1,15 +0,0 @@
1
- import { intersection } from 'lodash-es';
2
- import { OutputBox } from '@rosen-bridge/scanner-interfaces';
3
-
4
- /**
5
- * Check box to have specified tokens
6
- * @param box
7
- * @return true if box has the required token and false otherwise
8
- */
9
- export const boxHasToken = (box: OutputBox, tokenIds: string[]) => {
10
- if (!box.assets) return false;
11
- const boxTokens = box.assets.map((token) => token.tokenId);
12
- const requiredTokens = intersection(tokenIds, boxTokens);
13
- if (requiredTokens.length == tokenIds.length) return true;
14
- return false;
15
- };
package/lib/index.ts DELETED
@@ -1,3 +0,0 @@
1
- export * from './ergo';
2
- export * from './constants';
3
- export * from './abstractExtractor';
@@ -1,33 +0,0 @@
1
- import { V1 } from '@rosen-clients/ergo-explorer';
2
- import { BlockInfo, OutputBox } from '@rosen-bridge/scanner-interfaces';
3
-
4
- import {
5
- AbstractErgoExtractor,
6
- AbstractBoxData,
7
- AbstractErgoExtractorAction,
8
- AbstractErgoExtractorEntity,
9
- } from '../lib';
10
-
11
- export class MockedErgoExtractor extends AbstractErgoExtractor<
12
- AbstractBoxData,
13
- AbstractErgoExtractorEntity
14
- > {
15
- actions: AbstractErgoExtractorAction<
16
- AbstractBoxData,
17
- AbstractErgoExtractorEntity
18
- >;
19
-
20
- getId = () => 'Test';
21
-
22
- initializeBoxes: (initialBlock: BlockInfo) => Promise<void>;
23
-
24
- hasData = (
25
- box: V1.OutputInfo | OutputBox, // eslint-disable-line @typescript-eslint/no-unused-vars
26
- ) => false;
27
-
28
- extractBoxData = (
29
- box: V1.OutputInfo | OutputBox, // eslint-disable-line @typescript-eslint/no-unused-vars
30
- ): AbstractBoxData | undefined => {
31
- return undefined;
32
- };
33
- }
@@ -1,284 +0,0 @@
1
- import { V1 } from '@rosen-clients/ergo-explorer';
2
- import { OutputBox } from '@rosen-bridge/scanner-interfaces';
3
-
4
- import {
5
- AbstractBoxData,
6
- AbstractErgoExtractorAction,
7
- CallbackType,
8
- AbstractErgoExtractorEntity,
9
- } from '../lib';
10
- import { block, extractedData, tx } from './testData';
11
- import { MockedErgoExtractor } from './AbstractErgoExtractor.mock';
12
-
13
- describe('AbstractErgoExtractor', () => {
14
- describe('processTransactions', () => {
15
- /**
16
- * @target processTransactions should initialize extractor with specified id and insert status into db
17
- * @dependencies
18
- * @scenario
19
- * - mock extractor
20
- * - mock `hasData` to return true for one box
21
- * - spy `extractBoxData` and `storeBoxes`
22
- * - run test (call `processTransactions`)
23
- * @expected
24
- * - to call `extractBoxData` for the specific box and all input extensions
25
- * - to insert the extracted box to database
26
- * - to return true when total procedure is successful
27
- * - to trigger `INSERT` callbacks with correct data
28
- */
29
- it('should process boxes with data and insert data into database', async () => {
30
- const extractor = new MockedErgoExtractor();
31
- const triggerCallbacks = vitest.fn();
32
- extractor['triggerCallbacks'] = triggerCallbacks;
33
- extractor.hasData = (box: V1.OutputInfo | OutputBox) => {
34
- if (box.boxId == tx.outputs[0].boxId) return true;
35
- return false;
36
- };
37
- const extractSpy = vitest.fn().mockReturnValue(extractedData);
38
- extractor.extractBoxData = extractSpy;
39
- const storeSpy = vitest.fn().mockResolvedValue(true);
40
- const spendSpy = vitest.fn().mockResolvedValue([]);
41
- extractor['actions'] = {
42
- storeBoxes: storeSpy,
43
- spendBoxes: spendSpy,
44
- } as unknown as AbstractErgoExtractorAction<
45
- AbstractBoxData,
46
- AbstractErgoExtractorEntity
47
- >;
48
- const result = await extractor.processTransactions([tx], block);
49
-
50
- expect(extractSpy).toBeCalledTimes(1);
51
- expect(extractSpy).toBeCalledWith(
52
- tx.outputs[0],
53
- [tx.inputs[0].extension, {}],
54
- {},
55
- );
56
- expect(storeSpy).toBeCalledWith([extractedData], block, 'Test');
57
- expect(result).toEqual(true);
58
- expect(triggerCallbacks).toBeCalledWith(CallbackType.Insert, [
59
- extractedData,
60
- ]);
61
- });
62
-
63
- /**
64
- * @target processTransactions should extract spending information of all input boxes
65
- * @dependencies
66
- * @scenario
67
- * - mock extractor (hasData returns false as default)
68
- * - spy `extractBoxData`, `storeBoxes` and `spendBoxes`
69
- * - run test (call `processTransactions`)
70
- * @expected
71
- * - not to call `extractBoxData` and `storeBoxes` when there is not any box with data
72
- * - to extractor spend info of input boxes and call `spendBoxes`
73
- * - to return true when total procedure is successful
74
- * - to trigger `SPEND` callbacks with correct data
75
- */
76
- it('should extract spending information of all input boxes', async () => {
77
- const extractor = new MockedErgoExtractor();
78
- const triggerCallbacks = vitest.fn();
79
- extractor['triggerCallbacks'] = triggerCallbacks;
80
- const extractSpy = vitest.fn();
81
- extractor.extractBoxData = extractSpy;
82
- const storeSpy = vitest.fn().mockResolvedValue(true);
83
- const spendSpy = vitest
84
- .fn()
85
- .mockResolvedValue([
86
- { boxId: tx.inputs[0].boxId },
87
- { boxId: tx.inputs[1].boxId },
88
- ]);
89
- extractor['actions'] = {
90
- storeBoxes: storeSpy,
91
- spendBoxes: spendSpy,
92
- } as unknown as AbstractErgoExtractorAction<
93
- AbstractBoxData,
94
- AbstractErgoExtractorEntity
95
- >;
96
- const result = await extractor.processTransactions([tx], block);
97
-
98
- expect(extractSpy).not.toBeCalled();
99
- expect(storeSpy).not.toBeCalled();
100
- expect(spendSpy).toBeCalledWith(
101
- [
102
- { boxId: tx.inputs[0].boxId, txId: tx.id, index: 1 },
103
- { boxId: tx.inputs[1].boxId, txId: tx.id, index: 2 },
104
- ],
105
- block,
106
- 'Test',
107
- );
108
- expect(result).toEqual(true);
109
- expect(triggerCallbacks).toBeCalledWith(CallbackType.Spend, [
110
- { boxId: tx.inputs[0].boxId },
111
- { boxId: tx.inputs[1].boxId },
112
- ]);
113
- });
114
-
115
- /**
116
- * @target processTransactions should return false if data insertion fails
117
- * @dependencies
118
- * @scenario
119
- * - mock extractor
120
- * - mock `hasData` to return true for one box
121
- * - spy `extractBoxData` and `storeBoxes`
122
- * - run test (call `processTransactions`)
123
- * @expected
124
- * - to return false when `insertBoxes` returns false
125
- * - not to call `spendBoxes` if data insertion fails
126
- */
127
- it('should return false if data insertion fails', async () => {
128
- const extractor = new MockedErgoExtractor();
129
- extractor.hasData = (box: V1.OutputInfo | OutputBox) => {
130
- if (box.boxId == tx.outputs[0].boxId) return true;
131
- return false;
132
- };
133
- const extractSpy = vitest.fn().mockReturnValue(extractedData);
134
- extractor.extractBoxData = extractSpy;
135
- const storeSpy = vitest.fn().mockResolvedValue(false);
136
- const spendSpy = vitest.fn();
137
- extractor['actions'] = {
138
- storeBoxes: storeSpy,
139
- spendBoxes: spendSpy,
140
- } as unknown as AbstractErgoExtractorAction<
141
- AbstractBoxData,
142
- AbstractErgoExtractorEntity
143
- >;
144
- const result = await extractor.processTransactions([tx], block);
145
-
146
- expect(result).toEqual(false);
147
- expect(spendSpy).not.toBeCalled();
148
- });
149
- });
150
-
151
- describe('forkBlock', () => {
152
- /**
153
- * @target forkBlock should remove all data extracted from the specified block
154
- * @dependencies
155
- * @scenario
156
- * - mock extractor
157
- * - spy `deleteBlockBoxes`
158
- * - run test (call `forkBlock`)
159
- * @expected
160
- * - to call `deleteBlockBoxes` for the specific box
161
- * - to trigger `DELETE` callbacks for the deleted box
162
- * - to trigger `UPDATE` callbacks for the spent box
163
- */
164
- it('should remove all data extracted from the specified block', async () => {
165
- const extractor = new MockedErgoExtractor();
166
- const removeSpy = vitest.fn().mockResolvedValue({
167
- deletedData: [{ boxId: 'box1' }],
168
- updatedData: [{ boxId: 'box2' }],
169
- });
170
- extractor['actions'] = {
171
- deleteBlockBoxes: removeSpy,
172
- } as unknown as AbstractErgoExtractorAction<
173
- AbstractBoxData,
174
- AbstractErgoExtractorEntity
175
- >;
176
- const triggerCallbackSpy = vitest.fn().mockClear();
177
- extractor['triggerCallbacks'] = triggerCallbackSpy;
178
- await extractor.forkBlock(block.hash);
179
- expect(removeSpy).toBeCalledWith(block.hash, 'Test');
180
- expect(triggerCallbackSpy).toBeCalledWith(CallbackType.Delete, [
181
- { boxId: 'box1' },
182
- ]);
183
- expect(triggerCallbackSpy).toBeCalledWith(CallbackType.Update, [
184
- { boxId: 'box2' },
185
- ]);
186
- });
187
- });
188
-
189
- describe('hook', () => {
190
- /**
191
- * @target hook should hook a new callback on insert with the new id
192
- * @dependencies
193
- * @scenario
194
- * - mock extractor
195
- * - mock a callback for insert
196
- * - run test (call `hook`)
197
- * @expected
198
- * - hook the callback with the specified id
199
- * - return true
200
- */
201
- it('should hook a new callback on insert with the new id', async () => {
202
- const extractor = new MockedErgoExtractor();
203
- const insertCallback = vitest.fn();
204
- const id = await extractor.hook(CallbackType.Insert, insertCallback);
205
- expect(extractor['callbacks'][CallbackType.Insert]).toEqual(
206
- new Map().set(id, insertCallback),
207
- );
208
- });
209
- });
210
-
211
- describe('unhook', () => {
212
- /**
213
- * @target unhook should unhook the callback on insert with the specified id
214
- * @dependencies
215
- * @scenario
216
- * - mock extractor
217
- * - mock a callback for insert
218
- * - hook the callback
219
- * - run test (call `unhook`)
220
- * @expected
221
- * - unhook the callback with the specified id
222
- * - return true
223
- */
224
- it('should unhook the callback on insert with the specified id', async () => {
225
- const extractor = new MockedErgoExtractor();
226
- const insertCallback = vitest.fn();
227
- const id = await extractor.hook(CallbackType.Insert, insertCallback);
228
- const result = await extractor.unhook(CallbackType.Insert, id);
229
- expect(result).toBeTruthy();
230
- expect(extractor['callbacks'][CallbackType.Insert].get(id)).toEqual(
231
- undefined,
232
- );
233
- });
234
-
235
- /**
236
- * @target unhook should not unhook callbacks with the same id on other types
237
- * @dependencies
238
- * @scenario
239
- * - mock extractor
240
- * - mock two callbacks for insert
241
- * - hook the first callback
242
- * - run test (call `unhook` with the same id for second callback)
243
- * @expected
244
- * - not to change hooked callbacks when the callback with the id
245
- * doesn't exists on the specified type
246
- * - return false
247
- */
248
- it('should not unhook callbacks with the same id on other types', async () => {
249
- const extractor = new MockedErgoExtractor();
250
- const insertCallback = vitest.fn();
251
- const id = await extractor.hook(CallbackType.Insert, insertCallback);
252
- const result = await extractor.unhook(CallbackType.Update, id);
253
- expect(result).toBeFalsy();
254
- expect(extractor['callbacks'][CallbackType.Insert].get(id)).toEqual(
255
- insertCallback,
256
- );
257
- expect(extractor['callbacks'][CallbackType.Update].get(id)).toEqual(
258
- undefined,
259
- );
260
- });
261
- });
262
-
263
- describe('triggerCallbacks', () => {
264
- /**
265
- * @target triggerCallbacks should trigger all callbacks hooked on a type
266
- * @dependencies
267
- * @scenario
268
- * - mock extractor
269
- * - mock a callback for insert
270
- * - hook the callback
271
- * - run test (call `triggerCallbacks` for insert type)
272
- * @expected
273
- * - trigger all callbacks with the specified id
274
- */
275
- it('should trigger all callbacks hooked on a type', async () => {
276
- const extractor = new MockedErgoExtractor();
277
- const insertCallback = vitest.fn();
278
- await extractor.hook(CallbackType.Insert, insertCallback);
279
- const insertedData = [{ boxId: 'boxId', serialized: 'serialized' }];
280
- await extractor['triggerCallbacks'](CallbackType.Insert, insertedData);
281
- expect(insertCallback).toBeCalledWith(insertedData);
282
- });
283
- });
284
- });
@@ -1,45 +0,0 @@
1
- import { DataSource } from '@rosen-bridge/extended-typeorm';
2
- import { pick } from 'lodash-es';
3
- import { BlockInfo } from '@rosen-bridge/scanner-interfaces';
4
-
5
- import {
6
- AbstractErgoExtractorAction,
7
- AbstractErgoExtractorEntity,
8
- AbstractBoxData,
9
- } from '../lib';
10
- import { TestEntity } from './testUtils';
11
-
12
- export class TestErgoExtractorAction extends AbstractErgoExtractorAction<
13
- AbstractBoxData,
14
- AbstractErgoExtractorEntity
15
- > {
16
- constructor(dataSource: DataSource) {
17
- super(dataSource, TestEntity);
18
- }
19
-
20
- /**
21
- * create the test database entity from data and block information
22
- */
23
- createEntity = (
24
- boxes: AbstractBoxData[],
25
- block: BlockInfo,
26
- extractor: string,
27
- ): Omit<AbstractErgoExtractorEntity, 'id'>[] => {
28
- return boxes.map((box) => ({
29
- boxId: box.boxId,
30
- block: block.hash,
31
- height: block.height,
32
- serialized: box.serialized,
33
- extractor: extractor,
34
- }));
35
- };
36
-
37
- /**
38
- * convert the database entity back to raw data
39
- */
40
- convertEntityToData = (
41
- entities: AbstractErgoExtractorEntity[],
42
- ): AbstractBoxData[] => {
43
- return entities.map((data) => pick(data, ['boxId', 'serialized']));
44
- };
45
- }