feat(trello): add basics of trello config model
This commit is contained in:
parent
de94004be3
commit
c8f9780226
8 changed files with 190 additions and 155 deletions
|
@ -1,32 +1,32 @@
|
|||
//
|
||||
// use kxio::net::Response;
|
||||
//
|
||||
// use crate::{e, s};
|
||||
use kxio::net::Response;
|
||||
|
||||
// pub struct APIResult<T> {
|
||||
// pub text: String,
|
||||
// pub result: Result<T, kxio::net::Error>,
|
||||
// }
|
||||
use crate::{e, s};
|
||||
|
||||
// impl<T: for<'a> serde::Deserialize<'a>> APIResult<T> {
|
||||
// pub async fn new(response: kxio::net::Result<Response>) -> Self {
|
||||
// match response {
|
||||
// Ok(response) => {
|
||||
// let text = response.text().await.unwrap_or_default();
|
||||
// let text = if text.is_empty() { s!("null") } else { text };
|
||||
// let result = serde_json::from_str::<T>(&text)
|
||||
// .map_err(|e| e.to_string())
|
||||
// .map_err(|e| {
|
||||
// e!("{e}: {text}");
|
||||
// e
|
||||
// })
|
||||
// .map_err(kxio::net::Error::from);
|
||||
// Self { text, result }
|
||||
// }
|
||||
// Err(e) => Self {
|
||||
// text: s!(""),
|
||||
// result: Err(e),
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
pub struct APIResult<T> {
|
||||
pub text: String,
|
||||
pub result: Result<T, kxio::net::Error>,
|
||||
}
|
||||
|
||||
impl<T: for<'a> serde::Deserialize<'a>> APIResult<T> {
|
||||
pub async fn new(response: kxio::net::Result<Response>) -> Self {
|
||||
match response {
|
||||
Ok(response) => {
|
||||
let text = response.text().await.unwrap_or_default();
|
||||
let text = if text.is_empty() { s!("null") } else { text };
|
||||
let result = serde_json::from_str::<T>(&text)
|
||||
.map_err(|e| e.to_string())
|
||||
.map_err(|e| {
|
||||
e!("{e}: {text}");
|
||||
e
|
||||
})
|
||||
.map_err(kxio::net::Error::from);
|
||||
Self { text, result }
|
||||
}
|
||||
Err(e) => Self {
|
||||
text: s!(""),
|
||||
result: Err(e),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,13 @@ use color_eyre::Result;
|
|||
|
||||
use crate::{f, s, Ctx, NAME};
|
||||
|
||||
#[derive(Clone, Debug, derive_more::From, PartialEq, Eq, PartialOrd, Ord, serde::Deserialize)]
|
||||
pub struct TrelloConfig {
|
||||
pub api_key: String,
|
||||
pub api_secret: String,
|
||||
pub board_name: String,
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Clone,
|
||||
Debug,
|
||||
|
@ -14,7 +21,9 @@ use crate::{f, s, Ctx, NAME};
|
|||
derive_more::AsRef,
|
||||
serde::Deserialize,
|
||||
)]
|
||||
pub struct AppConfig {}
|
||||
pub struct AppConfig {
|
||||
pub trello: TrelloConfig,
|
||||
}
|
||||
impl AppConfig {
|
||||
pub fn load(ctx: &Ctx) -> Result<Self> {
|
||||
let file = ctx.fs.base().join(f!("{NAME}.toml"));
|
||||
|
|
|
@ -4,12 +4,12 @@ use std::path::PathBuf;
|
|||
use clap::Parser;
|
||||
use kxio::{fs::FileSystem, net::Net};
|
||||
|
||||
mod api_result;
|
||||
// mod api_result;
|
||||
mod config;
|
||||
mod init;
|
||||
mod macros;
|
||||
mod template;
|
||||
mod trello;
|
||||
// mod trello;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
|
|
@ -9,19 +9,41 @@ use crate::{config::AppConfig, f, NAME};
|
|||
mod config {
|
||||
use super::*;
|
||||
|
||||
use crate::config::TrelloConfig;
|
||||
use crate::s;
|
||||
|
||||
#[test]
|
||||
fn load_config() {
|
||||
//given
|
||||
let fs = given::a_filesystem();
|
||||
let file = fs.base().join(f!("{}.toml", NAME));
|
||||
fs.file(&file).write("").expect("write file");
|
||||
fs.file(&file)
|
||||
.write(
|
||||
[
|
||||
"[trello]",
|
||||
"api_key = \"trello-api-key\"",
|
||||
"api_secret = \"trello-api-secret\"",
|
||||
"board_name = \"trello-board-name\"",
|
||||
]
|
||||
.join("\n"),
|
||||
)
|
||||
.expect("write file");
|
||||
let ctx = given::a_context(fs.as_real(), given::a_network().into());
|
||||
|
||||
//when
|
||||
let_assert!(Ok(config) = AppConfig::load(&ctx));
|
||||
|
||||
//then
|
||||
assert_eq!(config, AppConfig {});
|
||||
assert_eq!(
|
||||
config,
|
||||
AppConfig {
|
||||
trello: TrelloConfig {
|
||||
api_key: s!("trello-api-key"),
|
||||
api_secret: s!("trello-api-secret"),
|
||||
board_name: s!("trello-board-name"),
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,54 +1,54 @@
|
|||
//
|
||||
// use kxio::net::Net;
|
||||
use kxio::net::Net;
|
||||
|
||||
// use crate::api_result::APIResult;
|
||||
// use crate::{
|
||||
// f,
|
||||
// trello::{
|
||||
// types::{TrelloAuth, board::TrelloBoard},
|
||||
// url,
|
||||
// },
|
||||
// };
|
||||
//
|
||||
// /// Get lists from named board that Member belongs to
|
||||
// ///
|
||||
// /// Get Boards that Member belongs to
|
||||
// /// https://developer.atlassian.com/cloud/trello/rest/api-group-members/#api-members-id-boards-get
|
||||
// /// /members/{id}/boards
|
||||
// ///
|
||||
// /// Lists the boards that the user is a member of.
|
||||
// ///
|
||||
// /// Request
|
||||
// ///
|
||||
// /// Path parameters
|
||||
// ///
|
||||
// /// - id TrelloID REQUIRED
|
||||
// ///
|
||||
// ///
|
||||
// /// Query parameters
|
||||
// ///
|
||||
// /// - fields string
|
||||
// /// Default: all
|
||||
// /// Valid values: id, name, desc, descData, closed, idMemberCreator, idOrganization, pinned, url, shortUrl, prefs, labelNames, starred, limits, memberships, enterpriseOwned
|
||||
// ///
|
||||
// /// - lists string
|
||||
// /// Which lists to include with the boards. One of: all, closed, none, open
|
||||
// /// Default: none
|
||||
// /// Valid values: all, closed, none, open
|
||||
// ///
|
||||
// /// curl --request GET \
|
||||
// /// --url "https://api.trello.com/1/members/$TRELLO_USERNAME/boards?key=$TRELLO_KEY&token=$TRELLO_SECRET&lists=open" \
|
||||
// /// --header 'Accept: application/json'
|
||||
// pub async fn get_boards_that_member_belongs_to(
|
||||
// auth: &TrelloAuth,
|
||||
// net: &Net,
|
||||
// ) -> APIResult<Vec<TrelloBoard>> {
|
||||
// APIResult::new(
|
||||
// net.get(url(f!("/members/{}/boards?lists=open", **auth.user())))
|
||||
// .headers(auth.into())
|
||||
// .header("Accept", "application/json")
|
||||
// .send()
|
||||
// .await,
|
||||
// )
|
||||
// .await
|
||||
// }
|
||||
use crate::api_result::APIResult;
|
||||
use crate::{
|
||||
f,
|
||||
trello::{
|
||||
types::{auth::TrelloAuth, board::TrelloBoard},
|
||||
url,
|
||||
},
|
||||
};
|
||||
|
||||
/// Get lists from named board that Member belongs to
|
||||
///
|
||||
/// Get Boards that Member belongs to
|
||||
/// https://developer.atlassian.com/cloud/trello/rest/api-group-members/#api-members-id-boards-get
|
||||
/// /members/{id}/boards
|
||||
///
|
||||
/// Lists the boards that the user is a member of.
|
||||
///
|
||||
/// Request
|
||||
///
|
||||
/// Path parameters
|
||||
///
|
||||
/// - id TrelloID REQUIRED
|
||||
///
|
||||
///
|
||||
/// Query parameters
|
||||
///
|
||||
/// - fields string
|
||||
/// Default: all
|
||||
/// Valid values: id, name, desc, descData, closed, idMemberCreator, idOrganization, pinned, url, shortUrl, prefs, labelNames, starred, limits, memberships, enterpriseOwned
|
||||
///
|
||||
/// - lists string
|
||||
/// Which lists to include with the boards. One of: all, closed, none, open
|
||||
/// Default: none
|
||||
/// Valid values: all, closed, none, open
|
||||
///
|
||||
/// curl --request GET \
|
||||
/// --url "https://api.trello.com/1/members/$TRELLO_USERNAME/boards?key=$TRELLO_KEY&token=$TRELLO_SECRET&lists=open" \
|
||||
/// --header 'Accept: application/json'
|
||||
pub async fn get_boards_that_member_belongs_to(
|
||||
auth: &TrelloAuth,
|
||||
net: &Net,
|
||||
) -> APIResult<Vec<TrelloBoard>> {
|
||||
APIResult::new(
|
||||
net.get(url(f!("/members/{}/boards?lists=open", **auth.user())))
|
||||
.headers(auth.into())
|
||||
.header("Accept", "application/json")
|
||||
.send()
|
||||
.await,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
// use kxio::net::MockNet;
|
||||
//
|
||||
use kxio::net::MockNet;
|
||||
|
||||
// use crate::trello::types::auth::{TrelloApiKey, TrelloApiSecret, TrelloAuth, TrelloUser};
|
||||
use crate::trello::types::auth::{TrelloApiKey, TrelloApiSecret, TrelloAuth, TrelloUser};
|
||||
|
||||
// pub(crate) fn a_network() -> MockNet {
|
||||
// kxio::net::mock()
|
||||
// }
|
||||
pub(crate) fn a_network() -> MockNet {
|
||||
kxio::net::mock()
|
||||
}
|
||||
|
||||
// pub(crate) fn an_auth() -> TrelloAuth {
|
||||
// TrelloAuth::new(
|
||||
// TrelloApiKey::new("foo"),
|
||||
// TrelloApiSecret::new("bar"),
|
||||
// TrelloUser::new("baz"),
|
||||
// )
|
||||
// }
|
||||
pub(crate) fn an_auth() -> TrelloAuth {
|
||||
TrelloAuth::new(
|
||||
TrelloApiKey::new("foo"),
|
||||
TrelloApiSecret::new("bar"),
|
||||
TrelloUser::new("baz"),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,59 +1,62 @@
|
|||
// use super::*;
|
||||
|
||||
use super::*;
|
||||
mod given;
|
||||
|
||||
// type TestResult = color_eyre::Result<()>;
|
||||
type TestResult = color_eyre::Result<()>;
|
||||
|
||||
mod members {
|
||||
|
||||
// use std::collections::HashMap;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// use kxio::net::StatusCode;
|
||||
// use serde_json::json;
|
||||
use kxio::net::StatusCode;
|
||||
use serde_json::json;
|
||||
|
||||
// use crate::{
|
||||
// s,
|
||||
// trello::{
|
||||
// // api::members::get_boards_that_member_belongs_to,
|
||||
// types::{board::TrelloBoard, TrelloBoardId, TrelloBoardName},
|
||||
// },
|
||||
// };
|
||||
use crate::{
|
||||
s,
|
||||
trello::{
|
||||
api::members::get_boards_that_member_belongs_to,
|
||||
types::{board::TrelloBoard, TrelloBoardId, TrelloBoardName},
|
||||
},
|
||||
};
|
||||
|
||||
// use super::*;
|
||||
//
|
||||
// #[tokio::test]
|
||||
// async fn get_member_boards() -> TestResult {
|
||||
// //given
|
||||
// let net = given::a_network();
|
||||
// let auth = given::an_auth();
|
||||
//
|
||||
// net.on()
|
||||
// .get("https://api.trello.com/1/members/baz/boards?lists=open")
|
||||
// .headers(HashMap::from([
|
||||
// (
|
||||
// s!("authorization"),
|
||||
// s!("OAuth oauth_consumer_key=\"foo\", oauth_token=\"bar\""),
|
||||
// ),
|
||||
// (s!("accept"), s!("application/json")),
|
||||
// ]))
|
||||
// .respond(StatusCode::OK)
|
||||
// .body(s!(json!([
|
||||
// {"id": "1", "name": "board-1", "lists":[]}
|
||||
// ])))?;
|
||||
//
|
||||
// //when
|
||||
// let result = get_boards_that_member_belongs_to(&auth, &net.into()).await;
|
||||
//
|
||||
// assert_eq!(
|
||||
// result.result?,
|
||||
// vec![TrelloBoard::new(
|
||||
// TrelloBoardId::new("1"),
|
||||
// TrelloBoardName::new("board-1"),
|
||||
// vec![]
|
||||
// )]
|
||||
// );
|
||||
//
|
||||
// //then
|
||||
// Ok(())
|
||||
// }
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn get_member_boards() -> TestResult {
|
||||
//given
|
||||
let net = given::a_network();
|
||||
let auth = given::an_auth();
|
||||
|
||||
net.on()
|
||||
.get("https://api.trello.com/1/members/baz/boards?lists=open")
|
||||
.headers(HashMap::from([
|
||||
(
|
||||
s!("authorization"),
|
||||
s!("OAuth oauth_consumer_key=\"foo\", oauth_token=\"bar\""),
|
||||
),
|
||||
(s!("accept"), s!("application/json")),
|
||||
]))
|
||||
.respond(StatusCode::OK)
|
||||
.body(s!(json!([
|
||||
{"id": "1", "name": "board-1", "lists":[]}
|
||||
])))?;
|
||||
|
||||
//when
|
||||
let result = get_boards_that_member_belongs_to(&auth, &net.into())
|
||||
.await
|
||||
.result?;
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
vec![TrelloBoard::new(
|
||||
TrelloBoardId::new("1"),
|
||||
TrelloBoardName::new("board-1"),
|
||||
vec![]
|
||||
)]
|
||||
);
|
||||
|
||||
//then
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,10 +5,10 @@ pub mod types;
|
|||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
// use crate::f;
|
||||
use crate::f;
|
||||
|
||||
// pub fn url(path: impl Into<String>) -> String {
|
||||
// let path = path.into();
|
||||
// assert!(path.starts_with("/"));
|
||||
// f!("https://api.trello.com/1{path}")
|
||||
// }
|
||||
pub fn url(path: impl Into<String>) -> String {
|
||||
let path = path.into();
|
||||
assert!(path.starts_with("/"));
|
||||
f!("https://api.trello.com/1{path}")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue