diff --git a/packages/integrations/netlify/package.json b/packages/integrations/netlify/package.json index 5cbe0a5c6bbd..1885aa72ac1e 100644 --- a/packages/integrations/netlify/package.json +++ b/packages/integrations/netlify/package.json @@ -33,10 +33,11 @@ "build": "astro-scripts build \"src/**/*.ts\" && tsc", "build:ci": "astro-scripts build \"src/**/*.ts\"", "test": "pnpm run test-fn && pnpm run test-static && pnpm run test:dev", - "test-fn": "astro-scripts test \"test/functions/*.test.js\"", - "test:dev": "astro-scripts test \"test/development/*.test.js\"", - "test-static": "astro-scripts test \"test/static/*.test.js\"", - "test:hosted": "astro-scripts test \"test/hosted/*.test.js\"" + "test-fn": "astro-scripts test \"test/functions/*.test.ts\"", + "test:dev": "astro-scripts test \"test/development/*.test.ts\"", + "test-static": "astro-scripts test \"test/static/*.test.ts\"", + "test:hosted": "astro-scripts test \"test/hosted/*.test.ts\"", + "typecheck:tests": "tsc --build tsconfig.test.json" }, "dependencies": { "@astrojs/internal-helpers": "workspace:*", diff --git a/packages/integrations/netlify/test/development/primitives.test.js b/packages/integrations/netlify/test/development/primitives.test.ts similarity index 93% rename from packages/integrations/netlify/test/development/primitives.test.js rename to packages/integrations/netlify/test/development/primitives.test.ts index 016305e42cae..2bad2bd8ce36 100644 --- a/packages/integrations/netlify/test/development/primitives.test.js +++ b/packages/integrations/netlify/test/development/primitives.test.ts @@ -2,14 +2,13 @@ import assert from 'node:assert/strict'; import { after, afterEach, before, describe, it } from 'node:test'; import * as cheerio from 'cheerio'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; import netlifyAdapter from '../../dist/index.js'; +import { type DevServer, type Fixture, loadFixture } from '../test-utils.ts'; describe('Netlify primitives', () => { describe('Development', () => { - /** @type {import('../../../../astro/test/test-utils').Fixture} */ - let fixture; - let devServer; + let fixture: Fixture; + let devServer: DevServer; before(async () => { fixture = await loadFixture({ root: new URL('./fixtures/primitives/', import.meta.url), @@ -101,7 +100,7 @@ describe('Netlify primitives', () => { } } finally { await cdnDisabledServer.stop(); - process.env.DISABLE_IMAGE_CDN = undefined; + delete process.env.DISABLE_IMAGE_CDN; } }); }); diff --git a/packages/integrations/netlify/test/functions/cookies.test.js b/packages/integrations/netlify/test/functions/cookies.test.ts similarity index 83% rename from packages/integrations/netlify/test/functions/cookies.test.js rename to packages/integrations/netlify/test/functions/cookies.test.ts index 2e5bd03dc1ef..a412dc6537ec 100644 --- a/packages/integrations/netlify/test/functions/cookies.test.js +++ b/packages/integrations/netlify/test/functions/cookies.test.ts @@ -1,9 +1,9 @@ import * as assert from 'node:assert/strict'; import { before, describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('Cookies', { timeout: 120000 }, () => { - let fixture; + let fixture: Fixture; before(async () => { fixture = await loadFixture({ root: new URL('./fixtures/cookies/', import.meta.url) }); @@ -15,7 +15,7 @@ describe('Cookies', { timeout: 120000 }, () => { './fixtures/cookies/.netlify/v1/functions/ssr/ssr.mjs', import.meta.url, ); - const { default: handler } = await import(entryURL); + const { default: handler } = await import(entryURL.href); const resp = await handler( new Request('http://example.com/login', { method: 'POST', body: '{}' }), {}, @@ -30,10 +30,10 @@ describe('Cookies', { timeout: 120000 }, () => { './fixtures/cookies/.netlify/v1/functions/ssr/ssr.mjs', import.meta.url, ); - const { default: handler } = await import(entryURL); + const { default: handler } = await import(entryURL.href); const resp = await handler(new Request('http://example.com/partitioned'), {}); assert.equal(resp.status, 200); - const cookie = resp.headers.getSetCookie()[0]; + const cookie = resp.headers.getSetCookie()[0]!; assert.ok(cookie.includes('Partitioned'), 'Cookie should include Partitioned attribute'); }); @@ -42,7 +42,7 @@ describe('Cookies', { timeout: 120000 }, () => { './fixtures/cookies/.netlify/v1/functions/ssr/ssr.mjs', import.meta.url, ); - const { default: handler } = await import(entryURL); + const { default: handler } = await import(entryURL.href); const resp = await handler( new Request('http://example.com/nonexistant-page', { headers: { diff --git a/packages/integrations/netlify/test/functions/edge-middleware.test.js b/packages/integrations/netlify/test/functions/edge-middleware.test.ts similarity index 89% rename from packages/integrations/netlify/test/functions/edge-middleware.test.js rename to packages/integrations/netlify/test/functions/edge-middleware.test.ts index 2e84d3048028..bc6abbe64877 100644 --- a/packages/integrations/netlify/test/functions/edge-middleware.test.js +++ b/packages/integrations/netlify/test/functions/edge-middleware.test.ts @@ -1,12 +1,12 @@ import * as assert from 'node:assert/strict'; import { after, before, describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('Middleware', { timeout: 120000 }, () => { const root = new URL('./fixtures/middleware/', import.meta.url); describe('middlewareMode: classic', () => { - let fixture; + let fixture: Fixture; before(async () => { process.env.EDGE_MIDDLEWARE = 'false'; fixture = await loadFixture({ root }); @@ -27,13 +27,13 @@ describe('Middleware', { timeout: 120000 }, () => { }); after(async () => { - process.env.EDGE_MIDDLEWARE = undefined; + delete process.env.EDGE_MIDDLEWARE; await fixture.clean(); }); }); describe('middlewareMode: edge', () => { - let fixture; + let fixture: Fixture; before(async () => { process.env.EDGE_MIDDLEWARE = 'true'; fixture = await loadFixture({ root }); @@ -53,7 +53,7 @@ describe('Middleware', { timeout: 120000 }, () => { }); after(async () => { - process.env.EDGE_MIDDLEWARE = undefined; + delete process.env.EDGE_MIDDLEWARE; await fixture.clean(); }); }); diff --git a/packages/integrations/netlify/test/functions/image-cdn.test.js b/packages/integrations/netlify/test/functions/image-cdn.test.ts similarity index 76% rename from packages/integrations/netlify/test/functions/image-cdn.test.js rename to packages/integrations/netlify/test/functions/image-cdn.test.ts index c398130366a2..709c306ec3c1 100644 --- a/packages/integrations/netlify/test/functions/image-cdn.test.js +++ b/packages/integrations/netlify/test/functions/image-cdn.test.ts @@ -1,15 +1,26 @@ import * as assert from 'node:assert/strict'; import { after, before, describe, it } from 'node:test'; import { remotePatternToRegex } from '@astrojs/netlify'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; import imageService from '../../dist/image-service.js'; +import { loadFixture, SpyIntegrationLogger } from '../test-utils.ts'; +import type { ImageTransform } from 'astro'; + +async function getURL(options: ImageTransform) { + return await imageService.getURL( + options, + // @ts-expect-error The second argument is not used in the current + // implementation of `imageService.getURL`, but we need to pass it + // to satisfy the type signature. + {}, + ); +} describe('Image CDN', { timeout: 120000 }, () => { const root = new URL('./fixtures/middleware/', import.meta.url); describe('configuration', () => { after(() => { - process.env.DISABLE_IMAGE_CDN = undefined; + delete process.env.DISABLE_IMAGE_CDN; }); it('enables Netlify Image CDN', async () => { @@ -31,7 +42,7 @@ describe('Image CDN', { timeout: 120000 }, () => { }); describe('remote image config', () => { - let regexes; + let regexes: RegExp[]; before(async () => { const fixture = await loadFixture({ root }); @@ -39,7 +50,9 @@ describe('Image CDN', { timeout: 120000 }, () => { const config = await fixture.readFile('../.netlify/v1/config.json'); if (config) { - regexes = JSON.parse(config).images.remote_images.map((pattern) => new RegExp(pattern)); + regexes = JSON.parse(config).images.remote_images.map( + (pattern: string) => new RegExp(pattern), + ); } }); @@ -48,7 +61,7 @@ describe('Image CDN', { timeout: 120000 }, () => { }); it('generates correct config for domains', async () => { - const domain = regexes[0]; + const domain = regexes[0]!; assert.equal(domain.test('https://example.net/image.jpg'), true); assert.equal( domain.test('https://www.example.net/image.jpg'), @@ -61,7 +74,7 @@ describe('Image CDN', { timeout: 120000 }, () => { true, 'subpath should match', ); - const subdomain = regexes[1]; + const subdomain = regexes[1]!; assert.equal( subdomain.test('https://secret.example.edu/image.jpg'), true, @@ -75,7 +88,7 @@ describe('Image CDN', { timeout: 120000 }, () => { }); it('generates correct config for remotePatterns', async () => { - const patterns = regexes[2]; + const patterns = regexes[2]!; assert.equal(patterns.test('https://example.org/images/1.jpg'), true, 'should match domain'); assert.equal( patterns.test('https://www.example.org/images/2.jpg'), @@ -94,10 +107,8 @@ describe('Image CDN', { timeout: 120000 }, () => { ); }); - it('warns when remotepatterns generates an invalid regex', async (t) => { - const logger = { - warn: t.mock.fn(), - }; + it('warns when remotepatterns generates an invalid regex', async () => { + const logger = new SpyIntegrationLogger(); const regex = remotePatternToRegex( { hostname: '*.examp[le.org', @@ -106,18 +117,19 @@ describe('Image CDN', { timeout: 120000 }, () => { logger, ); assert.strictEqual(regex, undefined); - const calls = logger.warn.mock.calls; - assert.strictEqual(calls.length, 1); + assert.strictEqual(logger.messages.length, 1); + const message = logger.messages[0]; + assert.equal(message.level, 'warn'); assert.equal( - calls[0].arguments[0], + message.message, 'Could not generate a valid regex from the remotePattern "{"hostname":"*.examp[le.org","pathname":"/images/*"}". Please check the syntax.', ); }); }); describe('fit parameter', () => { - it('includes fit parameter in image URL', () => { - const url = imageService.getURL({ + it('includes fit parameter in image URL', async () => { + const url = await getURL({ src: 'images/astronaut.jpg', width: 300, height: 400, @@ -127,7 +139,7 @@ describe('Image CDN', { timeout: 120000 }, () => { assert.ok(url.includes('fit=cover'), `Expected fit=cover in URL, got: ${url}`); }); - it('maps Astro fit values to Netlify equivalents', () => { + it('maps Astro fit values to Netlify equivalents', async () => { const cases = [ ['contain', 'contain'], ['cover', 'cover'], @@ -137,7 +149,7 @@ describe('Image CDN', { timeout: 120000 }, () => { ['scale-down', 'contain'], ]; for (const [astroFit, netlifyFit] of cases) { - const url = imageService.getURL({ + const url = await getURL({ src: 'img.jpg', width: 100, height: 100, @@ -150,8 +162,8 @@ describe('Image CDN', { timeout: 120000 }, () => { } }); - it('omits fit parameter when fit is none or unset', () => { - const withNone = imageService.getURL({ + it('omits fit parameter when fit is none or unset', async () => { + const withNone = await getURL({ src: 'img.jpg', width: 100, height: 100, @@ -162,7 +174,7 @@ describe('Image CDN', { timeout: 120000 }, () => { `Expected no fit param for fit="none", got: ${withNone}`, ); - const withoutFit = imageService.getURL({ src: 'img.jpg', width: 100, height: 100 }); + const withoutFit = await getURL({ src: 'img.jpg', width: 100, height: 100 }); assert.ok( !withoutFit.includes('fit='), `Expected no fit param when unset, got: ${withoutFit}`, diff --git a/packages/integrations/netlify/test/functions/include-files.test.js b/packages/integrations/netlify/test/functions/include-files.test.ts similarity index 93% rename from packages/integrations/netlify/test/functions/include-files.test.js rename to packages/integrations/netlify/test/functions/include-files.test.ts index 31446785095f..5efdd6227869 100644 --- a/packages/integrations/netlify/test/functions/include-files.test.js +++ b/packages/integrations/netlify/test/functions/include-files.test.ts @@ -4,10 +4,10 @@ import { after, before, describe, it } from 'node:test'; import netlify from '@astrojs/netlify'; import * as cheerio from 'cheerio'; import { globSync } from 'tinyglobby'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('Included vite assets files', { timeout: 120000 }, () => { - let fixture; + let fixture: Fixture; const root = new URL('./fixtures/includes/', import.meta.url); const expectedCwd = new URL('.netlify/v1/functions/ssr/packages/integrations/netlify/', root); @@ -55,7 +55,7 @@ describe('Included vite assets files', { timeout: 120000 }, () => { }); describe('Included files', { timeout: 120000 }, () => { - let fixture; + let fixture: Fixture; const root = new URL('./fixtures/includes/', import.meta.url); const expectedCwd = new URL( @@ -90,7 +90,7 @@ describe('Included files', { timeout: 120000 }, () => { './fixtures/includes/.netlify/v1/functions/ssr/ssr.mjs', import.meta.url, ); - const { default: handler } = await import(entryURL); + const { default: handler } = await import(entryURL.href); const resp = await handler(new Request('http://example.com/?file=include-this.txt'), {}); const html = await resp.text(); const $ = cheerio.load(html); @@ -102,7 +102,7 @@ describe('Included files', { timeout: 120000 }, () => { '.netlify/v1/functions/ssr/node_modules/.pnpm/cowsay@1.6.0/node_modules/cowsay/cows/happy-whale.cow', root, ); - assert.ok(existsSync(expected, 'Expected excluded file to exist in default build')); + assert.ok(existsSync(expected), 'Expected excluded file to exist in default build'); }); after(async () => { @@ -111,7 +111,7 @@ describe('Included files', { timeout: 120000 }, () => { }); describe('Excluded files', { timeout: 120000 }, () => { - let fixture; + let fixture: Fixture; const root = new URL('./fixtures/includes/', import.meta.url); const expectedCwd = new URL( diff --git a/packages/integrations/netlify/test/functions/redirects.test.js b/packages/integrations/netlify/test/functions/redirects.test.ts similarity index 90% rename from packages/integrations/netlify/test/functions/redirects.test.js rename to packages/integrations/netlify/test/functions/redirects.test.ts index 93df3f16202f..553885096486 100644 --- a/packages/integrations/netlify/test/functions/redirects.test.js +++ b/packages/integrations/netlify/test/functions/redirects.test.ts @@ -1,10 +1,10 @@ import * as assert from 'node:assert/strict'; import { createServer } from 'node:http'; import { before, describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('SSR - Redirects', { timeout: 120000 }, () => { - let fixture; + let fixture: Fixture; before(async () => { fixture = await loadFixture({ root: new URL('./fixtures/redirects/', import.meta.url) }); @@ -33,7 +33,7 @@ describe('SSR - Redirects', { timeout: 120000 }, () => { './fixtures/redirects/.netlify/v1/functions/ssr/ssr.mjs', import.meta.url, ); - const { default: handler } = await import(entryURL); + const { default: handler } = await import(entryURL.href); const resp = await handler(new Request('http://example.com/nonexistant-page'), {}); assert.equal(resp.status, 404); assert.equal(resp.headers.get('content-type'), 'text/html; charset=utf-8'); @@ -53,7 +53,7 @@ describe('SSR - Redirects', { timeout: 120000 }, () => { './fixtures/redirects/.netlify/v1/functions/ssr/ssr.mjs', import.meta.url, ); - const { default: handler } = await import(entryURL); + const { default: handler } = await import(entryURL.href); const resp = await handler(new Request('http://localhost:5678/nonexistant-page'), {}); assert.equal(resp.status, 404); assert.equal(testServerCalls, 0); diff --git a/packages/integrations/netlify/test/functions/sessions.test.js b/packages/integrations/netlify/test/functions/sessions.test.ts similarity index 83% rename from packages/integrations/netlify/test/functions/sessions.test.js rename to packages/integrations/netlify/test/functions/sessions.test.ts index 7b41cb129648..99c0283ccb76 100644 --- a/packages/integrations/netlify/test/functions/sessions.test.js +++ b/packages/integrations/netlify/test/functions/sessions.test.ts @@ -1,12 +1,11 @@ -// @ts-check import assert from 'node:assert/strict'; import { mkdir, rm } from 'node:fs/promises'; import { after, before, describe, it } from 'node:test'; import { BlobsServer } from '@netlify/blobs/server'; +import { sessionDrivers } from 'astro/config'; import * as devalue from 'devalue'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; import netlify from '../../dist/index.js'; -import { sessionDrivers } from 'astro/config'; +import { type Fixture, loadFixture } from '../test-utils.ts'; const token = 'mock'; const siteID = '1'; @@ -14,11 +13,9 @@ const dataDir = '.netlify/sessions'; describe('Astro.session', () => { describe('Production', () => { - /** @type {import('../../../../astro/test/test-utils.js').Fixture} */ - let fixture; + let fixture: Fixture; - /** @type {BlobsServer} */ - let blobServer; + let blobServer: BlobsServer; before(async () => { process.env.NETLIFY = '1'; await rm(dataDir, { recursive: true, force: true }).catch(() => {}); @@ -30,11 +27,11 @@ describe('Astro.session', () => { }); await blobServer.start(); fixture = await loadFixture({ - // @ts-ignore root: new URL('./fixtures/sessions/', import.meta.url), output: 'server', adapter: netlify(), session: { + // @ts-expect-error: the default type of the TDriver in AstroUserConfig must be changed so that this can pass driver: sessionDrivers.netlifyBlobs({ name: 'test', uncachedEdgeURL: `http://localhost:8971`, @@ -52,24 +49,19 @@ describe('Astro.session', () => { const mod = await import(entryURL.href); handler = mod.default; }); - /** @type {(request: Request, options: {}) => Promise} */ - let handler; + let handler: (request: Request, options: object) => Promise; after(async () => { await blobServer.stop(); delete process.env.NETLIFY; }); - /** - * @param {string} path - * @param {RequestInit} requestInit - */ - function fetchResponse(path, requestInit) { + function fetchResponse(path: string, requestInit: RequestInit) { return handler(new Request(new URL(path, 'http://example.com'), requestInit), {}); } it('can regenerate session cookies upon request', async () => { const firstResponse = await fetchResponse('/regenerate', { method: 'GET' }); const firstHeaders = firstResponse.headers.get('set-cookie')?.split(',') ?? ''; - const firstSessionId = firstHeaders[0].split(';')[0].split('=')[1]; + const firstSessionId = firstHeaders[0]!.split(';')[0]!.split('=')[1]; const secondResponse = await fetchResponse('/regenerate', { method: 'GET', @@ -78,7 +70,7 @@ describe('Astro.session', () => { }, }); const secondHeaders = secondResponse.headers.get('set-cookie')?.split(',') ?? ''; - const secondSessionId = secondHeaders[0].split(';')[0].split('=')[1]; + const secondSessionId = secondHeaders[0]!.split(';')[0]!.split('=')[1]; assert.notEqual(firstSessionId, secondSessionId); }); @@ -88,7 +80,7 @@ describe('Astro.session', () => { assert.equal(firstValue.previousValue, 'none'); const firstHeaders = firstResponse.headers.get('set-cookie')?.split(',') ?? ''; - const firstSessionId = firstHeaders[0].split(';')[0].split('=')[1]; + const firstSessionId = firstHeaders[0]!.split(';')[0]!.split('=')[1]; const secondResponse = await fetchResponse('/update', { method: 'GET', headers: { @@ -110,7 +102,7 @@ describe('Astro.session', () => { assert.equal(firstResponse.ok, true); const firstHeaders = firstResponse.headers.get('set-cookie')?.split(',') ?? ''; - const firstSessionId = firstHeaders[0].split(';')[0].split('=')[1]; + const firstSessionId = firstHeaders[0]!.split(';')[0]!.split('=')[1]; const data = devalue.parse(await firstResponse.text()); assert.equal(data.message, 'Favorite URL set to https://domain.invalid/ from nothing'); diff --git a/packages/integrations/netlify/test/functions/skew-protection.test.js b/packages/integrations/netlify/test/functions/skew-protection.test.ts similarity index 93% rename from packages/integrations/netlify/test/functions/skew-protection.test.js rename to packages/integrations/netlify/test/functions/skew-protection.test.ts index 6d639d83b586..b92f03cb958b 100644 --- a/packages/integrations/netlify/test/functions/skew-protection.test.js +++ b/packages/integrations/netlify/test/functions/skew-protection.test.ts @@ -1,10 +1,10 @@ import * as assert from 'node:assert/strict'; import { readFile } from 'node:fs/promises'; import { before, describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('Skew Protection', { timeout: 120000 }, () => { - let fixture; + let fixture: Fixture; before(async () => { // Set DEPLOY_ID env var for the test @@ -25,7 +25,7 @@ describe('Skew Protection', { timeout: 120000 }, () => { './fixtures/skew-protection/.netlify/v1/functions/ssr/ssr.mjs', import.meta.url, ); - const { default: handler } = await import(entryURL); + const { default: handler } = await import(entryURL.href); const resp = await handler(new Request('http://example.com/server-island'), {}); const html = await resp.text(); diff --git a/packages/integrations/netlify/test/hosted/hosted.test.js b/packages/integrations/netlify/test/hosted/hosted.test.ts similarity index 74% rename from packages/integrations/netlify/test/hosted/hosted.test.js rename to packages/integrations/netlify/test/hosted/hosted.test.ts index 3bc9349f960b..3657c17cb7fa 100644 --- a/packages/integrations/netlify/test/hosted/hosted.test.js +++ b/packages/integrations/netlify/test/hosted/hosted.test.ts @@ -20,10 +20,10 @@ describe('Hosted Netlify Tests', () => { }); it('Server returns fresh content', async () => { - const responseOne = await fetch(`${NETLIFY_TEST_URL}/time`).then((res) => res.text()); + const responseOne: string = await fetch(`${NETLIFY_TEST_URL}/time`).then((res) => res.text()); - const responseTwo = await fetch(`${NETLIFY_TEST_URL}/time`).then((res) => res.text()); + const responseTwo: string = await fetch(`${NETLIFY_TEST_URL}/time`).then((res) => res.text()); - assert.notEqual(responseOne.body, responseTwo.body); + assert.notEqual(responseOne, responseTwo); }); }); diff --git a/packages/integrations/netlify/test/static/headers.test.js b/packages/integrations/netlify/test/static/headers.test.ts similarity index 87% rename from packages/integrations/netlify/test/static/headers.test.js rename to packages/integrations/netlify/test/static/headers.test.ts index 5c1400098b10..c5316742d352 100644 --- a/packages/integrations/netlify/test/static/headers.test.js +++ b/packages/integrations/netlify/test/static/headers.test.ts @@ -1,9 +1,9 @@ import * as assert from 'node:assert/strict'; import { before, describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('SSG - headers', () => { - let fixture; + let fixture: Fixture; before(async () => { fixture = await loadFixture({ root: new URL('./fixtures/redirects/', import.meta.url) }); diff --git a/packages/integrations/netlify/test/static/image-missing-dimension.test.js b/packages/integrations/netlify/test/static/image-missing-dimension.test.ts similarity index 88% rename from packages/integrations/netlify/test/static/image-missing-dimension.test.js rename to packages/integrations/netlify/test/static/image-missing-dimension.test.ts index 932958ad399d..3e29122228da 100644 --- a/packages/integrations/netlify/test/static/image-missing-dimension.test.js +++ b/packages/integrations/netlify/test/static/image-missing-dimension.test.ts @@ -1,6 +1,6 @@ import * as assert from 'node:assert/strict'; import { describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { loadFixture } from '../test-utils.ts'; describe('Image validation when is not size specification in netlify.', () => { it('throw on missing dimension in static build', async () => { @@ -14,7 +14,7 @@ describe('Image validation when is not size specification in netlify.', () => { } catch (e) { // check the error image about missing image dimension assert.match( - e.name, + (e as Error).name, /MissingImageDimension/, `Build failed but not with the expected "MissingImageDimension"`, ); diff --git a/packages/integrations/netlify/test/static/redirects.test.js b/packages/integrations/netlify/test/static/redirects.test.ts similarity index 90% rename from packages/integrations/netlify/test/static/redirects.test.js rename to packages/integrations/netlify/test/static/redirects.test.ts index 9e9d0c87298e..ceafb5856720 100644 --- a/packages/integrations/netlify/test/static/redirects.test.js +++ b/packages/integrations/netlify/test/static/redirects.test.ts @@ -1,9 +1,9 @@ import * as assert from 'node:assert/strict'; import { before, describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('SSG - Redirects', () => { - let fixture; + let fixture: Fixture; before(async () => { fixture = await loadFixture({ root: new URL('./fixtures/redirects/', import.meta.url) }); diff --git a/packages/integrations/netlify/test/static/static-headers.test.js b/packages/integrations/netlify/test/static/static-headers.test.ts similarity index 78% rename from packages/integrations/netlify/test/static/static-headers.test.js rename to packages/integrations/netlify/test/static/static-headers.test.ts index a5b7014894b0..297b0ed57dff 100644 --- a/packages/integrations/netlify/test/static/static-headers.test.js +++ b/packages/integrations/netlify/test/static/static-headers.test.ts @@ -1,10 +1,10 @@ import * as assert from 'node:assert/strict'; import { existsSync, readdirSync } from 'node:fs'; import { before, describe, it } from 'node:test'; -import { loadFixture } from '../../../../astro/test/test-utils.js'; +import { type Fixture, loadFixture } from '../test-utils.ts'; describe('Static headers', () => { - let fixture; + let fixture: Fixture; before(async () => { fixture = await loadFixture({ root: new URL('./fixtures/static-headers/', import.meta.url) }); @@ -22,8 +22,9 @@ describe('Static headers', () => { it('CSP headers are added when CSP is enabled', async () => { const config = await fixture.readFile('../.netlify/v1/config.json'); - const headers = JSON.parse(config).headers; - const index = headers.find((x) => x.for === '/'); + const headers: Array<{ for: string; values: Record }> = + JSON.parse(config).headers; + const index = headers.find((x) => x.for === '/')!; assert.notEqual(index, undefined, 'the index must have CSP headers'); assert.notEqual( @@ -32,7 +33,7 @@ describe('Static headers', () => { 'the index must have CSP headers', ); assert.ok( - index.values['Content-Security-Policy'].includes('script-src'), + index.values['Content-Security-Policy']!.includes('script-src'), 'must contain the script-src directive because of the server island', ); }); diff --git a/packages/integrations/netlify/test/test-utils.ts b/packages/integrations/netlify/test/test-utils.ts new file mode 100644 index 000000000000..3f1f0bbdb101 --- /dev/null +++ b/packages/integrations/netlify/test/test-utils.ts @@ -0,0 +1,37 @@ +import { + type DevServer, + type AstroInlineConfig, + type Fixture, + loadFixture as baseLoadFixture, +} from '../../../astro/test/test-utils.js'; +import { + AstroIntegrationLogger, + type AstroLogMessage, +} from '../../../astro/dist/core/logger/core.js'; + +export type { AstroInlineConfig, DevServer, Fixture }; + +export function loadFixture(config: AstroInlineConfig) { + return baseLoadFixture(config); +} + +export class SpyIntegrationLogger extends AstroIntegrationLogger { + readonly messages: AstroLogMessage[]; + + constructor() { + const messages: AstroLogMessage[] = []; + super( + { + destination: { + write(chunk): boolean { + messages.push(chunk); + return true; + }, + }, + level: 'warn', + }, + 'test-spy', + ); + this.messages = messages; + } +} diff --git a/packages/integrations/netlify/tsconfig.test.json b/packages/integrations/netlify/tsconfig.test.json new file mode 100644 index 000000000000..462c7b7db770 --- /dev/null +++ b/packages/integrations/netlify/tsconfig.test.json @@ -0,0 +1,13 @@ +{ + "extends": "../../../tsconfig.base.json", + "include": ["test/**/*.ts"], + "exclude": ["test/**/fixtures/**", "test/hosted/hosted-astro-project/**"], + "compilerOptions": { + "allowJs": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "rewriteRelativeImportExtensions": true, + "rootDir": "." + }, + "references": [{ "path": "../../astro/tsconfig.test.json" }] +}