1+ import request from 'supertest' ;
2+ import express from 'express' ;
3+ import contractRegistryRoutes from '../../routes/contractRegistryRoutes.js' ;
4+ import { ContractRegistryService } from '../../services/contractRegistryService.js' ;
5+ import logger from '../../utils/logger.js' ;
6+
7+ jest . mock ( '../../services/contractRegistryService' ) ;
8+ jest . mock ( '../../utils/logger' ) ;
9+
10+ const app = express ( ) ;
11+ app . use ( express . json ( ) ) ;
12+ app . use ( '/api' , contractRegistryRoutes ) ;
13+
14+ describe ( 'Contract Registry API Integration' , ( ) => {
15+ beforeEach ( ( ) => {
16+ jest . clearAllMocks ( ) ;
17+ } ) ;
18+
19+ describe ( 'GET /api/contracts' , ( ) => {
20+ it ( 'returns all networks when no query param provided' , async ( ) => {
21+ ( ContractRegistryService . getAllContracts as jest . Mock )
22+ . mockReturnValue ( {
23+ testnet : {
24+ bulk_payment : {
25+ contractId : 'CBULK_TEST' ,
26+ version : '1.0.0' ,
27+ deployedAt : 123456 ,
28+ } ,
29+ } ,
30+ } ) ;
31+
32+ const response = await request ( app ) . get ( '/api/contracts' ) ;
33+
34+ expect ( response . status ) . toBe ( 200 ) ;
35+ expect ( response . body ) . toHaveProperty ( 'networks' ) ;
36+ expect ( response . body . count ) . toBe ( 1 ) ;
37+ expect ( response . body . networks . testnet ) . toBeDefined ( ) ;
38+ expect ( response . body ) . toHaveProperty ( 'timestamp' ) ;
39+ } ) ;
40+
41+ it ( 'returns specific network when query param is provided' , async ( ) => {
42+ ( ContractRegistryService . getContractsByNetwork as jest . Mock )
43+ . mockReturnValue ( {
44+ bulk_payment : {
45+ contractId : 'CBULK_TEST' ,
46+ version : '1.0.0' ,
47+ deployedAt : 123456 ,
48+ } ,
49+ } ) ;
50+
51+ const response = await request ( app )
52+ . get ( '/api/contracts' )
53+ . query ( { network : 'testnet' } ) ;
54+
55+ expect ( response . status ) . toBe ( 200 ) ;
56+ expect ( response . body . network ) . toBe ( 'testnet' ) ;
57+ expect ( response . body . contracts . bulk_payment ) . toBeDefined ( ) ;
58+ expect ( response . body . count ) . toBe ( 1 ) ;
59+ } ) ;
60+
61+ it ( 'returns 500 when service throws error' , async ( ) => {
62+ ( ContractRegistryService . getAllContracts as jest . Mock )
63+ . mockImplementation ( ( ) => {
64+ throw new Error ( 'Registry load failed' ) ;
65+ } ) ;
66+
67+ const response = await request ( app ) . get ( '/api/contracts' ) ;
68+
69+ expect ( response . status ) . toBe ( 500 ) ;
70+ expect ( response . body . error ) . toBe ( 'Internal Server Error' ) ;
71+ expect ( response . body . message ) . toBe ( 'Registry load failed' ) ;
72+ expect ( logger . error ) . toHaveBeenCalled ( ) ;
73+ } ) ;
74+
75+ it ( 'logs warning if response time exceeds 500ms' , async ( ) => {
76+ ( ContractRegistryService . getAllContracts as jest . Mock )
77+ . mockReturnValue ( { } ) ;
78+
79+ // Mock slow response
80+ const originalNow = Date . now ;
81+ let time = 0 ;
82+ Date . now = jest . fn ( ( ) => {
83+ time += 600 ;
84+ return time ;
85+ } ) ;
86+
87+ await request ( app ) . get ( '/api/contracts' ) ;
88+
89+ expect ( logger . warn ) . toHaveBeenCalledWith (
90+ expect . stringContaining ( 'Contract registry response slow' )
91+ ) ;
92+
93+ Date . now = originalNow ;
94+ } ) ;
95+ } ) ;
96+ } ) ;
0 commit comments