mod detail;
use std::io;
use mockall_double::double;
use crate::cli::detail::CliConfig;
#[double]
use crate::cli::detail::helpers;
use crate::core::{Credentials, Error, Result};
pub fn get_cli_credentials() -> Result<Credentials> {
let mut config_file_path = helpers::get_cli_config_dir()
.ok_or_else(|| io::Error::from(io::ErrorKind::NotFound))
.or_else(|_| helpers::current_dir())?;
config_file_path.push("user.json");
match helpers::read_to_string(&config_file_path) {
Ok(config) => {
let config = CliConfig::from_string(config.as_str())?;
Ok(Credentials::from_api_token(config.api_token))
},
Err(err) if err.kind() == io::ErrorKind::NotFound => Err(Error::ConfigNotFound),
Err(err) => Err(Error::from(err)),
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
mod get_cli_credentials {
use std::env;
use std::path::PathBuf;
use assert_matches::assert_matches;
use mockall::predicate::eq;
use serial_test::serial;
use super::*;
#[test]
#[serial(cli_rs_get_cli_credentials)]
fn test_valid() {
let expected_config_dir = "/some/config/dir".into();
let gccd_ctx = helpers::get_cli_config_dir_context();
gccd_ctx
.expect()
.return_once(move || Some(expected_config_dir));
let expected_config_path: PathBuf = ["/some/config/dir", "user.json"].iter().collect();
let expected_json_file = "{\"token\": \"some_token\"}".into();
let rts_ctx = helpers::read_to_string_context();
rts_ctx
.expect()
.with(eq(expected_config_path))
.return_once(move |_| Ok(expected_json_file));
assert_matches!(get_cli_credentials(),
Ok(creds) if creds == Credentials::from_api_token("some_token"));
}
#[test]
#[serial(cli_rs_get_cli_credentials)]
fn test_no_config_dir() {
let gccd_ctx = helpers::get_cli_config_dir_context();
gccd_ctx.expect().return_once(|| None);
let cd_ctx = helpers::current_dir_context();
cd_ctx.expect().return_once(env::current_dir);
let expected_config_path: PathBuf = [env::current_dir().unwrap(), "user.json".into()]
.iter()
.collect();
let expected_json_file = "{\"token\": \"some_token\"}".into();
let rts_ctx = helpers::read_to_string_context();
rts_ctx
.expect()
.with(eq(expected_config_path))
.return_once(move |_| Ok(expected_json_file));
assert_matches!(get_cli_credentials(),
Ok(creds) if creds == Credentials::from_api_token("some_token"));
}
#[test]
#[serial(cli_rs_get_cli_credentials)]
fn test_config_dir_error() {
let gccd_ctx = helpers::get_cli_config_dir_context();
gccd_ctx.expect().return_once(|| None);
let cd_ctx = helpers::current_dir_context();
cd_ctx
.expect()
.return_once(|| Err(io::Error::from(io::ErrorKind::NotFound)));
let actual = get_cli_credentials();
assert_matches!(
actual,
Err(Error::ConfigReadError(io_err)) if io_err.kind() == io::ErrorKind::NotFound
);
}
#[test]
#[serial(cli_rs_get_cli_credentials)]
fn test_invalid_config() {
let expected_config_dir = "/some/config/dir".into();
let gccd_ctx = helpers::get_cli_config_dir_context();
gccd_ctx
.expect()
.return_once(move || Some(expected_config_dir));
let expected_config_path: PathBuf = ["/some/config/dir", "user.json"].iter().collect();
let expected_json_file = "{invalid: json}".into();
let rts_ctx = helpers::read_to_string_context();
rts_ctx
.expect()
.with(eq(expected_config_path))
.return_once(move |_| Ok(expected_json_file));
assert_matches!(get_cli_credentials(),
Err(Error::ConfigParseError(json_error)) if json_error.is_syntax());
}
#[test]
#[serial(cli_rs_get_cli_credentials)]
fn test_config_file_not_found() {
let expected_config_dir = "/some/config/dir".into();
let gccd_ctx = helpers::get_cli_config_dir_context();
gccd_ctx
.expect()
.return_once(move || Some(expected_config_dir));
let expected_config_path: PathBuf = ["/some/config/dir", "user.json"].iter().collect();
let rts_ctx = helpers::read_to_string_context();
rts_ctx
.expect()
.with(eq(expected_config_path))
.return_once(|_| Err(io::Error::from(io::ErrorKind::NotFound)));
assert_matches!(get_cli_credentials(), Err(Error::ConfigNotFound));
}
#[test]
#[serial(cli_rs_get_cli_credentials)]
fn test_config_file_inaccessible() {
let expected_config_dir = "/some/config/dir".into();
let gccd_ctx = helpers::get_cli_config_dir_context();
gccd_ctx
.expect()
.return_once(move || Some(expected_config_dir));
let expected_config_path: PathBuf = ["/some/config/dir", "user.json"].iter().collect();
let rts_ctx = helpers::read_to_string_context();
rts_ctx
.expect()
.with(eq(expected_config_path))
.return_once(|_| Err(io::Error::from(io::ErrorKind::PermissionDenied)));
assert_matches!(get_cli_credentials(),
Err(Error::ConfigReadError(io_error)) if io_error.kind() == io::ErrorKind::PermissionDenied);
}
}
}