diff --git a/.gitignore b/.gitignore index 4fffb2f..48d5723 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +.env /target /Cargo.lock diff --git a/Cargo.toml b/Cargo.toml index c2452b8..ae04370 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,4 +21,5 @@ serde = { version = "1.0.152", features = ["derive"] } serde_json = "1.0.91" [dev-dependencies] +dotenv = "0.15.0" tokio = { version = "1.28.1", features = ["macros"] } diff --git a/src/lib.rs b/src/lib.rs index 1ede266..d07fd6e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -368,48 +368,6 @@ impl Databases { } } -#[cfg(test)] -mod tests { - use super::*; - - #[tokio::test] - async fn check_database_query() { - let databases = Client::new() - .api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud") - .build() - .search::(SearchOptions { - filter: Some(json!( - { - "value": "database", - "property": "object" - } - )), - query: None, - page_size: None, - sort: None, - start_cursor: None, - }) - .await; - - println!("{databases:#?}"); - } - - #[tokio::test] - async fn test_blocks() { - let blocks = Client::new() - .api_key("secret_FuhJkAoOVZlk8YUT9ZOeYqWBRRZN6OMISJwhb4dTnud") - .build() - .blocks - .children() - .list(BlockChildrenListOptions { - block_id: "0d253ab0f751443aafb9bcec14012897", - }) - .await; - - println!("{blocks:#?}") - } -} - #[derive(Debug, Default)] pub struct DatabaseQueryOptions<'a> { pub database_id: &'a str, @@ -1211,10 +1169,20 @@ where ( key.to_owned(), serde_json::from_value::(value.to_owned()).unwrap_or_else(|error| { - log::warn!( - "Could not parse value because of error, defaulting to Property::Unsupported:\n= ERROR:\n{error:#?}\n= JSON:\n{}\n---", - serde_json::to_string_pretty(&value).unwrap() - ); + println!("GOT HERE????"); + match value.get("type") { + Some(Value::String(kind)) => match kind.as_ref() { + "multi_select" => println!("found multi_select!"), + _ => {} + }, + Some(_) | None => { + log::warn!( + "Could not parse value because of error, defaulting to Property::Unsupported:\n= ERROR:\n{error:#?}\n= JSON:\n{}\n---", + serde_json::to_string_pretty(&value).unwrap() + ); + } + } + Property::Unsupported(value.to_owned()) }), ) @@ -1473,3 +1441,114 @@ pub enum DatabaseFormulaType { Number, String, } + +#[cfg(test)] +mod tests { + use super::*; + + fn get_key() -> String { + let _ = dotenv::dotenv(); + std::env::var("NOTION_API_KEY").unwrap() + } + + #[tokio::test] + async fn check_database_query() { + let databases = Client::new() + .api_key(&get_key()) + .build() + .search::(SearchOptions { + filter: Some(json!( + { + "value": "database", + "property": "object" + } + )), + query: None, + page_size: None, + sort: None, + start_cursor: None, + }) + .await; + + println!("{databases:#?}"); + } + + #[tokio::test] + async fn test_blocks() { + let blocks = Client::new() + .api_key(&get_key()) + .build() + .blocks + .children() + .list(BlockChildrenListOptions { + block_id: "0d253ab0f751443aafb9bcec14012897", + }) + .await; + + println!("{blocks:#?}") + } + + #[test] + fn parse_json_1() { + let data = r#" + { + "id": "FzYl", + "name": "Currently with", + "select": { + "options": [ + { + "color": "default", + "description": null, + "id": "nT[N", + "name": "Someone else" + }, + { + "color": "red", + "description": null, + "id": "fgu_", + "name": "Me" + } + ] + }, + "type": "select" + }"#; + + serde_json::from_str::(data).unwrap(); + } + + // TODO: write test using https://stackoverflow.com/a/75979520 + #[test] + fn parse_json_multi_select_failed_because_of_map_instead_of_sequence() { + let data = r#" + { + "id": "pvSs", + "multi_select": { + "options": [ + { + "color": "orange", + "description": null, + "id": "|FMC", + "name": "Loan" + }, + { + "color": "green", + "description": null, + "id": "\\Iu\\", + "name": "Checking " + }, + { + "color": "blue", + "description": null, + "id": "q]rZ", + "name": "Credit" + } + ] + }, + "name": "Type", + "type": "multi_select" + } + "#; + + serde_json::from_str::(data).unwrap(); + } +} diff --git a/unit-testable-json.txt b/unit-testable-json.txt new file mode 100644 index 0000000..31aa132 --- /dev/null +++ b/unit-testable-json.txt @@ -0,0 +1,464 @@ +{ + "id": "FzYl", + "name": "Currently with", + "select": { + "options": [ + { + "color": "default", + "description": null, + "id": "nT[N", + "name": "Someone else" + }, + { + "color": "red", + "description": null, + "id": "fgu_", + "name": "Me" + } + ] + }, + "type": "select" +} +--- +{ + "files": null, + "id": "KTSO", + "name": "Files & media", + "type": "files" +} +--- +{ + "id": "CEPX", + "name": "Focus", + "select": { + "options": [ + { + "color": "orange", + "description": null, + "id": "J^N_", + "name": "Web Dev" + }, + { + "color": "purple", + "description": null, + "id": "}xYt", + "name": "Work" + }, + { + "color": "blue", + "description": null, + "id": ";u]:", + "name": "UK" + }, + { + "color": "yellow", + "description": null, + "id": "d{Rl", + "name": "US" + } + ] + }, + "name": "Location", + "type": "multi_select" +} +--- +{ + "id": "%7CMD%3B", + "multi_select": { + "options": [ + { + "color": "pink", + "description": null, + "id": "gks?", + "name": "Yes" + }, + { + "color": "default", + "description": null, + "id": "moPz", + "name": "No" + } + ] + }, + "name": "Subscriptions?", + "type": "multi_select" +} +--- +{ + "id": "pvSs", + "multi_select": { + "options": [ + { + "color": "orange", + "description": null, + "id": "|FMC", + "name": "Loan" + }, + { + "color": "green", + "description": null, + "id": "\\Iu\\", + "name": "Checking " + }, + { + "color": "blue", + "description": null, + "id": "q]rZ", + "name": "Credit" + } + ] + }, + "name": "Type", + "type": "multi_select" +} +--- +{ + "id": "yDni", + "multi_select": { + "options": [ + { + "color": "blue", + "description": null, + "id": "a8225f34-713e-48da-92d6-f372a814f048", + "name": "Onboarding" + }, + { + "color": "green", + "description": null, + "id": "7f2c6dcf-6c6a-4b9d-8e11-d2966b670bf5", + "name": "Design" + } + ] + }, + "name": "Tags", + "type": "multi_select" +} +--- +{ + "id": "H%7D%3BY", + "last_edited_time": null, + "name": "上次编辑时间", + "type": "last_edited_time" +} +--- +{ + "created_time": null, + "id": "notion%3A%2F%2Fmeetings%2Fcreated_time_property", + "name": "Created time", + "type": "created_time" +} +--- +{ + "id": "notion%3A%2F%2Fmeetings%2Flast_edited_time_property", + "last_edited_time": null, + "name": "Last edited time", + "type": "last_edited_time" +} +--- +{ + "created_time": null, + "id": "notion%3A%2F%2Fmeetings%2Fcreated_time_property", + "name": "Created time", + "type": "created_time" +} +--- +{ + "id": "notion%3A%2F%2Fmeetings%2Flast_edited_time_property", + "last_edited_time": null, + "name": "Last edited time", + "type": "last_edited_time" +} +--- +{ + "id": "notion%3A%2F%2Fmeetings%2Fmeeting_type_property", + "name": "Type", + "select": { + "options": [ + { + "color": "yellow", + "description": null, + "id": "standup", + "name": "Standup" + }, + { + "color": "blue", + "description": null, + "id": "brainstorm", + "name": "Brainstorm" + }, + { + "color": "green", + "description": null, + "id": "team_weekly", + "name": "Team weekly" + }, + { + "color": "pink", + "description": null, + "id": "training", + "name": "Training" + } + ] + }, + "type": "select" +} +--- +{ + "id": "notion%3A%2F%2Ftasks%2Fpriority_property", + "name": "Priority", + "select": { + "options": [ + { + "color": "green", + "description": null, + "id": "priority_low", + "name": "Low" + }, + { + "color": "yellow", + "description": null, + "id": "priority_medium", + "name": "Medium" + }, + { + "color": "red", + "description": null, + "id": "priority_high", + "name": "High" + } + ] + }, + "type": "select" +} +--- +{ + "id": "notion%3A%2F%2Ftasks%2Ftags_property", + "multi_select": { + "options": [ + { + "color": "purple", + "description": null, + "id": "Mobile", + "name": "Mobile" + }, + { + "color": "blue", + "description": null, + "id": "Website", + "name": "Website" + }, + { + "color": "pink", + "description": null, + "id": "Improvement", + "name": "Improvement" + } + ] + }, + "name": "Tags", + "type": "multi_select" +} +--- +{ + "id": "rWCq", + "name": "Address", + "rich_text": null, + "type": "rich_text" +} +--- +{ + "id": "jhSN", + "name": "Category", + "select": { + "options": [ + { + "color": "pink", + "description": null, + "id": "f7672afb-be22-44e8-b01e-76b3edaaa0b2", + "name": "Healing (Social & Emotional Wellbeing) ✨" + }, + { + "color": "pink", + "description": null, + "id": "yyXf", + "name": "Personal" + }, + { + "color": "pink", + "description": null, + "id": "fee9b2a6-4bb0-4064-b328-23cbf9b7fbc9", + "name": "Medication" + }, + { + "color": "pink", + "description": null, + "id": "4cb37ac5-8182-4948-b4a9-a43c3f7b44bd", + "name": "Physical Healing ✨" + }, + { + "color": "purple", + "description": null, + "id": "kAOz", + "name": "Work" + }, + { + "color": "purple", + "description": null, + "id": "BL[V", + "name": "Home" + }, + { + "color": "purple", + "description": null, + "id": "48ad8f71-98f5-463c-a057-cb72ce1c47f1", + "name": "Car" + }, + { + "color": "blue", + "description": null, + "id": "