diff options
| author | DanConwayDev <DanConwayDev@protonmail.com> | 2023-10-01 00:00:00 +0100 |
|---|---|---|
| committer | DanConwayDev <DanConwayDev@protonmail.com> | 2023-10-01 00:00:00 +0100 |
| commit | e237328ec611a5891586530c1d3cb26c16c1093b (patch) | |
| tree | 22ac36baa240354d06ae82eb070609fa3e3fcb82 /tests | |
| parent | 000901c0cbca8464b5a89bcc93c5474f6564bafd (diff) | |
feat(login) fetch user relays and metadata
get user relay list and metadata events from relays when keys are
used and last fetch attempt was more than an hour ago
uses user's write relays if known, otherwise uses fallback relays
to achieve this a method for intergration testing event fetching
from relays was added
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/login.rs | 1100 | ||||
| -rw-r--r-- | tests/prs_create.rs | 22 |
2 files changed, 855 insertions, 267 deletions
diff --git a/tests/login.rs b/tests/login.rs index a75608d..d565620 100644 --- a/tests/login.rs +++ b/tests/login.rs | |||
| @@ -8,7 +8,7 @@ static EXPECTED_SET_PASSWORD_CONFIRM_PROMPT: &str = "confirm password"; | |||
| 8 | static EXPECTED_PASSWORD_PROMPT: &str = "password"; | 8 | static EXPECTED_PASSWORD_PROMPT: &str = "password"; |
| 9 | 9 | ||
| 10 | fn standard_login() -> Result<CliTester> { | 10 | fn standard_login() -> Result<CliTester> { |
| 11 | let mut p = CliTester::new(["login"]); | 11 | let mut p = CliTester::new(["login", "--offline"]); |
| 12 | 12 | ||
| 13 | p.expect_input_eventually(EXPECTED_NSEC_PROMPT)? | 13 | p.expect_input_eventually(EXPECTED_NSEC_PROMPT)? |
| 14 | .succeeds_with(TEST_KEY_1_NSEC)?; | 14 | .succeeds_with(TEST_KEY_1_NSEC)?; |
| @@ -20,74 +20,602 @@ fn standard_login() -> Result<CliTester> { | |||
| 20 | p.expect_end_eventually()?; | 20 | p.expect_end_eventually()?; |
| 21 | Ok(p) | 21 | Ok(p) |
| 22 | } | 22 | } |
| 23 | mod with_relays { | ||
| 24 | use anyhow::Ok; | ||
| 25 | use futures::join; | ||
| 26 | use test_utils::relay::{shutdown_relay, ListenerReqFunc, Relay}; | ||
| 23 | 27 | ||
| 24 | mod when_first_time_login { | ||
| 25 | use super::*; | 28 | use super::*; |
| 26 | 29 | ||
| 27 | #[test] | 30 | mod when_first_time_login { |
| 28 | #[serial] | 31 | use super::*; |
| 29 | fn prompts_for_nsec_and_password() -> Result<()> { | ||
| 30 | before()?; | ||
| 31 | standard_login()?; | ||
| 32 | after() | ||
| 33 | } | ||
| 34 | |||
| 35 | #[test] | ||
| 36 | #[serial] | ||
| 37 | fn succeeds_with_text_logged_in_as_npub() -> Result<()> { | ||
| 38 | with_fresh_config(|| { | ||
| 39 | let mut p = CliTester::new(["login"]); | ||
| 40 | 32 | ||
| 41 | p.expect_input(EXPECTED_NSEC_PROMPT)? | 33 | // falls_back_to_fallback_relays - this is implict in the tests |
| 42 | .succeeds_with(TEST_KEY_1_NSEC)?; | 34 | |
| 35 | mod dislays_logged_in_with_correct_name { | ||
| 36 | |||
| 37 | use super::*; | ||
| 38 | |||
| 39 | async fn run_test_displays_correct_name( | ||
| 40 | relay_listener1: Option<ListenerReqFunc<'_>>, | ||
| 41 | relay_listener2: Option<ListenerReqFunc<'_>>, | ||
| 42 | ) -> Result<()> { | ||
| 43 | let (mut r51, mut r52) = ( | ||
| 44 | Relay::new(8051, None, relay_listener1), | ||
| 45 | Relay::new(8052, None, relay_listener2), | ||
| 46 | ); | ||
| 47 | |||
| 48 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | ||
| 49 | with_fresh_config(|| { | ||
| 50 | let mut p = CliTester::new(["login"]); | ||
| 51 | |||
| 52 | p.expect_input(EXPECTED_NSEC_PROMPT)? | ||
| 53 | .succeeds_with(TEST_KEY_1_NSEC)?; | ||
| 54 | |||
| 55 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? | ||
| 56 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? | ||
| 57 | .succeeds_with(TEST_PASSWORD)?; | ||
| 58 | |||
| 59 | p.expect("searching for your details...\r\n")?; | ||
| 60 | p.expect("\r")?; | ||
| 61 | |||
| 62 | p.expect_end_with("logged in as fred\r\n")?; | ||
| 63 | for p in [51, 52] { | ||
| 64 | shutdown_relay(8000 + p)?; | ||
| 65 | } | ||
| 66 | Ok(()) | ||
| 67 | }) | ||
| 68 | }); | ||
| 69 | |||
| 70 | // launch relay | ||
| 71 | let _ = join!(r51.listen_until_close(), r52.listen_until_close(),); | ||
| 72 | |||
| 73 | cli_tester_handle.join().unwrap()?; | ||
| 74 | Ok(()) | ||
| 75 | } | ||
| 76 | |||
| 77 | #[test] | ||
| 78 | #[serial] | ||
| 79 | fn when_latest_metadata_and_relay_list_on_all_relays() -> Result<()> { | ||
| 80 | futures::executor::block_on(run_test_displays_correct_name( | ||
| 81 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 82 | relay.respond_events( | ||
| 83 | client_id, | ||
| 84 | &subscription_id, | ||
| 85 | &vec![ | ||
| 86 | generate_test_key_1_metadata_event("fred"), | ||
| 87 | generate_test_key_1_relay_list_event(), | ||
| 88 | ], | ||
| 89 | )?; | ||
| 90 | Ok(()) | ||
| 91 | }), | ||
| 92 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 93 | relay.respond_events( | ||
| 94 | client_id, | ||
| 95 | &subscription_id, | ||
| 96 | &vec![ | ||
| 97 | generate_test_key_1_metadata_event("fred"), | ||
| 98 | generate_test_key_1_relay_list_event(), | ||
| 99 | ], | ||
| 100 | )?; | ||
| 101 | Ok(()) | ||
| 102 | }), | ||
| 103 | )) | ||
| 104 | } | ||
| 105 | |||
| 106 | #[test] | ||
| 107 | #[serial] | ||
| 108 | fn when_latest_metadata_and_relay_list_on_some_relays_but_others_have_none() | ||
| 109 | -> Result<()> { | ||
| 110 | futures::executor::block_on(run_test_displays_correct_name( | ||
| 111 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 112 | relay.respond_events( | ||
| 113 | client_id, | ||
| 114 | &subscription_id, | ||
| 115 | &vec![ | ||
| 116 | generate_test_key_1_metadata_event("fred"), | ||
| 117 | generate_test_key_1_relay_list_event(), | ||
| 118 | ], | ||
| 119 | )?; | ||
| 120 | Ok(()) | ||
| 121 | }), | ||
| 122 | None, | ||
| 123 | )) | ||
| 124 | } | ||
| 125 | |||
| 126 | #[test] | ||
| 127 | #[serial] | ||
| 128 | fn when_latest_metadata_only_on_relay_and_relay_list_on_another() -> Result<()> { | ||
| 129 | futures::executor::block_on(run_test_displays_correct_name( | ||
| 130 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 131 | relay.respond_events( | ||
| 132 | client_id, | ||
| 133 | &subscription_id, | ||
| 134 | &vec![generate_test_key_1_metadata_event("fred")], | ||
| 135 | )?; | ||
| 136 | Ok(()) | ||
| 137 | }), | ||
| 138 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 139 | relay.respond_events( | ||
| 140 | client_id, | ||
| 141 | &subscription_id, | ||
| 142 | &vec![generate_test_key_1_relay_list_event()], | ||
| 143 | )?; | ||
| 144 | Ok(()) | ||
| 145 | }), | ||
| 146 | )) | ||
| 147 | } | ||
| 148 | |||
| 149 | #[test] | ||
| 150 | #[serial] | ||
| 151 | fn when_some_relays_return_old_metadata_event() -> Result<()> { | ||
| 152 | futures::executor::block_on(run_test_displays_correct_name( | ||
| 153 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 154 | relay.respond_events( | ||
| 155 | client_id, | ||
| 156 | &subscription_id, | ||
| 157 | &vec![ | ||
| 158 | generate_test_key_1_metadata_event("fred"), | ||
| 159 | generate_test_key_1_relay_list_event(), | ||
| 160 | ], | ||
| 161 | )?; | ||
| 162 | Ok(()) | ||
| 163 | }), | ||
| 164 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 165 | relay.respond_events( | ||
| 166 | client_id, | ||
| 167 | &subscription_id, | ||
| 168 | &vec![generate_test_key_1_metadata_event_old("fred old")], | ||
| 169 | )?; | ||
| 170 | Ok(()) | ||
| 171 | }), | ||
| 172 | )) | ||
| 173 | } | ||
| 174 | |||
| 175 | #[test] | ||
| 176 | #[serial] | ||
| 177 | fn when_some_relays_return_other_users_metadata() -> Result<()> { | ||
| 178 | futures::executor::block_on(run_test_displays_correct_name( | ||
| 179 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 180 | relay.respond_events( | ||
| 181 | client_id, | ||
| 182 | &subscription_id, | ||
| 183 | &vec![generate_test_key_2_metadata_event("carole")], | ||
| 184 | )?; | ||
| 185 | Ok(()) | ||
| 186 | }), | ||
| 187 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 188 | relay.respond_events( | ||
| 189 | client_id, | ||
| 190 | &subscription_id, | ||
| 191 | &vec![ | ||
| 192 | generate_test_key_1_metadata_event_old("fred"), | ||
| 193 | generate_test_key_1_relay_list_event(), | ||
| 194 | ], | ||
| 195 | )?; | ||
| 196 | Ok(()) | ||
| 197 | }), | ||
| 198 | )) | ||
| 199 | } | ||
| 200 | |||
| 201 | #[test] | ||
| 202 | #[serial] | ||
| 203 | fn when_some_relays_return_other_event_kinds() -> Result<()> { | ||
| 204 | futures::executor::block_on(run_test_displays_correct_name( | ||
| 205 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 206 | let mut event = generate_test_key_1_metadata_event("Fred"); | ||
| 207 | event.kind = nostr::Kind::TextNote; | ||
| 208 | relay.respond_events( | ||
| 209 | client_id, | ||
| 210 | &subscription_id, | ||
| 211 | &vec![make_event_old_or_change_user(event, &TEST_KEY_1_KEYS, 0)], | ||
| 212 | )?; | ||
| 213 | Ok(()) | ||
| 214 | }), | ||
| 215 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 216 | relay.respond_events( | ||
| 217 | client_id, | ||
| 218 | &subscription_id, | ||
| 219 | &vec![ | ||
| 220 | generate_test_key_1_metadata_event_old("fred"), | ||
| 221 | generate_test_key_1_relay_list_event(), | ||
| 222 | ], | ||
| 223 | )?; | ||
| 224 | Ok(()) | ||
| 225 | }), | ||
| 226 | )) | ||
| 227 | } | ||
| 228 | |||
| 229 | mod when_specifying_command_line_nsec_only { | ||
| 230 | use super::*; | ||
| 231 | |||
| 232 | #[test] | ||
| 233 | #[serial] | ||
| 234 | fn displays_correct_name() -> Result<()> { | ||
| 235 | futures::executor::block_on( | ||
| 236 | run_test_when_specifying_command_line_nsec_only_displays_correct_name( | ||
| 237 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 238 | relay.respond_events( | ||
| 239 | client_id, | ||
| 240 | &subscription_id, | ||
| 241 | &vec![ | ||
| 242 | generate_test_key_1_metadata_event("fred"), | ||
| 243 | generate_test_key_1_relay_list_event(), | ||
| 244 | ], | ||
| 245 | )?; | ||
| 246 | Ok(()) | ||
| 247 | }), | ||
| 248 | None, | ||
| 249 | ), | ||
| 250 | ) | ||
| 251 | } | ||
| 252 | async fn run_test_when_specifying_command_line_nsec_only_displays_correct_name( | ||
| 253 | relay_listener1: Option<ListenerReqFunc<'_>>, | ||
| 254 | relay_listener2: Option<ListenerReqFunc<'_>>, | ||
| 255 | ) -> Result<()> { | ||
| 256 | let (mut r51, mut r52) = ( | ||
| 257 | Relay::new(8051, None, relay_listener1), | ||
| 258 | Relay::new(8052, None, relay_listener2), | ||
| 259 | ); | ||
| 260 | |||
| 261 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | ||
| 262 | with_fresh_config(|| { | ||
| 263 | let mut p = CliTester::new(["login", "--nsec", TEST_KEY_1_NSEC]); | ||
| 264 | |||
| 265 | p.expect("searching for your details...\r\n")?; | ||
| 266 | p.expect("\r")?; | ||
| 267 | |||
| 268 | p.expect_end_with("logged in as fred\r\n")?; | ||
| 269 | for p in [51, 52] { | ||
| 270 | shutdown_relay(8000 + p)?; | ||
| 271 | } | ||
| 272 | Ok(()) | ||
| 273 | }) | ||
| 274 | }); | ||
| 275 | |||
| 276 | // launch relay | ||
| 277 | let _ = join!(r51.listen_until_close(), r52.listen_until_close(),); | ||
| 278 | |||
| 279 | cli_tester_handle.join().unwrap()?; | ||
| 280 | Ok(()) | ||
| 281 | } | ||
| 282 | } | ||
| 283 | mod when_specifying_command_line_password_only { | ||
| 284 | use super::*; | ||
| 285 | |||
| 286 | #[test] | ||
| 287 | #[serial] | ||
| 288 | fn displays_correct_name() -> Result<()> { | ||
| 289 | futures::executor::block_on( | ||
| 290 | run_test_when_specifying_command_line_password_only_displays_correct_name( | ||
| 291 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 292 | relay.respond_events( | ||
| 293 | client_id, | ||
| 294 | &subscription_id, | ||
| 295 | &vec![ | ||
| 296 | generate_test_key_1_metadata_event("fred"), | ||
| 297 | generate_test_key_1_relay_list_event(), | ||
| 298 | ], | ||
| 299 | )?; | ||
| 300 | Ok(()) | ||
| 301 | }), | ||
| 302 | None, | ||
| 303 | ), | ||
| 304 | ) | ||
| 305 | } | ||
| 306 | async fn run_test_when_specifying_command_line_password_only_displays_correct_name( | ||
| 307 | relay_listener1: Option<ListenerReqFunc<'_>>, | ||
| 308 | relay_listener2: Option<ListenerReqFunc<'_>>, | ||
| 309 | ) -> Result<()> { | ||
| 310 | let (mut r51, mut r52) = ( | ||
| 311 | Relay::new(8051, None, relay_listener1), | ||
| 312 | Relay::new(8052, None, relay_listener2), | ||
| 313 | ); | ||
| 314 | |||
| 315 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | ||
| 316 | with_fresh_config(|| { | ||
| 317 | CliTester::new([ | ||
| 318 | "login", | ||
| 319 | "--offline", | ||
| 320 | "--nsec", | ||
| 321 | TEST_KEY_1_NSEC, | ||
| 322 | "--password", | ||
| 323 | TEST_PASSWORD, | ||
| 324 | ]) | ||
| 325 | .expect_end_eventually()?; | ||
| 326 | |||
| 327 | let mut p = CliTester::new(["login", "--password", TEST_PASSWORD]); | ||
| 328 | |||
| 329 | p.expect("searching for your details...\r\n")?; | ||
| 330 | p.expect("\r")?; | ||
| 331 | |||
| 332 | p.expect_end_with("logged in as fred\r\n")?; | ||
| 333 | for p in [51, 52] { | ||
| 334 | shutdown_relay(8000 + p)?; | ||
| 335 | } | ||
| 336 | Ok(()) | ||
| 337 | }) | ||
| 338 | }); | ||
| 339 | |||
| 340 | // launch relay | ||
| 341 | let _ = join!(r51.listen_until_close(), r52.listen_until_close(),); | ||
| 342 | |||
| 343 | cli_tester_handle.join().unwrap()?; | ||
| 344 | Ok(()) | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | mod when_specifying_command_line_nsec_and_password { | ||
| 349 | use super::*; | ||
| 350 | |||
| 351 | #[test] | ||
| 352 | #[serial] | ||
| 353 | fn displays_correct_name() -> Result<()> { | ||
| 354 | futures::executor::block_on( | ||
| 355 | run_test_when_specifying_command_line_nsec_and_password_displays_correct_name( | ||
| 356 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 357 | relay.respond_events( | ||
| 358 | client_id, | ||
| 359 | &subscription_id, | ||
| 360 | &vec![ | ||
| 361 | generate_test_key_1_metadata_event("fred"), | ||
| 362 | generate_test_key_1_relay_list_event(), | ||
| 363 | ], | ||
| 364 | )?; | ||
| 365 | Ok(()) | ||
| 366 | }), | ||
| 367 | None, | ||
| 368 | ), | ||
| 369 | ) | ||
| 370 | } | ||
| 371 | async fn run_test_when_specifying_command_line_nsec_and_password_displays_correct_name( | ||
| 372 | relay_listener1: Option<ListenerReqFunc<'_>>, | ||
| 373 | relay_listener2: Option<ListenerReqFunc<'_>>, | ||
| 374 | ) -> Result<()> { | ||
| 375 | let (mut r51, mut r52) = ( | ||
| 376 | Relay::new(8051, None, relay_listener1), | ||
| 377 | Relay::new(8052, None, relay_listener2), | ||
| 378 | ); | ||
| 379 | |||
| 380 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | ||
| 381 | with_fresh_config(|| { | ||
| 382 | let mut p = CliTester::new([ | ||
| 383 | "login", | ||
| 384 | "--nsec", | ||
| 385 | TEST_KEY_1_NSEC, | ||
| 386 | "--password", | ||
| 387 | TEST_PASSWORD, | ||
| 388 | ]); | ||
| 389 | |||
| 390 | p.expect("searching for your details...\r\n")?; | ||
| 391 | p.expect("\r")?; | ||
| 392 | |||
| 393 | p.expect_end_with("logged in as fred\r\n")?; | ||
| 394 | for p in [51, 52] { | ||
| 395 | shutdown_relay(8000 + p)?; | ||
| 396 | } | ||
| 397 | Ok(()) | ||
| 398 | }) | ||
| 399 | }); | ||
| 400 | |||
| 401 | // launch relay | ||
| 402 | let _ = join!(r51.listen_until_close(), r52.listen_until_close(),); | ||
| 403 | |||
| 404 | cli_tester_handle.join().unwrap()?; | ||
| 405 | Ok(()) | ||
| 406 | } | ||
| 407 | } | ||
| 408 | } | ||
| 43 | 409 | ||
| 44 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? | 410 | mod when_no_metadata_found { |
| 45 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? | 411 | use super::*; |
| 46 | .succeeds_with(TEST_PASSWORD)?; | 412 | |
| 413 | #[test] | ||
| 414 | #[serial] | ||
| 415 | fn warm_user_and_displays_npub() -> Result<()> { | ||
| 416 | futures::executor::block_on( | ||
| 417 | run_test_when_no_metadata_found_warns_user_and_uses_npub(None, None), | ||
| 418 | ) | ||
| 419 | } | ||
| 420 | |||
| 421 | async fn run_test_when_no_metadata_found_warns_user_and_uses_npub( | ||
| 422 | relay_listener1: Option<ListenerReqFunc<'_>>, | ||
| 423 | relay_listener2: Option<ListenerReqFunc<'_>>, | ||
| 424 | ) -> Result<()> { | ||
| 425 | let (mut r51, mut r52) = ( | ||
| 426 | Relay::new(8051, None, relay_listener1), | ||
| 427 | Relay::new(8052, None, relay_listener2), | ||
| 428 | ); | ||
| 429 | |||
| 430 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | ||
| 431 | with_fresh_config(|| { | ||
| 432 | let mut p = CliTester::new(["login"]); | ||
| 433 | |||
| 434 | p.expect_input(EXPECTED_NSEC_PROMPT)? | ||
| 435 | .succeeds_with(TEST_KEY_1_NSEC)?; | ||
| 436 | |||
| 437 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? | ||
| 438 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? | ||
| 439 | .succeeds_with(TEST_PASSWORD)?; | ||
| 440 | |||
| 441 | p.expect("searching for your details...\r\n")?; | ||
| 442 | p.expect("\r")?; | ||
| 443 | p.expect("cannot find your account metadata (name, etc) on relays\r\n")?; | ||
| 444 | |||
| 445 | p.expect_end_with(format!("logged in as {TEST_KEY_1_NPUB}\r\n").as_str())?; | ||
| 446 | for p in [51, 52] { | ||
| 447 | shutdown_relay(8000 + p)?; | ||
| 448 | } | ||
| 449 | Ok(()) | ||
| 450 | }) | ||
| 451 | }); | ||
| 452 | |||
| 453 | // launch relay | ||
| 454 | let _ = join!(r51.listen_until_close(), r52.listen_until_close(),); | ||
| 455 | |||
| 456 | cli_tester_handle.join().unwrap()?; | ||
| 457 | Ok(()) | ||
| 458 | } | ||
| 459 | } | ||
| 47 | 460 | ||
| 48 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | 461 | mod when_metadata_but_no_relay_list_found { |
| 49 | }) | 462 | use super::*; |
| 463 | |||
| 464 | #[test] | ||
| 465 | #[serial] | ||
| 466 | fn warm_user_and_displays_name() -> Result<()> { | ||
| 467 | futures::executor::block_on( | ||
| 468 | run_test_when_no_relay_list_found_warns_user_and_uses_npub( | ||
| 469 | Some(&|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 470 | relay.respond_events( | ||
| 471 | client_id, | ||
| 472 | &subscription_id, | ||
| 473 | &vec![generate_test_key_1_metadata_event("fred")], | ||
| 474 | )?; | ||
| 475 | Ok(()) | ||
| 476 | }), | ||
| 477 | None, | ||
| 478 | ), | ||
| 479 | ) | ||
| 480 | } | ||
| 481 | |||
| 482 | async fn run_test_when_no_relay_list_found_warns_user_and_uses_npub( | ||
| 483 | relay_listener1: Option<ListenerReqFunc<'_>>, | ||
| 484 | relay_listener2: Option<ListenerReqFunc<'_>>, | ||
| 485 | ) -> Result<()> { | ||
| 486 | let (mut r51, mut r52) = ( | ||
| 487 | Relay::new(8051, None, relay_listener1), | ||
| 488 | Relay::new(8052, None, relay_listener2), | ||
| 489 | ); | ||
| 490 | |||
| 491 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | ||
| 492 | with_fresh_config(|| { | ||
| 493 | let mut p = CliTester::new(["login"]); | ||
| 494 | |||
| 495 | p.expect_input(EXPECTED_NSEC_PROMPT)? | ||
| 496 | .succeeds_with(TEST_KEY_1_NSEC)?; | ||
| 497 | |||
| 498 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? | ||
| 499 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? | ||
| 500 | .succeeds_with(TEST_PASSWORD)?; | ||
| 501 | |||
| 502 | p.expect("searching for your details...\r\n")?; | ||
| 503 | p.expect("\r")?; | ||
| 504 | p.expect("cannot find your relay list. consider using another nostr client to create one to enhance your nostr experience.\r\n")?; | ||
| 505 | |||
| 506 | p.expect_end_with("logged in as fred\r\n")?; | ||
| 507 | for p in [51, 52] { | ||
| 508 | shutdown_relay(8000 + p)?; | ||
| 509 | } | ||
| 510 | Ok(()) | ||
| 511 | }) | ||
| 512 | }); | ||
| 513 | |||
| 514 | // launch relay | ||
| 515 | let _ = join!(r51.listen_until_close(), r52.listen_until_close(),); | ||
| 516 | |||
| 517 | cli_tester_handle.join().unwrap()?; | ||
| 518 | Ok(()) | ||
| 519 | } | ||
| 520 | } | ||
| 50 | } | 521 | } |
| 51 | 522 | ||
| 52 | #[test] | 523 | mod when_second_time_login_and_details_already_fetched { |
| 53 | #[serial] | 524 | use super::*; |
| 54 | fn succeeds_with_hex_secret_key_in_place_of_nsec() -> Result<()> { | ||
| 55 | with_fresh_config(|| { | ||
| 56 | let mut p = CliTester::new(["login"]); | ||
| 57 | |||
| 58 | p.expect_input(EXPECTED_NSEC_PROMPT)? | ||
| 59 | .succeeds_with(TEST_KEY_1_SK_HEX)?; | ||
| 60 | |||
| 61 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? | ||
| 62 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? | ||
| 63 | .succeeds_with(TEST_PASSWORD)?; | ||
| 64 | 525 | ||
| 65 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | 526 | // TODO: the following two tests would require a fake config file or |
| 66 | }) | 527 | // fake time |
| 528 | // - uses_relays_from_user_relay_list | ||
| 529 | // - dislays_correct_name - when_local_metadata_is_the_most_recent | ||
| 530 | |||
| 531 | mod uses_cache { | ||
| 532 | use super::*; | ||
| 533 | |||
| 534 | #[test] | ||
| 535 | #[serial] | ||
| 536 | fn dislays_logged_in_with_correct_name() -> Result<()> { | ||
| 537 | futures::executor::block_on(run_test_dislays_logged_in_with_correct_name(Some( | ||
| 538 | &|relay, client_id, subscription_id, _| -> Result<()> { | ||
| 539 | relay.respond_events( | ||
| 540 | client_id, | ||
| 541 | &subscription_id, | ||
| 542 | &vec![ | ||
| 543 | generate_test_key_1_metadata_event("fred"), | ||
| 544 | generate_test_key_1_relay_list_event(), | ||
| 545 | ], | ||
| 546 | )?; | ||
| 547 | Ok(()) | ||
| 548 | }, | ||
| 549 | ))) | ||
| 550 | } | ||
| 551 | async fn run_test_dislays_logged_in_with_correct_name( | ||
| 552 | relay_listener: Option<ListenerReqFunc<'_>>, | ||
| 553 | ) -> Result<()> { | ||
| 554 | let (mut r51, mut r52) = ( | ||
| 555 | Relay::new(8051, None, relay_listener), | ||
| 556 | Relay::new(8052, None, None), | ||
| 557 | ); | ||
| 558 | |||
| 559 | let cli_tester_handle = std::thread::spawn(move || -> Result<()> { | ||
| 560 | with_fresh_config(|| { | ||
| 561 | let mut p = CliTester::new([ | ||
| 562 | "login", | ||
| 563 | "--nsec", | ||
| 564 | TEST_KEY_1_NSEC, | ||
| 565 | "--password", | ||
| 566 | TEST_PASSWORD, | ||
| 567 | ]); | ||
| 568 | |||
| 569 | p.expect_end_eventually_with("logged in as fred\r\n")?; | ||
| 570 | |||
| 571 | for p in [51, 52] { | ||
| 572 | shutdown_relay(8000 + p)?; | ||
| 573 | } | ||
| 574 | |||
| 575 | let mut p = CliTester::new(["login", "--password", TEST_PASSWORD]); | ||
| 576 | |||
| 577 | p.expect("searching for your details...\r\n")?; | ||
| 578 | p.expect("\r")?; | ||
| 579 | |||
| 580 | p.expect_end_eventually_with("logged in as fred\r\n")?; | ||
| 581 | |||
| 582 | Ok(()) | ||
| 583 | }) | ||
| 584 | }); | ||
| 585 | |||
| 586 | // launch relay | ||
| 587 | let _ = join!(r51.listen_until_close(), r52.listen_until_close(),); | ||
| 588 | |||
| 589 | cli_tester_handle.join().unwrap()?; | ||
| 590 | |||
| 591 | Ok(()) | ||
| 592 | } | ||
| 593 | } | ||
| 67 | } | 594 | } |
| 595 | } | ||
| 68 | 596 | ||
| 69 | mod when_invalid_nsec { | 597 | /// using the offline flag simplifies the test. relay interaction is tested |
| 598 | /// seperately | ||
| 599 | mod with_offline_flag { | ||
| 600 | use super::*; | ||
| 601 | mod when_first_time_login { | ||
| 70 | use super::*; | 602 | use super::*; |
| 71 | 603 | ||
| 72 | #[test] | 604 | #[test] |
| 73 | #[serial] | 605 | #[serial] |
| 74 | fn prompts_for_nsec_until_valid() -> Result<()> { | 606 | fn prompts_for_nsec_and_password() -> Result<()> { |
| 75 | with_fresh_config(|| { | 607 | before()?; |
| 76 | let invalid_nsec_response = | 608 | standard_login()?; |
| 77 | "invalid nsec. try again with nsec (or hex private key)"; | 609 | after() |
| 610 | } | ||
| 78 | 611 | ||
| 79 | let mut p = CliTester::new(["login"]); | 612 | #[test] |
| 613 | #[serial] | ||
| 614 | fn succeeds_with_text_logged_in_as_npub() -> Result<()> { | ||
| 615 | with_fresh_config(|| { | ||
| 616 | let mut p = CliTester::new(["login", "--offline"]); | ||
| 80 | 617 | ||
| 81 | p.expect_input(EXPECTED_NSEC_PROMPT)? | 618 | p.expect_input(EXPECTED_NSEC_PROMPT)? |
| 82 | // this behaviour is intentional. rejecting the response with dialoguer hides | ||
| 83 | // the original input from the user so they cannot see the | ||
| 84 | // mistake they made. | ||
| 85 | .succeeds_with(TEST_INVALID_NSEC)?; | ||
| 86 | |||
| 87 | p.expect_input(invalid_nsec_response)? | ||
| 88 | .succeeds_with(TEST_INVALID_NSEC)?; | ||
| 89 | |||
| 90 | p.expect_input(invalid_nsec_response)? | ||
| 91 | .succeeds_with(TEST_KEY_1_NSEC)?; | 619 | .succeeds_with(TEST_KEY_1_NSEC)?; |
| 92 | 620 | ||
| 93 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? | 621 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? |
| @@ -97,178 +625,174 @@ mod when_first_time_login { | |||
| 97 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | 625 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 98 | }) | 626 | }) |
| 99 | } | 627 | } |
| 100 | } | ||
| 101 | } | ||
| 102 | 628 | ||
| 103 | mod when_second_time_login { | 629 | #[test] |
| 104 | use super::*; | 630 | #[serial] |
| 631 | fn succeeds_with_hex_secret_key_in_place_of_nsec() -> Result<()> { | ||
| 632 | with_fresh_config(|| { | ||
| 633 | let mut p = CliTester::new(["login", "--offline"]); | ||
| 105 | 634 | ||
| 106 | #[test] | 635 | p.expect_input(EXPECTED_NSEC_PROMPT)? |
| 107 | #[serial] | 636 | .succeeds_with(TEST_KEY_1_SK_HEX)?; |
| 108 | fn prints_login_as_npub() -> Result<()> { | ||
| 109 | with_fresh_config(|| { | ||
| 110 | standard_login()?.exit()?; | ||
| 111 | 637 | ||
| 112 | CliTester::new(["login"]) | 638 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? |
| 113 | .expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? | 639 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? |
| 114 | .exit() | 640 | .succeeds_with(TEST_PASSWORD)?; |
| 115 | }) | ||
| 116 | } | ||
| 117 | 641 | ||
| 118 | #[test] | 642 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 119 | #[serial] | 643 | }) |
| 120 | fn prompts_for_password_and_succeeds_with_logged_in_as_npub() -> Result<()> { | 644 | } |
| 121 | with_fresh_config(|| { | ||
| 122 | standard_login()?.exit()?; | ||
| 123 | 645 | ||
| 124 | let mut p = CliTester::new(["login"]); | 646 | mod when_invalid_nsec { |
| 647 | use super::*; | ||
| 125 | 648 | ||
| 126 | p.expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? | 649 | #[test] |
| 127 | .expect_password(EXPECTED_PASSWORD_PROMPT)? | 650 | #[serial] |
| 128 | .succeeds_with(TEST_PASSWORD)?; | 651 | fn prompts_for_nsec_until_valid() -> Result<()> { |
| 652 | with_fresh_config(|| { | ||
| 653 | let invalid_nsec_response = | ||
| 654 | "invalid nsec. try again with nsec (or hex private key)"; | ||
| 129 | 655 | ||
| 130 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | 656 | let mut p = CliTester::new(["login", "--offline"]); |
| 131 | }) | ||
| 132 | } | ||
| 133 | 657 | ||
| 134 | #[test] | 658 | p.expect_input(EXPECTED_NSEC_PROMPT)? |
| 135 | #[serial] | 659 | // this behaviour is intentional. rejecting the response with dialoguer |
| 136 | fn when_invalid_password_exit_with_error() -> Result<()> { | 660 | // hides the original input from the user so they |
| 137 | with_fresh_config(|| { | 661 | // cannot see the mistake they made. |
| 138 | standard_login()?.exit()?; | 662 | .succeeds_with(TEST_INVALID_NSEC)?; |
| 139 | 663 | ||
| 140 | let mut p = CliTester::new(["login"]); | 664 | p.expect_input(invalid_nsec_response)? |
| 665 | .succeeds_with(TEST_INVALID_NSEC)?; | ||
| 141 | 666 | ||
| 142 | p.expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? | 667 | p.expect_input(invalid_nsec_response)? |
| 143 | .expect_password(EXPECTED_PASSWORD_PROMPT)? | 668 | .succeeds_with(TEST_KEY_1_NSEC)?; |
| 144 | .succeeds_with(TEST_INVALID_PASSWORD)?; | ||
| 145 | p.expect_end_with(format!("Error: failed to log in as {}\r\n\r\nCaused by:\r\n 0: failed to decrypt key with provided password\r\n 1: failed to decrypt\r\n", TEST_KEY_1_NPUB).as_str()) | ||
| 146 | }) | ||
| 147 | } | ||
| 148 | } | ||
| 149 | 669 | ||
| 150 | mod when_called_with_nsec_parameter_only { | 670 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? |
| 151 | use super::*; | 671 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? |
| 672 | .succeeds_with(TEST_PASSWORD)?; | ||
| 152 | 673 | ||
| 153 | #[test] | 674 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 154 | #[serial] | 675 | }) |
| 155 | fn valid_nsec_param_succeeds_without_prompts() -> Result<()> { | 676 | } |
| 156 | with_fresh_config(|| { | 677 | } |
| 157 | CliTester::new(["login", "--nsec", TEST_KEY_1_NSEC]) | ||
| 158 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | ||
| 159 | }) | ||
| 160 | } | 678 | } |
| 161 | 679 | ||
| 162 | #[test] | 680 | mod when_second_time_login { |
| 163 | #[serial] | 681 | use super::*; |
| 164 | fn forgets_identity() -> Result<()> { | ||
| 165 | with_fresh_config(|| { | ||
| 166 | CliTester::new(["login", "--nsec", TEST_KEY_1_NSEC]) | ||
| 167 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; | ||
| 168 | 682 | ||
| 169 | let mut p = CliTester::new(["login"]); | 683 | #[test] |
| 684 | #[serial] | ||
| 685 | fn prints_login_as_npub() -> Result<()> { | ||
| 686 | with_fresh_config(|| { | ||
| 687 | standard_login()?.exit()?; | ||
| 170 | 688 | ||
| 171 | p.expect_input(EXPECTED_NSEC_PROMPT)? | 689 | CliTester::new(["login", "--offline"]) |
| 172 | .succeeds_with(TEST_KEY_1_NSEC)?; | 690 | .expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? |
| 691 | .exit() | ||
| 692 | }) | ||
| 693 | } | ||
| 173 | 694 | ||
| 174 | p.exit() | 695 | #[test] |
| 175 | }) | 696 | #[serial] |
| 176 | } | 697 | fn prompts_for_password_and_succeeds_with_logged_in_as_npub() -> Result<()> { |
| 698 | with_fresh_config(|| { | ||
| 699 | standard_login()?.exit()?; | ||
| 177 | 700 | ||
| 178 | mod when_logging_in_as_different_nsec { | 701 | let mut p = CliTester::new(["login", "--offline"]); |
| 179 | use super::*; | 702 | |
| 703 | p.expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? | ||
| 704 | .expect_password(EXPECTED_PASSWORD_PROMPT)? | ||
| 705 | .succeeds_with(TEST_PASSWORD)?; | ||
| 706 | |||
| 707 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | ||
| 708 | }) | ||
| 709 | } | ||
| 180 | 710 | ||
| 181 | #[test] | 711 | #[test] |
| 182 | #[serial] | 712 | #[serial] |
| 183 | fn valid_nsec_param_succeeds_without_prompts_and_logs_in() -> Result<()> { | 713 | fn when_invalid_password_exit_with_error() -> Result<()> { |
| 184 | with_fresh_config(|| { | 714 | with_fresh_config(|| { |
| 185 | standard_login()?.exit()?; | 715 | standard_login()?.exit()?; |
| 186 | 716 | ||
| 187 | CliTester::new(["login", "--nsec", TEST_KEY_2_NSEC]) | 717 | let mut p = CliTester::new(["login", "--offline"]); |
| 188 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_2_NPUB).as_str()) | 718 | |
| 719 | p.expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? | ||
| 720 | .expect_password(EXPECTED_PASSWORD_PROMPT)? | ||
| 721 | .succeeds_with(TEST_INVALID_PASSWORD)?; | ||
| 722 | p.expect_end_with(format!("Error: failed to log in as {}\r\n\r\nCaused by:\r\n 0: failed to decrypt key with provided password\r\n 1: failed to decrypt\r\n", TEST_KEY_1_NPUB).as_str()) | ||
| 189 | }) | 723 | }) |
| 190 | } | 724 | } |
| 191 | } | 725 | } |
| 192 | #[test] | ||
| 193 | #[serial] | ||
| 194 | fn invalid_nsec_param_fails_without_prompts() -> Result<()> { | ||
| 195 | with_fresh_config(|| { | ||
| 196 | CliTester::new(["login", "--nsec", TEST_INVALID_NSEC]).expect_end_with( | ||
| 197 | "Error: invalid nsec parameter\r\n\r\nCaused by:\r\n Invalid secret key\r\n", | ||
| 198 | ) | ||
| 199 | }) | ||
| 200 | } | ||
| 201 | } | ||
| 202 | 726 | ||
| 203 | mod when_called_with_nsec_and_password_parameter { | 727 | mod when_called_with_nsec_parameter_only { |
| 204 | use super::*; | 728 | use super::*; |
| 205 | 729 | ||
| 206 | #[test] | 730 | #[test] |
| 207 | #[serial] | 731 | #[serial] |
| 208 | fn valid_nsec_param_succeeds_without_prompts() -> Result<()> { | 732 | fn valid_nsec_param_succeeds_without_prompts() -> Result<()> { |
| 209 | with_fresh_config(|| { | 733 | with_fresh_config(|| { |
| 210 | CliTester::new([ | 734 | CliTester::new(["login", "--offline", "--nsec", TEST_KEY_1_NSEC]) |
| 211 | "login", | 735 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 212 | "--nsec", | 736 | }) |
| 213 | TEST_KEY_1_NSEC, | 737 | } |
| 214 | "--password", | ||
| 215 | TEST_PASSWORD, | ||
| 216 | ]) | ||
| 217 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | ||
| 218 | }) | ||
| 219 | } | ||
| 220 | 738 | ||
| 221 | #[test] | 739 | #[test] |
| 222 | #[serial] | 740 | #[serial] |
| 223 | fn remembers_identity() -> Result<()> { | 741 | fn forgets_identity() -> Result<()> { |
| 224 | with_fresh_config(|| { | 742 | with_fresh_config(|| { |
| 225 | CliTester::new([ | 743 | CliTester::new(["login", "--offline", "--nsec", TEST_KEY_1_NSEC]) |
| 226 | "login", | 744 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; |
| 227 | "--nsec", | 745 | |
| 228 | TEST_KEY_1_NSEC, | 746 | let mut p = CliTester::new(["login", "--offline"]); |
| 229 | "--password", | ||
| 230 | TEST_PASSWORD, | ||
| 231 | ]) | ||
| 232 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; | ||
| 233 | |||
| 234 | CliTester::new(["login"]) | ||
| 235 | .expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? | ||
| 236 | .exit() | ||
| 237 | }) | ||
| 238 | } | ||
| 239 | 747 | ||
| 240 | #[test] | 748 | p.expect_input(EXPECTED_NSEC_PROMPT)? |
| 241 | #[serial] | 749 | .succeeds_with(TEST_KEY_1_NSEC)?; |
| 242 | fn parameters_can_be_called_globally() -> Result<()> { | 750 | |
| 243 | with_fresh_config(|| { | 751 | p.exit() |
| 244 | CliTester::new([ | 752 | }) |
| 245 | "--nsec", | 753 | } |
| 246 | TEST_KEY_1_NSEC, | 754 | |
| 247 | "--password", | 755 | mod when_logging_in_as_different_nsec { |
| 248 | TEST_PASSWORD, | 756 | use super::*; |
| 249 | "login", | 757 | |
| 250 | ]) | 758 | #[test] |
| 251 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | 759 | #[serial] |
| 252 | }) | 760 | fn valid_nsec_param_succeeds_without_prompts_and_logs_in() -> Result<()> { |
| 761 | with_fresh_config(|| { | ||
| 762 | standard_login()?.exit()?; | ||
| 763 | |||
| 764 | CliTester::new(["login", "--offline", "--nsec", TEST_KEY_2_NSEC]) | ||
| 765 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_2_NPUB).as_str()) | ||
| 766 | }) | ||
| 767 | } | ||
| 768 | } | ||
| 769 | #[test] | ||
| 770 | #[serial] | ||
| 771 | fn invalid_nsec_param_fails_without_prompts() -> Result<()> { | ||
| 772 | with_fresh_config(|| { | ||
| 773 | CliTester::new(["login", "--offline", "--nsec", TEST_INVALID_NSEC]).expect_end_with( | ||
| 774 | "Error: invalid nsec parameter\r\n\r\nCaused by:\r\n Invalid secret key\r\n", | ||
| 775 | ) | ||
| 776 | }) | ||
| 777 | } | ||
| 253 | } | 778 | } |
| 254 | 779 | ||
| 255 | mod when_logging_in_as_different_nsec { | 780 | mod when_called_with_nsec_and_password_parameter { |
| 256 | use super::*; | 781 | use super::*; |
| 257 | 782 | ||
| 258 | #[test] | 783 | #[test] |
| 259 | #[serial] | 784 | #[serial] |
| 260 | fn valid_nsec_param_succeeds_without_prompts_and_logs_in() -> Result<()> { | 785 | fn valid_nsec_param_succeeds_without_prompts() -> Result<()> { |
| 261 | with_fresh_config(|| { | 786 | with_fresh_config(|| { |
| 262 | standard_login()?.exit()?; | ||
| 263 | |||
| 264 | CliTester::new([ | 787 | CliTester::new([ |
| 265 | "login", | 788 | "login", |
| 789 | "--offline", | ||
| 266 | "--nsec", | 790 | "--nsec", |
| 267 | TEST_KEY_2_NSEC, | 791 | TEST_KEY_1_NSEC, |
| 268 | "--password", | 792 | "--password", |
| 269 | TEST_PASSWORD, | 793 | TEST_PASSWORD, |
| 270 | ]) | 794 | ]) |
| 271 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_2_NPUB).as_str()) | 795 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 272 | }) | 796 | }) |
| 273 | } | 797 | } |
| 274 | 798 | ||
| @@ -276,120 +800,182 @@ mod when_called_with_nsec_and_password_parameter { | |||
| 276 | #[serial] | 800 | #[serial] |
| 277 | fn remembers_identity() -> Result<()> { | 801 | fn remembers_identity() -> Result<()> { |
| 278 | with_fresh_config(|| { | 802 | with_fresh_config(|| { |
| 279 | standard_login()?.exit()?; | ||
| 280 | |||
| 281 | CliTester::new([ | 803 | CliTester::new([ |
| 282 | "login", | 804 | "login", |
| 805 | "--offline", | ||
| 283 | "--nsec", | 806 | "--nsec", |
| 284 | TEST_KEY_2_NSEC, | 807 | TEST_KEY_1_NSEC, |
| 285 | "--password", | 808 | "--password", |
| 286 | TEST_PASSWORD, | 809 | TEST_PASSWORD, |
| 287 | ]) | 810 | ]) |
| 288 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_2_NPUB).as_str())?; | 811 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; |
| 289 | 812 | ||
| 290 | CliTester::new(["login"]) | 813 | CliTester::new(["login", "--offline"]) |
| 291 | .expect(format!("login as {}\r\n", TEST_KEY_2_NPUB).as_str())? | 814 | .expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? |
| 292 | .exit() | 815 | .exit() |
| 293 | }) | 816 | }) |
| 294 | } | 817 | } |
| 295 | } | ||
| 296 | |||
| 297 | mod when_provided_with_new_password { | ||
| 298 | use super::*; | ||
| 299 | 818 | ||
| 300 | #[test] | 819 | #[test] |
| 301 | #[serial] | 820 | #[serial] |
| 302 | fn password_changes() -> Result<()> { | 821 | fn parameters_can_be_called_globally() -> Result<()> { |
| 303 | with_fresh_config(|| { | 822 | with_fresh_config(|| { |
| 304 | standard_login()?.exit()?; | ||
| 305 | |||
| 306 | CliTester::new([ | 823 | CliTester::new([ |
| 307 | "login", | ||
| 308 | "--nsec", | 824 | "--nsec", |
| 309 | TEST_KEY_1_NSEC, | 825 | TEST_KEY_1_NSEC, |
| 310 | "--password", | 826 | "--password", |
| 311 | TEST_INVALID_PASSWORD, | 827 | TEST_PASSWORD, |
| 828 | "login", | ||
| 829 | "--offline", | ||
| 312 | ]) | 830 | ]) |
| 313 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; | 831 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 314 | |||
| 315 | CliTester::new(["--password", TEST_INVALID_PASSWORD, "login"]) | ||
| 316 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | ||
| 317 | }) | 832 | }) |
| 318 | } | 833 | } |
| 319 | } | ||
| 320 | 834 | ||
| 321 | #[test] | 835 | mod when_logging_in_as_different_nsec { |
| 322 | #[serial] | 836 | use super::*; |
| 323 | fn invalid_nsec_param_fails_without_prompts() -> Result<()> { | 837 | |
| 324 | with_fresh_config(|| { | 838 | #[test] |
| 325 | CliTester::new([ | 839 | #[serial] |
| 326 | "login", | 840 | fn valid_nsec_param_succeeds_without_prompts_and_logs_in() -> Result<()> { |
| 327 | "--nsec", | 841 | with_fresh_config(|| { |
| 328 | TEST_INVALID_NSEC, | 842 | standard_login()?.exit()?; |
| 329 | "--password", | 843 | |
| 330 | TEST_PASSWORD, | 844 | CliTester::new([ |
| 331 | ]) | 845 | "login", |
| 332 | .expect_end_with( | 846 | "--offline", |
| 333 | "Error: invalid nsec parameter\r\n\r\nCaused by:\r\n Invalid secret key\r\n", | 847 | "--nsec", |
| 334 | ) | 848 | TEST_KEY_2_NSEC, |
| 335 | }) | 849 | "--password", |
| 850 | TEST_PASSWORD, | ||
| 851 | ]) | ||
| 852 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_2_NPUB).as_str()) | ||
| 853 | }) | ||
| 854 | } | ||
| 855 | |||
| 856 | #[test] | ||
| 857 | #[serial] | ||
| 858 | fn remembers_identity() -> Result<()> { | ||
| 859 | with_fresh_config(|| { | ||
| 860 | standard_login()?.exit()?; | ||
| 861 | |||
| 862 | CliTester::new([ | ||
| 863 | "login", | ||
| 864 | "--offline", | ||
| 865 | "--nsec", | ||
| 866 | TEST_KEY_2_NSEC, | ||
| 867 | "--password", | ||
| 868 | TEST_PASSWORD, | ||
| 869 | ]) | ||
| 870 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_2_NPUB).as_str())?; | ||
| 871 | |||
| 872 | CliTester::new(["login", "--offline"]) | ||
| 873 | .expect(format!("login as {}\r\n", TEST_KEY_2_NPUB).as_str())? | ||
| 874 | .exit() | ||
| 875 | }) | ||
| 876 | } | ||
| 877 | } | ||
| 878 | |||
| 879 | mod when_provided_with_new_password { | ||
| 880 | use super::*; | ||
| 881 | |||
| 882 | #[test] | ||
| 883 | #[serial] | ||
| 884 | fn password_changes() -> Result<()> { | ||
| 885 | with_fresh_config(|| { | ||
| 886 | standard_login()?.exit()?; | ||
| 887 | |||
| 888 | CliTester::new([ | ||
| 889 | "login", | ||
| 890 | "--offline", | ||
| 891 | "--nsec", | ||
| 892 | TEST_KEY_1_NSEC, | ||
| 893 | "--password", | ||
| 894 | TEST_INVALID_PASSWORD, | ||
| 895 | ]) | ||
| 896 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; | ||
| 897 | |||
| 898 | CliTester::new(["--password", TEST_INVALID_PASSWORD, "login", "--offline"]) | ||
| 899 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | ||
| 900 | }) | ||
| 901 | } | ||
| 902 | } | ||
| 903 | |||
| 904 | #[test] | ||
| 905 | #[serial] | ||
| 906 | fn invalid_nsec_param_fails_without_prompts() -> Result<()> { | ||
| 907 | with_fresh_config(|| { | ||
| 908 | CliTester::new([ | ||
| 909 | "login", | ||
| 910 | "--offline", | ||
| 911 | "--nsec", | ||
| 912 | TEST_INVALID_NSEC, | ||
| 913 | "--password", | ||
| 914 | TEST_PASSWORD, | ||
| 915 | ]) | ||
| 916 | .expect_end_with( | ||
| 917 | "Error: invalid nsec parameter\r\n\r\nCaused by:\r\n Invalid secret key\r\n", | ||
| 918 | ) | ||
| 919 | }) | ||
| 920 | } | ||
| 336 | } | 921 | } |
| 337 | } | ||
| 338 | 922 | ||
| 339 | mod when_called_with_password_parameter_only { | 923 | mod when_called_with_password_parameter_only { |
| 340 | use super::*; | 924 | use super::*; |
| 341 | 925 | ||
| 342 | #[test] | 926 | #[test] |
| 343 | #[serial] | 927 | #[serial] |
| 344 | fn when_nsec_stored_logs_in_without_prompts() -> Result<()> { | 928 | fn when_nsec_stored_logs_in_without_prompts() -> Result<()> { |
| 345 | with_fresh_config(|| { | 929 | with_fresh_config(|| { |
| 346 | standard_login()?.exit()?; | 930 | standard_login()?.exit()?; |
| 347 | 931 | ||
| 348 | CliTester::new(["login", "--password", TEST_PASSWORD]) | 932 | CliTester::new(["login", "--offline", "--password", TEST_PASSWORD]) |
| 349 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | 933 | .expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 350 | }) | 934 | }) |
| 351 | } | 935 | } |
| 352 | 936 | ||
| 353 | #[test] | 937 | #[test] |
| 354 | #[serial] | 938 | #[serial] |
| 355 | fn when_no_nsec_stored_logs_error() -> Result<()> { | 939 | fn when_no_nsec_stored_logs_error() -> Result<()> { |
| 356 | with_fresh_config(|| { | 940 | with_fresh_config(|| { |
| 357 | CliTester::new(["login", "--password", TEST_PASSWORD]) | 941 | CliTester::new(["login", "--offline", "--password", TEST_PASSWORD]).expect_end_with( |
| 358 | .expect_end_with("Error: no nsec available to decrypt with specified password\r\n") | 942 | "Error: no nsec available to decrypt with specified password\r\n", |
| 359 | }) | 943 | ) |
| 944 | }) | ||
| 945 | } | ||
| 360 | } | 946 | } |
| 361 | } | ||
| 362 | 947 | ||
| 363 | mod when_weak_password { | 948 | mod when_weak_password { |
| 364 | use super::*; | 949 | use super::*; |
| 365 | 950 | ||
| 366 | #[test] | 951 | #[test] |
| 367 | #[serial] | 952 | #[serial] |
| 368 | // combined into a single test as it is computationally expensive to run | 953 | // combined into a single test as it is computationally expensive to run |
| 369 | fn warns_it_might_take_a_few_seconds_then_succeeds_then_second_login_prompts_for_password_then_warns_again_then_succeeds() | 954 | fn warns_it_might_take_a_few_seconds_then_succeeds_then_second_login_prompts_for_password_then_warns_again_then_succeeds() |
| 370 | -> Result<()> { | 955 | -> Result<()> { |
| 371 | with_fresh_config(|| { | 956 | with_fresh_config(|| { |
| 372 | let mut p = CliTester::new_with_timeout(10000, ["login"]); | 957 | let mut p = CliTester::new_with_timeout(10000, ["login", "--offline"]); |
| 373 | p.expect_input(EXPECTED_NSEC_PROMPT)? | 958 | p.expect_input(EXPECTED_NSEC_PROMPT)? |
| 374 | .succeeds_with(TEST_KEY_1_NSEC)?; | 959 | .succeeds_with(TEST_KEY_1_NSEC)?; |
| 375 | 960 | ||
| 376 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? | 961 | p.expect_password(EXPECTED_SET_PASSWORD_PROMPT)? |
| 377 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? | 962 | .with_confirmation(EXPECTED_SET_PASSWORD_CONFIRM_PROMPT)? |
| 378 | .succeeds_with(TEST_WEAK_PASSWORD)?; | 963 | .succeeds_with(TEST_WEAK_PASSWORD)?; |
| 379 | 964 | ||
| 380 | p.expect("this may take a few seconds...\r\n")?; | 965 | p.expect("this may take a few seconds...\r\n")?; |
| 381 | 966 | ||
| 382 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; | 967 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str())?; |
| 383 | 968 | ||
| 384 | p = CliTester::new_with_timeout(10000, ["login"]); | 969 | p = CliTester::new_with_timeout(10000, ["login", "--offline"]); |
| 385 | 970 | ||
| 386 | p.expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? | 971 | p.expect(format!("login as {}\r\n", TEST_KEY_1_NPUB).as_str())? |
| 387 | .expect_password(EXPECTED_PASSWORD_PROMPT)? | 972 | .expect_password(EXPECTED_PASSWORD_PROMPT)? |
| 388 | .succeeds_with(TEST_WEAK_PASSWORD)?; | 973 | .succeeds_with(TEST_WEAK_PASSWORD)?; |
| 389 | 974 | ||
| 390 | p.expect("this may take a few seconds...\r\n")?; | 975 | p.expect("this may take a few seconds...\r\n")?; |
| 391 | 976 | ||
| 392 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) | 977 | p.expect_end_with(format!("logged in as {}\r\n", TEST_KEY_1_NPUB).as_str()) |
| 393 | }) | 978 | }) |
| 979 | } | ||
| 394 | } | 980 | } |
| 395 | } | 981 | } |
diff --git a/tests/prs_create.rs b/tests/prs_create.rs index 0863496..564ef16 100644 --- a/tests/prs_create.rs +++ b/tests/prs_create.rs | |||
| @@ -195,9 +195,9 @@ mod sends_pr_and_2_patches_to_3_relays { | |||
| 195 | let git_repo = prep_git_repo()?; | 195 | let git_repo = prep_git_repo()?; |
| 196 | 196 | ||
| 197 | let (mut r51, mut r52, mut r53) = ( | 197 | let (mut r51, mut r52, mut r53) = ( |
| 198 | Relay::new(8051, None), | 198 | Relay::new(8051, None, None), |
| 199 | Relay::new(8052, None), | 199 | Relay::new(8052, None, None), |
| 200 | Relay::new(8053, None), | 200 | Relay::new(8053, None, None), |
| 201 | ); | 201 | ); |
| 202 | 202 | ||
| 203 | // // check relay had the right number of events | 203 | // // check relay had the right number of events |
| @@ -427,9 +427,9 @@ mod sends_pr_and_2_patches_to_3_relays { | |||
| 427 | let git_repo = prep_git_repo()?; | 427 | let git_repo = prep_git_repo()?; |
| 428 | 428 | ||
| 429 | let (mut r51, mut r52, mut r53) = ( | 429 | let (mut r51, mut r52, mut r53) = ( |
| 430 | Relay::new(8051, None), | 430 | Relay::new(8051, None, None), |
| 431 | Relay::new(8052, None), | 431 | Relay::new(8052, None, None), |
| 432 | Relay::new(8053, None), | 432 | Relay::new(8053, None, None), |
| 433 | ); | 433 | ); |
| 434 | 434 | ||
| 435 | // // check relay had the right number of events | 435 | // // check relay had the right number of events |
| @@ -477,15 +477,16 @@ mod sends_pr_and_2_patches_to_3_relays { | |||
| 477 | let git_repo = prep_git_repo()?; | 477 | let git_repo = prep_git_repo()?; |
| 478 | 478 | ||
| 479 | let (mut r51, mut r52, mut r53) = ( | 479 | let (mut r51, mut r52, mut r53) = ( |
| 480 | Relay::new(8051, None), | 480 | Relay::new(8051, None, None), |
| 481 | Relay::new( | 481 | Relay::new( |
| 482 | 8052, | 482 | 8052, |
| 483 | Some(&|relay, client_id, event| -> Result<()> { | 483 | Some(&|relay, client_id, event| -> Result<()> { |
| 484 | relay.respond_ok(client_id, event, Some("Payment Required"))?; | 484 | relay.respond_ok(client_id, event, Some("Payment Required"))?; |
| 485 | Ok(()) | 485 | Ok(()) |
| 486 | }), | 486 | }), |
| 487 | None, | ||
| 487 | ), | 488 | ), |
| 488 | Relay::new(8053, None), | 489 | Relay::new(8053, None, None), |
| 489 | ); | 490 | ); |
| 490 | 491 | ||
| 491 | // // check relay had the right number of events | 492 | // // check relay had the right number of events |
| @@ -523,15 +524,16 @@ mod sends_pr_and_2_patches_to_3_relays { | |||
| 523 | let git_repo = prep_git_repo()?; | 524 | let git_repo = prep_git_repo()?; |
| 524 | 525 | ||
| 525 | let (mut r51, mut r52, mut r53) = ( | 526 | let (mut r51, mut r52, mut r53) = ( |
| 526 | Relay::new(8051, None), | 527 | Relay::new(8051, None, None), |
| 527 | Relay::new( | 528 | Relay::new( |
| 528 | 8052, | 529 | 8052, |
| 529 | Some(&|relay, client_id, event| -> Result<()> { | 530 | Some(&|relay, client_id, event| -> Result<()> { |
| 530 | relay.respond_ok(client_id, event, Some("Payment Required"))?; | 531 | relay.respond_ok(client_id, event, Some("Payment Required"))?; |
| 531 | Ok(()) | 532 | Ok(()) |
| 532 | }), | 533 | }), |
| 534 | None, | ||
| 533 | ), | 535 | ), |
| 534 | Relay::new(8053, None), | 536 | Relay::new(8053, None, None), |
| 535 | ); | 537 | ); |
| 536 | 538 | ||
| 537 | // // check relay had the right number of events | 539 | // // check relay had the right number of events |