11import { assert } from '@open-wc/testing' ;
22import sinon from 'sinon' ;
3- import {
4- fetchAsset ,
5- hasNftProduct ,
6- fetchAssetMetadata ,
7- } from '../asset/asset-service' ;
3+ import { fetchAsset , hasNftProduct } from '../asset/asset-service' ;
84import { Constant } from '../constant' ;
95
106suite ( '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