1
1
import { fireEvent , screen , waitFor , within } from "@testing-library/react" ;
2
- import * as API from "../../../api/api " ;
3
- import { renderWithAuth } from "../../../ testHelpers/renderHelpers" ;
2
+ import userEvent from "@testing-library/user-event " ;
3
+ import { renderWithAuth } from "testHelpers/renderHelpers" ;
4
4
import { SchedulePage } from "./SchedulePage" ;
5
-
6
- const renderPage = ( ) => {
7
- return renderWithAuth ( < SchedulePage /> ) ;
8
- } ;
5
+ import { server } from "testHelpers/server" ;
6
+ import { MockUser } from "testHelpers/entities" ;
7
+ import { rest } from "msw" ;
9
8
10
9
const fillForm = async ( {
11
- hours ,
12
- minutes ,
10
+ hour ,
11
+ minute ,
13
12
timezone,
14
13
} : {
15
- hours : number ;
16
- minutes : number ;
14
+ hour : number ;
15
+ minute : number ;
17
16
timezone : string ;
18
17
} ) => {
19
- await waitFor ( ( ) => screen . findByLabelText ( "Hours" ) ) ;
20
- await waitFor ( ( ) => screen . findByLabelText ( "Minutes" ) ) ;
21
- fireEvent . change ( screen . getByLabelText ( "Hours" ) , {
22
- target : { value : hours } ,
23
- } ) ;
24
- fireEvent . change ( screen . getByLabelText ( "Minutes" ) , {
25
- target : { value : minutes } ,
18
+ const user = userEvent . setup ( ) ;
19
+ await waitFor ( ( ) => screen . findByLabelText ( "Start time" ) ) ;
20
+ const HH = hour . toString ( ) . padStart ( 2 , "0" ) ;
21
+ const mm = minute . toString ( ) . padStart ( 2 , "0" ) ;
22
+ fireEvent . change ( screen . getByLabelText ( "Start time" ) , {
23
+ target : { value : `${ HH } :${ mm } ` } ,
26
24
} ) ;
27
25
28
- await waitFor ( ( ) => screen . findByLabelText ( "Timezone" ) ) ;
29
- fireEvent . click ( screen . getByLabelText ( "Timezone" ) ) ;
30
- // TODO: fix the options targeting
31
- const optionsList = screen . getByRole ( "listbox" ) ;
32
- const option = within ( optionsList ) . getByText ( timezone ) ;
33
- fireEvent . click ( option ) ;
26
+ const timezoneDropdown = screen . getByLabelText ( "Timezone" ) ;
27
+ await user . click ( timezoneDropdown ) ;
28
+ const list = screen . getByRole ( "listbox" ) ;
29
+ const option = within ( list ) . getByText ( timezone ) ;
30
+ await user . click ( option ) ;
34
31
} ;
35
32
36
33
const readCronExpression = ( ) => {
37
- return screen . getByLabelText ( "Cron schedule" ) . getAttribute ( "value" ) ;
38
- } ;
39
-
40
- const readNextOccurrence = ( ) => {
41
- return screen . getByLabelText ( "Next occurrence" ) . getAttribute ( "value" ) ;
34
+ return ;
42
35
} ;
43
36
44
37
const submitForm = async ( ) => {
@@ -56,75 +49,83 @@ const defaultQuietHoursResponse = {
56
49
const cronTests = [
57
50
{
58
51
timezone : "Australia/Sydney" ,
59
- hours : 0 ,
60
- minutes : 0 ,
61
- currentTime : new Date ( "2023-09-06T15:00:00.000+10:00Z" ) ,
62
- expectedNext : "12:00AM tomorrow (in 9 hours)" ,
52
+ hour : 0 ,
53
+ minute : 0 ,
63
54
} ,
64
- ] ;
55
+ ] as const ;
65
56
66
57
describe ( "SchedulePage" , ( ) => {
67
- describe ( "cron tests" , ( ) => {
68
- for ( let i = 0 ; i < cronTests . length ; i ++ ) {
69
- const test = cronTests [ i ] ;
70
- describe ( `case ${ i } ` , ( ) => {
71
- it ( "has the correct expected time" , async ( ) => {
72
- jest
73
- . spyOn ( API , "getUserQuietHoursSchedule" )
74
- . mockImplementationOnce ( ( ) =>
75
- Promise . resolve ( defaultQuietHoursResponse ) ,
76
- ) ;
77
- jest
78
- . spyOn ( API , "updateUserQuietHoursSchedule" )
79
- . mockImplementationOnce ( ( userId , data ) => {
80
- return Promise . resolve ( {
81
- raw_schedule : data . schedule ,
82
- user_set : true ,
83
- time : `${ test . hours . toString ( ) . padStart ( 2 , "0" ) } :${ test . minutes
84
- . toString ( )
85
- . padStart ( 2 , "0" ) } `,
86
- timezone : test . timezone ,
87
- next : "" , // This value isn't used in the UI, the UI generates it.
88
- } ) ;
89
- } ) ;
90
- const { user } = renderPage ( ) ;
58
+ beforeEach ( ( ) => {
59
+ // appear logged out
60
+ server . use (
61
+ rest . get ( `/api/v2/users/${ MockUser . id } /quiet-hours` , ( req , res , ctx ) => {
62
+ return res ( ctx . status ( 200 ) , ctx . json ( defaultQuietHoursResponse ) ) ;
63
+ } ) ,
64
+ ) ;
65
+ } ) ;
91
66
92
- await fillForm ( test ) ;
67
+ describe ( "cron tests" , ( ) => {
68
+ it . each ( cronTests ) (
69
+ "case %# has the correct expected time" ,
70
+ async ( test ) => {
71
+ server . use (
72
+ rest . put (
73
+ `/api/v2/users/${ MockUser . id } /quiet-hours` ,
74
+ async ( req , res , ctx ) => {
75
+ const data = await req . json ( ) ;
76
+ return res (
77
+ ctx . status ( 200 ) ,
78
+ ctx . json ( {
79
+ response : { } ,
80
+ raw_schedule : data . schedule ,
81
+ user_set : true ,
82
+ time : `${ test . hour . toString ( ) . padStart ( 2 , "0" ) } :${ test . minute
83
+ . toString ( )
84
+ . padStart ( 2 , "0" ) } `,
85
+ timezone : test . timezone ,
86
+ next : "" , // This value isn't used in the UI, the UI generates it.
87
+ } ) ,
88
+ ) ;
89
+ } ,
90
+ ) ,
91
+ ) ;
93
92
94
- const expectedCronSchedule = `CRON_TZ=${ test . timezone } ${ test . minutes } ${ test . hours } * * *` ;
95
- expect ( readCronExpression ( ) ) . toEqual ( expectedCronSchedule ) ;
96
- expect ( readNextOccurrence ( ) ) . toEqual ( test . expectedNext ) ;
93
+ const expectedCronSchedule = `CRON_TZ=${ test . timezone } ${ test . minute } ${ test . hour } * * *` ;
94
+ renderWithAuth ( < SchedulePage /> ) ;
95
+ await fillForm ( test ) ;
96
+ const cron = screen . getByLabelText ( "Cron schedule" ) ;
97
+ expect ( cron . getAttribute ( "value" ) ) . toEqual ( expectedCronSchedule ) ;
97
98
98
- await submitForm ( ) ;
99
- const successMessage = await screen . findByText (
100
- "Schedule updated successfully" ,
101
- ) ;
102
- expect ( successMessage ) . toBeDefined ( ) ;
103
- expect ( API . updateUserQuietHoursSchedule ) . toBeCalledTimes ( 1 ) ;
104
- expect ( API . updateUserQuietHoursSchedule ) . toBeCalledWith ( user . id , {
105
- schedule : expectedCronSchedule ,
106
- } ) ;
107
- } ) ;
108
- } ) ;
109
- }
99
+ await submitForm ( ) ;
100
+ const successMessage = await screen . findByText (
101
+ "Schedule updated successfully" ,
102
+ ) ;
103
+ expect ( successMessage ) . toBeDefined ( ) ;
104
+ } ,
105
+ ) ;
110
106
} ) ;
111
107
112
108
describe ( "when it is an unknown error" , ( ) => {
113
109
it ( "shows a generic error message" , async ( ) => {
114
- jest
115
- . spyOn ( API , "getUserQuietHoursSchedule" )
116
- . mockImplementationOnce ( ( ) =>
117
- Promise . resolve ( defaultQuietHoursResponse ) ,
118
- ) ;
119
- jest . spyOn ( API , "updateUserQuietHoursSchedule" ) . mockRejectedValueOnce ( {
120
- data : "unknown error" ,
121
- } ) ;
110
+ server . use (
111
+ rest . put (
112
+ `/api/v2/users/${ MockUser . id } /quiet-hours` ,
113
+ ( req , res , ctx ) => {
114
+ return res (
115
+ ctx . status ( 500 ) ,
116
+ ctx . json ( {
117
+ message : "oh no!" ,
118
+ } ) ,
119
+ ) ;
120
+ } ,
121
+ ) ,
122
+ ) ;
122
123
123
- renderPage ( ) ;
124
+ renderWithAuth ( < SchedulePage /> ) ;
124
125
await fillForm ( cronTests [ 0 ] ) ;
125
126
await submitForm ( ) ;
126
127
127
- const errorMessage = await screen . findByText ( "Something went wrong " ) ;
128
+ const errorMessage = await screen . findByText ( "oh no! " ) ;
128
129
expect ( errorMessage ) . toBeDefined ( ) ;
129
130
} ) ;
130
131
} ) ;
0 commit comments