@@ -161,6 +161,42 @@ test('basic select overrideTypes from builder', async () => {
161161 "status": 200,
162162 "statusText": "OK",
163163 }
164+ ` ) ;
165+ } )
166+
167+ test ( 'basic select with maybeSingle yielding more than one result' , async ( ) => {
168+ const res = await postgrest . from ( 'users' ) . select ( ) . maybeSingle ( )
169+ expect ( res ) . toMatchInlineSnapshot ( `
170+ Object {
171+ "count": null,
172+ "data": null,
173+ "error": Object {
174+ "code": "PGRST116",
175+ "details": "Results contain 5 rows, application/vnd.pgrst.object+json requires 1 row",
176+ "hint": null,
177+ "message": "JSON object requested, multiple (or no) rows returned",
178+ },
179+ "status": 406,
180+ "statusText": "Not Acceptable",
181+ }
182+ ` )
183+ } )
184+
185+ test ( 'basic select with single yielding more than one result' , async ( ) => {
186+ const res = await postgrest . from ( 'users' ) . select ( ) . single ( )
187+ expect ( res ) . toMatchInlineSnapshot ( `
188+ Object {
189+ "count": null,
190+ "data": null,
191+ "error": Object {
192+ "code": "PGRST116",
193+ "details": "The result contains 5 rows",
194+ "hint": null,
195+ "message": "JSON object requested, multiple (or no) rows returned",
196+ },
197+ "status": 406,
198+ "statusText": "Not Acceptable",
199+ }
164200 ` )
165201} )
166202
@@ -2011,3 +2047,187 @@ test('join on 1-1 relation with nullables', async () => {
20112047 }
20122048 ` )
20132049} )
2050+
2051+ test ( 'custom fetch function' , async ( ) => {
2052+ const customFetch = jest . fn ( ) . mockImplementation ( ( ) =>
2053+ Promise . resolve ( {
2054+ ok : true ,
2055+ status : 200 ,
2056+ statusText : 'OK' ,
2057+ text : ( ) => Promise . resolve ( '[]' ) ,
2058+ } )
2059+ )
2060+
2061+ const postgrestWithCustomFetch = new PostgrestClient < Database > ( REST_URL , {
2062+ fetch : customFetch ,
2063+ } )
2064+
2065+ await postgrestWithCustomFetch . from ( 'users' ) . select ( )
2066+
2067+ expect ( customFetch ) . toHaveBeenCalledWith (
2068+ expect . stringContaining ( REST_URL ) ,
2069+ expect . objectContaining ( {
2070+ method : 'GET' ,
2071+ headers : expect . any ( Object ) ,
2072+ } )
2073+ )
2074+ } )
2075+
2076+ test ( 'handles undefined global fetch' , async ( ) => {
2077+ // Store original fetch
2078+ const originalFetch = globalThis . fetch
2079+ // Delete global fetch to simulate environments where it's undefined
2080+ delete ( globalThis as any ) . fetch
2081+
2082+ try {
2083+ const postgrestClient = new PostgrestClient < Database > ( REST_URL )
2084+ const result = await postgrestClient . from ( 'users' ) . select ( )
2085+ expect ( result ) . toMatchInlineSnapshot ( `
2086+ Object {
2087+ "count": null,
2088+ "data": Array [
2089+ Object {
2090+ "age_range": "[1,2)",
2091+ "catchphrase": "'cat' 'fat'",
2092+ "data": null,
2093+ "status": "ONLINE",
2094+ "username": "supabot",
2095+ },
2096+ Object {
2097+ "age_range": "[25,35)",
2098+ "catchphrase": "'bat' 'cat'",
2099+ "data": null,
2100+ "status": "OFFLINE",
2101+ "username": "kiwicopple",
2102+ },
2103+ Object {
2104+ "age_range": "[25,35)",
2105+ "catchphrase": "'bat' 'rat'",
2106+ "data": null,
2107+ "status": "ONLINE",
2108+ "username": "awailas",
2109+ },
2110+ Object {
2111+ "age_range": "[20,30)",
2112+ "catchphrase": "'json' 'test'",
2113+ "data": Object {
2114+ "foo": Object {
2115+ "bar": Object {
2116+ "nested": "value",
2117+ },
2118+ "baz": "string value",
2119+ },
2120+ },
2121+ "status": "ONLINE",
2122+ "username": "jsonuser",
2123+ },
2124+ Object {
2125+ "age_range": "[20,30)",
2126+ "catchphrase": "'fat' 'rat'",
2127+ "data": null,
2128+ "status": "ONLINE",
2129+ "username": "dragarcia",
2130+ },
2131+ ],
2132+ "error": null,
2133+ "status": 200,
2134+ "statusText": "OK",
2135+ }
2136+ ` )
2137+ // Test passes if we reach here without errors, as it means nodeFetch was used
2138+ } finally {
2139+ // Restore original fetch
2140+ globalThis . fetch = originalFetch
2141+ }
2142+ } )
2143+
2144+ test ( 'handles array error with 404 status' , async ( ) => {
2145+ // Mock the fetch response to return an array error with 404
2146+ const customFetch = jest . fn ( ) . mockImplementation ( ( ) =>
2147+ Promise . resolve ( {
2148+ ok : false ,
2149+ status : 404 ,
2150+ statusText : 'Not Found' ,
2151+ text : ( ) => Promise . resolve ( '[]' ) ,
2152+ } )
2153+ )
2154+
2155+ const postgrestWithCustomFetch = new PostgrestClient < Database > ( REST_URL , {
2156+ fetch : customFetch ,
2157+ } )
2158+
2159+ const res = await postgrestWithCustomFetch . from ( 'users' ) . select ( )
2160+
2161+ expect ( res ) . toMatchInlineSnapshot ( `
2162+ Object {
2163+ "count": null,
2164+ "data": Array [],
2165+ "error": null,
2166+ "status": 200,
2167+ "statusText": "OK",
2168+ }
2169+ ` )
2170+ } )
2171+
2172+ test ( 'handles empty body with 404 status' , async ( ) => {
2173+ // Mock the fetch response to return an empty body with 404
2174+ const customFetch = jest . fn ( ) . mockImplementation ( ( ) =>
2175+ Promise . resolve ( {
2176+ ok : false ,
2177+ status : 404 ,
2178+ statusText : 'Not Found' ,
2179+ text : ( ) => Promise . resolve ( '' ) ,
2180+ } )
2181+ )
2182+
2183+ const postgrestWithCustomFetch = new PostgrestClient < Database > ( REST_URL , {
2184+ fetch : customFetch ,
2185+ } )
2186+
2187+ const res = await postgrestWithCustomFetch . from ( 'users' ) . select ( )
2188+
2189+ expect ( res ) . toMatchInlineSnapshot ( `
2190+ Object {
2191+ "count": null,
2192+ "data": null,
2193+ "error": null,
2194+ "status": 204,
2195+ "statusText": "No Content",
2196+ }
2197+ ` )
2198+ } )
2199+
2200+ test ( 'maybeSingle handles zero rows error' , async ( ) => {
2201+ const customFetch = jest . fn ( ) . mockImplementation ( ( ) =>
2202+ Promise . resolve ( {
2203+ ok : false ,
2204+ status : 406 ,
2205+ statusText : 'Not Acceptable' ,
2206+ text : ( ) =>
2207+ Promise . resolve (
2208+ JSON . stringify ( {
2209+ code : 'PGRST116' ,
2210+ details : '0 rows' ,
2211+ hint : null ,
2212+ message : 'JSON object requested, multiple (or no) rows returned' ,
2213+ } )
2214+ ) ,
2215+ } )
2216+ )
2217+
2218+ const postgrestWithCustomFetch = new PostgrestClient < Database > ( REST_URL , {
2219+ fetch : customFetch ,
2220+ } )
2221+
2222+ const res = await postgrestWithCustomFetch . from ( 'users' ) . select ( ) . maybeSingle ( )
2223+
2224+ expect ( res ) . toMatchInlineSnapshot ( `
2225+ Object {
2226+ "count": null,
2227+ "data": null,
2228+ "error": null,
2229+ "status": 200,
2230+ "statusText": "OK",
2231+ }
2232+ ` )
2233+ } )
0 commit comments