@@ -15,113 +15,97 @@ limitations under the License.
15
15
*/
16
16
17
17
import React from "react" ;
18
- // eslint-disable-next-line deprecate/import
19
- import { mount , ReactWrapper } from "enzyme" ;
20
- import { act } from "react-dom/test-utils" ;
21
18
import { IPassphraseInfo } from "matrix-js-sdk/src/crypto/api" ;
19
+ import { act , fireEvent , render , screen } from "@testing-library/react" ;
20
+ import userEvent from "@testing-library/user-event" ;
21
+ import { MatrixClient } from "matrix-js-sdk/src/matrix" ;
22
+ import { Mocked } from "jest-mock" ;
22
23
23
- import { findByAttr , getMockClientWithEventEmitter , unmockClientPeg } from "../../../test-utils" ;
24
- import { findById , flushPromises } from "../../../test-utils" ;
24
+ import { getMockClientWithEventEmitter , mockPlatformPeg } from "../../../test-utils" ;
25
25
import AccessSecretStorageDialog from "../../../../src/components/views/dialogs/security/AccessSecretStorageDialog" ;
26
26
27
+ const securityKey = "EsTc WKmb ivvk jLS7 Y1NH 5CcQ mP1E JJwj B3Fd pFWm t4Dp dbyu" ;
28
+
27
29
describe ( "AccessSecretStorageDialog" , ( ) => {
28
- const mockClient = getMockClientWithEventEmitter ( {
29
- keyBackupKeyFromRecoveryKey : jest . fn ( ) ,
30
- checkSecretStorageKey : jest . fn ( ) ,
31
- isValidRecoveryKey : jest . fn ( ) ,
32
- } ) ;
30
+ let mockClient : Mocked < MatrixClient > ;
31
+
33
32
const defaultProps = {
34
33
onFinished : jest . fn ( ) ,
35
34
checkPrivateKey : jest . fn ( ) ,
36
35
keyInfo : undefined ,
37
36
} ;
38
- const getComponent = ( props = { } ) : ReactWrapper =>
39
- mount ( < AccessSecretStorageDialog { ...defaultProps } { ...props } /> ) ;
40
-
41
- beforeEach ( ( ) => {
42
- jest . clearAllMocks ( ) ;
43
- mockClient . keyBackupKeyFromRecoveryKey . mockReturnValue ( "a raw key" as unknown as Uint8Array ) ;
44
- mockClient . isValidRecoveryKey . mockReturnValue ( false ) ;
45
- } ) ;
46
-
47
- afterAll ( ( ) => {
48
- unmockClientPeg ( ) ;
49
- } ) ;
50
37
51
- it ( "Closes the dialog when the form is submitted with a valid key" , async ( ) => {
52
- const onFinished = jest . fn ( ) ;
53
- const checkPrivateKey = jest . fn ( ) . mockResolvedValue ( true ) ;
54
- const wrapper = getComponent ( { onFinished, checkPrivateKey } ) ;
38
+ const renderComponent = ( props = { } ) : void => {
39
+ render ( < AccessSecretStorageDialog { ...defaultProps } { ...props } /> ) ;
40
+ } ;
55
41
56
- // force into valid state
42
+ const enterSecurityKey = ( placeholder = "Security Key" ) : void => {
57
43
act ( ( ) => {
58
- wrapper . setState ( {
59
- recoveryKeyValid : true ,
60
- recoveryKey : "a" ,
44
+ fireEvent . change ( screen . getByPlaceholderText ( placeholder ) , {
45
+ target : {
46
+ value : securityKey ,
47
+ } ,
61
48
} ) ;
49
+ // wait for debounce
50
+ jest . advanceTimersByTime ( 250 ) ;
62
51
} ) ;
63
- const e = { preventDefault : ( ) => { } } ;
52
+ } ;
64
53
65
- act ( ( ) => {
66
- wrapper . find ( "form" ) . simulate ( "submit" , e ) ;
67
- } ) ;
54
+ const submitDialog = async ( ) : Promise < void > => {
55
+ await userEvent . click ( screen . getByText ( "Continue" ) , { delay : null } ) ;
56
+ } ;
68
57
69
- await flushPromises ( ) ;
58
+ beforeAll ( ( ) => {
59
+ jest . useFakeTimers ( ) ;
60
+ mockPlatformPeg ( ) ;
61
+ } ) ;
70
62
71
- expect ( checkPrivateKey ) . toHaveBeenCalledWith ( { recoveryKey : "a" } ) ;
72
- expect ( onFinished ) . toHaveBeenCalledWith ( { recoveryKey : "a" } ) ;
63
+ afterAll ( ( ) => {
64
+ jest . useRealTimers ( ) ;
65
+ jest . restoreAllMocks ( ) ;
73
66
} ) ;
74
67
75
- it ( "Considers a valid key to be valid" , async ( ) => {
76
- const checkPrivateKey = jest . fn ( ) . mockResolvedValue ( true ) ;
77
- const wrapper = getComponent ( { checkPrivateKey } ) ;
78
- mockClient . keyBackupKeyFromRecoveryKey . mockReturnValue ( "a raw key" as unknown as Uint8Array ) ;
68
+ beforeEach ( ( ) => {
69
+ mockClient = getMockClientWithEventEmitter ( {
70
+ keyBackupKeyFromRecoveryKey : jest . fn ( ) ,
71
+ checkSecretStorageKey : jest . fn ( ) ,
72
+ isValidRecoveryKey : jest . fn ( ) ,
73
+ } ) ;
74
+ } ) ;
75
+
76
+ it ( "Closes the dialog when the form is submitted with a valid key" , async ( ) => {
79
77
mockClient . checkSecretStorageKey . mockResolvedValue ( true ) ;
78
+ mockClient . isValidRecoveryKey . mockReturnValue ( true ) ;
80
79
81
- const v = "asdf" ;
82
- const e = { target : { value : v } } ;
83
- act ( ( ) => {
84
- findById ( wrapper , "mx_securityKey" ) . find ( "input" ) . simulate ( "change" , e ) ;
85
- wrapper . setProps ( { } ) ;
86
- } ) ;
87
- await act ( async ( ) => {
88
- // force a validation now because it debounces
89
- // @ts -ignore
90
- await wrapper . instance ( ) . validateRecoveryKey ( ) ;
91
- wrapper . setProps ( { } ) ;
92
- } ) ;
80
+ const onFinished = jest . fn ( ) ;
81
+ const checkPrivateKey = jest . fn ( ) . mockResolvedValue ( true ) ;
82
+ renderComponent ( { onFinished, checkPrivateKey } ) ;
83
+
84
+ // check that the input field is focused
85
+ expect ( screen . getByPlaceholderText ( "Security Key" ) ) . toHaveFocus ( ) ;
93
86
94
- const submitButton = findByAttr ( "data-testid" ) ( wrapper , "dialog-primary-button" ) . at ( 0 ) ;
95
- // submit button is enabled when key is valid
96
- expect ( submitButton . props ( ) . disabled ) . toBeFalsy ( ) ;
97
- expect ( wrapper . find ( ".mx_AccessSecretStorageDialog_recoveryKeyFeedback" ) . text ( ) ) . toEqual ( "Looks good!" ) ;
87
+ await enterSecurityKey ( ) ;
88
+ await submitDialog ( ) ;
89
+
90
+ expect ( screen . getByText ( "Looks good!" ) ) . toBeInTheDocument ( ) ;
91
+ expect ( checkPrivateKey ) . toHaveBeenCalledWith ( { recoveryKey : securityKey } ) ;
92
+ expect ( onFinished ) . toHaveBeenCalledWith ( { recoveryKey : securityKey } ) ;
98
93
} ) ;
99
94
100
95
it ( "Notifies the user if they input an invalid Security Key" , async ( ) => {
101
- const checkPrivateKey = jest . fn ( ) . mockResolvedValue ( false ) ;
102
- const wrapper = getComponent ( { checkPrivateKey } ) ;
103
- const e = { target : { value : "a" } } ;
96
+ const onFinished = jest . fn ( ) ;
97
+ const checkPrivateKey = jest . fn ( ) . mockResolvedValue ( true ) ;
98
+ renderComponent ( { onFinished, checkPrivateKey } ) ;
99
+
104
100
mockClient . keyBackupKeyFromRecoveryKey . mockImplementation ( ( ) => {
105
101
throw new Error ( "that's no key" ) ;
106
102
} ) ;
107
103
108
- act ( ( ) => {
109
- findById ( wrapper , "mx_securityKey" ) . find ( "input" ) . simulate ( "change" , e ) ;
110
- } ) ;
111
- // force a validation now because it debounces
112
- // @ts -ignore private
113
- await wrapper . instance ( ) . validateRecoveryKey ( ) ;
114
-
115
- const submitButton = findByAttr ( "data-testid" ) ( wrapper , "dialog-primary-button" ) . at ( 0 ) ;
116
- // submit button is disabled when recovery key is invalid
117
- expect ( submitButton . props ( ) . disabled ) . toBeTruthy ( ) ;
118
- expect ( wrapper . find ( ".mx_AccessSecretStorageDialog_recoveryKeyFeedback" ) . text ( ) ) . toEqual (
119
- "Invalid Security Key" ,
120
- ) ;
121
-
122
- wrapper . setProps ( { } ) ;
123
- const notification = wrapper . find ( ".mx_AccessSecretStorageDialog_recoveryKeyFeedback" ) ;
124
- expect ( notification . props ( ) . children ) . toEqual ( "Invalid Security Key" ) ;
104
+ await enterSecurityKey ( ) ;
105
+ await submitDialog ( ) ;
106
+
107
+ expect ( screen . getByText ( "Continue" ) ) . toBeDisabled ( ) ;
108
+ expect ( screen . getByText ( "Invalid Security Key" ) ) . toBeInTheDocument ( ) ;
125
109
} ) ;
126
110
127
111
it ( "Notifies the user if they input an invalid passphrase" , async function ( ) {
@@ -139,30 +123,17 @@ describe("AccessSecretStorageDialog", () => {
139
123
} ,
140
124
} ;
141
125
const checkPrivateKey = jest . fn ( ) . mockResolvedValue ( false ) ;
142
- const wrapper = getComponent ( { checkPrivateKey, keyInfo } ) ;
126
+ renderComponent ( { checkPrivateKey, keyInfo } ) ;
143
127
mockClient . isValidRecoveryKey . mockReturnValue ( false ) ;
144
128
145
- // update passphrase
146
- act ( ( ) => {
147
- const e = { target : { value : "a" } } ;
148
- findById ( wrapper , "mx_passPhraseInput" ) . at ( 1 ) . simulate ( "change" , e ) ;
149
- } ) ;
150
- wrapper . setProps ( { } ) ;
151
-
152
- // input updated
153
- expect ( findById ( wrapper , "mx_passPhraseInput" ) . at ( 0 ) . props ( ) . value ) . toEqual ( "a" ) ;
129
+ await enterSecurityKey ( "Security Phrase" ) ;
130
+ expect ( screen . getByPlaceholderText ( "Security Phrase" ) ) . toHaveValue ( securityKey ) ;
131
+ await submitDialog ( ) ;
154
132
155
- // submit the form
156
- act ( ( ) => {
157
- wrapper . find ( "form" ) . at ( 0 ) . simulate ( "submit" ) ;
158
- } ) ;
159
- await flushPromises ( ) ;
160
-
161
- wrapper . setProps ( { } ) ;
162
- const notification = wrapper . find ( ".mx_AccessSecretStorageDialog_keyStatus" ) ;
163
- expect ( notification . props ( ) . children ) . toEqual ( [
164
- "\uD83D\uDC4E " ,
165
- "Unable to access secret storage. Please verify that you " + "entered the correct Security Phrase." ,
166
- ] ) ;
133
+ expect (
134
+ screen . getByText (
135
+ "👎 Unable to access secret storage. Please verify that you entered the correct Security Phrase." ,
136
+ ) ,
137
+ ) . toBeInTheDocument ( ) ;
167
138
} ) ;
168
139
} ) ;
0 commit comments