Skip to main content

gitlab/api/projects/variables/
create.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use derive_builder::Builder;
8
9use crate::api::common::NameOrId;
10use crate::api::endpoint_prelude::*;
11use crate::api::ParamValue;
12
13/// The type of a project variable.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15#[non_exhaustive]
16pub enum ProjectVariableType {
17    /// An environment variable.
18    ///
19    /// The value of the variable is available as the value of the named environment variable.
20    EnvVar,
21    /// A file variable.
22    ///
23    /// The value of the variable is available in a file given by the value of the named
24    /// environment variable.
25    File,
26}
27
28impl ProjectVariableType {
29    /// The variable type query parameter.
30    fn as_str(self) -> &'static str {
31        match self {
32            ProjectVariableType::EnvVar => "env_var",
33            ProjectVariableType::File => "file",
34        }
35    }
36}
37
38impl ParamValue<'static> for ProjectVariableType {
39    fn as_value(&self) -> Cow<'static, str> {
40        self.as_str().into()
41    }
42}
43
44/// Add a variable to a project.
45#[derive(Debug, Builder, Clone)]
46#[builder(setter(strip_option))]
47pub struct CreateProjectVariable<'a> {
48    /// The project to add the variable to.
49    #[builder(setter(into))]
50    project: NameOrId<'a>,
51    /// The key of the variable
52    #[builder(setter(into))]
53    key: Cow<'a, str>,
54    /// The value of a variable
55    #[builder(setter(into))]
56    value: Cow<'a, str>,
57    /// The type of the variable.
58    #[builder(default)]
59    variable_type: Option<ProjectVariableType>,
60    /// Whether the variable is protected.
61    #[builder(default)]
62    protected: Option<bool>,
63    /// Whether the variable is masked.
64    #[builder(default)]
65    masked: Option<bool>,
66    /// Whether the variable is masked and hidden.
67    #[builder(default)]
68    masked_and_hidden: Option<bool>,
69    /// Whether the variable is treated as a raw string.
70    #[builder(default)]
71    raw: Option<bool>,
72    /// The environment scope of the variable.
73    #[builder(setter(into), default)]
74    environment_scope: Option<Cow<'a, str>>,
75    /// The description of the variable.
76    #[builder(setter(into), default)]
77    description: Option<Cow<'a, str>>,
78}
79
80impl<'a> CreateProjectVariable<'a> {
81    /// Create a builder for the endpoint.
82    pub fn builder() -> CreateProjectVariableBuilder<'a> {
83        CreateProjectVariableBuilder::default()
84    }
85}
86
87impl Endpoint for CreateProjectVariable<'_> {
88    fn method(&self) -> Method {
89        Method::POST
90    }
91
92    fn endpoint(&self) -> Cow<'static, str> {
93        format!("projects/{}/variables", self.project).into()
94    }
95
96    fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
97        let mut params = FormParams::default();
98
99        params
100            .push("key", &self.key)
101            .push("value", &self.value)
102            .push_opt("variable_type", self.variable_type)
103            .push_opt("protected", self.protected)
104            .push_opt("masked", self.masked)
105            .push_opt("masked_and_hidden", self.masked_and_hidden)
106            .push_opt("raw", self.raw)
107            .push_opt("environment_scope", self.environment_scope.as_ref())
108            .push_opt("description", self.description.as_ref());
109
110        params.into_body()
111    }
112}
113
114#[cfg(test)]
115mod tests {
116    use http::Method;
117
118    use crate::api::projects::variables::create::{
119        CreateProjectVariable, CreateProjectVariableBuilderError, ProjectVariableType,
120    };
121    use crate::api::{self, Query};
122    use crate::test::client::{ExpectedUrl, SingleTestClient};
123
124    #[test]
125    fn project_variable_type_as_str() {
126        let items = &[
127            (ProjectVariableType::EnvVar, "env_var"),
128            (ProjectVariableType::File, "file"),
129        ];
130
131        for (i, s) in items {
132            assert_eq!(i.as_str(), *s);
133        }
134    }
135
136    #[test]
137    fn all_parameters_are_needed() {
138        let err = CreateProjectVariable::builder().build().unwrap_err();
139        crate::test::assert_missing_field!(err, CreateProjectVariableBuilderError, "project");
140    }
141
142    #[test]
143    fn project_is_necessary() {
144        let err = CreateProjectVariable::builder()
145            .key("testkey")
146            .value("testvalue")
147            .build()
148            .unwrap_err();
149        crate::test::assert_missing_field!(err, CreateProjectVariableBuilderError, "project");
150    }
151
152    #[test]
153    fn key_is_necessary() {
154        let err = CreateProjectVariable::builder()
155            .project(1)
156            .value("testvalue")
157            .build()
158            .unwrap_err();
159        crate::test::assert_missing_field!(err, CreateProjectVariableBuilderError, "key");
160    }
161
162    #[test]
163    fn value_level_is_necessary() {
164        let err = CreateProjectVariable::builder()
165            .project(1)
166            .key("testkey")
167            .build()
168            .unwrap_err();
169        crate::test::assert_missing_field!(err, CreateProjectVariableBuilderError, "value");
170    }
171
172    #[test]
173    fn sufficient_parameters() {
174        CreateProjectVariable::builder()
175            .project(1)
176            .key("testkey")
177            .value("testvalue")
178            .build()
179            .unwrap();
180    }
181
182    #[test]
183    fn endpoint() {
184        let endpoint = ExpectedUrl::builder()
185            .method(Method::POST)
186            .endpoint("projects/simple%2Fproject/variables")
187            .content_type("application/x-www-form-urlencoded")
188            .body_str(concat!("key=testkey", "&value=testvalue"))
189            .build()
190            .unwrap();
191        let client = SingleTestClient::new_raw(endpoint, "");
192
193        let endpoint = CreateProjectVariable::builder()
194            .project("simple/project")
195            .key("testkey")
196            .value("testvalue")
197            .build()
198            .unwrap();
199        api::ignore(endpoint).query(&client).unwrap();
200    }
201
202    #[test]
203    fn endpoint_variable_type() {
204        let endpoint = ExpectedUrl::builder()
205            .method(Method::POST)
206            .endpoint("projects/simple%2Fproject/variables")
207            .content_type("application/x-www-form-urlencoded")
208            .body_str(concat!(
209                "key=testkey",
210                "&value=testvalue",
211                "&variable_type=file"
212            ))
213            .build()
214            .unwrap();
215        let client = SingleTestClient::new_raw(endpoint, "");
216
217        let endpoint = CreateProjectVariable::builder()
218            .project("simple/project")
219            .key("testkey")
220            .value("testvalue")
221            .variable_type(ProjectVariableType::File)
222            .build()
223            .unwrap();
224        api::ignore(endpoint).query(&client).unwrap();
225    }
226
227    #[test]
228    fn endpoint_protected() {
229        let endpoint = ExpectedUrl::builder()
230            .method(Method::POST)
231            .endpoint("projects/simple%2Fproject/variables")
232            .content_type("application/x-www-form-urlencoded")
233            .body_str(concat!(
234                "key=testkey",
235                "&value=testvalue",
236                "&protected=true"
237            ))
238            .build()
239            .unwrap();
240        let client = SingleTestClient::new_raw(endpoint, "");
241
242        let endpoint = CreateProjectVariable::builder()
243            .project("simple/project")
244            .key("testkey")
245            .value("testvalue")
246            .protected(true)
247            .build()
248            .unwrap();
249        api::ignore(endpoint).query(&client).unwrap();
250    }
251
252    #[test]
253    fn endpoint_masked() {
254        let endpoint = ExpectedUrl::builder()
255            .method(Method::POST)
256            .endpoint("projects/simple%2Fproject/variables")
257            .content_type("application/x-www-form-urlencoded")
258            .body_str(concat!("key=testkey", "&value=testvalue", "&masked=true"))
259            .build()
260            .unwrap();
261        let client = SingleTestClient::new_raw(endpoint, "");
262
263        let endpoint = CreateProjectVariable::builder()
264            .project("simple/project")
265            .key("testkey")
266            .value("testvalue")
267            .masked(true)
268            .build()
269            .unwrap();
270        api::ignore(endpoint).query(&client).unwrap();
271    }
272
273    #[test]
274    fn endpoint_masked_and_hidden() {
275        let endpoint = ExpectedUrl::builder()
276            .method(Method::POST)
277            .endpoint("projects/simple%2Fproject/variables")
278            .content_type("application/x-www-form-urlencoded")
279            .body_str(concat!(
280                "key=testkey",
281                "&value=testvalue",
282                "&masked_and_hidden=true",
283            ))
284            .build()
285            .unwrap();
286        let client = SingleTestClient::new_raw(endpoint, "");
287
288        let endpoint = CreateProjectVariable::builder()
289            .project("simple/project")
290            .key("testkey")
291            .value("testvalue")
292            .masked_and_hidden(true)
293            .build()
294            .unwrap();
295        api::ignore(endpoint).query(&client).unwrap();
296    }
297
298    #[test]
299    fn endpoint_raw() {
300        let endpoint = ExpectedUrl::builder()
301            .method(Method::POST)
302            .endpoint("projects/simple%2Fproject/variables")
303            .content_type("application/x-www-form-urlencoded")
304            .body_str(concat!("key=testkey", "&value=testvalue", "&raw=true"))
305            .build()
306            .unwrap();
307        let client = SingleTestClient::new_raw(endpoint, "");
308
309        let endpoint = CreateProjectVariable::builder()
310            .project("simple/project")
311            .key("testkey")
312            .value("testvalue")
313            .raw(true)
314            .build()
315            .unwrap();
316        api::ignore(endpoint).query(&client).unwrap();
317    }
318
319    #[test]
320    fn endpoint_environment_scope() {
321        let endpoint = ExpectedUrl::builder()
322            .method(Method::POST)
323            .endpoint("projects/simple%2Fproject/variables")
324            .content_type("application/x-www-form-urlencoded")
325            .body_str(concat!(
326                "key=testkey",
327                "&value=testvalue",
328                "&environment_scope=*"
329            ))
330            .build()
331            .unwrap();
332        let client = SingleTestClient::new_raw(endpoint, "");
333
334        let endpoint = CreateProjectVariable::builder()
335            .project("simple/project")
336            .key("testkey")
337            .value("testvalue")
338            .environment_scope("*")
339            .build()
340            .unwrap();
341        api::ignore(endpoint).query(&client).unwrap();
342    }
343
344    #[test]
345    fn endpoint_description() {
346        let endpoint = ExpectedUrl::builder()
347            .method(Method::POST)
348            .endpoint("projects/simple%2Fproject/variables")
349            .content_type("application/x-www-form-urlencoded")
350            .body_str(concat!(
351                "key=testkey",
352                "&value=testvalue",
353                "&description=desc"
354            ))
355            .build()
356            .unwrap();
357        let client = SingleTestClient::new_raw(endpoint, "");
358
359        let endpoint = CreateProjectVariable::builder()
360            .project("simple/project")
361            .key("testkey")
362            .value("testvalue")
363            .description("desc")
364            .build()
365            .unwrap();
366        api::ignore(endpoint).query(&client).unwrap();
367    }
368}