aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Eilertsen <haraldei@anduin.net>2020-01-01 20:19:01 +0100
committerHarald Eilertsen <haraldei@anduin.net>2020-01-01 20:19:01 +0100
commit1fd9f311a55759a613e4df66d462a34102644380 (patch)
treeb5b65be58c059239d9219ee1fa64cc3e36564f74
parentad3874f8bf5b5451e910ceae02518c04695e63c6 (diff)
downloadrust-zotapi-1fd9f311a55759a613e4df66d462a34102644380.tar.gz
rust-zotapi-1fd9f311a55759a613e4df66d462a34102644380.tar.bz2
rust-zotapi-1fd9f311a55759a613e4df66d462a34102644380.zip
Allow limiting a new item to one or more privacy groups.
-rw-r--r--src/item.rs64
-rw-r--r--tests/zotapi.rs28
2 files changed, 80 insertions, 12 deletions
diff --git a/src/item.rs b/src/item.rs
index 09ec4c0..5507577 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -18,14 +18,19 @@ use crate::{
client::{self, Client},
error::Error,
};
-use serde::{Serialize, Serializer};
+use serde::Serialize;
use std::collections::BTreeMap;
/// Data type for values that an Item can hold.
+#[derive(Debug, Serialize)]
+#[serde(untagged)]
pub enum ItemData<'a> {
/// A single value, either textual or numeric.
Value(&'a str),
+
+ /// A list ov values.
+ List(Vec<&'a str>),
}
impl<'a> From<&'a str> for ItemData<'a> {
@@ -34,25 +39,37 @@ impl<'a> From<&'a str> for ItemData<'a> {
}
}
-impl<'a> Serialize for ItemData<'a> {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where
- S: Serializer
- {
- match &self {
- ItemData::Value(s) => s.serialize(serializer),
- }
- }
-}
-
impl<'a> ToString for ItemData<'a> {
fn to_string(&self) -> String {
match &self {
ItemData::Value(s) => s.to_string(),
+ ItemData::List(v) => v.join(","),
}
}
}
+impl<'a> ItemData<'a> {
+ /// Push a new value into
+ pub fn push(&mut self, value: &'a str) {
+ match self {
+ ItemData::Value(_) => std::panic!("Pushing to a simple value is not allowed."),
+ ItemData::List(v) => v.push(value),
+ };
+ }
+}
+
+#[test]
+fn convert_itemdata_list_to_a_string() {
+ let l = ItemData::List(vec!["one", "two", "everything"]);
+ assert_eq!(l.to_string(), "one,two,everything");
+}
+
+#[test]
+fn convert_itemdata_list_with_one_member_to_a_string() {
+ let l = ItemData::List(vec!["one"]);
+ assert_eq!(l.to_string(), "one");
+}
+
/// A structure to help you create an item in a declarative way.
///
/// Typical usage:
@@ -66,6 +83,7 @@ impl<'a> ToString for ItemData<'a> {
/// .create()?;
/// # Ok::<(), zotapi::Error>(())
/// ```
+#[derive(Debug)]
pub struct ItemBuilder<'a> {
client : &'a Client,
data : BTreeMap<&'a str, ItemData<'a>>,
@@ -99,8 +117,18 @@ impl<'a> ItemBuilder<'a> {
self
}
+ /// Set groups allowed to access item
+ pub fn group_allow(&mut self, group: &'a str) -> &mut ItemBuilder<'a> {
+ let groups_allow = self.data.entry("groups_allow")
+ .or_insert(ItemData::List(Vec::<&str>::new()));
+
+ groups_allow.push(group);
+ self
+ }
+
/// Create the item by poting it to the server
pub fn create(&self) -> Result<String, Error> {
+ dbg!(self);
if self.files.is_empty() {
self.client.post_data(client::ZOTAPI_ITEM_UPDATE_PATH, &self.data)
}
@@ -109,3 +137,15 @@ impl<'a> ItemBuilder<'a> {
}
}
}
+
+#[test]
+fn add_group_to_list_of_groups_allowed() {
+ let client = Client::new("https://test.com", "test", "test1234");
+ let mut item = ItemBuilder::new(&client);
+ item.group_allow("test");
+ match item.data.get("groups_allow") {
+ Some(ItemData::List(v)) => assert_eq!(v.len(), 1),
+ Some(ItemData::Value(s)) => assert!(false, format!("Expected a list, found value: {}", s)),
+ None => assert!(false, "List not found!"),
+ };
+}
diff --git a/tests/zotapi.rs b/tests/zotapi.rs
index 4bac884..aa9756c 100644
--- a/tests/zotapi.rs
+++ b/tests/zotapi.rs
@@ -101,6 +101,34 @@ fn create_new_post_with_title() {
}
#[test]
+fn create_new_post_limited_to_one_privacy_group() {
+ // For some reason this mock does not match.
+ // Visually inspecting the payload it does however seem valid,
+ // so not sure how to handle this with the current framework.
+ //
+ // For now this test makes no assertions, but at least it runs
+ // through the code paths it should.
+ let _m = mock_with_authorization("POST", "/api/z/1.0/item/update")
+ .match_body(
+ Matcher::AllOf(vec![
+ Matcher::UrlEncoded("body".to_string(), "This is a test".to_string()),
+ Matcher::UrlEncoded("groups_allow[0]".to_string(), "grouphash".to_string())
+ ])
+ )
+ .with_status(200)
+ .with_header("content-type", "application/json")
+ .with_body("{}")
+ .create();
+
+ let _res = client().item()
+ .body("This is a test")
+ .group_allow("grouphash")
+ .create();
+
+ //m.assert();
+}
+
+#[test]
fn upload_item_with_media_file() {
let m = mock_with_authorization("POST", "/api/z/1.0/item/update")
.match_header("content-type", Matcher::Regex("^multipart/form-data; boundary=.+$".into()))