@@ -2,57 +2,107 @@ import { expect } from '@playwright/test'
2
2
import { test } from '../utils/playwright-helpers.js'
3
3
4
4
test . describe ( 'Dynamic CMS' , ( ) => {
5
- test ( 'Invalidates 404 pages from durable cache' , async ( { page, dynamicCms } ) => {
6
- // 1. Verify the status and headers of the dynamic page
7
- const response1 = await page . goto ( new URL ( '/content/blog' , dynamicCms . url ) . href )
8
- const headers1 = response1 ?. headers ( ) || { }
9
-
10
- expect ( response1 ?. status ( ) ) . toEqual ( 404 )
11
- expect ( headers1 [ 'cache-control' ] ) . toEqual ( 'public,max-age=0,must-revalidate' )
12
- expect ( headers1 [ 'cache-status' ] ) . toEqual (
13
- '"Next.js"; fwd=miss, "Netlify Durable"; fwd=uri-miss; stored, "Netlify Edge"; fwd=miss' ,
14
- )
15
- expect ( headers1 [ 'netlify-cache-tag' ] ) . toEqual ( '_n_t_/content/blog' )
16
- expect ( headers1 [ 'netlify-cdn-cache-control' ] ) . toMatch (
17
- / s - m a x a g e = 3 1 5 3 6 0 0 0 , ( s t a l e - w h i l e - r e v a l i d a t e = 3 1 5 3 6 0 0 0 , ) ? d u r a b l e / ,
18
- )
19
-
20
- // 2. Publish the blob, revalidate the dynamic page, and wait to regenerate
21
- await page . goto ( new URL ( '/cms/publish' , dynamicCms . url ) . href )
22
- await page . goto ( new URL ( '/api/revalidate?path=/content/blog' , dynamicCms . url ) . href )
23
- await page . waitForTimeout ( 1000 )
24
-
25
- // 3. Verify the status and headers of the dynamic page
26
- const response2 = await page . goto ( new URL ( '/content/blog' , dynamicCms . url ) . href )
27
- const headers2 = response2 ?. headers ( ) || { }
28
-
29
- expect ( response2 ?. status ( ) ) . toEqual ( 200 )
30
- expect ( headers2 [ 'cache-control' ] ) . toEqual ( 'public,max-age=0,must-revalidate' )
31
- expect ( headers2 [ 'cache-status' ] ) . toMatch (
32
- / " N e x t .j s " ; h i t , " N e t l i f y D u r a b l e " ; f w d = s t a l e ; t t l = [ 0 - 9 ] + ; s t o r e d , " N e t l i f y E d g e " ; f w d = ( s t a l e | m i s s ) / ,
33
- )
34
- expect ( headers2 [ 'netlify-cache-tag' ] ) . toEqual ( '_n_t_/content/blog' )
35
- expect ( headers2 [ 'netlify-cdn-cache-control' ] ) . toMatch (
36
- / s - m a x a g e = 3 1 5 3 6 0 0 0 , ( s t a l e - w h i l e - r e v a l i d a t e = 3 1 5 3 6 0 0 0 , ) ? d u r a b l e / ,
37
- )
38
-
39
- // 4. Unpublish the blob, revalidate the dynamic page, and wait to regenerate
40
- await page . goto ( new URL ( '/cms/unpublish' , dynamicCms . url ) . href )
41
- await page . goto ( new URL ( '/api/revalidate?path=/content/blog' , dynamicCms . url ) . href )
42
- await page . waitForTimeout ( 1000 )
43
-
44
- // 5. Verify the status and headers of the dynamic page
45
- const response3 = await page . goto ( new URL ( '/content/blog' , dynamicCms . url ) . href )
46
- const headers3 = response3 ?. headers ( ) || { }
47
-
48
- expect ( response3 ?. status ( ) ) . toEqual ( 404 )
49
- expect ( headers3 [ 'cache-control' ] ) . toEqual ( 'public,max-age=0,must-revalidate' )
50
- expect ( headers3 [ 'cache-status' ] ) . toMatch (
51
- / " N e x t .j s " ; f w d = m i s s , " N e t l i f y D u r a b l e " ; f w d = s t a l e ; t t l = [ 0 - 9 ] + ; s t o r e d , " N e t l i f y E d g e " ; f w d = ( s t a l e | m i s s ) / ,
52
- )
53
- expect ( headers3 [ 'netlify-cache-tag' ] ) . toEqual ( '_n_t_/content/blog' )
54
- expect ( headers3 [ 'netlify-cdn-cache-control' ] ) . toMatch (
55
- / s - m a x a g e = 3 1 5 3 6 0 0 0 , ( s t a l e - w h i l e - r e v a l i d a t e = 3 1 5 3 6 0 0 0 , ) ? d u r a b l e / ,
56
- )
5
+ test . describe ( 'Invalidates 404 pages from durable cache' , ( ) => {
6
+ // using postFix allows to rerun tests without having to redeploy the app because paths/keys will be unique for each test run
7
+ const postFix = Date . now ( )
8
+ for ( const { label, contentKey, expectedCacheTag, urlPath, pathToRevalidate } of [
9
+ {
10
+ label : 'Invalidates 404 html from durable cache (implicit default locale)' ,
11
+ urlPath : `/content/html-implicit-default-locale-${ postFix } ` ,
12
+ contentKey : `html-implicit-default-locale-${ postFix } ` ,
13
+ expectedCacheTag : `_n_t_/en/content/html-implicit-default-locale-${ postFix } ` ,
14
+ } ,
15
+ {
16
+ label : 'Invalidates 404 html from durable cache (explicit default locale)' ,
17
+ urlPath : `/en/content/html-explicit-default-locale-${ postFix } ` ,
18
+ contentKey : `html-explicit-default-locale-${ postFix } ` ,
19
+ expectedCacheTag : `_n_t_/en/content/html-explicit-default-locale-${ postFix } ` ,
20
+ } ,
21
+ // json paths don't have implicit locale routing
22
+ {
23
+ label : 'Invalidates 404 json from durable cache (default locale)' ,
24
+ urlPath : `/_next/data/build-id/en/content/json-default-locale-${ postFix } .json` ,
25
+ // for html, we can use html path as param for revalidate,
26
+ // for json we can't use json path and instead use one of html paths
27
+ // let's use implicit default locale here, as we will have another case for
28
+ // non-default locale which will have to use explicit one
29
+ pathToRevalidate : `/content/json-default-locale-${ postFix } ` ,
30
+ contentKey : `json-default-locale-${ postFix } ` ,
31
+ expectedCacheTag : `_n_t_/en/content/json-default-locale-${ postFix } ` ,
32
+ } ,
33
+ {
34
+ label : 'Invalidates 404 html from durable cache (non-default locale)' ,
35
+ urlPath : `/fr/content/html-non-default-locale-${ postFix } ` ,
36
+ contentKey : `html-non-default-locale-${ postFix } ` ,
37
+ expectedCacheTag : `_n_t_/fr/content/html-non-default-locale-${ postFix } ` ,
38
+ } ,
39
+ {
40
+ label : 'Invalidates 404 json from durable cache (non-default locale)' ,
41
+ urlPath : `/_next/data/build-id/fr/content/json-non-default-locale-${ postFix } .json` ,
42
+ pathToRevalidate : `/fr/content/json-non-default-locale-${ postFix } ` ,
43
+ contentKey : `json-non-default-locale-${ postFix } ` ,
44
+ expectedCacheTag : `_n_t_/fr/content/json-non-default-locale-${ postFix } ` ,
45
+ } ,
46
+ ] ) {
47
+ test ( label , async ( { page, dynamicCms } ) => {
48
+ const routeUrl = new URL ( urlPath , dynamicCms . url ) . href
49
+ const revalidateAPiUrl = new URL (
50
+ `/api/revalidate?path=${ pathToRevalidate ?? urlPath } ` ,
51
+ dynamicCms . url ,
52
+ ) . href
53
+
54
+ // 1. Verify the status and headers of the dynamic page
55
+ const response1 = await page . goto ( routeUrl )
56
+ const headers1 = response1 ?. headers ( ) || { }
57
+
58
+ expect ( response1 ?. status ( ) ) . toEqual ( 404 )
59
+ expect ( headers1 [ 'cache-control' ] ) . toEqual ( 'public,max-age=0,must-revalidate' )
60
+ expect ( headers1 [ 'cache-status' ] ) . toEqual (
61
+ '"Next.js"; fwd=miss, "Netlify Durable"; fwd=uri-miss; stored, "Netlify Edge"; fwd=miss' ,
62
+ )
63
+ expect ( headers1 [ 'netlify-cache-tag' ] ) . toEqual ( expectedCacheTag )
64
+ expect ( headers1 [ 'netlify-cdn-cache-control' ] ) . toMatch (
65
+ / s - m a x a g e = 3 1 5 3 6 0 0 0 , ( s t a l e - w h i l e - r e v a l i d a t e = 3 1 5 3 6 0 0 0 , ) ? d u r a b l e / ,
66
+ )
67
+
68
+ // 2. Publish the blob, revalidate the dynamic page, and wait to regenerate
69
+ await page . goto ( new URL ( `/cms/publish/${ contentKey } ` , dynamicCms . url ) . href )
70
+ await page . goto ( revalidateAPiUrl )
71
+ await page . waitForTimeout ( 1000 )
72
+
73
+ // 3. Verify the status and headers of the dynamic page
74
+ const response2 = await page . goto ( routeUrl )
75
+ const headers2 = response2 ?. headers ( ) || { }
76
+
77
+ expect ( response2 ?. status ( ) ) . toEqual ( 200 )
78
+ expect ( headers2 [ 'cache-control' ] ) . toEqual ( 'public,max-age=0,must-revalidate' )
79
+ expect ( headers2 [ 'cache-status' ] ) . toMatch (
80
+ / " N e x t .j s " ; h i t , " N e t l i f y D u r a b l e " ; f w d = s t a l e ; t t l = [ 0 - 9 ] + ; s t o r e d , " N e t l i f y E d g e " ; f w d = ( s t a l e | m i s s ) / ,
81
+ )
82
+ expect ( headers2 [ 'netlify-cache-tag' ] ) . toEqual ( expectedCacheTag )
83
+ expect ( headers2 [ 'netlify-cdn-cache-control' ] ) . toMatch (
84
+ / s - m a x a g e = 3 1 5 3 6 0 0 0 , ( s t a l e - w h i l e - r e v a l i d a t e = 3 1 5 3 6 0 0 0 , ) ? d u r a b l e / ,
85
+ )
86
+
87
+ // 4. Unpublish the blob, revalidate the dynamic page, and wait to regenerate
88
+ await page . goto ( new URL ( `/cms/unpublish/${ contentKey } ` , dynamicCms . url ) . href )
89
+ await page . goto ( revalidateAPiUrl )
90
+ await page . waitForTimeout ( 1000 )
91
+
92
+ // 5. Verify the status and headers of the dynamic page
93
+ const response3 = await page . goto ( routeUrl )
94
+ const headers3 = response3 ?. headers ( ) || { }
95
+
96
+ expect ( response3 ?. status ( ) ) . toEqual ( 404 )
97
+ expect ( headers3 [ 'cache-control' ] ) . toEqual ( 'public,max-age=0,must-revalidate' )
98
+ expect ( headers3 [ 'cache-status' ] ) . toMatch (
99
+ / " N e x t .j s " ; f w d = m i s s , " N e t l i f y D u r a b l e " ; f w d = s t a l e ; t t l = [ 0 - 9 ] + ; s t o r e d , " N e t l i f y E d g e " ; f w d = ( s t a l e | m i s s ) / ,
100
+ )
101
+ expect ( headers3 [ 'netlify-cache-tag' ] ) . toEqual ( expectedCacheTag )
102
+ expect ( headers3 [ 'netlify-cdn-cache-control' ] ) . toMatch (
103
+ / s - m a x a g e = 3 1 5 3 6 0 0 0 , ( s t a l e - w h i l e - r e v a l i d a t e = 3 1 5 3 6 0 0 0 , ) ? d u r a b l e / ,
104
+ )
105
+ } )
106
+ }
57
107
} )
58
108
} )
0 commit comments