gitlab/api/projects/releases/links/
create.rs1use crate::api::common::{self, NameOrId};
8use crate::api::endpoint_prelude::*;
9use derive_builder::Builder;
10
11use super::LinkType;
12
13#[derive(Debug, Builder, Clone)]
15#[builder(setter(strip_option))]
16pub struct CreateReleaseLink<'a> {
17 #[builder(setter(into))]
19 project: NameOrId<'a>,
20
21 #[builder(setter(into))]
23 tag_name: Cow<'a, str>,
24
25 #[builder(setter(into))]
29 name: Cow<'a, str>,
30
31 #[builder(setter(into))]
35 url: Cow<'a, str>,
36
37 #[builder(setter(into), default)]
39 direct_asset_path: Option<Cow<'a, str>>,
40
41 #[builder(setter(into), default)]
45 link_type: Option<LinkType>,
46}
47
48impl<'a> CreateReleaseLink<'a> {
49 pub fn builder() -> CreateReleaseLinkBuilder<'a> {
51 CreateReleaseLinkBuilder::default()
52 }
53}
54
55impl Endpoint for CreateReleaseLink<'_> {
56 fn method(&self) -> Method {
57 Method::POST
58 }
59
60 fn endpoint(&self) -> Cow<'static, str> {
61 format!(
62 "projects/{}/releases/{}/assets/links",
63 self.project,
64 common::path_escaped(self.tag_name.as_ref()),
65 )
66 .into()
67 }
68
69 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
70 let mut params = FormParams::default();
71
72 params
73 .push("name", &self.name)
74 .push("url", &self.url)
75 .push_opt("direct_asset_path", self.direct_asset_path.as_ref())
76 .push_opt("link_type", self.link_type);
77
78 params.into_body()
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use http::Method;
85
86 use crate::{
87 api::{
88 self,
89 projects::releases::links::{CreateReleaseLinkBuilderError, LinkType},
90 Query,
91 },
92 test::client::{ExpectedUrl, SingleTestClient},
93 };
94
95 use super::CreateReleaseLink;
96
97 #[test]
98 fn project_is_needed() {
99 let err = CreateReleaseLink::builder()
100 .tag_name("1.2.3")
101 .name("test")
102 .url("test.com/file")
103 .build()
104 .unwrap_err();
105
106 crate::test::assert_missing_field!(err, CreateReleaseLinkBuilderError, "project");
107 }
108
109 #[test]
110 fn tag_name_is_needed() {
111 let err = CreateReleaseLink::builder()
112 .project(1)
113 .name("test")
114 .url("test.com/file")
115 .build()
116 .unwrap_err();
117
118 crate::test::assert_missing_field!(err, CreateReleaseLinkBuilderError, "tag_name");
119 }
120
121 #[test]
122 fn name_is_needed() {
123 let err = CreateReleaseLink::builder()
124 .project(1)
125 .tag_name("1.2.3")
126 .url("test.com/file")
127 .build()
128 .unwrap_err();
129
130 crate::test::assert_missing_field!(err, CreateReleaseLinkBuilderError, "name");
131 }
132
133 #[test]
134 fn url_is_needed() {
135 let err = CreateReleaseLink::builder()
136 .project(1)
137 .tag_name("1.2.3")
138 .name("test")
139 .build()
140 .unwrap_err();
141
142 crate::test::assert_missing_field!(err, CreateReleaseLinkBuilderError, "url");
143 }
144
145 #[test]
146 fn required_parameter_are_sufficient() {
147 CreateReleaseLink::builder()
148 .project(1)
149 .tag_name("1.2.3")
150 .name("test")
151 .url("test.com/file")
152 .build()
153 .unwrap();
154 }
155
156 #[test]
157 fn endpoint() {
158 let endpoint = ExpectedUrl::builder()
159 .method(Method::POST)
160 .endpoint("projects/1337/releases/1.2.3%2001/assets/links")
161 .body_str(concat!("name=test", "&url=test.com%2Ffile"))
162 .content_type("application/x-www-form-urlencoded")
163 .build()
164 .unwrap();
165 let client = SingleTestClient::new_raw(endpoint, "");
166
167 let endpoint = CreateReleaseLink::builder()
168 .project(1337)
169 .tag_name("1.2.3 01")
170 .name("test")
171 .url("test.com/file")
172 .build()
173 .unwrap();
174 api::ignore(endpoint).query(&client).unwrap();
175 }
176
177 #[test]
178 fn endpoint_direct_asset_path() {
179 let endpoint = ExpectedUrl::builder()
180 .method(Method::POST)
181 .endpoint("projects/1337/releases/1.2.3%2001/assets/links")
182 .body_str(concat!(
183 "name=test",
184 "&url=test.com%2Ffile",
185 "&direct_asset_path=path%2Fto%2Ffile",
186 ))
187 .content_type("application/x-www-form-urlencoded")
188 .build()
189 .unwrap();
190 let client = SingleTestClient::new_raw(endpoint, "");
191
192 let endpoint = CreateReleaseLink::builder()
193 .project(1337)
194 .tag_name("1.2.3 01")
195 .name("test")
196 .url("test.com/file")
197 .direct_asset_path("path/to/file")
198 .build()
199 .unwrap();
200 api::ignore(endpoint).query(&client).unwrap();
201 }
202
203 #[test]
204 fn endpoint_link_type() {
205 let endpoint = ExpectedUrl::builder()
206 .method(Method::POST)
207 .endpoint("projects/1337/releases/1.2.3%2001/assets/links")
208 .body_str(concat!(
209 "name=test",
210 "&url=test.com%2Ffile",
211 "&link_type=other",
212 ))
213 .content_type("application/x-www-form-urlencoded")
214 .build()
215 .unwrap();
216 let client = SingleTestClient::new_raw(endpoint, "");
217
218 let endpoint = CreateReleaseLink::builder()
219 .project(1337)
220 .tag_name("1.2.3 01")
221 .name("test")
222 .url("test.com/file")
223 .link_type(LinkType::Other)
224 .build()
225 .unwrap();
226 api::ignore(endpoint).query(&client).unwrap();
227 }
228}