gitlab/api/projects/milestones/
create.rs1use derive_builder::Builder;
8
9use chrono::NaiveDate;
10
11use crate::api::common::NameOrId;
12use crate::api::endpoint_prelude::*;
13
14#[derive(Debug, Builder, Clone)]
16#[builder(setter(strip_option))]
17pub struct CreateProjectMilestone<'a> {
18 #[builder(setter(into))]
20 project: NameOrId<'a>,
21 #[builder(setter(into))]
23 title: Cow<'a, str>,
24
25 #[builder(setter(into), default)]
27 description: Option<Cow<'a, str>>,
28 #[builder(default)]
30 due_date: Option<NaiveDate>,
31 #[builder(default)]
33 start_date: Option<NaiveDate>,
34}
35
36impl<'a> CreateProjectMilestone<'a> {
37 pub fn builder() -> CreateProjectMilestoneBuilder<'a> {
39 CreateProjectMilestoneBuilder::default()
40 }
41}
42
43impl Endpoint for CreateProjectMilestone<'_> {
44 fn method(&self) -> Method {
45 Method::POST
46 }
47
48 fn endpoint(&self) -> Cow<'static, str> {
49 format!("projects/{}/milestones", self.project).into()
50 }
51
52 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
53 let mut params = FormParams::default();
54
55 params
56 .push("title", &self.title)
57 .push_opt("description", self.description.as_ref())
58 .push_opt("due_date", self.due_date)
59 .push_opt("start_date", self.start_date);
60
61 params.into_body()
62 }
63}
64
65#[cfg(test)]
66mod tests {
67 use chrono::NaiveDate;
68 use http::Method;
69
70 use crate::api::projects::milestones::{
71 CreateProjectMilestone, CreateProjectMilestoneBuilderError,
72 };
73 use crate::api::{self, Query};
74 use crate::test::client::{ExpectedUrl, SingleTestClient};
75
76 #[test]
77 fn project_and_title_are_necessary() {
78 let err = CreateProjectMilestone::builder().build().unwrap_err();
79 crate::test::assert_missing_field!(err, CreateProjectMilestoneBuilderError, "project");
80 }
81
82 #[test]
83 fn project_is_necessary() {
84 let err = CreateProjectMilestone::builder()
85 .title("title")
86 .build()
87 .unwrap_err();
88 crate::test::assert_missing_field!(err, CreateProjectMilestoneBuilderError, "project");
89 }
90
91 #[test]
92 fn title_is_necessary() {
93 let err = CreateProjectMilestone::builder()
94 .project("project")
95 .build()
96 .unwrap_err();
97 crate::test::assert_missing_field!(err, CreateProjectMilestoneBuilderError, "title");
98 }
99
100 #[test]
101 fn project_and_title_are_sufficient() {
102 CreateProjectMilestone::builder()
103 .project("project")
104 .title("title")
105 .build()
106 .unwrap();
107 }
108
109 #[test]
110 fn endpoint() {
111 let endpoint = ExpectedUrl::builder()
112 .method(Method::POST)
113 .endpoint("projects/simple%2Fproject/milestones")
114 .content_type("application/x-www-form-urlencoded")
115 .body_str("title=title")
116 .build()
117 .unwrap();
118 let client = SingleTestClient::new_raw(endpoint, "");
119
120 let endpoint = CreateProjectMilestone::builder()
121 .project("simple/project")
122 .title("title")
123 .build()
124 .unwrap();
125 api::ignore(endpoint).query(&client).unwrap();
126 }
127
128 #[test]
129 fn endpoint_description() {
130 let endpoint = ExpectedUrl::builder()
131 .method(Method::POST)
132 .endpoint("projects/simple%2Fproject/milestones")
133 .content_type("application/x-www-form-urlencoded")
134 .body_str(concat!("title=title", "&description=description"))
135 .build()
136 .unwrap();
137 let client = SingleTestClient::new_raw(endpoint, "");
138
139 let endpoint = CreateProjectMilestone::builder()
140 .project("simple/project")
141 .title("title")
142 .description("description")
143 .build()
144 .unwrap();
145 api::ignore(endpoint).query(&client).unwrap();
146 }
147
148 #[test]
149 fn endpoint_due_date() {
150 let endpoint = ExpectedUrl::builder()
151 .method(Method::POST)
152 .endpoint("projects/simple%2Fproject/milestones")
153 .content_type("application/x-www-form-urlencoded")
154 .body_str(concat!("title=title", "&due_date=2020-01-01"))
155 .build()
156 .unwrap();
157 let client = SingleTestClient::new_raw(endpoint, "");
158
159 let endpoint = CreateProjectMilestone::builder()
160 .project("simple/project")
161 .title("title")
162 .due_date(NaiveDate::from_ymd_opt(2020, 1, 1).unwrap())
163 .build()
164 .unwrap();
165 api::ignore(endpoint).query(&client).unwrap();
166 }
167
168 #[test]
169 fn endpoint_start_date() {
170 let endpoint = ExpectedUrl::builder()
171 .method(Method::POST)
172 .endpoint("projects/simple%2Fproject/milestones")
173 .content_type("application/x-www-form-urlencoded")
174 .body_str(concat!("title=title", "&start_date=2020-01-01"))
175 .build()
176 .unwrap();
177 let client = SingleTestClient::new_raw(endpoint, "");
178
179 let endpoint = CreateProjectMilestone::builder()
180 .project("simple/project")
181 .title("title")
182 .start_date(NaiveDate::from_ymd_opt(2020, 1, 1).unwrap())
183 .build()
184 .unwrap();
185 api::ignore(endpoint).query(&client).unwrap();
186 }
187}