|
| 1 | +// Test next-on-netlify when a custom distDir is set in next.config.js |
| 2 | +const { parse, join } = require('path') |
| 3 | +const { copySync, emptyDirSync, existsSync, |
| 4 | + readdirSync, readFileSync, readJsonSync } = require('fs-extra') |
| 5 | +const npmRunBuild = require("./helpers/npmRunBuild") |
| 6 | + |
| 7 | +// The name of this test file (without extension) |
| 8 | +const FILENAME = parse(__filename).name |
| 9 | + |
| 10 | +// The directory which will be used for testing. |
| 11 | +// We simulate a NextJS app within that directory, with pages, and a |
| 12 | +// package.json file. |
| 13 | +const PROJECT_PATH = join(__dirname, "builds", FILENAME) |
| 14 | + |
| 15 | +// The directory that contains the fixtures, such as NextJS pages, |
| 16 | +// NextJS config, and package.json |
| 17 | +const FIXTURE_PATH = join(__dirname, "fixtures") |
| 18 | + |
| 19 | +// Capture the output of `npm run build` to verify successful build |
| 20 | +let BUILD_OUTPUT |
| 21 | + |
| 22 | +beforeAll( |
| 23 | + async () => { |
| 24 | + // Clear project directory |
| 25 | + emptyDirSync(PROJECT_PATH) |
| 26 | + emptyDirSync(join(PROJECT_PATH, "pages")) |
| 27 | + |
| 28 | + // Copy NextJS pages and config |
| 29 | + copySync( |
| 30 | + join(FIXTURE_PATH, "pages"), |
| 31 | + join(PROJECT_PATH, "pages") |
| 32 | + ) |
| 33 | + copySync( |
| 34 | + join(FIXTURE_PATH, "next.config.js-with-distDir.js"), |
| 35 | + join(PROJECT_PATH, "next.config.js") |
| 36 | + ) |
| 37 | + |
| 38 | + // Copy package.json |
| 39 | + copySync( |
| 40 | + join(FIXTURE_PATH, "package.json"), |
| 41 | + join(PROJECT_PATH, "package.json") |
| 42 | + ) |
| 43 | + |
| 44 | + // Invoke `npm run build`: Build Next and run next-on-netlify |
| 45 | + const { stdout } = await npmRunBuild({ directory: PROJECT_PATH }) |
| 46 | + BUILD_OUTPUT = stdout |
| 47 | + }, |
| 48 | + // time out after 30 seconds |
| 49 | + 30 * 1000 |
| 50 | +) |
| 51 | + |
| 52 | +describe('Next', () => { |
| 53 | + test('builds successfully', () => { |
| 54 | + expect(BUILD_OUTPUT).toMatch("Creating an optimized production build...") |
| 55 | + expect(BUILD_OUTPUT).toMatch("Automatically optimizing pages...") |
| 56 | + expect(BUILD_OUTPUT).toMatch("First Load JS shared by all") |
| 57 | + }) |
| 58 | +}) |
| 59 | + |
| 60 | +describe('SSR Pages', () => { |
| 61 | + const router = join(PROJECT_PATH, "functions", "nextRouter") |
| 62 | + |
| 63 | + test('creates nextRouter.js Netlify Function', () => { |
| 64 | + expect(existsSync(join(router, "nextRouter.js"))).toBe(true) |
| 65 | + }) |
| 66 | + |
| 67 | + test('lists all routes in routes.json', () => { |
| 68 | + // read routes |
| 69 | + const { routes } = readJsonSync(join(router, "routes.json")) |
| 70 | + |
| 71 | + // check entries |
| 72 | + expect(routes).toContainEqual({ |
| 73 | + file: "pages/index.js", |
| 74 | + regex: "^\\/(?:\\/)?$" |
| 75 | + }) |
| 76 | + expect(routes).toContainEqual({ |
| 77 | + file: "pages/shows/[id].js", |
| 78 | + regex: "^\\/shows\\/([^\\/]+?)(?:\\/)?$" |
| 79 | + }) |
| 80 | + expect(routes).toContainEqual({ |
| 81 | + file: "pages/shows/[...params].js", |
| 82 | + regex: "^\\/shows(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))?(?:\\/)?$" |
| 83 | + }) |
| 84 | + }) |
| 85 | + |
| 86 | + test('requires all pages in allPages.js', () => { |
| 87 | + // read allPages.js |
| 88 | + const contents = readFileSync(join(router, "allPages.js")) |
| 89 | + |
| 90 | + // Convert contents into an array, each line being one element |
| 91 | + const requires = contents.toString().split("\n") |
| 92 | + |
| 93 | + // Verify presence of require statements |
| 94 | + expect(requires).toContain('require("./pages/index.js")') |
| 95 | + expect(requires).toContain('require("./pages/shows/[id].js")') |
| 96 | + expect(requires).toContain('require("./pages/shows/[...params].js")') |
| 97 | + }) |
| 98 | + |
| 99 | + test('bundles all SSR-pages in /pages', () => { |
| 100 | + const pages = join(PROJECT_PATH, "public", "_next", "pages") |
| 101 | + |
| 102 | + expect(existsSync(join(router, "pages", "index.js"))).toBe(true) |
| 103 | + expect(existsSync(join(router, "pages", "shows", "[id].js"))).toBe(true) |
| 104 | + expect(existsSync(join(router, "pages", "shows", "[...params].js"))).toBe(true) |
| 105 | + }) |
| 106 | +}) |
| 107 | + |
| 108 | +describe('Static Pages', () => { |
| 109 | + test('copies static pages to public/_next/ directory', () => { |
| 110 | + const pages = join(PROJECT_PATH, "public", "_next", "pages") |
| 111 | + |
| 112 | + expect(existsSync(join(pages, "static.html"))).toBe(true) |
| 113 | + expect(existsSync(join(pages, "static/[id].html"))).toBe(true) |
| 114 | + }) |
| 115 | + |
| 116 | + test('copies static assets to public/_next/ directory', () => { |
| 117 | + const dirs = readdirSync(join(PROJECT_PATH, "public", "_next", "static")) |
| 118 | + |
| 119 | + expect(dirs.length).toBe(3) |
| 120 | + expect(dirs).toContain("chunks") |
| 121 | + expect(dirs).toContain("runtime") |
| 122 | + }) |
| 123 | +}) |
| 124 | + |
| 125 | +describe('Routing',() => { |
| 126 | + test('creates Netlify redirects', async () => { |
| 127 | + // Read _redirects file |
| 128 | + const contents = readFileSync(join(PROJECT_PATH, "public", "_redirects")) |
| 129 | + |
| 130 | + // Convert contents into an array, each line being one element |
| 131 | + const redirects = contents.toString().split("\n") |
| 132 | + |
| 133 | + // Check that routes are present |
| 134 | + expect(redirects).toContain("/static /_next/pages/static.html 200") |
| 135 | + expect(redirects).toContain("/static/:id /_next/pages/static/[id].html 200") |
| 136 | + expect(redirects).toContain("/ /.netlify/functions/nextRouter?_path=/ 200") |
| 137 | + expect(redirects).toContain("/index /.netlify/functions/nextRouter?_path=/index 200") |
| 138 | + expect(redirects).toContain("/shows/:id /.netlify/functions/nextRouter?_path=/shows/:id 200") |
| 139 | + expect(redirects).toContain("/shows/* /.netlify/functions/nextRouter?_path=/shows/* 200") |
| 140 | + }) |
| 141 | +}) |
0 commit comments