@@ -20,9 +20,10 @@ use alloc::vec::Vec;
2020use pb:: response:: Response ;
2121
2222use crate :: backup;
23- use crate :: workflow:: { confirm, status , unlock } ;
23+ use crate :: workflow:: { confirm, unlock , Workflows } ;
2424
25- pub async fn check (
25+ pub async fn check < W : Workflows > (
26+ workflows : & mut W ,
2627 & pb:: CheckBackupRequest { silent } : & pb:: CheckBackupRequest ,
2728) -> Result < Response , Error > {
2829 if !bitbox02:: sd:: sdcard_inserted ( ) {
@@ -34,29 +35,31 @@ pub async fn check(
3435 let ( backup_data, metadata) = backup:: load ( & id) ?;
3536 if seed. as_slice ( ) != backup_data. get_seed ( ) {
3637 if !silent {
37- status :: status ( "Backup missing\n or invalid" , false ) . await ;
38+ workflows . status ( "Backup missing\n or invalid" , false ) . await ;
3839 }
3940 return Err ( Error :: Generic ) ;
4041 }
4142 if !silent {
42- confirm:: confirm ( & confirm:: Params {
43- title : "Name?" ,
44- body : & metadata. name ,
45- scrollable : true ,
46- accept_is_nextarrow : true ,
47- ..Default :: default ( )
48- } )
49- . await ?;
43+ workflows
44+ . confirm ( & confirm:: Params {
45+ title : "Name?" ,
46+ body : & metadata. name ,
47+ scrollable : true ,
48+ accept_is_nextarrow : true ,
49+ ..Default :: default ( )
50+ } )
51+ . await ?;
5052
51- confirm:: confirm ( & confirm:: Params {
52- title : "ID?" ,
53- body : & id,
54- scrollable : true ,
55- ..Default :: default ( )
56- } )
57- . await ?;
53+ workflows
54+ . confirm ( & confirm:: Params {
55+ title : "ID?" ,
56+ body : & id,
57+ scrollable : true ,
58+ ..Default :: default ( )
59+ } )
60+ . await ?;
5861
59- status :: status ( "Backup valid" , true ) . await ;
62+ workflows . status ( "Backup valid" , true ) . await ;
6063 }
6164 Ok ( Response :: CheckBackup ( pb:: CheckBackupResponse { id } ) )
6265}
@@ -69,19 +72,21 @@ pub async fn check(
6972/// If the device is initialized, an existing backup is overwritten, but the seed birthdate is
7073/// retained from the previous backup. If no backup existed, the seed birthdate is set to 0, meaning
7174/// it is unknown.
72- pub async fn create (
75+ pub async fn create < W : Workflows > (
76+ workflows : & mut W ,
7377 & pb:: CreateBackupRequest {
7478 timestamp,
7579 timezone_offset,
7680 } : & pb:: CreateBackupRequest ,
7781) -> Result < Response , Error > {
78- confirm:: confirm ( & confirm:: Params {
79- title : "Is today?" ,
80- body : & bitbox02:: format_datetime ( timestamp, timezone_offset, true )
81- . map_err ( |_| Error :: InvalidInput ) ?,
82- ..Default :: default ( )
83- } )
84- . await ?;
82+ workflows
83+ . confirm ( & confirm:: Params {
84+ title : "Is today?" ,
85+ body : & bitbox02:: format_datetime ( timestamp, timezone_offset, true )
86+ . map_err ( |_| Error :: InvalidInput ) ?,
87+ ..Default :: default ( )
88+ } )
89+ . await ?;
8590
8691 // Wait for sd card
8792 super :: sdcard:: process ( & pb:: InsertRemoveSdCardRequest {
@@ -92,7 +97,7 @@ pub async fn create(
9297 let is_initialized = bitbox02:: memory:: is_initialized ( ) ;
9398
9499 if is_initialized {
95- unlock:: unlock_keystore ( "Unlock device" , unlock:: CanCancel :: Yes ) . await ?;
100+ unlock:: unlock_keystore ( workflows , "Unlock device" , unlock:: CanCancel :: Yes ) . await ?;
96101 }
97102
98103 let seed = bitbox02:: keystore:: copy_seed ( ) ?;
@@ -122,12 +127,12 @@ pub async fn create(
122127 // process again.
123128 let _ = bitbox02:: memory:: set_initialized ( ) ;
124129
125- status :: status ( "Backup created" , true ) . await ;
130+ workflows . status ( "Backup created" , true ) . await ;
126131 Ok ( Response :: Success ( pb:: Success { } ) )
127132 }
128133 Err ( err) => {
129134 let msg = format ! ( "Backup not created\n Please contact\n support ({:?})" , err) ;
130- status :: status ( & msg, false ) . await ;
135+ workflows . status ( & msg, false ) . await ;
131136 Err ( Error :: Generic )
132137 }
133138 }
@@ -154,6 +159,7 @@ mod tests {
154159 use super :: * ;
155160
156161 use crate :: bb02_async:: block_on;
162+ use crate :: workflow:: testing:: { Screen , TestingWorkflows } ;
157163 use alloc:: boxed:: Box ;
158164 use bitbox02:: testing:: {
159165 mock, mock_memory, mock_sd, mock_unlocked, mock_unlocked_using_mnemonic, Data ,
@@ -167,26 +173,44 @@ mod tests {
167173 // All good.
168174 mock ( Data {
169175 sdcard_inserted : Some ( true ) ,
170- ui_confirm_create : Some ( Box :: new ( |params| {
171- assert_eq ! ( params. body, "Mon 2020-09-28" ) ;
172- true
173- } ) ) ,
174176 ..Default :: default ( )
175177 } ) ;
176178 mock_sd ( ) ;
177179 mock_memory ( ) ;
178180 mock_unlocked ( ) ;
181+
182+ let mut mock_workflows = TestingWorkflows :: new ( ) ;
179183 assert_eq ! (
180- block_on( create( & pb:: CreateBackupRequest {
181- timestamp: EXPECTED_TIMESTMAP ,
182- timezone_offset: 18000 ,
183- } ) ) ,
184+ block_on( create(
185+ & mut mock_workflows,
186+ & pb:: CreateBackupRequest {
187+ timestamp: EXPECTED_TIMESTMAP ,
188+ timezone_offset: 18000 ,
189+ }
190+ ) ) ,
184191 Ok ( Response :: Success ( pb:: Success { } ) )
185192 ) ;
186193 assert_eq ! ( EXPECTED_TIMESTMAP , bitbox02:: memory:: get_seed_birthdate( ) ) ;
194+ assert_eq ! (
195+ mock_workflows. screens,
196+ vec![
197+ Screen :: Confirm {
198+ title: "Is today?" . into( ) ,
199+ body: "Mon 2020-09-28" . into( ) ,
200+ longtouch: false
201+ } ,
202+ Screen :: Status {
203+ title: "Backup created" . into( ) ,
204+ success: true
205+ }
206+ ]
207+ ) ;
187208
188209 assert_eq ! (
189- block_on( check( & pb:: CheckBackupRequest { silent: true } ) ) ,
210+ block_on( check(
211+ & mut TestingWorkflows :: new( ) ,
212+ & pb:: CheckBackupRequest { silent: true }
213+ ) ) ,
190214 Ok ( Response :: CheckBackup ( pb:: CheckBackupResponse {
191215 id: "41233dfbad010723dbbb93514b7b81016b73f8aa35c5148e1b478f60d5750dce" . into( )
192216 } ) )
@@ -197,29 +221,10 @@ mod tests {
197221 /// should catch regressions when changing backup loading/verification in the firmware code.
198222 #[ test]
199223 fn test_fixture ( ) {
200- static mut UI_COUNTER : u32 = 0 ;
201- static EXPECTED_ID : & str =
224+ const EXPECTED_ID : & str =
202225 "577782fdfffbe314b23acaeefc39ad5e8641fba7e7dbe418a35956a879a67dd2" ;
203226 mock ( Data {
204227 sdcard_inserted : Some ( true ) ,
205- ui_confirm_create : Some ( Box :: new ( |params| {
206- match unsafe {
207- UI_COUNTER += 1 ;
208- UI_COUNTER
209- } {
210- 1 => {
211- assert_eq ! ( params. title, "Name?" ) ;
212- assert_eq ! ( params. body, "My BitBox" ) ;
213- true
214- }
215- 2 => {
216- assert_eq ! ( params. title, "ID?" ) ;
217- assert_eq ! ( params. body, EXPECTED_ID ) ;
218- true
219- }
220- _ => panic ! ( "unexpected UI dialog" ) ,
221- }
222- } ) ) ,
223228 ..Default :: default ( )
224229 } ) ;
225230 mock_sd ( ) ;
@@ -241,13 +246,35 @@ mod tests {
241246 . unwrap ( ) ;
242247 }
243248 // Check that the loaded seed matches the backup.
249+ let mut mock_workflows = TestingWorkflows :: new ( ) ;
244250 assert_eq ! (
245- block_on( check( & pb:: CheckBackupRequest { silent: false } ) ) ,
251+ block_on( check(
252+ & mut mock_workflows,
253+ & pb:: CheckBackupRequest { silent: false }
254+ ) ) ,
246255 Ok ( Response :: CheckBackup ( pb:: CheckBackupResponse {
247256 id: EXPECTED_ID . into( )
248257 } ) )
249258 ) ;
250- assert_eq ! ( unsafe { UI_COUNTER } , 2 ) ;
259+ assert_eq ! (
260+ mock_workflows. screens,
261+ vec![
262+ Screen :: Confirm {
263+ title: "Name?" . into( ) ,
264+ body: "My BitBox" . into( ) ,
265+ longtouch: false
266+ } ,
267+ Screen :: Confirm {
268+ title: "ID?" . into( ) ,
269+ body: EXPECTED_ID . into( ) ,
270+ longtouch: false
271+ } ,
272+ Screen :: Status {
273+ title: "Backup valid" . into( ) ,
274+ success: true
275+ } ,
276+ ]
277+ ) ;
251278 }
252279
253280 #[ test]
@@ -270,17 +297,19 @@ mod tests {
270297 // Create one backup.
271298 mock ( Data {
272299 sdcard_inserted : Some ( true ) ,
273- ui_confirm_create : Some ( Box :: new ( |_params| true ) ) ,
274300 ..Default :: default ( )
275301 } ) ;
276302 mock_memory ( ) ;
277303 mock_unlocked_using_mnemonic ( "purity concert above invest pigeon category peace tuition hazard vivid latin since legal speak nation session onion library travel spell region blast estate stay" , "" ) ;
278304
279305 bitbox02:: memory:: set_device_name ( DEVICE_NAME_1 ) . unwrap ( ) ;
280- assert ! ( block_on( create( & pb:: CreateBackupRequest {
281- timestamp: EXPECTED_TIMESTAMP ,
282- timezone_offset: 18000 ,
283- } ) )
306+ assert ! ( block_on( create(
307+ & mut TestingWorkflows :: new( ) ,
308+ & pb:: CreateBackupRequest {
309+ timestamp: EXPECTED_TIMESTAMP ,
310+ timezone_offset: 18000 ,
311+ }
312+ ) )
284313 . is_ok( ) ) ;
285314
286315 assert_eq ! (
@@ -297,16 +326,18 @@ mod tests {
297326 // Create another backup.
298327 mock ( Data {
299328 sdcard_inserted : Some ( true ) ,
300- ui_confirm_create : Some ( Box :: new ( |_params| true ) ) ,
301329 ..Default :: default ( )
302330 } ) ;
303331 mock_memory ( ) ;
304332 mock_unlocked_using_mnemonic ( "goddess item rack improve shaft occur actress rib emerge salad rich blame model glare lounge stable electric height scrub scrub oyster now dinner oven" , "" ) ;
305333 bitbox02:: memory:: set_device_name ( DEVICE_NAME_2 ) . unwrap ( ) ;
306- assert ! ( block_on( create( & pb:: CreateBackupRequest {
307- timestamp: EXPECTED_TIMESTAMP ,
308- timezone_offset: 18000 ,
309- } ) )
334+ assert ! ( block_on( create(
335+ & mut TestingWorkflows :: new( ) ,
336+ & pb:: CreateBackupRequest {
337+ timestamp: EXPECTED_TIMESTAMP ,
338+ timezone_offset: 18000 ,
339+ }
340+ ) )
310341 . is_ok( ) ) ;
311342
312343 assert_eq ! (
0 commit comments