Skip to content

Commit b3de0cd

Browse files
committed
Add tests for endpoints with and without origins
1 parent c157717 commit b3de0cd

File tree

2 files changed

+106
-10
lines changed

2 files changed

+106
-10
lines changed

src/lib/seam/connect/seam-http-request.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,22 +46,23 @@ export class SeamHttpRequest<
4646

4747
public get url(): URL {
4848
const { client } = this.#parent
49-
const baseUrl = client.defaults.baseURL
50-
if (baseUrl === undefined) {
51-
throw new Error('baseUrl is required')
52-
}
53-
54-
const params = this.#config.params
55-
if (params === undefined) {
56-
return new URL(this.#config.path, baseUrl)
57-
}
49+
const { params } = this.#config
5850

5951
const serializer =
6052
typeof client.defaults.paramsSerializer === 'function'
6153
? client.defaults.paramsSerializer
6254
: serializeUrlSearchParams
6355

64-
return new URL(`${this.#config.path}?${serializer(params)}`, baseUrl)
56+
const origin = getUrlPrefix(client.defaults.baseURL ?? '')
57+
58+
const pathname = this.#config.path.startsWith('/')
59+
? this.#config.path
60+
: `/${this.#config.path}`
61+
62+
const path =
63+
params == null ? pathname : [pathname, serializer(params)].join('?')
64+
65+
return new URL([origin, path].join(''))
6566
}
6667

6768
public get method(): Method {
@@ -128,3 +129,17 @@ export class SeamHttpRequest<
128129
return this.execute().then(onfulfilled, onrejected)
129130
}
130131
}
132+
133+
const getUrlPrefix = (input: string): string => {
134+
try {
135+
const url = new URL(input).toString()
136+
if (url.endsWith('/')) return url.slice(0, -1)
137+
return url
138+
} catch (err: unknown) {
139+
if (globalThis.location != null) {
140+
const pathname = input.startsWith('/') ? input : `/${input}`
141+
return new URL([globalThis.location.origin, pathname].join('')).toString()
142+
}
143+
throw err
144+
}
145+
}

test/seam/connect/seam-http-request.test.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,87 @@ test('SeamHttpRequest: url is a URL for get requests', async (t) => {
6565
)
6666
})
6767

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' })
75+
76+
t.true(url instanceof URL)
77+
t.deepEqual(
78+
toPlainUrlObject(url),
79+
toPlainUrlObject(new URL('https://example.com/devices/get')),
80+
)
81+
})
82+
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',
87+
})
88+
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')),
95+
)
96+
})
97+
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, { code: 'ERR_INVALID_URL' })
147+
})
148+
68149
const toPlainUrlObject = (url: URL): Omit<URL, 'searchParams' | 'toJSON'> => {
69150
return {
70151
pathname: url.pathname,

0 commit comments

Comments
 (0)