Skip to content

Commit f639ff1

Browse files
committed
Add URLSearchParams constructor tests
Tests for object, array-of-pairs, copy, size, encoding, and fetch body usage. Points runtime-v8 to local path for development.
1 parent 9521a40 commit f639ff1

3 files changed

Lines changed: 139 additions & 4 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ openworkers-core = { git = "https://github.com/openworkers/openworkers-core", ta
6262
openworkers-transform = { git = "https://github.com/openworkers/openworkers-transform", tag = "v0.1.0" }
6363

6464
# Runtime backend (v8 only for now, others require older version of core)
65-
openworkers-runtime-v8 = { git = "https://github.com/openworkers/openworkers-runtime-v8", tag = "v0.13.7", optional = true, features = ["ptrcomp"] }
65+
openworkers-runtime-v8 = { path = "../openworkers-runtime-v8", optional = true, features = ["ptrcomp"] }
6666

6767
# WASM runtime (optional)
6868
# openworkers-runtime-wasm = { path = "../openworkers-runtime-wasm", optional = true }

tests/web_api_test.rs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,143 @@ async fn test_url_search_params_encoding() {
278278
.await;
279279
}
280280

281+
// ============================================================================
282+
// URLSearchParams constructor variants
283+
// ============================================================================
284+
285+
#[tokio::test]
286+
async fn test_url_search_params_from_object() {
287+
run_local(|| async {
288+
let result = eval_js(
289+
r#"addEventListener('fetch', (event) => {
290+
const params = new URLSearchParams({
291+
grant_type: 'authorization_code',
292+
client_id: 'my-client',
293+
client_secret: 'my-secret',
294+
code: 'abc123'
295+
});
296+
event.respondWith(new Response(params.toString()));
297+
});"#,
298+
)
299+
.await;
300+
301+
assert_eq!(
302+
result,
303+
"grant_type=authorization_code&client_id=my-client&client_secret=my-secret&code=abc123"
304+
);
305+
})
306+
.await;
307+
}
308+
309+
#[tokio::test]
310+
async fn test_url_search_params_from_object_encodes_special_chars() {
311+
run_local(|| async {
312+
let result = eval_js(
313+
r#"addEventListener('fetch', (event) => {
314+
const params = new URLSearchParams({
315+
redirect_uri: 'https://example.com/callback?foo=bar',
316+
scope: 'read write'
317+
});
318+
event.respondWith(new Response(params.toString()));
319+
});"#,
320+
)
321+
.await;
322+
323+
assert_eq!(
324+
result,
325+
"redirect_uri=https%3A%2F%2Fexample.com%2Fcallback%3Ffoo%3Dbar&scope=read%20write"
326+
);
327+
})
328+
.await;
329+
}
330+
331+
#[tokio::test]
332+
async fn test_url_search_params_from_array_of_pairs() {
333+
run_local(|| async {
334+
let result = eval_js(
335+
r#"addEventListener('fetch', (event) => {
336+
const params = new URLSearchParams([['a', '1'], ['b', '2'], ['a', '3']]);
337+
const all = params.getAll('a');
338+
event.respondWith(new Response(params.toString() + '|' + all.join(',')));
339+
});"#,
340+
)
341+
.await;
342+
343+
assert_eq!(result, "a=1&b=2&a=3|1,3");
344+
})
345+
.await;
346+
}
347+
348+
#[tokio::test]
349+
async fn test_url_search_params_from_another_instance() {
350+
run_local(|| async {
351+
let result = eval_js(
352+
r#"addEventListener('fetch', (event) => {
353+
const original = new URLSearchParams('x=1&y=2');
354+
const copy = new URLSearchParams(original);
355+
copy.set('y', '99');
356+
// original should be unaffected
357+
event.respondWith(new Response(original.toString() + '|' + copy.toString()));
358+
});"#,
359+
)
360+
.await;
361+
362+
assert_eq!(result, "x=1&y=2|x=1&y=99");
363+
})
364+
.await;
365+
}
366+
367+
#[tokio::test]
368+
async fn test_url_search_params_size() {
369+
run_local(|| async {
370+
let result = eval_js(
371+
r#"addEventListener('fetch', (event) => {
372+
const empty = new URLSearchParams();
373+
const three = new URLSearchParams('a=1&b=2&c=3');
374+
event.respondWith(new Response(empty.size + ',' + three.size));
375+
});"#,
376+
)
377+
.await;
378+
379+
assert_eq!(result, "0,3");
380+
})
381+
.await;
382+
}
383+
384+
#[tokio::test]
385+
async fn test_url_search_params_as_fetch_body() {
386+
run_local(|| async {
387+
let result = eval_js(
388+
r#"addEventListener('fetch', (event) => {
389+
// Simulate what the PlanetScale OAuth code does:
390+
// new URLSearchParams({...}) passed as body to fetch
391+
const params = new URLSearchParams({
392+
grant_type: 'authorization_code',
393+
client_id: 'abc',
394+
code: 'xyz'
395+
});
396+
397+
// fetch() calls body.toString() — verify it produces valid form data
398+
const body = params.toString();
399+
const reparsed = new URLSearchParams(body);
400+
401+
const ok = reparsed.get('grant_type') === 'authorization_code'
402+
&& reparsed.get('client_id') === 'abc'
403+
&& reparsed.get('code') === 'xyz';
404+
405+
event.respondWith(new Response(ok ? body : 'FAIL: ' + body));
406+
});"#,
407+
)
408+
.await;
409+
410+
assert_eq!(
411+
result,
412+
"grant_type=authorization_code&client_id=abc&code=xyz"
413+
);
414+
})
415+
.await;
416+
}
417+
281418
// ============================================================================
282419
// btoa / atob (binary strings, NOT UTF-8)
283420
// ============================================================================

0 commit comments

Comments
 (0)