@@ -5,55 +5,163 @@ import { SeamHttp } from '@seamapi/http/connect'
55
66import { SeamHttpRequest } from 'lib/seam/connect/seam-http-request.js'
77
8- test ( 'returns a SeamHttpRequest' , async ( t ) => {
8+ test ( 'SeamHttp: returns a SeamHttpRequest' , async ( t ) => {
99 const { seed, endpoint } = await getTestServer ( t )
1010 const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , { endpoint } )
1111
12- const deviceRequest = seam . devices . get ( { device_id : seed . august_device_1 } )
12+ const request = seam . devices . get ( { device_id : seed . august_device_1 } )
1313
14- t . true ( deviceRequest instanceof SeamHttpRequest )
15- t . is ( deviceRequest . url . pathname , '/devices/get' )
16- t . deepEqual ( deviceRequest . body , {
14+ t . true ( request instanceof SeamHttpRequest )
15+ t . truthy ( request . url )
16+ t . is ( request . responseKey , 'device' )
17+ t . deepEqual ( request . body , {
1718 device_id : seed . august_device_1 ,
1819 } )
19- t . is ( deviceRequest . responseKey , 'device' )
20- const device = await deviceRequest
20+
21+ const device = await request
2122 t . is ( device . workspace_id , seed . seed_workspace_1 )
2223 t . is ( device . device_id , seed . august_device_1 )
2324
2425 // Ensure that the type of the response is correct.
25- type Expected = ResponseFromSeamHttpRequest < typeof deviceRequest >
26-
26+ type Expected = ResponseFromSeamHttpRequest < typeof request >
2727 const validDeviceType : Expected [ 'device_type' ] = 'august_lock'
2828 t . truthy ( validDeviceType )
2929
30- // @ts -expect-error because it's an invalid device type.
30+ // @ts -expect-error invalid device type.
3131 const invalidDeviceType : Expected [ 'device_type' ] = 'invalid_device_type'
3232 t . truthy ( invalidDeviceType )
3333} )
3434
35- test ( "populates SeamHttpRequest's url property" , async ( t ) => {
35+ test ( 'SeamHttpRequest: url is a URL for post requests' , async ( t ) => {
36+ const { seed, endpoint } = await getTestServer ( t )
37+ const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , { endpoint } )
38+
39+ const { url } = seam . devices . get ( { device_id : 'abc123' } )
40+
41+ t . true ( url instanceof URL )
42+ t . deepEqual (
43+ toPlainUrlObject ( url ) ,
44+ toPlainUrlObject ( new URL ( `${ endpoint } /devices/get` ) ) ,
45+ )
46+ } )
47+
48+ test ( 'SeamHttpRequest: url is a URL for get requests' , async ( t ) => {
3649 const { seed, endpoint } = await getTestServer ( t )
3750 const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , { endpoint } )
3851
39- const deviceRequest = seam . devices . get ( { device_id : 'abc123' } )
52+ const { url } = seam . connectWebviews . view ( {
53+ connect_webview_id : 'connect_webview_1' ,
54+ auth_token : 'auth_token_1' ,
55+ } )
56+
57+ t . true ( url instanceof URL )
58+ t . deepEqual (
59+ toPlainUrlObject ( url ) ,
60+ toPlainUrlObject (
61+ new URL (
62+ `${ endpoint } /connect_webviews/view?auth_token=auth_token_1&connect_webview_id=connect_webview_1` ,
63+ ) ,
64+ ) ,
65+ )
66+ } )
67+
68+ test ( 'SeamHttpRequest: url is a URL when endpoint is a url without a path' , async ( t ) => {
69+ const { seed } = await getTestServer ( t )
70+ const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , {
71+ endpoint : 'https://example.com' ,
72+ } )
73+
74+ const { url } = seam . devices . get ( { device_id : 'abc123' } )
4075
41- t . is ( deviceRequest . url . pathname , '/devices/get' )
42- t . is ( deviceRequest . url . search , '' )
76+ t . true ( url instanceof URL )
77+ t . deepEqual (
78+ toPlainUrlObject ( url ) ,
79+ toPlainUrlObject ( new URL ( 'https://example.com/devices/get' ) ) ,
80+ )
81+ } )
4382
44- const connectWebviewsViewRequest = seam . connectWebviews . view ( {
45- connect_webview_id : 'abc123' ,
46- auth_token : 'invalid' ,
83+ test ( 'SeamHttpRequest: url is a URL when endpoint is a url with a path' , async ( t ) => {
84+ const { seed } = await getTestServer ( t )
85+ const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , {
86+ endpoint : 'https://example.com/some/sub/path' ,
4787 } )
4888
49- t . is ( connectWebviewsViewRequest . url . pathname , '/connect_webviews/view' )
50- t . is ( connectWebviewsViewRequest . url . searchParams . get ( 'auth_token' ) , 'invalid' )
51- t . is (
52- connectWebviewsViewRequest . url . searchParams . get ( 'connect_webview_id' ) ,
53- 'abc123' ,
89+ const { url } = seam . devices . get ( { device_id : 'abc123' } )
90+
91+ t . true ( url instanceof URL )
92+ t . deepEqual (
93+ toPlainUrlObject ( url ) ,
94+ toPlainUrlObject ( new URL ( 'https://example.com/some/sub/path/devices/get' ) ) ,
5495 )
5596} )
5697
98+ test . failing (
99+ 'SeamHttpRequest: url is a URL when endpoint is path' ,
100+ async ( t ) => {
101+ const { seed } = await getTestServer ( t )
102+ const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , {
103+ endpoint : '/some/sub/path' ,
104+ } )
105+
106+ const { url } = seam . devices . get ( { device_id : 'abc123' } )
107+
108+ t . true ( url instanceof URL )
109+ t . deepEqual (
110+ toPlainUrlObject ( url ) ,
111+ toPlainUrlObject (
112+ new URL ( 'https://example.com/some/sub/path/devices/get' ) ,
113+ ) ,
114+ )
115+ } ,
116+ )
117+
118+ test . failing (
119+ 'SeamHttpRequest: url is a URL when endpoint is empty' ,
120+ async ( t ) => {
121+ const { seed } = await getTestServer ( t )
122+ const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , {
123+ endpoint : '' ,
124+ } )
125+
126+ // TODO: Set globalThis.location.origin = 'https://example.com'
127+
128+ const { url } = seam . devices . get ( { device_id : 'abc123' } )
129+
130+ t . true ( url instanceof URL )
131+ t . deepEqual (
132+ toPlainUrlObject ( url ) ,
133+ toPlainUrlObject ( new URL ( 'https://example.com/devices/get' ) ) ,
134+ )
135+ } ,
136+ )
137+
138+ test ( 'SeamHttpRequest: url throws if unable to resolve origin' , async ( t ) => {
139+ const { seed } = await getTestServer ( t )
140+ const seam = SeamHttp . fromApiKey ( seed . seam_apikey1_token , {
141+ endpoint : '' ,
142+ } )
143+
144+ const request = seam . devices . get ( { device_id : 'abc123' } )
145+
146+ t . throws ( ( ) => request . url , { message : / C a n n o t r e s o l v e o r i g i n / } )
147+ } )
148+
149+ const toPlainUrlObject = ( url : URL ) : Omit < URL , 'searchParams' | 'toJSON' > => {
150+ return {
151+ pathname : url . pathname ,
152+ hash : url . hash ,
153+ hostname : url . hostname ,
154+ protocol : url . protocol ,
155+ username : url . username ,
156+ port : url . port ,
157+ password : url . password ,
158+ host : url . host ,
159+ href : url . href ,
160+ origin : url . origin ,
161+ search : url . search ,
162+ }
163+ }
164+
57165type ResponseFromSeamHttpRequest < T > =
58166 T extends SeamHttpRequest < any , infer TResponse , infer TResponseKey >
59167 ? TResponseKey extends keyof TResponse
0 commit comments