oparl_types/
membership.rs

1// SPDX-FileCopyrightText: Politik im Blick developers
2// SPDX-FileCopyrightText: Wolfgang Silbermayr <wolfgang@silbermayr.at>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later OR EUPL-1.2
5
6use url::Url;
7
8use crate::{
9    date::Date, namespace::MembershipNamespaceUrl, DateTime, Keyword, MembershipId, OrganizationId,
10    PersonId,
11};
12
13#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
14#[serde(rename_all = "camelCase")]
15pub struct Membership {
16    pub id: MembershipId,
17
18    #[serde(rename = "type")]
19    pub namespace: MembershipNamespaceUrl,
20
21    #[serde(default, skip_serializing_if = "Option::is_none")]
22    pub person: Option<PersonId>,
23
24    #[serde(default, skip_serializing_if = "Option::is_none")]
25    pub organization: Option<OrganizationId>,
26
27    #[serde(default, skip_serializing_if = "Option::is_none")]
28    pub role: Option<String>,
29
30    #[serde(default, skip_serializing_if = "Option::is_none")]
31    pub voting_right: Option<bool>,
32
33    #[serde(default, skip_serializing_if = "Option::is_none")]
34    pub start_date: Option<Date>,
35
36    #[serde(default, skip_serializing_if = "Option::is_none")]
37    pub end_date: Option<Date>,
38
39    #[serde(default, skip_serializing_if = "Option::is_none")]
40    pub on_behalf_of: Option<OrganizationId>,
41
42    #[serde(default, skip_serializing_if = "Option::is_none")]
43    pub license: Option<Url>,
44
45    #[serde(default, skip_serializing_if = "Vec::is_empty")]
46    pub keyword: Vec<Keyword>,
47
48    pub created: DateTime,
49
50    pub modified: DateTime,
51
52    #[serde(default, skip_serializing_if = "Option::is_none")]
53    pub web: Option<Url>,
54
55    #[serde(default, skip_serializing_if = "Option::is_none")]
56    pub deleted: Option<bool>,
57}
58
59#[cfg(test)]
60mod serde_tests {
61    use super::Membership;
62    use crate::namespace::MembershipNamespaceUrl;
63
64    use pretty_assertions::assert_eq;
65    use serde_json::json;
66    use time::macros::{date, datetime};
67
68    fn example_membership() -> Membership {
69        Membership {
70            id: "https://oparl.example.org/memberships/385"
71                .parse()
72                .expect("value must be parseable as id"),
73            namespace: MembershipNamespaceUrl::Identifier,
74            person: Some(
75                "https://oparl.example.org/person/29"
76                    .parse()
77                    .expect("value must be parseable as url"),
78            ),
79            organization: Some(
80                "https://oparl.example.org/organizations/5"
81                    .parse()
82                    .expect("value must be parseable as url"),
83            ),
84            role: Some("Vorsitzende".into()),
85            voting_right: Some(true),
86            start_date: Some(date!(2013 - 12 - 03).into()),
87            end_date: None,
88            on_behalf_of: None,
89            license: None,
90            keyword: vec![],
91            created: datetime!(2011-11-11 11:11:00 +01:00).into(),
92            modified: datetime!(2012-08-16 14:05:27 +02:00).into(),
93            web: None,
94            deleted: None,
95        }
96    }
97
98    fn example_membership_json() -> serde_json::Value {
99        json!({
100            "id": "https://oparl.example.org/memberships/385",
101            "type": "https://schema.oparl.org/1.1/Membership",
102            "person": "https://oparl.example.org/person/29",
103            "organization": "https://oparl.example.org/organizations/5",
104            "role": "Vorsitzende",
105            "votingRight": true,
106            "startDate": "2013-12-03",
107            "created": "2011-11-11T11:11:00+01:00",
108            "modified": "2012-08-16T14:05:27+02:00"
109        })
110    }
111
112    #[test]
113    fn serialize() {
114        assert_eq!(json!(example_membership()), example_membership_json());
115    }
116
117    #[test]
118    fn deserialize_good() {
119        let deserialized: Membership = serde_json::from_value(example_membership_json())
120            .expect("value must be deserializable as Membership");
121        assert_eq!(deserialized, example_membership());
122    }
123
124    #[test]
125    fn deserialize_bad() {
126        assert!(serde_json::from_value::<Membership>(json!("xyzabcd")).is_err());
127        assert!(serde_json::from_value::<Membership>(json!(true)).is_err());
128        assert!(serde_json::from_value::<Membership>(json!(123)).is_err());
129    }
130}