1use super::Sdk;
4use crate::backend::postident::{get_case_details, get_new_case_id, update_case_status};
5use crate::error::Result;
6use crate::types::users::KycType;
7use api_types::api::postident::{CaseDetailsResponse, NewCaseIdResponse};
8use log::info;
9
10impl Sdk {
11 pub async fn start_kyc_verification_for_postident(&mut self) -> Result<NewCaseIdResponse> {
23 info!("Starting PostIdent Verification for user");
24 let Some(repo) = &mut self.repo else {
25 return Err(crate::Error::UserRepoNotInitialized);
26 };
27 let Some(active_user) = &mut self.active_user else {
28 return Err(crate::Error::UserNotInitialized);
29 };
30 let user = repo.get(&active_user.username)?;
31 if user.is_kyc_verified {
32 return Err(crate::Error::UserAlreadyKycVerified);
33 }
34 if user.kyc_type == KycType::Undefined {
35 repo.set_kyc_type(&active_user.username, KycType::Postident)?;
36 } else {
37 return Err(crate::Error::UserAlreadyKycVerified);
38 }
39
40 let access_token = self
41 .access_token
42 .as_ref()
43 .ok_or(crate::error::Error::MissingAccessToken)?;
44 let config = self.config.as_ref().ok_or(crate::Error::MissingConfig)?;
45 let response = get_new_case_id(config, access_token).await?;
46
47 Ok(response)
48 }
49
50 pub async fn get_kyc_details_for_postident(&self) -> Result<CaseDetailsResponse> {
60 info!("Fetching KYC details for postident");
61 let Some(_user) = &self.active_user else {
62 return Err(crate::Error::UserNotInitialized);
63 };
64 let access_token = self
65 .access_token
66 .as_ref()
67 .ok_or(crate::error::Error::MissingAccessToken)?;
68 let config = self.config.as_ref().ok_or(crate::Error::MissingConfig)?;
69 let case_details = get_case_details(config, access_token).await?;
70 Ok(case_details)
71 }
72
73 pub async fn update_kyc_status_for_postident(&self, case_id: &str) -> Result<()> {
87 info!("updating KYC details for postident");
88 let Some(_user) = &self.active_user else {
89 return Err(crate::Error::UserNotInitialized);
90 };
91
92 let access_token = self
93 .access_token
94 .as_ref()
95 .ok_or(crate::error::Error::MissingAccessToken)?;
96
97 let config = self.config.as_ref().ok_or(crate::Error::MissingConfig)?;
98 update_case_status(config, access_token, case_id).await?;
99
100 Ok(())
101 }
102}
103
104#[cfg(test)]
105mod tests {
106 use super::*;
107 use crate::core::core_testing_utils::handle_error_test_cases;
108 use crate::testing_utils::{
109 AUTH_PROVIDER, CASE_ID, HEADER_X_APP_NAME, TOKEN, USERNAME, example_case_details, example_get_user,
110 example_new_case_id, set_config,
111 };
112 use crate::{core::Sdk, user::MockUserRepo, wallet_manager::MockWalletManager};
113 use api_types::api::postident::{NewCaseIdResponse, UpdateCaseStatusRequest};
114 use api_types::api::viviswap::detail::SwapPaymentDetailKey;
115 use mockito::Matcher;
116 use rstest::rstest;
117
118 #[rstest]
119 #[case::success(Ok(example_new_case_id()))]
120 #[case::repo_init_error(Err(crate::Error::UserRepoNotInitialized))]
121 #[case::user_init_error(Err(crate::Error::UserNotInitialized))]
122 #[case::user_verified_erro(Err(crate::Error::UserAlreadyKycVerified))]
123 #[case::unauthorized(Err(crate::Error::MissingAccessToken))]
124 #[case::missing_config(Err(crate::Error::MissingConfig))]
125 #[tokio::test]
126 async fn test_start_kyc_verification_for_postident(#[case] expected: Result<NewCaseIdResponse>) {
127 let (mut srv, config, _cleanup) = set_config().await;
129 let mut sdk = Sdk::new(config).unwrap();
130 let mut mock_server = None;
131
132 match &expected {
133 Ok(_) => {
134 let mut mock_user_repo = example_get_user(SwapPaymentDetailKey::Iota, false, 1, KycType::Undefined);
135 mock_user_repo
136 .expect_set_kyc_type()
137 .times(1)
138 .returning(move |username, typ| {
139 assert_eq!(username, USERNAME);
140 assert_eq!(typ, KycType::Postident);
141 Ok(())
142 });
143
144 sdk.repo = Some(Box::new(mock_user_repo));
145 sdk.active_user = Some(crate::types::users::ActiveUser {
146 username: USERNAME.into(),
147 wallet_manager: Box::new(MockWalletManager::new()),
148 mnemonic_derivation_options: Default::default(),
149 });
150 sdk.access_token = Some(TOKEN.clone());
151
152 let mock_response = example_new_case_id();
153 let body = serde_json::to_string(&mock_response).unwrap();
154
155 mock_server = Some(
156 srv.mock("GET", "/api/postident/get-new-case-id")
157 .match_header(HEADER_X_APP_NAME, AUTH_PROVIDER)
158 .match_header("authorization", format!("Bearer {}", TOKEN.as_str()).as_str())
159 .with_status(200)
160 .with_header("content-type", "application/json")
161 .with_body(&body)
162 .expect(1)
163 .create(),
164 );
165 }
166 Err(crate::Error::MissingAccessToken) => {
167 let mut mock_user_repo = example_get_user(SwapPaymentDetailKey::Iota, false, 1, KycType::Undefined);
168 mock_user_repo
169 .expect_set_kyc_type()
170 .times(1)
171 .returning(move |username, typ| {
172 assert_eq!(username, USERNAME);
173 assert_eq!(typ, KycType::Postident);
174 Ok(())
175 });
176 sdk.repo = Some(Box::new(mock_user_repo));
177 sdk.active_user = Some(crate::types::users::ActiveUser {
178 username: USERNAME.into(),
179 wallet_manager: Box::new(MockWalletManager::new()),
180 mnemonic_derivation_options: Default::default(),
181 });
182 sdk.access_token = None;
183 }
184 Err(crate::Error::MissingConfig) => {
185 let mut mock_user_repo = example_get_user(SwapPaymentDetailKey::Iota, false, 1, KycType::Undefined);
186 mock_user_repo
187 .expect_set_kyc_type()
188 .times(1)
189 .returning(move |username, typ| {
190 assert_eq!(username, USERNAME);
191 assert_eq!(typ, KycType::Postident);
192 Ok(())
193 });
194 sdk.repo = Some(Box::new(mock_user_repo));
195 sdk.active_user = Some(crate::types::users::ActiveUser {
196 username: USERNAME.into(),
197 wallet_manager: Box::new(MockWalletManager::new()),
198 mnemonic_derivation_options: Default::default(),
199 });
200 sdk.access_token = Some(TOKEN.clone());
201 sdk.config = None;
202 }
203 Err(crate::Error::UserAlreadyKycVerified) => {
204 let mock_user_repo = example_get_user(SwapPaymentDetailKey::Iota, true, 1, KycType::Postident);
205 sdk.repo = Some(Box::new(mock_user_repo));
206 sdk.active_user = Some(crate::types::users::ActiveUser {
207 username: USERNAME.into(),
208 wallet_manager: Box::new(MockWalletManager::new()),
209 mnemonic_derivation_options: Default::default(),
210 });
211 }
212 Err(error) => {
213 handle_error_test_cases(error, &mut sdk, 1, 1).await;
214 }
215 }
216
217 let response = sdk.start_kyc_verification_for_postident().await;
219
220 match expected {
222 Ok(resp) => {
223 assert_eq!(response.unwrap(), resp);
224 }
225 Err(ref expected_err) => {
226 assert_eq!(response.err().unwrap().to_string(), expected_err.to_string());
227 }
228 }
229 if let Some(m) = mock_server {
230 m.assert();
231 }
232 }
233
234 #[rstest]
235 #[case::success(Ok(example_case_details()))]
236 #[case::user_init_error(Err(crate::Error::UserNotInitialized))]
237 #[case::unauthorized(Err(crate::Error::MissingAccessToken))]
238 #[case::missing_config(Err(crate::Error::MissingConfig))]
239 #[tokio::test]
240 async fn test_get_postident_kyc_details(#[case] expected: Result<CaseDetailsResponse>) {
241 let (mut srv, config, _cleanup) = set_config().await;
243 let mut sdk = Sdk::new(config).unwrap();
244 let mut mock_server = None;
245
246 match &expected {
247 Ok(_) => {
248 sdk.repo = Some(Box::new(MockUserRepo::new()));
249 sdk.active_user = Some(crate::types::users::ActiveUser {
250 username: USERNAME.into(),
251 wallet_manager: Box::new(MockWalletManager::new()),
252 mnemonic_derivation_options: Default::default(),
253 });
254 sdk.access_token = Some(TOKEN.clone());
255
256 let mock_response = example_case_details();
257 let body = serde_json::to_string(&mock_response).unwrap();
258
259 mock_server = Some(
260 srv.mock("GET", "/api/postident/get-case-details")
261 .match_header(HEADER_X_APP_NAME, AUTH_PROVIDER)
262 .match_header("authorization", format!("Bearer {}", TOKEN.as_str()).as_str())
263 .with_status(200)
264 .with_header("content-type", "application/json")
265 .with_body(&body)
266 .expect(1)
267 .create(),
268 );
269 }
270 Err(error) => {
271 handle_error_test_cases(error, &mut sdk, 0, 0).await;
272 }
273 }
274
275 let response = sdk.get_kyc_details_for_postident().await;
277
278 match expected {
280 Ok(resp) => {
281 assert_eq!(response.unwrap(), resp);
282 }
283 Err(ref expected_err) => {
284 assert_eq!(response.err().unwrap().to_string(), expected_err.to_string());
285 }
286 }
287 if let Some(m) = mock_server {
288 m.assert();
289 }
290 }
291
292 #[rstest]
293 #[case::success(Ok(()))]
294 #[case::user_init_error(Err(crate::Error::UserNotInitialized))]
295 #[case::unauthorized(Err(crate::Error::MissingAccessToken))]
296 #[case::missing_config(Err(crate::Error::MissingConfig))]
297 #[tokio::test]
298 async fn test_update_postident_kyc_details(#[case] expected: Result<()>) {
299 let (mut srv, config, _cleanup) = set_config().await;
301 let mut sdk = Sdk::new(config).unwrap();
302 let mut mock_server = None;
303
304 match &expected {
305 Ok(_) => {
306 sdk.repo = Some(Box::new(MockUserRepo::new()));
307 sdk.active_user = Some(crate::types::users::ActiveUser {
308 username: USERNAME.into(),
309 wallet_manager: Box::new(MockWalletManager::new()),
310 mnemonic_derivation_options: Default::default(),
311 });
312 sdk.access_token = Some(TOKEN.clone());
313
314 let req = UpdateCaseStatusRequest {
315 case_id: CASE_ID.into(),
316 };
317 let req = serde_json::to_string(&req).unwrap();
318
319 mock_server = Some(
320 srv.mock("POST", "/api/postident/update-case-status")
321 .match_header(HEADER_X_APP_NAME, AUTH_PROVIDER)
322 .match_header("authorization", format!("Bearer {}", TOKEN.as_str()).as_str())
323 .with_status(202)
324 .with_header("content-type", "application/json")
325 .match_body(Matcher::Exact(req))
326 .expect(1)
327 .create(),
328 );
329 }
330 Err(error) => {
331 handle_error_test_cases(error, &mut sdk, 0, 0).await;
332 }
333 }
334
335 let response = sdk.update_kyc_status_for_postident(CASE_ID).await;
337
338 match expected {
340 Ok(_) => response.unwrap(),
341 Err(ref err) => {
342 assert_eq!(response.unwrap_err().to_string(), err.to_string());
343 }
344 }
345 if let Some(m) = mock_server {
346 m.assert();
347 }
348 }
349}