@@ -25,18 +25,40 @@ import MatrixClientContext from "../../../../src/contexts/MatrixClientContext";
2525
2626describe ( "<DevicesPanel />" , ( ) => {
2727 const userId = "@alice:server.org" ;
28- const device1 = { device_id : "device_1" } ;
29- const device2 = { device_id : "device_2" } ;
30- const device3 = { device_id : "device_3" } ;
28+
29+ // the local device
30+ const ownDevice = { device_id : "device_1" } ;
31+
32+ // a device which we have verified via cross-signing
33+ const verifiedDevice = { device_id : "device_2" } ;
34+
35+ // a device which we have *not* verified via cross-signing
36+ const unverifiedDevice = { device_id : "device_3" } ;
37+
38+ // a device which is returned by `getDevices` but getDeviceVerificationStatus returns `null` for
39+ // (as it would for a device with no E2E keys).
40+ const nonCryptoDevice = { device_id : "non_crypto" } ;
41+
3142 const mockCrypto = {
32- getDeviceVerificationStatus : jest . fn ( ) . mockResolvedValue ( {
33- crossSigningVerified : false ,
43+ getDeviceVerificationStatus : jest . fn ( ) . mockImplementation ( ( _userId , deviceId ) => {
44+ if ( _userId !== userId ) {
45+ throw new Error ( `bad user id ${ _userId } ` ) ;
46+ }
47+ if ( deviceId === ownDevice . device_id || deviceId === verifiedDevice . device_id ) {
48+ return { crossSigningVerified : true } ;
49+ } else if ( deviceId === unverifiedDevice . device_id ) {
50+ return {
51+ crossSigningVerified : false ,
52+ } ;
53+ } else {
54+ return null ;
55+ }
3456 } ) ,
3557 } ;
3658 const mockClient = getMockClientWithEventEmitter ( {
3759 ...mockClientMethodsUser ( userId ) ,
3860 getDevices : jest . fn ( ) ,
39- getDeviceId : jest . fn ( ) . mockReturnValue ( device1 . device_id ) ,
61+ getDeviceId : jest . fn ( ) . mockReturnValue ( ownDevice . device_id ) ,
4062 deleteMultipleDevices : jest . fn ( ) ,
4163 getStoredDevice : jest . fn ( ) . mockReturnValue ( new DeviceInfo ( "id" ) ) ,
4264 generateClientSecret : jest . fn ( ) ,
@@ -54,12 +76,14 @@ describe("<DevicesPanel />", () => {
5476 beforeEach ( ( ) => {
5577 jest . clearAllMocks ( ) ;
5678
57- mockClient . getDevices . mockReset ( ) . mockResolvedValue ( { devices : [ device1 , device2 , device3 ] } ) ;
79+ mockClient . getDevices
80+ . mockReset ( )
81+ . mockResolvedValue ( { devices : [ ownDevice , verifiedDevice , unverifiedDevice , nonCryptoDevice ] } ) ;
5882
5983 mockClient . getPushers . mockReset ( ) . mockResolvedValue ( {
6084 pushers : [
6185 mkPusher ( {
62- [ PUSHER_DEVICE_ID . name ] : device1 . device_id ,
86+ [ PUSHER_DEVICE_ID . name ] : ownDevice . device_id ,
6387 [ PUSHER_ENABLED . name ] : true ,
6488 } ) ,
6589 ] ,
@@ -88,16 +112,16 @@ describe("<DevicesPanel />", () => {
88112 it ( "deletes selected devices when interactive auth is not required" , async ( ) => {
89113 mockClient . deleteMultipleDevices . mockResolvedValue ( { } ) ;
90114 mockClient . getDevices
91- . mockResolvedValueOnce ( { devices : [ device1 , device2 , device3 ] } )
115+ . mockResolvedValueOnce ( { devices : [ ownDevice , verifiedDevice , unverifiedDevice ] } )
92116 // pretend it was really deleted on refresh
93- . mockResolvedValueOnce ( { devices : [ device1 , device3 ] } ) ;
117+ . mockResolvedValueOnce ( { devices : [ ownDevice , unverifiedDevice ] } ) ;
94118
95119 const { container, getByTestId } = render ( getComponent ( ) ) ;
96120 await flushPromises ( ) ;
97121
98122 expect ( container . getElementsByClassName ( "mx_DevicesPanel_device" ) . length ) . toEqual ( 3 ) ;
99123
100- toggleDeviceSelection ( container , device2 . device_id ) ;
124+ toggleDeviceSelection ( container , verifiedDevice . device_id ) ;
101125
102126 mockClient . getDevices . mockClear ( ) ;
103127
@@ -106,7 +130,7 @@ describe("<DevicesPanel />", () => {
106130 } ) ;
107131
108132 expect ( container . getElementsByClassName ( "mx_Spinner" ) . length ) . toBeTruthy ( ) ;
109- expect ( mockClient . deleteMultipleDevices ) . toHaveBeenCalledWith ( [ device2 . device_id ] , undefined ) ;
133+ expect ( mockClient . deleteMultipleDevices ) . toHaveBeenCalledWith ( [ verifiedDevice . device_id ] , undefined ) ;
110134
111135 await flushPromises ( ) ;
112136
@@ -124,9 +148,9 @@ describe("<DevicesPanel />", () => {
124148 . mockResolvedValueOnce ( { } ) ;
125149
126150 mockClient . getDevices
127- . mockResolvedValueOnce ( { devices : [ device1 , device2 , device3 ] } )
151+ . mockResolvedValueOnce ( { devices : [ ownDevice , verifiedDevice , unverifiedDevice ] } )
128152 // pretend it was really deleted on refresh
129- . mockResolvedValueOnce ( { devices : [ device1 , device3 ] } ) ;
153+ . mockResolvedValueOnce ( { devices : [ ownDevice , unverifiedDevice ] } ) ;
130154
131155 const { container, getByTestId, getByLabelText } = render ( getComponent ( ) ) ;
132156
@@ -135,7 +159,7 @@ describe("<DevicesPanel />", () => {
135159 // reset mock count after initial load
136160 mockClient . getDevices . mockClear ( ) ;
137161
138- toggleDeviceSelection ( container , device2 . device_id ) ;
162+ toggleDeviceSelection ( container , verifiedDevice . device_id ) ;
139163
140164 act ( ( ) => {
141165 fireEvent . click ( getByTestId ( "sign-out-devices-btn" ) ) ;
@@ -145,7 +169,7 @@ describe("<DevicesPanel />", () => {
145169 // modal rendering has some weird sleeps
146170 await sleep ( 100 ) ;
147171
148- expect ( mockClient . deleteMultipleDevices ) . toHaveBeenCalledWith ( [ device2 . device_id ] , undefined ) ;
172+ expect ( mockClient . deleteMultipleDevices ) . toHaveBeenCalledWith ( [ verifiedDevice . device_id ] , undefined ) ;
149173
150174 const modal = document . getElementsByClassName ( "mx_Dialog" ) ;
151175 expect ( modal ) . toMatchSnapshot ( ) ;
@@ -159,7 +183,7 @@ describe("<DevicesPanel />", () => {
159183 await flushPromises ( ) ;
160184
161185 // called again with auth
162- expect ( mockClient . deleteMultipleDevices ) . toHaveBeenCalledWith ( [ device2 . device_id ] , {
186+ expect ( mockClient . deleteMultipleDevices ) . toHaveBeenCalledWith ( [ verifiedDevice . device_id ] , {
163187 identifier : {
164188 type : "m.id.user" ,
165189 user : userId ,
@@ -182,9 +206,9 @@ describe("<DevicesPanel />", () => {
182206 . mockResolvedValueOnce ( { } ) ;
183207
184208 mockClient . getDevices
185- . mockResolvedValueOnce ( { devices : [ device1 , device2 , device3 ] } )
209+ . mockResolvedValueOnce ( { devices : [ ownDevice , verifiedDevice , unverifiedDevice ] } )
186210 // pretend it was really deleted on refresh
187- . mockResolvedValueOnce ( { devices : [ device1 , device3 ] } ) ;
211+ . mockResolvedValueOnce ( { devices : [ ownDevice , unverifiedDevice ] } ) ;
188212
189213 const { container, getByTestId } = render ( getComponent ( ) ) ;
190214
@@ -193,7 +217,7 @@ describe("<DevicesPanel />", () => {
193217 // reset mock count after initial load
194218 mockClient . getDevices . mockClear ( ) ;
195219
196- toggleDeviceSelection ( container , device2 . device_id ) ;
220+ toggleDeviceSelection ( container , verifiedDevice . device_id ) ;
197221
198222 act ( ( ) => {
199223 fireEvent . click ( getByTestId ( "sign-out-devices-btn" ) ) ;
0 commit comments