upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/key_handling
diff options
context:
space:
mode:
authorDanConwayDev <DanConwayDev@protonmail.com>2023-09-01 00:00:00 +0000
committerDanConwayDev <DanConwayDev@protonmail.com>2023-09-13 09:24:49 +0000
commit6423baebd92e45c9be85157c443dff42e65d8d14 (patch)
tree6548edfd80d0cd9d1267378ebe816ec95e394137 /src/key_handling
parent5c5feaa732363e32e2a980a887fa42b4394b1a5e (diff)
refactor: rebuild app skeleton
Create skeleton for a complete rebuild of the prototype as a production ready product. Includes design patterns for: - dependency injection - unit testing with dependency mocking - integration testing - error handling - config storage BREAKING-CHANGE: ground-up redesign with incompatible protocol standards
Diffstat (limited to 'src/key_handling')
-rw-r--r--src/key_handling/mod.rs1
-rw-r--r--src/key_handling/users.rs124
2 files changed, 125 insertions, 0 deletions
diff --git a/src/key_handling/mod.rs b/src/key_handling/mod.rs
new file mode 100644
index 0000000..913bd46
--- /dev/null
+++ b/src/key_handling/mod.rs
@@ -0,0 +1 @@
pub mod users;
diff --git a/src/key_handling/users.rs b/src/key_handling/users.rs
new file mode 100644
index 0000000..bd1748a
--- /dev/null
+++ b/src/key_handling/users.rs
@@ -0,0 +1,124 @@
1use anyhow::{Context, Result};
2
3use crate::{
4 cli_interactor::{Interactor, InteractorPrompt, PromptInputParms},
5 config::{ConfigManagement, ConfigManager, MyConfig, UserRef},
6};
7
8#[derive(Default)]
9pub struct UserManager {
10 config_manager: ConfigManager,
11 interactor: Interactor,
12}
13
14pub trait UserManagement {
15 fn add(&self, nsec: &Option<String>) -> Result<()>;
16}
17
18#[cfg(test)]
19use duplicate::duplicate_item;
20#[cfg_attr(test, duplicate_item(UserManager; [UserManager]; [self::tests::MockUserManager]))]
21impl UserManagement for UserManager {
22 fn add(&self, nsec: &Option<String>) -> Result<()> {
23 let nsec = match nsec.clone() {
24 Some(nsec) => nsec,
25 None => self
26 .interactor
27 .input(
28 PromptInputParms::default().with_prompt("login with nsec (or hex private key)"),
29 )
30 .context("failed to get nsec input from interactor.input")?,
31 };
32
33 self.config_manager
34 .save(&MyConfig {
35 users: vec![UserRef {
36 nsec: nsec.to_string(),
37 }],
38 ..MyConfig::default()
39 })
40 .context("failed to save application configuration with new user details in")?;
41
42 println!("logged in as {nsec}");
43
44 Ok(())
45 }
46}
47
48#[cfg(test)]
49mod tests {
50 use test_utils::*;
51
52 use super::*;
53 use crate::{cli_interactor::MockInteractorPrompt, config::MockConfigManagement};
54
55 #[derive(Default)]
56 pub struct MockUserManager {
57 pub config_manager: MockConfigManagement,
58 pub interactor: MockInteractorPrompt,
59 }
60
61 mod add {
62 use super::*;
63
64 impl MockUserManager {
65 fn add_return_expected_responses(mut self) -> Self {
66 self.config_manager
67 .expect_load()
68 .returning(|| Ok(MyConfig::default()));
69 self.config_manager.expect_save().returning(|_| Ok(()));
70 self.interactor
71 .expect_input()
72 .returning(|_| Ok(TEST_KEY_1_NSEC.into()));
73 self
74 }
75 }
76
77 mod when_nsec_is_passed {
78 use super::*;
79
80 #[test]
81 fn user_isnt_prompted() {
82 let mut m = MockUserManager::default().add_return_expected_responses();
83 m.interactor = MockInteractorPrompt::default();
84 m.interactor.expect_input().never();
85
86 let _ = m.add(&Some(TEST_KEY_1_NSEC.into()));
87 }
88 }
89
90 mod when_no_nsec_is_passed {
91 use super::*;
92
93 #[test]
94 fn prompt_for_nsec() {
95 let mut m = MockUserManager::default().add_return_expected_responses();
96
97 m.interactor = MockInteractorPrompt::new();
98 m.interactor
99 .expect_input()
100 .once()
101 .withf(|p| p.prompt.eq("login with nsec (or hex private key)"))
102 .returning(|_| Ok(TEST_KEY_1_NSEC.into()));
103
104 let _ = m.add(&None);
105 }
106
107 #[test]
108 fn stored_in_config() {
109 let mut m = MockUserManager::default().add_return_expected_responses();
110
111 m.config_manager = MockConfigManagement::new();
112 m.config_manager
113 .expect_load()
114 .returning(|| Ok(MyConfig::default()));
115 m.config_manager
116 .expect_save()
117 .withf(|cfg| cfg.users.len().eq(&1) && cfg.users[0].nsec.eq(TEST_KEY_1_NSEC))
118 .returning(|_| Ok(()));
119
120 let _ = m.add(&None);
121 }
122 }
123 }
124}