summaryrefslogtreecommitdiff
path: root/packages/integrations/node/test
diff options
context:
space:
mode:
Diffstat (limited to 'packages/integrations/node/test')
-rw-r--r--packages/integrations/node/test/api-route.test.js45
-rw-r--r--packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts16
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/package.json (renamed from packages/integrations/node/test/fixtures/prerender-404/package.json)3
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css3
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts17
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts17
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro5
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro6
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro4
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404-500/src/pages/static.astro (renamed from packages/integrations/node/test/fixtures/prerender-404/src/pages/static.astro)0
-rw-r--r--packages/integrations/node/test/fixtures/prerender-404/src/pages/404.astro5
-rw-r--r--packages/integrations/node/test/prerender-404-500.test.js (renamed from packages/integrations/node/test/prerender-404.test.js)144
12 files changed, 232 insertions, 33 deletions
diff --git a/packages/integrations/node/test/api-route.test.js b/packages/integrations/node/test/api-route.test.js
index 7fbd95776..c830eee2d 100644
--- a/packages/integrations/node/test/api-route.test.js
+++ b/packages/integrations/node/test/api-route.test.js
@@ -1,6 +1,7 @@
import nodejs from '../dist/index.js';
import { loadFixture, createRequestAndResponse } from './test-utils.js';
import { expect } from 'chai';
+import crypto from 'node:crypto';
describe('API routes', () => {
/** @type {import('./test-utils').Fixture} */
@@ -22,9 +23,11 @@ describe('API routes', () => {
url: '/recipes',
});
- handler(req, res);
+ req.once('async_iterator', () => {
+ req.send(JSON.stringify({ id: 2 }));
+ });
- req.send(JSON.stringify({ id: 2 }));
+ handler(req, res);
let [buffer] = await done;
@@ -43,11 +46,47 @@ describe('API routes', () => {
url: '/binary',
});
+ req.once('async_iterator', () => {
+ req.send(Buffer.from(new Uint8Array([1, 2, 3, 4, 5])));
+ });
+
handler(req, res);
- req.send(Buffer.from(new Uint8Array([1, 2, 3, 4, 5])));
let [out] = await done;
let arr = Array.from(new Uint8Array(out.buffer));
expect(arr).to.deep.equal([5, 4, 3, 2, 1]);
});
+
+ it('Can post large binary data', async () => {
+ const { handler } = await import('./fixtures/api-route/dist/server/entry.mjs');
+
+ let { req, res, done } = createRequestAndResponse({
+ method: 'POST',
+ url: '/hash',
+ });
+
+ handler(req, res);
+
+ let expectedDigest = null;
+ req.once('async_iterator', () => {
+ // Send 256MB of garbage data in 256KB chunks. This should be fast (< 1sec).
+ let remainingBytes = 256 * 1024 * 1024;
+ const chunkSize = 256 * 1024;
+
+ const hash = crypto.createHash('sha256');
+ while (remainingBytes > 0) {
+ const size = Math.min(remainingBytes, chunkSize);
+ const chunk = Buffer.alloc(size, Math.floor(Math.random() * 256));
+ hash.update(chunk);
+ req.emit('data', chunk);
+ remainingBytes -= size;
+ }
+
+ req.emit('end');
+ expectedDigest = hash.digest();
+ });
+
+ let [out] = await done;
+ expect(new Uint8Array(out.buffer)).to.deep.equal(expectedDigest);
+ });
});
diff --git a/packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts b/packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts
new file mode 100644
index 000000000..fbf44c547
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/api-route/src/pages/hash.ts
@@ -0,0 +1,16 @@
+import crypto from 'node:crypto';
+
+export async function post({ request }: { request: Request }) {
+ const hash = crypto.createHash('sha256');
+
+ const iterable = request.body as unknown as AsyncIterable<Uint8Array>;
+ for await (const chunk of iterable) {
+ hash.update(chunk);
+ }
+
+ return new Response(hash.digest(), {
+ headers: {
+ 'Content-Type': 'application/octet-stream'
+ }
+ });
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404/package.json b/packages/integrations/node/test/fixtures/prerender-404-500/package.json
index dfd109c91..f962fe991 100644
--- a/packages/integrations/node/test/fixtures/prerender-404/package.json
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/package.json
@@ -1,7 +1,8 @@
{
- "name": "@test/nodejs-prerender-404",
+ "name": "@test/nodejs-prerender-404-500",
"version": "0.0.0",
"private": true,
+ "type": "module",
"dependencies": {
"astro": "workspace:*",
"@astrojs/node": "workspace:*"
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css b/packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css
new file mode 100644
index 000000000..5f331948a
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/external-stylesheet.css
@@ -0,0 +1,3 @@
+body {
+ background-color: ivory;
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts
new file mode 100644
index 000000000..1795c26b0
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-404.ts
@@ -0,0 +1,17 @@
+// This module is only used by the prerendered 404.astro.
+// It exhibits different behavior if it's called more than once,
+// which is detected by a test and interpreted as a failure.
+
+let usedOnce = false
+let dynamicMessage = "Page was not prerendered"
+
+export default function () {
+ if (usedOnce === false) {
+ usedOnce = true
+ return "Page does not exist"
+ }
+
+ dynamicMessage += "+"
+
+ return dynamicMessage
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts
new file mode 100644
index 000000000..8f8024a60
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/nondeterminism-500.ts
@@ -0,0 +1,17 @@
+// This module is only used by the prerendered 500.astro.
+// It exhibits different behavior if it's called more than once,
+// which is detected by a test and interpreted as a failure.
+
+let usedOnce = false
+let dynamicMessage = "Page was not prerendered"
+
+export default function () {
+ if (usedOnce === false) {
+ usedOnce = true
+ return "Something went wrong"
+ }
+
+ dynamicMessage += "+"
+
+ return dynamicMessage
+}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro
new file mode 100644
index 000000000..37fd1c1d3
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/404.astro
@@ -0,0 +1,5 @@
+---
+import message from "../nondeterminism-404"
+export const prerender = true;
+---
+{message()}
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro
new file mode 100644
index 000000000..ef91ad0ff
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/500.astro
@@ -0,0 +1,6 @@
+---
+import "../external-stylesheet.css"
+import message from "../nondeterminism-500"
+export const prerender = true
+---
+<h1>{message()}</h1>
diff --git a/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro
new file mode 100644
index 000000000..99d103567
--- /dev/null
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/fivehundred.astro
@@ -0,0 +1,4 @@
+---
+return new Response(null, { status: 500 })
+---
+<p>This html will not be served</p>
diff --git a/packages/integrations/node/test/fixtures/prerender-404/src/pages/static.astro b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/static.astro
index af6bad2fb..af6bad2fb 100644
--- a/packages/integrations/node/test/fixtures/prerender-404/src/pages/static.astro
+++ b/packages/integrations/node/test/fixtures/prerender-404-500/src/pages/static.astro
diff --git a/packages/integrations/node/test/fixtures/prerender-404/src/pages/404.astro b/packages/integrations/node/test/fixtures/prerender-404/src/pages/404.astro
deleted file mode 100644
index 230402bbc..000000000
--- a/packages/integrations/node/test/fixtures/prerender-404/src/pages/404.astro
+++ /dev/null
@@ -1,5 +0,0 @@
----
-export const prerender = true;
----
-
-Page does not exist
diff --git a/packages/integrations/node/test/prerender-404.test.js b/packages/integrations/node/test/prerender-404-500.test.js
index 3a39a9470..8816ebe4c 100644
--- a/packages/integrations/node/test/prerender-404.test.js
+++ b/packages/integrations/node/test/prerender-404-500.test.js
@@ -9,10 +9,11 @@ import * as cheerio from 'cheerio';
async function load() {
const mod = await import(
- `./fixtures/prerender-404/dist/server/entry.mjs?dropcache=${Date.now()}`
+ `./fixtures/prerender-404-500/dist/server/entry.mjs?dropcache=${Date.now()}`
);
return mod;
}
+
describe('Prerender 404', () => {
/** @type {import('./test-utils').Fixture} */
let fixture;
@@ -24,8 +25,12 @@ describe('Prerender 404', () => {
process.env.PRERENDER = true;
fixture = await loadFixture({
+ // inconsequential config that differs between tests
+ // to bust cache and prevent modules and their state
+ // from being reused
+ site: 'https://test.dev/',
base: '/some-base',
- root: './fixtures/prerender-404/',
+ root: './fixtures/prerender-404-500/',
output: 'server',
adapter: nodejs({ mode: 'standalone' }),
});
@@ -51,13 +56,53 @@ describe('Prerender 404', () => {
});
it('Can handle prerendered 404', async () => {
- const res = await fetch(`http://${server.host}:${server.port}/some-base/missing`);
- const html = await res.text();
- const $ = cheerio.load(html);
+ const url = `http://${server.host}:${server.port}/some-base/missing`;
+ const res1 = await fetch(url);
+ const res2 = await fetch(url);
+ const res3 = await fetch(url);
+
+ expect(res1.status).to.equal(404);
+ expect(res2.status).to.equal(404);
+ expect(res3.status).to.equal(404);
+
+ const html1 = await res1.text();
+ const html2 = await res2.text();
+ const html3 = await res3.text();
+
+ expect(html1).to.equal(html2);
+ expect(html2).to.equal(html3);
+
+ const $ = cheerio.load(html1);
- expect(res.status).to.equal(404);
expect($('body').text()).to.equal('Page does not exist');
});
+
+ it(' Can handle prerendered 500 called indirectly', async () => {
+ const url = `http://${server.host}:${server.port}/some-base/fivehundred`;
+ const response1 = await fetch(url);
+ const response2 = await fetch(url);
+ const response3 = await fetch(url);
+
+ expect(response1.status).to.equal(500);
+
+ const html1 = await response1.text();
+ const html2 = await response2.text();
+ const html3 = await response3.text();
+
+ expect(html1).to.contain('Something went wrong');
+
+ expect(html1).to.equal(html2);
+ expect(html2).to.equal(html3);
+ });
+
+ it('prerendered 500 page includes expected styles', async () => {
+ const response = await fetch(`http://${server.host}:${server.port}/some-base/fivehundred`);
+ const html = await response.text();
+ const $ = cheerio.load(html);
+
+ // length will be 0 if the stylesheet does not get included
+ expect($('link[rel=stylesheet]')).to.have.a.lengthOf(1);
+ });
});
describe('Without base', async () => {
@@ -66,12 +111,16 @@ describe('Prerender 404', () => {
process.env.PRERENDER = true;
fixture = await loadFixture({
- root: './fixtures/prerender-404/',
+ // inconsequential config that differs between tests
+ // to bust cache and prevent modules and their state
+ // from being reused
+ site: 'https://test.info/',
+ root: './fixtures/prerender-404-500/',
output: 'server',
adapter: nodejs({ mode: 'standalone' }),
});
await fixture.build();
- const { startServer } = await await load();
+ const { startServer } = await load();
let res = startServer();
server = res.server;
});
@@ -92,11 +141,24 @@ describe('Prerender 404', () => {
});
it('Can handle prerendered 404', async () => {
- const res = await fetch(`http://${server.host}:${server.port}/missing`);
- const html = await res.text();
- const $ = cheerio.load(html);
+ const url = `http://${server.host}:${server.port}/some-base/missing`;
+ const res1 = await fetch(url);
+ const res2 = await fetch(url);
+ const res3 = await fetch(url);
+
+ expect(res1.status).to.equal(404);
+ expect(res2.status).to.equal(404);
+ expect(res3.status).to.equal(404);
+
+ const html1 = await res1.text();
+ const html2 = await res2.text();
+ const html3 = await res3.text();
+
+ expect(html1).to.equal(html2);
+ expect(html2).to.equal(html3);
+
+ const $ = cheerio.load(html1);
- expect(res.status).to.equal(404);
expect($('body').text()).to.equal('Page does not exist');
});
});
@@ -112,13 +174,17 @@ describe('Hybrid 404', () => {
process.env.ASTRO_NODE_AUTOSTART = 'disabled';
process.env.PRERENDER = false;
fixture = await loadFixture({
+ // inconsequential config that differs between tests
+ // to bust cache and prevent modules and their state
+ // from being reused
+ site: 'https://test.com/',
base: '/some-base',
- root: './fixtures/prerender-404/',
+ root: './fixtures/prerender-404-500/',
output: 'hybrid',
adapter: nodejs({ mode: 'standalone' }),
});
await fixture.build();
- const { startServer } = await await load();
+ const { startServer } = await load();
let res = startServer();
server = res.server;
});
@@ -139,11 +205,24 @@ describe('Hybrid 404', () => {
});
it('Can handle prerendered 404', async () => {
- const res = await fetch(`http://${server.host}:${server.port}/some-base/missing`);
- const html = await res.text();
- const $ = cheerio.load(html);
+ const url = `http://${server.host}:${server.port}/some-base/missing`;
+ const res1 = await fetch(url);
+ const res2 = await fetch(url);
+ const res3 = await fetch(url);
+
+ expect(res1.status).to.equal(404);
+ expect(res2.status).to.equal(404);
+ expect(res3.status).to.equal(404);
+
+ const html1 = await res1.text();
+ const html2 = await res2.text();
+ const html3 = await res3.text();
+
+ expect(html1).to.equal(html2);
+ expect(html2).to.equal(html3);
+
+ const $ = cheerio.load(html1);
- expect(res.status).to.equal(404);
expect($('body').text()).to.equal('Page does not exist');
});
});
@@ -153,12 +232,16 @@ describe('Hybrid 404', () => {
process.env.ASTRO_NODE_AUTOSTART = 'disabled';
process.env.PRERENDER = false;
fixture = await loadFixture({
- root: './fixtures/prerender-404/',
+ // inconsequential config that differs between tests
+ // to bust cache and prevent modules and their state
+ // from being reused
+ site: 'https://test.net/',
+ root: './fixtures/prerender-404-500/',
output: 'hybrid',
adapter: nodejs({ mode: 'standalone' }),
});
await fixture.build();
- const { startServer } = await await load();
+ const { startServer } = await load();
let res = startServer();
server = res.server;
});
@@ -179,11 +262,24 @@ describe('Hybrid 404', () => {
});
it('Can handle prerendered 404', async () => {
- const res = await fetch(`http://${server.host}:${server.port}/missing`);
- const html = await res.text();
- const $ = cheerio.load(html);
+ const url = `http://${server.host}:${server.port}/missing`;
+ const res1 = await fetch(url);
+ const res2 = await fetch(url);
+ const res3 = await fetch(url);
+
+ expect(res1.status).to.equal(404);
+ expect(res2.status).to.equal(404);
+ expect(res3.status).to.equal(404);
+
+ const html1 = await res1.text();
+ const html2 = await res2.text();
+ const html3 = await res3.text();
+
+ expect(html1).to.equal(html2);
+ expect(html2).to.equal(html3);
+
+ const $ = cheerio.load(html1);
- expect(res.status).to.equal(404);
expect($('body').text()).to.equal('Page does not exist');
});
});