Skip to content

Commit d13a87c

Browse files
author
Omni
committed
fix: rewrite asset-service tests for current API format
The tests were written against the old Bubble.io API (verify.numbersprotocol.io) which has since been replaced. Updated to match the current Numbers API v3: - Remove fetchAssetMetadata tests (function no longer exists; hasC2pa and showcaseLink are now part of fetchAsset response) - Replace { response: { data: ... } } mock structure with flat JSON matching the v3 API response - Update field mappings: nit_commit_custom, signed_metadata, integrity_info, asset_file_mime_type, asset_file_thumbnail, etc. - Add tests for creator fallback chain, hasC2pa, and showcaseLink - Add test for null response body
1 parent 041799d commit d13a87c

1 file changed

Lines changed: 107 additions & 100 deletions

File tree

src/test/asset-service_test.ts

Lines changed: 107 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
import { assert } from '@open-wc/testing';
22
import sinon from 'sinon';
3-
import {
4-
fetchAsset,
5-
hasNftProduct,
6-
fetchAssetMetadata,
7-
} from '../asset/asset-service';
3+
import { fetchAsset, hasNftProduct } from '../asset/asset-service';
84
import { Constant } from '../constant';
95

106
suite('asset-service', () => {
@@ -20,60 +16,77 @@ suite('asset-service', () => {
2016

2117
suite('fetchAsset', () => {
2218
test('maps API response fields correctly to AssetModel', async () => {
23-
const mockData = {
24-
assetCreator: 'Test Creator',
25-
fullAssetTree: {
26-
'_api_c2_assetTree.creatorWallet': '0xabc123',
27-
'_api_c2_assetTree.encodingFormat': 'image/jpeg',
28-
'_api_c2_assetTree.assetLocationCreated': 'New York, USA',
19+
const mockResponse = {
20+
nit_commit_custom: {
21+
assetCreator: 'Test Creator',
22+
creatorWallet: '0xabc123',
23+
assetLocationCreated: 'New York, USA',
24+
assetSourceType: 'upload',
25+
usedBy: 'test-user',
26+
captureEyeCustom: [
27+
{
28+
field: 'Custom Field',
29+
value: 'Custom Value',
30+
iconSource: 'https://example.com/icon.png',
31+
url: 'https://example.com',
32+
},
33+
],
2934
},
30-
assetTimestampCreated: '2024-01-01T00:00:00Z',
31-
headline: 'Test Headline',
32-
abstract: 'Test Abstract',
33-
initial_transaction: '0x123abc',
34-
thumnail_url: 'https://example.com/thumb.jpg', // [sic] — intentional typo in the API field name
35-
assetSourceType: 'upload',
36-
integrity_capture_time: '2024-01-01T12:00:00Z',
37-
backend_owner_name: 'Owner Name',
38-
digitalSourceType: 'original',
39-
usedBy: 'test-user',
40-
captureEyeCustom: [
35+
signed_metadata: JSON.stringify({ created_at: 1704067200 }),
36+
integrity_info: [
4137
{
42-
_api_c2_field: 'Custom Field',
43-
_api_c2_value: 'Custom Value',
44-
_api_c2_iconSource: 'https://example.com/icon.png',
45-
_api_c2_url: 'https://example.com',
38+
search_id: '0x123abc',
39+
explorer_url: 'https://mainnet.num.network/tx/0x123abc',
4640
},
4741
],
42+
uploaded_at: '2024-01-01T00:00:00Z',
43+
asset_file_mime_type: 'image/jpeg',
44+
headline: 'Test Headline',
45+
caption: 'Test Abstract',
46+
asset_file_thumbnail: 'https://example.com/thumb.jpg',
47+
digital_source_type: 'original',
48+
owner_name: 'TestOwner',
49+
owner_profile_display_name: 'Owner Display Name',
50+
c2pa: true,
4851
};
4952

5053
fetchStub.resolves({
5154
ok: true,
52-
json: () =>
53-
Promise.resolve({ response: { data: mockData } }),
55+
json: () => Promise.resolve(mockResponse),
5456
} as unknown as Response);
5557

5658
const result = await fetchAsset('test-nid');
5759

5860
assert.isDefined(result);
5961
assert.equal(result!.creator, 'Test Creator');
6062
assert.equal(result!.creatorWallet, '0xabc123');
61-
assert.equal(result!.createdTime, '2024-01-01T00:00:00Z');
63+
assert.equal(
64+
result!.createdTime,
65+
new Date('2024-01-01T00:00:00Z').toUTCString()
66+
);
6267
assert.equal(result!.encodingFormat, 'image/jpeg');
6368
assert.equal(result!.headline, 'Test Headline');
6469
assert.equal(result!.abstract, 'Test Abstract');
6570
assert.equal(result!.initialTransaction, '0x123abc');
6671
assert.equal(result!.thumbnailUrl, 'https://example.com/thumb.jpg');
6772
assert.equal(
6873
result!.explorerUrl,
69-
`${Constant.url.explorer}/tx/0x123abc`
74+
'https://mainnet.num.network/tx/0x123abc'
7075
);
7176
assert.equal(result!.assetSourceType, 'upload');
72-
assert.equal(result!.captureTime, '2024-01-01T12:00:00Z');
77+
assert.equal(
78+
result!.captureTime,
79+
new Date(1704067200 * 1000).toUTCString()
80+
);
7381
assert.equal(result!.captureLocation, 'New York, USA');
74-
assert.equal(result!.backendOwnerName, 'Owner Name');
82+
assert.equal(result!.backendOwnerName, 'Owner Display Name');
7583
assert.equal(result!.digitalSourceType, 'original');
7684
assert.equal(result!.usedBy, 'test-user');
85+
assert.isTrue(result!.hasC2pa);
86+
assert.equal(
87+
result!.showcaseLink,
88+
`${Constant.url.showcase}/testowner`
89+
);
7790
assert.deepEqual(result!.captureEyeCustom, [
7891
{
7992
field: 'Custom Field',
@@ -84,25 +97,82 @@ suite('asset-service', () => {
8497
]);
8598
});
8699

87-
test('sets explorerUrl to empty string when initial_transaction is absent', async () => {
100+
test('sets explorerUrl to empty string when integrity_info is absent', async () => {
88101
fetchStub.resolves({
89102
ok: true,
90103
json: () =>
91104
Promise.resolve({
92-
response: { data: { assetCreator: 'Creator' } },
105+
creator_name: 'Creator',
93106
}),
94107
} as unknown as Response);
95108

96109
const result = await fetchAsset('test-nid');
97110
assert.isDefined(result);
98111
assert.equal(result!.explorerUrl, '');
112+
assert.isUndefined(result!.initialTransaction);
113+
});
114+
115+
test('falls back creator through priority chain', async () => {
116+
// No nit_commit_custom.assetCreator → fallback to creator_profile_display_name
117+
fetchStub.resolves({
118+
ok: true,
119+
json: () =>
120+
Promise.resolve({
121+
creator_profile_display_name: 'Display Name',
122+
creator_name: 'Username',
123+
}),
124+
} as unknown as Response);
125+
126+
const result = await fetchAsset('test-nid');
127+
assert.isDefined(result);
128+
assert.equal(result!.creator, 'Display Name');
129+
});
130+
131+
test('returns hasC2pa and showcaseLink fields', async () => {
132+
fetchStub.resolves({
133+
ok: true,
134+
json: () =>
135+
Promise.resolve({
136+
c2pa: true,
137+
owner_name: 'TestOwner',
138+
owner_profile_display_name: 'Owner Display',
139+
}),
140+
} as unknown as Response);
141+
142+
const result = await fetchAsset('test-nid');
143+
assert.isDefined(result);
144+
assert.isTrue(result!.hasC2pa);
145+
assert.equal(
146+
result!.showcaseLink,
147+
`${Constant.url.showcase}/testowner`
148+
);
149+
assert.equal(result!.backendOwnerName, 'Owner Display');
150+
});
151+
152+
test('showcaseLink is undefined when owner_name is absent', async () => {
153+
fetchStub.resolves({
154+
ok: true,
155+
json: () =>
156+
Promise.resolve({
157+
c2pa: false,
158+
owner_profile_display_name: 'Owner Display',
159+
}),
160+
} as unknown as Response);
161+
162+
const result = await fetchAsset('test-nid');
163+
assert.isDefined(result);
164+
assert.isFalse(result!.hasC2pa);
165+
assert.isUndefined(result!.showcaseLink);
99166
});
100167

101168
test('returns undefined on non-OK HTTP response', async () => {
102169
fetchStub.resolves({
103170
ok: false,
104171
status: 404,
105-
json: () => Promise.resolve({ message: 'Not Found' }),
172+
json: () =>
173+
Promise.resolve({
174+
error: { type: 'NotFound', message: 'Not Found' },
175+
}),
106176
} as unknown as Response);
107177

108178
const result = await fetchAsset('test-nid');
@@ -127,10 +197,10 @@ suite('asset-service', () => {
127197
assert.isUndefined(result);
128198
});
129199

130-
test('returns undefined when data is null', async () => {
200+
test('returns undefined when response body is null', async () => {
131201
fetchStub.resolves({
132202
ok: true,
133-
json: () => Promise.resolve({ response: { data: null } }),
203+
json: () => Promise.resolve(null),
134204
} as unknown as Response);
135205

136206
const result = await fetchAsset('test-nid');
@@ -180,67 +250,4 @@ suite('asset-service', () => {
180250
assert.isFalse(result);
181251
});
182252
});
183-
184-
suite('fetchAssetMetadata', () => {
185-
test('returns hasC2pa true and showcaseLink when owner_name is present', async () => {
186-
fetchStub.resolves({
187-
ok: true,
188-
json: () =>
189-
Promise.resolve({ c2pa: true, owner_name: 'TestOwner' }),
190-
} as unknown as Response);
191-
192-
const result = await fetchAssetMetadata('test-nid');
193-
assert.isDefined(result);
194-
assert.isTrue(result!.hasC2pa);
195-
assert.equal(
196-
result!.showcaseLink,
197-
`${Constant.url.showcase}/testowner`
198-
);
199-
});
200-
201-
test('returns hasC2pa false when c2pa field is not true', async () => {
202-
fetchStub.resolves({
203-
ok: true,
204-
json: () =>
205-
Promise.resolve({ c2pa: false, owner_name: 'TestOwner' }),
206-
} as unknown as Response);
207-
208-
const result = await fetchAssetMetadata('test-nid');
209-
assert.isDefined(result);
210-
assert.isFalse(result!.hasC2pa);
211-
});
212-
213-
test('returns showcaseLink as undefined when owner_name is absent', async () => {
214-
fetchStub.resolves({
215-
ok: true,
216-
json: () => Promise.resolve({ c2pa: true }),
217-
} as unknown as Response);
218-
219-
const result = await fetchAssetMetadata('test-nid');
220-
assert.isDefined(result);
221-
assert.isTrue(result!.hasC2pa);
222-
assert.isUndefined(result!.showcaseLink);
223-
});
224-
225-
test('returns undefined on non-OK HTTP response', async () => {
226-
fetchStub.resolves({
227-
ok: false,
228-
status: 403,
229-
json: () =>
230-
Promise.resolve({
231-
error: { type: 'Forbidden', message: 'Forbidden' },
232-
}),
233-
} as unknown as Response);
234-
235-
const result = await fetchAssetMetadata('test-nid');
236-
assert.isUndefined(result);
237-
});
238-
239-
test('returns undefined on network error', async () => {
240-
fetchStub.rejects(new Error('Network error'));
241-
242-
const result = await fetchAssetMetadata('test-nid');
243-
assert.isUndefined(result);
244-
});
245-
});
246253
});

0 commit comments

Comments
 (0)