@@ -19,12 +19,12 @@ import {
19
19
getLogger ( ) . level = 'alert'
20
20
21
21
beforeEach < FixtureTestContext > ( async ( ctx ) => {
22
- await startMockBlobStore ( ctx )
23
22
// set for each test a new deployID and siteID
24
23
ctx . deployID = generateRandomObjectID ( )
25
24
ctx . siteID = v4 ( )
26
25
vi . stubEnv ( 'DEPLOY_ID' , ctx . deployID )
27
- vi . stubEnv ( 'NETLIFY_BLOBS_CONTEXT' , createBlobContext ( ctx ) )
26
+
27
+ await startMockBlobStore ( ctx )
28
28
} )
29
29
30
30
describe ( 'page router' , ( ) => {
@@ -58,13 +58,13 @@ describe('page router', () => {
58
58
// now it should be a cache miss
59
59
const call2 = await invokeFunction ( ctx , { url : 'static/revalidate' } )
60
60
const call2Date = load ( call2 . body ) ( '[data-testid="date-now"]' ) . text ( )
61
- expect ( call2Date , 'the date was cached and is matching the initial one' ) . not . toBe ( call1Date )
62
61
expect ( call2 . statusCode ) . toBe ( 200 )
63
62
expect ( call2 . headers , 'a cache miss on a stale page' ) . toEqual (
64
63
expect . objectContaining ( {
65
64
'x-nextjs-cache' : 'MISS' ,
66
65
} ) ,
67
66
)
67
+ expect ( call2Date , 'the date was cached and is matching the initial one' ) . not . toBe ( call1Date )
68
68
69
69
// it does not wait for the cache.set so we have to manually wait here until the blob storage got populated
70
70
await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 100 ) )
@@ -150,20 +150,20 @@ describe('app router', () => {
150
150
)
151
151
152
152
// wait to have a stale page
153
- await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 1_000 ) )
153
+ await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 2_000 ) )
154
154
// after the dynamic call of `posts/3` it should be in cache, not this is after the timout as the cache set happens async
155
155
expect ( await ctx . blobStore . get ( 'server/app/posts/3' ) ) . not . toBeNull ( )
156
156
157
157
const stale = await invokeFunction ( ctx , { url : 'posts/1' } )
158
158
const staleDate = load ( stale . body ) ( '[data-testid="date-now"]' ) . text ( )
159
159
expect ( stale . statusCode ) . toBe ( 200 )
160
- // it should have a new date rendered
161
- expect ( staleDate , 'the date was cached and is matching the initial one' ) . not . toBe ( post1Date )
162
160
expect ( stale . headers , 'a cache miss on a stale page' ) . toEqual (
163
161
expect . objectContaining ( {
164
162
'x-nextjs-cache' : 'MISS' ,
165
163
} ) ,
166
164
)
165
+ // it should have a new date rendered
166
+ expect ( staleDate , 'the date was cached and is matching the initial one' ) . not . toBe ( post1Date )
167
167
168
168
// it does not wait for the cache.set so we have to manually wait here until the blob storage got populated
169
169
await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 100 ) )
@@ -180,21 +180,82 @@ describe('app router', () => {
180
180
)
181
181
} )
182
182
183
- test < FixtureTestContext > ( 'react- server-components' , async ( ctx ) => {
183
+ test < FixtureTestContext > ( 'server-components blob store created correctly ' , async ( ctx ) => {
184
184
await createFixture ( 'server-components' , ctx )
185
185
await runPlugin ( ctx )
186
186
// check if the blob entries where successful set on the build plugin
187
187
const blobEntries = await getBlobEntries ( ctx )
188
188
expect ( blobEntries ) . toEqual ( [
189
+ {
190
+ key : 'cache/fetch-cache/460ed46cd9a194efa197be9f2571e51b729a039d1cff9834297f416dce5ada29' ,
191
+ etag : expect . any ( String ) ,
192
+ } ,
189
193
{
190
194
key : 'cache/fetch-cache/ac26c54e17c3018c17bfe5ae6adc0e6d37dbfaf28445c1f767ff267144264ac9' ,
191
195
etag : expect . any ( String ) ,
192
196
} ,
193
197
{ key : 'server/app/_not-found' , etag : expect . any ( String ) } ,
198
+ { key : 'server/app/api/revalidate-handler' , etag : expect . any ( String ) } ,
194
199
{ key : 'server/app/index' , etag : expect . any ( String ) } ,
195
200
{ key : 'server/app/revalidate-fetch' , etag : expect . any ( String ) } ,
196
201
{ key : 'server/app/static-fetch-1' , etag : expect . any ( String ) } ,
197
202
{ key : 'server/app/static-fetch-2' , etag : expect . any ( String ) } ,
198
203
] )
199
204
} )
205
+
206
+ test < FixtureTestContext > ( 'route handler with revalidate' , async ( ctx ) => {
207
+ await createFixture ( 'server-components' , ctx )
208
+ await runPlugin ( ctx )
209
+
210
+ // check if the route got prerendered
211
+ const blobEntry = await ctx . blobStore . get ( 'server/app/api/revalidate-handler' , { type : 'json' } )
212
+ expect ( blobEntry ) . not . toBeNull ( )
213
+
214
+ // test the first invocation of the route
215
+ const call1 = await invokeFunction ( ctx , { url : '/api/revalidate-handler' } )
216
+ const call1Body = JSON . parse ( call1 . body )
217
+ const call1Time = call1Body . time
218
+ expect ( call1 . statusCode ) . toBe ( 200 )
219
+ expect ( call1Body ) . toMatchObject ( {
220
+ data : expect . objectContaining ( {
221
+ id : 1 ,
222
+ name : 'Under the Dome' ,
223
+ } ) ,
224
+ } )
225
+ expect ( call1 . headers , 'a cache hit on the first invocation of a prerendered route' ) . toEqual (
226
+ expect . objectContaining ( {
227
+ 'x-nextjs-cache' : 'HIT' ,
228
+ } ) ,
229
+ )
230
+ // wait to have a stale route
231
+ await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 1_500 ) )
232
+
233
+ const call2 = await invokeFunction ( ctx , { url : '/api/revalidate-handler' } )
234
+ const call2Body = JSON . parse ( call2 . body )
235
+ const call2Time = call2Body . time
236
+ expect ( call2 . statusCode ) . toBe ( 200 )
237
+ // it should have a new date rendered
238
+ expect ( call1Time , 'the date is a new one on a stale route' ) . not . toBe ( call2Time )
239
+ expect ( call2Body ) . toMatchObject ( { data : expect . objectContaining ( { id : 1 } ) } )
240
+ expect ( call2 . headers , 'a cache miss on a stale route' ) . toEqual (
241
+ expect . objectContaining ( {
242
+ 'x-nextjs-cache' : 'MISS' ,
243
+ } ) ,
244
+ )
245
+
246
+ // it does not wait for the cache.set so we have to manually wait here until the blob storage got populated
247
+ await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 100 ) )
248
+
249
+ const call3 = await invokeFunction ( ctx , { url : '/api/revalidate-handler' } )
250
+ expect ( call3 . statusCode ) . toBe ( 200 )
251
+ const call3Body = JSON . parse ( call3 . body )
252
+ const call3Time = call3Body . time
253
+ expect ( call3Time , 'the date was cached as well' ) . toBe ( call2Time )
254
+ expect ( call3Body ) . toMatchObject ( { data : expect . objectContaining ( { id : 1 } ) } )
255
+ expect ( call3 . headers , 'a cache hit after dynamically regenerating the stale route' ) . toEqual (
256
+ expect . objectContaining ( {
257
+ 'x-nextjs-cache' : 'HIT' ,
258
+ } ) ,
259
+ )
260
+ } )
200
261
} )
0 commit comments