gitlab/api/projects/protected_tags/
protect.rs1use std::collections::BTreeSet;
8
9use derive_builder::Builder;
10
11use crate::api::common::{NameOrId, ProtectedAccessLevel};
12use crate::api::endpoint_prelude::*;
13use crate::api::projects::protected_branches::ProtectedAccessPush;
14
15#[derive(Debug, Builder, Clone)]
17#[builder(setter(strip_option))]
18pub struct ProtectTag<'a> {
19 #[builder(setter(into))]
21 project: NameOrId<'a>,
22 #[builder(setter(into))]
24 name: Cow<'a, str>,
25 #[builder(default)]
27 create_access_level: Option<ProtectedAccessLevel>,
28 #[builder(setter(name = "_allowed_to_create"), default, private)]
30 allowed_to_create: BTreeSet<ProtectedAccessPush<ProtectedAccessLevel>>,
31}
32
33impl<'a> ProtectTag<'a> {
34 pub fn builder() -> ProtectTagBuilder<'a> {
36 ProtectTagBuilder::default()
37 }
38}
39
40impl ProtectTagBuilder<'_> {
41 pub fn allowed_to_create<A>(&mut self, access: A) -> &mut Self
43 where
44 A: Into<ProtectedAccessPush<ProtectedAccessLevel>>,
45 {
46 self.allowed_to_create
47 .get_or_insert_with(BTreeSet::new)
48 .insert(access.into());
49 self
50 }
51}
52
53impl Endpoint for ProtectTag<'_> {
54 fn method(&self) -> Method {
55 Method::POST
56 }
57
58 fn endpoint(&self) -> Cow<'static, str> {
59 format!("projects/{}/protected_tags", self.project).into()
60 }
61
62 fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
63 let mut params = FormParams::default();
64
65 params
66 .push("name", &self.name)
67 .push_opt("create_access_level", self.create_access_level);
68
69 self.allowed_to_create
70 .iter()
71 .for_each(|value| value.add_query("allowed_to_create", &mut params));
72
73 params.into_body()
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use http::Method;
80
81 use crate::api::common::ProtectedAccessLevel;
82 use crate::api::projects::protected_branches::ProtectedAccessPush;
83 use crate::api::projects::protected_tags::{
84 ProtectTag, ProtectTagBuilderError, ProtectedAccess,
85 };
86 use crate::api::{self, Query};
87 use crate::test::client::{ExpectedUrl, SingleTestClient};
88
89 #[test]
90 fn project_and_name_are_needed() {
91 let err = ProtectTag::builder().build().unwrap_err();
92 crate::test::assert_missing_field!(err, ProtectTagBuilderError, "project");
93 }
94
95 #[test]
96 fn project_is_required() {
97 let err = ProtectTag::builder().name("1.0").build().unwrap_err();
98 crate::test::assert_missing_field!(err, ProtectTagBuilderError, "project");
99 }
100
101 #[test]
102 fn name_is_required() {
103 let err = ProtectTag::builder().project(1).build().unwrap_err();
104 crate::test::assert_missing_field!(err, ProtectTagBuilderError, "name");
105 }
106
107 #[test]
108 fn project_and_name_are_sufficient() {
109 ProtectTag::builder()
110 .project(1)
111 .name("1.0")
112 .build()
113 .unwrap();
114 }
115
116 #[test]
117 fn endpoint() {
118 let endpoint = ExpectedUrl::builder()
119 .method(Method::POST)
120 .endpoint("projects/simple%2Fproject/protected_tags")
121 .content_type("application/x-www-form-urlencoded")
122 .body_str("name=1.0")
123 .build()
124 .unwrap();
125 let client = SingleTestClient::new_raw(endpoint, "");
126
127 let endpoint = ProtectTag::builder()
128 .project("simple/project")
129 .name("1.0")
130 .build()
131 .unwrap();
132 api::ignore(endpoint).query(&client).unwrap();
133 }
134
135 #[test]
136 fn endpoint_create_access_level() {
137 let endpoint = ExpectedUrl::builder()
138 .method(Method::POST)
139 .endpoint("projects/simple%2Fproject/protected_tags")
140 .content_type("application/x-www-form-urlencoded")
141 .body_str(concat!("name=1.0", "&create_access_level=40"))
142 .build()
143 .unwrap();
144 let client = SingleTestClient::new_raw(endpoint, "");
145
146 let endpoint = ProtectTag::builder()
147 .project("simple/project")
148 .name("1.0")
149 .create_access_level(ProtectedAccessLevel::Maintainer)
150 .build()
151 .unwrap();
152 api::ignore(endpoint).query(&client).unwrap();
153 }
154
155 #[test]
156 fn endpoint_allowed_to_create() {
157 let endpoint = ExpectedUrl::builder()
158 .method(Method::POST)
159 .endpoint("projects/simple%2Fproject/protected_tags")
160 .content_type("application/x-www-form-urlencoded")
161 .body_str(concat!(
162 "name=1.0",
163 "&allowed_to_create%5B%5D%5Buser_id%5D=1",
164 "&allowed_to_create%5B%5D%5Bgroup_id%5D=1",
165 "&allowed_to_create%5B%5D%5Bdeploy_key_id%5D=1",
166 "&allowed_to_create%5B%5D%5Baccess_level%5D=30",
167 ))
168 .build()
169 .unwrap();
170 let client = SingleTestClient::new_raw(endpoint, "");
171
172 let endpoint = ProtectTag::builder()
173 .project("simple/project")
174 .name("1.0")
175 .allowed_to_create(ProtectedAccess::User(1))
176 .allowed_to_create(ProtectedAccess::Group(1))
177 .allowed_to_create(ProtectedAccessPush::DeployKey(1))
178 .allowed_to_create(ProtectedAccess::Level(ProtectedAccessLevel::Developer))
179 .build()
180 .unwrap();
181 api::ignore(endpoint).query(&client).unwrap();
182 }
183}