From 5371efe42950be7b17739d99ae017b50b6ad459a Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Tue, 2 May 2023 22:10:33 +0800 Subject: [PATCH] Improve undici fetch failed errors in tests (#6960) --- .../astro/test/astro-get-static-paths.test.js | 174 +++++---------- .../ssr-prerender-get-static-paths.test.js | 206 ++++++------------ packages/astro/test/test-utils.js | 14 +- 3 files changed, 139 insertions(+), 255 deletions(-) diff --git a/packages/astro/test/astro-get-static-paths.test.js b/packages/astro/test/astro-get-static-paths.test.js index 3211f3318a..9914eb9384 100644 --- a/packages/astro/test/astro-get-static-paths.test.js +++ b/packages/astro/test/astro-get-static-paths.test.js @@ -3,11 +3,11 @@ import { loadFixture } from './test-utils.js'; import * as cheerio from 'cheerio'; describe('getStaticPaths - build calls', () => { - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; + /** @type {import('./test-utils').Fixture} */ + let fixture; - const fixture = await loadFixture({ + before(async () => { + fixture = await loadFixture({ root: './fixtures/astro-get-static-paths/', site: 'https://mysite.dev/', base: '/blog', @@ -15,10 +15,22 @@ describe('getStaticPaths - build calls', () => { await fixture.build(); }); + afterEach(() => { + // reset the flag used by [...calledTwiceTest].astro between each test + globalThis.isCalledOnce = false; + }); + it('is only called once during build', () => { // useless expect; if build() throws in setup then this test fails expect(true).to.equal(true); }); + + it('Astro.url sets the current pathname', async () => { + const html = await fixture.readFile('/food/tacos/index.html'); + const $ = cheerio.load(html); + + expect($('#url').text()).to.equal('/blog/food/tacos/'); + }); }); describe('getStaticPaths - dev calls', () => { @@ -26,11 +38,16 @@ describe('getStaticPaths - dev calls', () => { let devServer; before(async () => { + fixture = await loadFixture({ + root: './fixtures/astro-get-static-paths/', + site: 'https://mysite.dev/', + }); + devServer = await fixture.startDevServer(); + }); + + afterEach(() => { // reset the flag used by [...calledTwiceTest].astro between each test globalThis.isCalledOnce = false; - - fixture = await loadFixture({ root: './fixtures/astro-get-static-paths/' }); - devServer = await fixture.startDevServer(); }); after(async () => { @@ -47,95 +64,46 @@ describe('getStaticPaths - dev calls', () => { res = await fixture.fetch('/c'); expect(res.status).to.equal(200); }); -}); -describe('getStaticPaths - 404 behavior', () => { - let fixture; - let devServer; - - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ root: './fixtures/astro-get-static-paths/' }); - devServer = await fixture.startDevServer(); - }); - - after(async () => { - devServer.stop(); - }); - - it('resolves 200 on matching static path - named params', async () => { - const res = await fixture.fetch('/pizza/provolone-sausage'); - expect(res.status).to.equal(200); - }); - - it('resolves 404 on pattern match without static path - named params', async () => { - const res = await fixture.fetch('/pizza/provolone-pineapple'); - expect(res.status).to.equal(404); - }); - - it('resolves 200 on matching static path - rest params', async () => { - const res = await fixture.fetch('/pizza/grimaldis/new-york'); - expect(res.status).to.equal(200); - }); - - it('resolves 404 on pattern match without static path - rest params', async () => { - const res = await fixture.fetch('/pizza/pizza-hut'); - expect(res.status).to.equal(404); - }); -}); - -describe('getStaticPaths - route params type validation', () => { - let fixture, devServer; - - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ root: './fixtures/astro-get-static-paths/' }); - devServer = await fixture.startDevServer(); - }); - - after(async () => { - await devServer.stop(); - }); - - it('resolves 200 on nested array parameters', async () => { - const res = await fixture.fetch('/nested-arrays/slug1'); - expect(res.status).to.equal(200); - }); - - it('resolves 200 on matching static path - string params', async () => { - // route provided with { params: { year: "2022", slug: "post-2" }} - const res = await fixture.fetch('/blog/2022/post-1'); - expect(res.status).to.equal(200); - }); - - it('resolves 200 on matching static path - numeric params', async () => { - // route provided with { params: { year: 2022, slug: "post-2" }} - const res = await fixture.fetch('/blog/2022/post-2'); - expect(res.status).to.equal(200); - }); -}); - -describe('getStaticPaths - numeric route params', () => { - let fixture; - let devServer; - - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ - root: './fixtures/astro-get-static-paths/', - site: 'https://mysite.dev/', + describe('404 behavior', () => { + it('resolves 200 on matching static path - named params', async () => { + const res = await fixture.fetch('/pizza/provolone-sausage'); + expect(res.status).to.equal(200); + }); + + it('resolves 404 on pattern match without static path - named params', async () => { + const res = await fixture.fetch('/pizza/provolone-pineapple'); + expect(res.status).to.equal(404); + }); + + it('resolves 200 on matching static path - rest params', async () => { + const res = await fixture.fetch('/pizza/grimaldis/new-york'); + expect(res.status).to.equal(200); + }); + + it('resolves 404 on pattern match without static path - rest params', async () => { + const res = await fixture.fetch('/pizza/pizza-hut'); + expect(res.status).to.equal(404); }); - devServer = await fixture.startDevServer(); }); - after(async () => { - await devServer.stop(); + describe('route params type validation', () => { + it('resolves 200 on nested array parameters', async () => { + const res = await fixture.fetch('/nested-arrays/slug1'); + expect(res.status).to.equal(200); + }); + + it('resolves 200 on matching static path - string params', async () => { + // route provided with { params: { year: "2022", slug: "post-2" }} + const res = await fixture.fetch('/blog/2022/post-1'); + expect(res.status).to.equal(200); + }); + + it('resolves 200 on matching static path - numeric params', async () => { + // route provided with { params: { year: 2022, slug: "post-2" }} + const res = await fixture.fetch('/blog/2022/post-2'); + expect(res.status).to.equal(200); + }); }); it('resolves 200 on matching static paths', async () => { @@ -155,25 +123,3 @@ describe('getStaticPaths - numeric route params', () => { } }); }); - -describe('getStaticPaths - Astro.url', () => { - /** @type {import('./test-utils').Fixture} */ - let fixture; - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ - root: './fixtures/astro-get-static-paths/', - site: 'https://mysite.dev/', - }); - await fixture.build(); - }); - - it('Sets the current pathname', async () => { - const html = await fixture.readFile('/food/tacos/index.html'); - const $ = cheerio.load(html); - - expect($('#url').text()).to.equal('/food/tacos/'); - }); -}); diff --git a/packages/astro/test/ssr-prerender-get-static-paths.test.js b/packages/astro/test/ssr-prerender-get-static-paths.test.js index b0253eabfc..f7100372b6 100644 --- a/packages/astro/test/ssr-prerender-get-static-paths.test.js +++ b/packages/astro/test/ssr-prerender-get-static-paths.test.js @@ -3,11 +3,11 @@ import { loadFixture } from './test-utils.js'; import * as cheerio from 'cheerio'; describe('prerender getStaticPaths - build calls', () => { - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; + /** @type {import('./test-utils').Fixture} */ + let fixture; - const fixture = await loadFixture({ + before(async () => { + fixture = await loadFixture({ root: './fixtures/ssr-prerender-get-static-paths/', site: 'https://mysite.dev/', base: '/blog', @@ -15,10 +15,23 @@ describe('prerender getStaticPaths - build calls', () => { await fixture.build(); }); + afterEach(() => { + // reset the flag used by [...calledTwiceTest].astro between each test + globalThis.isCalledOnce = false; + }); + it('is only called once during build', () => { // useless expect; if build() throws in setup then this test fails expect(true).to.equal(true); }); + + it('Astro.url sets the current pathname', async () => { + const html = await fixture.readFile('/food/tacos/index.html'); + const $ = cheerio.load(html); + + expect($('#props').text()).to.equal('10'); + expect($('#url').text()).to.equal('/blog/food/tacos/'); + }); }); describe('prerender getStaticPaths - dev calls', () => { @@ -26,11 +39,17 @@ describe('prerender getStaticPaths - dev calls', () => { let devServer; before(async () => { + globalThis.isCalledOnce = false; + fixture = await loadFixture({ + root: './fixtures/ssr-prerender-get-static-paths/', + site: 'https://mysite.dev/', + }); + devServer = await fixture.startDevServer(); + }); + + afterEach(() => { // reset the flag used by [...calledTwiceTest].astro between each test globalThis.isCalledOnce = false; - - fixture = await loadFixture({ root: './fixtures/ssr-prerender-get-static-paths/' }); - devServer = await fixture.startDevServer(); }); after(async () => { @@ -47,99 +66,50 @@ describe('prerender getStaticPaths - dev calls', () => { res = await fixture.fetch('/c'); expect(res.status).to.equal(200); }); -}); -describe('prerender getStaticPaths - 404 behavior', () => { - let fixture; - let devServer; - - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ root: './fixtures/ssr-prerender-get-static-paths/' }); - devServer = await fixture.startDevServer(); - }); - - after(async () => { - devServer.stop(); - }); - - it('resolves 200 on matching static path - named params', async () => { - const res = await fixture.fetch('/pizza/provolone-sausage'); - expect(res.status).to.equal(200); - }); - - it('resolves 404 on pattern match without static path - named params', async () => { - const res = await fixture.fetch('/pizza/provolone-pineapple'); - const html = await res.text(); - expect(res.status).to.equal(404); - expect(html).to.match(/404/); - }); - - it('resolves 200 on matching static path - rest params', async () => { - const res = await fixture.fetch('/pizza/grimaldis/new-york'); - expect(res.status).to.equal(200); - }); - - it('resolves 404 on pattern match without static path - rest params', async () => { - const res = await fixture.fetch('/pizza/pizza-hut'); - const html = await res.text(); - expect(res.status).to.equal(404); - expect(html).to.match(/404/); - }); -}); - -describe('prerender getStaticPaths - route params type validation', () => { - let fixture, devServer; - - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ root: './fixtures/ssr-prerender-get-static-paths/' }); - devServer = await fixture.startDevServer(); - }); - - after(async () => { - await devServer.stop(); - }); - - it('resolves 200 on nested array parameters', async () => { - const res = await fixture.fetch('/nested-arrays/slug1'); - expect(res.status).to.equal(200); - }); - - it('resolves 200 on matching static path - string params', async () => { - // route provided with { params: { year: "2022", slug: "post-2" }} - const res = await fixture.fetch('/blog/2022/post-1'); - expect(res.status).to.equal(200); - }); - - it('resolves 200 on matching static path - numeric params', async () => { - // route provided with { params: { year: 2022, slug: "post-2" }} - const res = await fixture.fetch('/blog/2022/post-2'); - expect(res.status).to.equal(200); - }); -}); - -describe('prerender getStaticPaths - numeric route params', () => { - let fixture; - let devServer; - - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ - root: './fixtures/ssr-prerender-get-static-paths/', - site: 'https://mysite.dev/', + describe('404 behavior', () => { + it('resolves 200 on matching static path - named params', async () => { + const res = await fixture.fetch('/pizza/provolone-sausage'); + expect(res.status).to.equal(200); + }); + + it('resolves 404 on pattern match without static path - named params', async () => { + const res = await fixture.fetch('/pizza/provolone-pineapple'); + const html = await res.text(); + expect(res.status).to.equal(404); + expect(html).to.match(/404/); + }); + + it('resolves 200 on matching static path - rest params', async () => { + const res = await fixture.fetch('/pizza/grimaldis/new-york'); + expect(res.status).to.equal(200); + }); + + it('resolves 404 on pattern match without static path - rest params', async () => { + const res = await fixture.fetch('/pizza/pizza-hut'); + const html = await res.text(); + expect(res.status).to.equal(404); + expect(html).to.match(/404/); }); - devServer = await fixture.startDevServer(); }); - after(async () => { - await devServer.stop(); + describe('route params type validation', () => { + it('resolves 200 on nested array parameters', async () => { + const res = await fixture.fetch('/nested-arrays/slug1'); + expect(res.status).to.equal(200); + }); + + it('resolves 200 on matching static path - string params', async () => { + // route provided with { params: { year: "2022", slug: "post-2" }} + const res = await fixture.fetch('/blog/2022/post-1'); + expect(res.status).to.equal(200); + }); + + it('resolves 200 on matching static path - numeric params', async () => { + // route provided with { params: { year: 2022, slug: "post-2" }} + const res = await fixture.fetch('/blog/2022/post-2'); + expect(res.status).to.equal(200); + }); }); it('resolves 200 on matching static paths', async () => { @@ -159,47 +129,3 @@ describe('prerender getStaticPaths - numeric route params', () => { } }); }); - -describe('prerender getStaticPaths - Astro.url', () => { - /** @type {import('./test-utils').Fixture} */ - let fixture; - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ - root: './fixtures/ssr-prerender-get-static-paths/', - site: 'https://mysite.dev/', - }); - await fixture.build(); - }); - - it('Sets the current pathname', async () => { - const html = await fixture.readFile('/food/tacos/index.html'); - const $ = cheerio.load(html); - - expect($('#url').text()).to.equal('/food/tacos/'); - }); -}); - -describe('prerender getStaticPaths - props', () => { - /** @type {import('./test-utils').Fixture} */ - let fixture; - before(async () => { - // reset the flag used by [...calledTwiceTest].astro between each test - globalThis.isCalledOnce = false; - - fixture = await loadFixture({ - root: './fixtures/ssr-prerender-get-static-paths/', - site: 'https://mysite.dev/', - }); - await fixture.build(); - }); - - it('Sets the current pathname', async () => { - const html = await fixture.readFile('/food/tacos/index.html'); - const $ = cheerio.load(html); - - expect($('#props').text()).to.equal('10'); - }); -}); diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js index 3acf8df482..6e31139780 100644 --- a/packages/astro/test/test-utils.js +++ b/packages/astro/test/test-utils.js @@ -187,7 +187,19 @@ export async function loadFixture(inlineConfig) { }, config, resolveUrl, - fetch: (url, init) => fetch(resolveUrl(url), init), + fetch: async (url, init) => { + const resolvedUrl = resolveUrl(url); + try { + return await fetch(resolvedUrl, init); + } catch (err) { + // undici throws a vague error when it fails, so we log the url here to easily debug it + if (err.message?.includes('fetch failed')) { + console.error(`[astro test] failed to fetch ${resolvedUrl}`); + console.error(err); + } + throw err; + } + }, preview: async (opts = {}) => { process.env.NODE_ENV = 'production'; const previewServer = await preview(settings, {