1
1
// Test next-on-netlify when i18n is set in next.config.js (Next 10+)
2
2
3
3
const { parse, join } = require ( "path" ) ;
4
+ const {
5
+ existsSync,
6
+ readdirSync,
7
+ readFileSync,
8
+ readJsonSync,
9
+ } = require ( "fs-extra" ) ;
4
10
const buildNextApp = require ( "./helpers/buildNextApp" ) ;
5
11
6
12
// The name of this test file (without extension)
@@ -11,6 +17,8 @@ const FILENAME = parse(__filename).name;
11
17
// package.json file.
12
18
const PROJECT_PATH = join ( __dirname , "builds" , FILENAME ) ;
13
19
20
+ const DEFAULT_LOCALE = "en" ;
21
+
14
22
// Capture the output to verify successful build
15
23
let buildOutput ;
16
24
@@ -33,3 +41,283 @@ describe("next-on-netlify", () => {
33
41
expect ( buildOutput ) . toMatch ( "Success! All done!" ) ;
34
42
} ) ;
35
43
} ) ;
44
+
45
+ describe ( "next-on-netlify" , ( ) => {
46
+ test ( "builds successfully" , ( ) => {
47
+ expect ( buildOutput ) . toMatch ( "Next on Netlify" ) ;
48
+ expect ( buildOutput ) . toMatch ( "Copying static NextJS assets to out_publish/" ) ;
49
+ expect ( buildOutput ) . toMatch (
50
+ "Setting up API endpoints as Netlify Functions in out_functions/"
51
+ ) ;
52
+ expect ( buildOutput ) . toMatch (
53
+ "Setting up pages with getInitialProps as Netlify Functions in out_functions/"
54
+ ) ;
55
+ expect ( buildOutput ) . toMatch (
56
+ "Setting up pages with getServerSideProps as Netlify Functions in out_functions/"
57
+ ) ;
58
+ expect ( buildOutput ) . toMatch (
59
+ "Copying pre-rendered pages with getStaticProps and JSON data to out_publish/"
60
+ ) ;
61
+ expect ( buildOutput ) . toMatch (
62
+ "Setting up pages with getStaticProps and fallback: true as Netlify Functions in out_functions/"
63
+ ) ;
64
+ expect ( buildOutput ) . toMatch (
65
+ "Setting up pages with getStaticProps and revalidation interval as Netlify Functions in out_functions/"
66
+ ) ;
67
+ expect ( buildOutput ) . toMatch (
68
+ "Copying pre-rendered pages without props to out_publish/"
69
+ ) ;
70
+ expect ( buildOutput ) . toMatch ( "Setting up redirects" ) ;
71
+ expect ( buildOutput ) . toMatch ( "Success! All done!" ) ;
72
+ } ) ;
73
+ } ) ;
74
+
75
+ describe ( "SSR Pages" , ( ) => {
76
+ const functionsDir = join ( PROJECT_PATH , "out_functions" ) ;
77
+
78
+ test ( "creates a Netlify Function for each SSR page" , ( ) => {
79
+ expect ( existsSync ( join ( functionsDir , "next_index" , "next_index.js" ) ) ) . toBe (
80
+ true
81
+ ) ;
82
+ expect (
83
+ existsSync ( join ( functionsDir , "next_shows_id" , "next_shows_id.js" ) )
84
+ ) . toBe ( true ) ;
85
+ expect (
86
+ existsSync (
87
+ join ( functionsDir , "next_shows_params" , "next_shows_params.js" )
88
+ )
89
+ ) . toBe ( true ) ;
90
+ expect (
91
+ existsSync (
92
+ join (
93
+ functionsDir ,
94
+ "next_getServerSideProps_static" ,
95
+ "next_getServerSideProps_static.js"
96
+ )
97
+ )
98
+ ) . toBe ( true ) ;
99
+ expect (
100
+ existsSync (
101
+ join (
102
+ functionsDir ,
103
+ "next_getServerSideProps_id" ,
104
+ "next_getServerSideProps_id.js"
105
+ )
106
+ )
107
+ ) . toBe ( true ) ;
108
+ } ) ;
109
+ } ) ;
110
+
111
+ describe ( "API Pages" , ( ) => {
112
+ const functionsDir = join ( PROJECT_PATH , "out_functions" ) ;
113
+
114
+ test ( "creates a Netlify Function for each API endpoint" , ( ) => {
115
+ expect (
116
+ existsSync ( join ( functionsDir , "next_api_static" , "next_api_static.js" ) )
117
+ ) . toBe ( true ) ;
118
+ expect (
119
+ existsSync (
120
+ join ( functionsDir , "next_api_shows_id" , "next_api_shows_id.js" )
121
+ )
122
+ ) . toBe ( true ) ;
123
+ expect (
124
+ existsSync (
125
+ join ( functionsDir , "next_api_shows_params" , "next_api_shows_params.js" )
126
+ )
127
+ ) . toBe ( true ) ;
128
+ } ) ;
129
+ } ) ;
130
+
131
+ describe ( "SSG Pages with getStaticProps" , ( ) => {
132
+ test ( "creates pre-rendered HTML file in output directory" , ( ) => {
133
+ const defaultLocale = "en" ;
134
+ const OUTPUT_PATH = join ( PROJECT_PATH , "out_publish" , DEFAULT_LOCALE ) ;
135
+
136
+ expect ( existsSync ( join ( OUTPUT_PATH , "getStaticProps" , "static.html" ) ) ) . toBe (
137
+ true
138
+ ) ;
139
+ expect ( existsSync ( join ( OUTPUT_PATH , "getStaticProps" , "1.html" ) ) ) . toBe (
140
+ true
141
+ ) ;
142
+ expect ( existsSync ( join ( OUTPUT_PATH , "getStaticProps" , "2.html" ) ) ) . toBe (
143
+ true
144
+ ) ;
145
+ expect (
146
+ existsSync ( join ( OUTPUT_PATH , "getStaticProps" , "withFallback" , "3.html" ) )
147
+ ) . toBe ( true ) ;
148
+ expect (
149
+ existsSync ( join ( OUTPUT_PATH , "getStaticProps" , "withFallback" , "4.html" ) )
150
+ ) . toBe ( true ) ;
151
+ expect (
152
+ existsSync (
153
+ join (
154
+ OUTPUT_PATH ,
155
+ "getStaticProps" ,
156
+ "withFallback" ,
157
+ "my" ,
158
+ "path" ,
159
+ "1.html"
160
+ )
161
+ )
162
+ ) . toBe ( true ) ;
163
+ expect (
164
+ existsSync (
165
+ join (
166
+ OUTPUT_PATH ,
167
+ "getStaticProps" ,
168
+ "withFallback" ,
169
+ "my" ,
170
+ "path" ,
171
+ "2.html"
172
+ )
173
+ )
174
+ ) . toBe ( true ) ;
175
+ } ) ;
176
+
177
+ test ( "creates data .json file in /_next/data/ directory" , ( ) => {
178
+ // Get path to data files
179
+ const dirs = readdirSync (
180
+ join ( PROJECT_PATH , "out_publish" , "_next" , "data" )
181
+ ) ;
182
+ expect ( dirs . length ) . toBe ( 1 ) ;
183
+ const dataDir = join (
184
+ PROJECT_PATH ,
185
+ "out_publish" ,
186
+ "_next" ,
187
+ "data" ,
188
+ dirs [ 0 ] ,
189
+ DEFAULT_LOCALE
190
+ ) ;
191
+
192
+ expect ( existsSync ( join ( dataDir , "getStaticProps" , "static.json" ) ) ) . toBe (
193
+ true
194
+ ) ;
195
+ expect ( existsSync ( join ( dataDir , "getStaticProps" , "1.json" ) ) ) . toBe ( true ) ;
196
+ expect ( existsSync ( join ( dataDir , "getStaticProps" , "2.json" ) ) ) . toBe ( true ) ;
197
+ expect (
198
+ existsSync ( join ( dataDir , "getStaticProps" , "withFallback" , "3.json" ) )
199
+ ) . toBe ( true ) ;
200
+ expect (
201
+ existsSync ( join ( dataDir , "getStaticProps" , "withFallback" , "4.json" ) )
202
+ ) . toBe ( true ) ;
203
+ expect (
204
+ existsSync (
205
+ join ( dataDir , "getStaticProps" , "withFallback" , "my" , "path" , "1.json" )
206
+ )
207
+ ) . toBe ( true ) ;
208
+ expect (
209
+ existsSync (
210
+ join ( dataDir , "getStaticProps" , "withFallback" , "my" , "path" , "2.json" )
211
+ )
212
+ ) . toBe ( true ) ;
213
+ } ) ;
214
+
215
+ test ( "creates Netlify Functions for pages with fallback" , ( ) => {
216
+ const functionPath1 =
217
+ "next_getStaticProps_withFallback_id/next_getStaticProps_withFallback_id.js" ;
218
+ expect ( existsSync ( join ( PROJECT_PATH , "out_functions" , functionPath1 ) ) ) . toBe (
219
+ true
220
+ ) ;
221
+
222
+ const functionPath2 =
223
+ "next_getStaticProps_withFallback_slug/next_getStaticProps_withFallback_slug.js" ;
224
+ expect ( existsSync ( join ( PROJECT_PATH , "out_functions" , functionPath2 ) ) ) . toBe (
225
+ true
226
+ ) ;
227
+ } ) ;
228
+ } ) ;
229
+
230
+ describe ( "SSG Pages with getStaticProps and revalidate" , ( ) => {
231
+ const functionsDir = join ( PROJECT_PATH , "out_functions" ) ;
232
+
233
+ test ( "creates a Netlify Function for each page" , ( ) => {
234
+ expect (
235
+ existsSync (
236
+ join (
237
+ functionsDir ,
238
+ "next_getStaticProps_withrevalidate" ,
239
+ "next_getStaticProps_withrevalidate.js"
240
+ )
241
+ )
242
+ ) . toBe ( true ) ;
243
+ expect (
244
+ existsSync (
245
+ join (
246
+ functionsDir ,
247
+ "next_getStaticProps_withRevalidate_id" ,
248
+ "next_getStaticProps_withRevalidate_id.js"
249
+ )
250
+ )
251
+ ) . toBe ( true ) ;
252
+ expect (
253
+ existsSync (
254
+ join (
255
+ functionsDir ,
256
+ "next_getStaticProps_withRevalidate_withFallback_id" ,
257
+ "next_getStaticProps_withRevalidate_withFallback_id.js"
258
+ )
259
+ )
260
+ ) . toBe ( true ) ;
261
+ } ) ;
262
+ } ) ;
263
+
264
+ describe ( "Static Pages" , ( ) => {
265
+ test ( "copies static pages to output directory" , ( ) => {
266
+ const OUTPUT_PATH = join ( PROJECT_PATH , "out_publish" , DEFAULT_LOCALE ) ;
267
+
268
+ expect ( existsSync ( join ( OUTPUT_PATH , "static.html" ) ) ) . toBe ( true ) ;
269
+ expect ( existsSync ( join ( OUTPUT_PATH , "static/[id].html" ) ) ) . toBe ( true ) ;
270
+ } ) ;
271
+
272
+ test ( "copies static assets to out_publish/_next/ directory" , ( ) => {
273
+ const dirs = readdirSync (
274
+ join ( PROJECT_PATH , "out_publish" , "_next" , "static" )
275
+ ) ;
276
+
277
+ expect ( dirs . length ) . toBe ( 2 ) ;
278
+ expect ( dirs ) . toContain ( "chunks" ) ;
279
+ } ) ;
280
+
281
+ test . each ( [ "en" , "es" ] ) ( "multiple locales" , ( locale ) => {
282
+ const OUTPUT_PATH = join ( PROJECT_PATH , "out_publish" , locale ) ;
283
+
284
+ expect ( existsSync ( join ( OUTPUT_PATH , "static.html" ) ) ) . toBe ( true ) ;
285
+ expect ( existsSync ( join ( OUTPUT_PATH , "static/[id].html" ) ) ) . toBe ( true ) ;
286
+ } ) ;
287
+
288
+ test ( "locale not included in config" , ( ) => {
289
+ const notIncludedLocale = "fr" ;
290
+ const OUTPUT_PATH = join ( PROJECT_PATH , "out_publish" , notIncludedLocale ) ;
291
+
292
+ expect ( existsSync ( join ( OUTPUT_PATH , "static.html" ) ) ) . toBe ( false ) ;
293
+ expect ( existsSync ( join ( OUTPUT_PATH , "static/[id].html" ) ) ) . toBe ( false ) ;
294
+ } ) ;
295
+ } ) ;
296
+
297
+ describe ( "404 Page" , ( ) => {
298
+ test ( "copies 404.html to output directory" , ( ) => {
299
+ const OUTPUT_PATH = join ( PROJECT_PATH , "out_publish" , DEFAULT_LOCALE ) ;
300
+
301
+ expect ( existsSync ( join ( OUTPUT_PATH , "404.html" ) ) ) . toBe ( true ) ;
302
+ } ) ;
303
+ } ) ;
304
+
305
+ describe ( "Routing" , ( ) => {
306
+ test ( "creates Netlify redirects" , async ( ) => {
307
+ // Read _redirects file
308
+ const contents = readFileSync (
309
+ join ( PROJECT_PATH , "out_publish" , "_redirects" )
310
+ ) ;
311
+ let redirects = contents . toString ( ) ;
312
+
313
+ // Replace non-persistent build ID with placeholder
314
+
315
+ redirects = redirects . replace (
316
+ / \/ _ n e x t \/ d a t a \/ [ ^ \/ ] + \/ / g,
317
+ "/_next/data/%BUILD_ID%/"
318
+ ) ;
319
+
320
+ // Check that redirects match
321
+ expect ( redirects ) . toMatchSnapshot ( ) ;
322
+ } ) ;
323
+ } ) ;
0 commit comments