gitlab/api/projects/repository/tags/
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::*;
11
12/// Create a tag on a project.
13#[derive(Debug, Builder, Clone)]
14#[builder(setter(strip_option))]
15pub struct CreateTag<'a> {
16    /// The project to create a tag on.
17    #[builder(setter(into))]
18    project: NameOrId<'a>,
19    /// The name of the new tag.
20    #[builder(setter(into))]
21    tag_name: Cow<'a, str>,
22    /// The ref to create the tag from.
23    #[builder(setter(into))]
24    ref_: Cow<'a, str>,
25    /// Creates an annotated tag, if present.
26    #[builder(setter(into), default)]
27    message: Option<Cow<'a, str>>,
28}
29
30impl<'a> CreateTag<'a> {
31    /// Create a builder for the endpoint.
32    pub fn builder() -> CreateTagBuilder<'a> {
33        CreateTagBuilder::default()
34    }
35}
36
37impl Endpoint for CreateTag<'_> {
38    fn method(&self) -> Method {
39        Method::POST
40    }
41
42    fn endpoint(&self) -> Cow<'static, str> {
43        format!("projects/{}/repository/tags", self.project).into()
44    }
45
46    fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
47        let mut params = FormParams::default();
48
49        params
50            .push("tag_name", &self.tag_name)
51            .push("ref", &self.ref_)
52            .push_opt("message", self.message.as_ref());
53
54        params.into_body()
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use http::Method;
61
62    use crate::api::projects::repository::tags::{CreateTag, CreateTagBuilderError};
63    use crate::api::{self, Query};
64    use crate::test::client::{ExpectedUrl, SingleTestClient};
65
66    #[test]
67    fn project_is_necessary() {
68        let err = CreateTag::builder()
69            .tag_name("tag")
70            .ref_("ref")
71            .build()
72            .unwrap_err();
73        crate::test::assert_missing_field!(err, CreateTagBuilderError, "project");
74    }
75
76    #[test]
77    fn tag_name_is_necessary() {
78        let err = CreateTag::builder()
79            .project(1)
80            .ref_("ref")
81            .build()
82            .unwrap_err();
83        crate::test::assert_missing_field!(err, CreateTagBuilderError, "tag_name");
84    }
85
86    #[test]
87    fn ref_is_necessary() {
88        let err = CreateTag::builder()
89            .project(1)
90            .tag_name("a-tag-name")
91            .build()
92            .unwrap_err();
93        crate::test::assert_missing_field!(err, CreateTagBuilderError, "ref_");
94    }
95
96    #[test]
97    fn project_tag_name_and_ref_is_sufficient() {
98        CreateTag::builder()
99            .project(1)
100            .tag_name("a-tag-name")
101            .ref_("0000000000000000000000000000000000000000")
102            .build()
103            .unwrap();
104    }
105
106    #[test]
107    fn endpoint() {
108        let endpoint = ExpectedUrl::builder()
109            .method(Method::POST)
110            .endpoint("projects/simple%2Fproject/repository/tags")
111            .content_type("application/x-www-form-urlencoded")
112            .body_str(concat!(
113                "tag_name=a-tag",
114                "&ref=0000000000000000000000000000000000000000",
115            ))
116            .build()
117            .unwrap();
118        let client = SingleTestClient::new_raw(endpoint, "");
119
120        let endpoint = CreateTag::builder()
121            .project("simple/project")
122            .tag_name("a-tag")
123            .ref_("0000000000000000000000000000000000000000")
124            .build()
125            .unwrap();
126        api::ignore(endpoint).query(&client).unwrap();
127    }
128
129    #[test]
130    fn endpoint_message() {
131        let endpoint = ExpectedUrl::builder()
132            .method(Method::POST)
133            .endpoint("projects/simple%2Fproject/repository/tags")
134            .content_type("application/x-www-form-urlencoded")
135            .body_str(concat!(
136                "tag_name=a-tag",
137                "&ref=0000000000000000000000000000000000000000",
138                "&message=Hi+there",
139            ))
140            .build()
141            .unwrap();
142        let client = SingleTestClient::new_raw(endpoint, "");
143
144        let endpoint = CreateTag::builder()
145            .project("simple/project")
146            .tag_name("a-tag")
147            .ref_("0000000000000000000000000000000000000000")
148            .message("Hi there")
149            .build()
150            .unwrap();
151        api::ignore(endpoint).query(&client).unwrap();
152    }
153}