diff options
author | Matt Mastracci <matthew@mastracci.com> | 2024-02-10 13:22:13 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-10 20:22:13 +0000 |
commit | f5e46c9bf2f50d66a953fa133161fc829cecff06 (patch) | |
tree | 8faf2f5831c1c7b11d842cd9908d141082c869a5 /tests/unit/cache_api_test.ts | |
parent | d2477f780630a812bfd65e3987b70c0d309385bb (diff) |
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests ->
tests, and updates of relative paths for files.
This is the first step towards aggregate all of the integration test
files under tests/, which will lead to a set of integration tests that
can run without the CLI binary being built.
While we could leave these tests under `cli`, it would require us to
keep a more complex directory structure for the various test runners. In
addition, we have a lot of complexity to ignore various test files in
the `cli` project itself (cargo publish exclusion rules, autotests =
false, etc).
And finally, the `tests/` folder will eventually house the `test_ffi`,
`test_napi` and other testing code, reducing the size of the root repo
directory.
For easier review, the extremely large and noisy "move" is in the first
commit (with no changes -- just a move), while the remainder of the
changes to actual files is in the second commit.
Diffstat (limited to 'tests/unit/cache_api_test.ts')
-rw-r--r-- | tests/unit/cache_api_test.ts | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/tests/unit/cache_api_test.ts b/tests/unit/cache_api_test.ts new file mode 100644 index 000000000..792929870 --- /dev/null +++ b/tests/unit/cache_api_test.ts @@ -0,0 +1,207 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +import { + assert, + assertEquals, + assertFalse, + assertRejects, + assertThrows, +} from "./test_util.ts"; + +Deno.test(async function cacheStorage() { + const cacheName = "cache-v1"; + const _cache = await caches.open(cacheName); + assert(await caches.has(cacheName)); + assert(await caches.delete(cacheName)); + assertFalse(await caches.has(cacheName)); +}); + +Deno.test(async function cacheApi() { + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + // Test cache.put() with url string as key. + { + const req = "https://deno.com"; + await cache.put(req, new Response("deno.com - key is string")); + const res = await cache.match(req); + assertEquals(await res?.text(), "deno.com - key is string"); + assert(await cache.delete(req)); + } + // Test cache.put() with url instance as key. + { + const req = new URL("https://deno.com"); + await cache.put(req, new Response("deno.com - key is URL")); + const res = await cache.match(req); + assertEquals(await res?.text(), "deno.com - key is URL"); + assert(await cache.delete(req)); + } + // Test cache.put() with request instance as key. + { + const req = new Request("https://deno.com"); + await cache.put(req, new Response("deno.com - key is Request")); + const res = await cache.match(req); + assertEquals(await res?.text(), "deno.com - key is Request"); + assert(await cache.delete(req)); + } + + // Test cache.put() throws with response Vary header set to *. + { + const req = new Request("https://deno.com"); + assertRejects( + async () => { + await cache.put( + req, + new Response("deno.com - key is Request", { + headers: { Vary: "*" }, + }), + ); + }, + TypeError, + "Vary header must not contain '*'", + ); + } + + // Test cache.match() with same url but different values for Vary header. + { + await cache.put( + new Request("https://example.com/", { + headers: { + "Accept": "application/json", + }, + }), + Response.json({ msg: "hello world" }, { + headers: { + "Content-Type": "application/json", + "Vary": "Accept", + }, + }), + ); + const res = await cache.match("https://example.com/"); + assertEquals(res, undefined); + const res2 = await cache.match( + new Request("https://example.com/", { + headers: { "Accept": "text/html" }, + }), + ); + assertEquals(res2, undefined); + + const res3 = await cache.match( + new Request("https://example.com/", { + headers: { "Accept": "application/json" }, + }), + ); + assertEquals(await res3?.json(), { msg: "hello world" }); + } + + assert(await caches.delete(cacheName)); + assertFalse(await caches.has(cacheName)); +}); + +Deno.test(function cacheIllegalConstructor() { + assertThrows(() => new Cache(), TypeError, "Illegal constructor"); + // @ts-expect-error illegal constructor + assertThrows(() => new Cache("foo", "bar"), TypeError, "Illegal constructor"); +}); + +Deno.test(async function cachePutReaderLock() { + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + + const response = new Response("consumed"); + + const promise = cache.put( + new Request("https://example.com/"), + response, + ); + + await assertRejects( + async () => { + await response.arrayBuffer(); + }, + TypeError, + "Body already consumed.", + ); + + await promise; +}); + +Deno.test(async function cachePutResourceLeak() { + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + + const stream = new ReadableStream({ + start(controller) { + controller.error(new Error("leak")); + }, + }); + + await assertRejects( + async () => { + await cache.put( + new Request("https://example.com/leak"), + new Response(stream), + ); + }, + Error, + "leak", + ); +}); + +Deno.test(async function cachePutFailedBody() { + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + + const request = new Request("https://example.com/failed-body"); + const stream = new ReadableStream({ + start(controller) { + controller.error(new Error("corrupt")); + }, + }); + + await assertRejects( + async () => { + await cache.put( + request, + new Response(stream), + ); + }, + Error, + "corrupt", + ); + + const response = await cache.match(request); + // if it fails to read the body, the cache should be empty + assertEquals(response, undefined); +}); + +Deno.test(async function cachePutOverwrite() { + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + + const request = new Request("https://example.com/overwrite"); + const res1 = new Response("res1"); + const res2 = new Response("res2"); + + await cache.put(request, res1); + const res = await cache.match(request); + assertEquals(await res?.text(), "res1"); + + await cache.put(request, res2); + const res_ = await cache.match(request); + assertEquals(await res_?.text(), "res2"); +}); + +// Ensure that we can successfully put a response backed by a resource +Deno.test(async function cachePutResource() { + const tempFile = Deno.makeTempFileSync({ prefix: "deno-", suffix: ".txt" }); + Deno.writeTextFileSync(tempFile, "Contents".repeat(1024)); + + const file = Deno.openSync(tempFile); + + const cacheName = "cache-v1"; + const cache = await caches.open(cacheName); + + const request = new Request("https://example.com/file"); + await cache.put(request, new Response(file.readable)); + const res = await cache.match(request); + assertEquals(await res?.text(), "Contents".repeat(1024)); +}); |