gitlab/api/projects/merge_requests/
merge.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/// Merge a merge request.
13#[derive(Debug, Builder, Clone)]
14#[builder(setter(strip_option))]
15pub struct MergeMergeRequest<'a> {
16    /// The project with the merge request.
17    #[builder(setter(into))]
18    project: NameOrId<'a>,
19    /// The ID of the merge request.
20    merge_request: u64,
21
22    /// Commit message to use on the merge commit.
23    #[builder(setter(into), default)]
24    merge_commit_message: Option<Cow<'a, str>>,
25    /// Commit message to use on the squash commit.
26    #[builder(setter(into), default)]
27    squash_commit_message: Option<Cow<'a, str>>,
28    /// Squash source branch commits into a single merge commit?
29    #[builder(default)]
30    squash: Option<bool>,
31    /// Remove source branch on successful merge?
32    #[builder(default)]
33    should_remove_source_branch: Option<bool>,
34    /// Merge when pipeline succeeds?
35    #[builder(default)]
36    merge_when_pipeline_succeeds: Option<bool>,
37    /// Git commit SHA to merge. If set, this must match the head of the branch being merged or the
38    /// merge will fail.
39    #[builder(setter(into), default)]
40    sha: Option<Cow<'a, str>>,
41}
42
43impl<'a> MergeMergeRequest<'a> {
44    /// Create a builder for the endpoint.
45    pub fn builder() -> MergeMergeRequestBuilder<'a> {
46        MergeMergeRequestBuilder::default()
47    }
48}
49
50impl Endpoint for MergeMergeRequest<'_> {
51    fn method(&self) -> Method {
52        Method::PUT
53    }
54
55    fn endpoint(&self) -> Cow<'static, str> {
56        format!(
57            "projects/{}/merge_requests/{}/merge",
58            self.project, self.merge_request,
59        )
60        .into()
61    }
62
63    fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
64        let mut params = FormParams::default();
65
66        params
67            .push_opt("merge_commit_message", self.merge_commit_message.as_ref())
68            .push_opt("squash_commit_message", self.squash_commit_message.as_ref())
69            .push_opt("squash", self.squash)
70            .push_opt(
71                "should_remove_source_branch",
72                self.should_remove_source_branch,
73            )
74            .push_opt(
75                "merge_when_pipeline_succeeds",
76                self.merge_when_pipeline_succeeds,
77            )
78            .push_opt("sha", self.sha.as_ref());
79
80        params.into_body()
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use http::Method;
87
88    use crate::api::projects::merge_requests::{MergeMergeRequest, MergeMergeRequestBuilderError};
89    use crate::api::{self, Query};
90    use crate::test::client::{ExpectedUrl, SingleTestClient};
91
92    #[test]
93    fn project_and_merge_request_are_needed() {
94        let err = MergeMergeRequest::builder().build().unwrap_err();
95        crate::test::assert_missing_field!(err, MergeMergeRequestBuilderError, "project");
96    }
97
98    #[test]
99    fn project_is_needed() {
100        let err = MergeMergeRequest::builder()
101            .merge_request(1)
102            .build()
103            .unwrap_err();
104        crate::test::assert_missing_field!(err, MergeMergeRequestBuilderError, "project");
105    }
106
107    #[test]
108    fn merge_request_is_needed() {
109        let err = MergeMergeRequest::builder().project(1).build().unwrap_err();
110        crate::test::assert_missing_field!(err, MergeMergeRequestBuilderError, "merge_request");
111    }
112
113    #[test]
114    fn project_and_merge_request_are_sufficient() {
115        MergeMergeRequest::builder()
116            .project(1)
117            .merge_request(1)
118            .build()
119            .unwrap();
120    }
121
122    #[test]
123    fn endpoint() {
124        let endpoint = ExpectedUrl::builder()
125            .method(Method::PUT)
126            .endpoint("projects/simple%2Fproject/merge_requests/1/merge")
127            .content_type("application/x-www-form-urlencoded")
128            .body_str("")
129            .build()
130            .unwrap();
131        let client = SingleTestClient::new_raw(endpoint, "");
132
133        let endpoint = MergeMergeRequest::builder()
134            .project("simple/project")
135            .merge_request(1)
136            .build()
137            .unwrap();
138        api::ignore(endpoint).query(&client).unwrap();
139    }
140
141    #[test]
142    fn endpoint_merge_commit_message() {
143        let endpoint = ExpectedUrl::builder()
144            .method(Method::PUT)
145            .endpoint("projects/simple%2Fproject/merge_requests/1/merge")
146            .content_type("application/x-www-form-urlencoded")
147            .body_str("merge_commit_message=blahblahblah")
148            .build()
149            .unwrap();
150        let client = SingleTestClient::new_raw(endpoint, "");
151
152        let endpoint = MergeMergeRequest::builder()
153            .project("simple/project")
154            .merge_request(1)
155            .merge_commit_message("blahblahblah")
156            .build()
157            .unwrap();
158        api::ignore(endpoint).query(&client).unwrap();
159    }
160
161    #[test]
162    fn endpoint_squash_commit_message() {
163        let endpoint = ExpectedUrl::builder()
164            .method(Method::PUT)
165            .endpoint("projects/simple%2Fproject/merge_requests/1/merge")
166            .content_type("application/x-www-form-urlencoded")
167            .body_str("squash_commit_message=blahblahblah")
168            .build()
169            .unwrap();
170        let client = SingleTestClient::new_raw(endpoint, "");
171
172        let endpoint = MergeMergeRequest::builder()
173            .project("simple/project")
174            .merge_request(1)
175            .squash_commit_message("blahblahblah")
176            .build()
177            .unwrap();
178        api::ignore(endpoint).query(&client).unwrap();
179    }
180
181    #[test]
182    fn endpoint_merge_when_pipeline_succeeds() {
183        let endpoint = ExpectedUrl::builder()
184            .method(Method::PUT)
185            .endpoint("projects/simple%2Fproject/merge_requests/1/merge")
186            .content_type("application/x-www-form-urlencoded")
187            .body_str("merge_when_pipeline_succeeds=true")
188            .build()
189            .unwrap();
190        let client = SingleTestClient::new_raw(endpoint, "");
191
192        let endpoint = MergeMergeRequest::builder()
193            .project("simple/project")
194            .merge_request(1)
195            .merge_when_pipeline_succeeds(true)
196            .build()
197            .unwrap();
198        api::ignore(endpoint).query(&client).unwrap();
199    }
200
201    #[test]
202    fn endpoint_should_remove_source_branch() {
203        let endpoint = ExpectedUrl::builder()
204            .method(Method::PUT)
205            .endpoint("projects/simple%2Fproject/merge_requests/1/merge")
206            .content_type("application/x-www-form-urlencoded")
207            .body_str("should_remove_source_branch=true")
208            .build()
209            .unwrap();
210        let client = SingleTestClient::new_raw(endpoint, "");
211
212        let endpoint = MergeMergeRequest::builder()
213            .project("simple/project")
214            .merge_request(1)
215            .should_remove_source_branch(true)
216            .build()
217            .unwrap();
218        api::ignore(endpoint).query(&client).unwrap();
219    }
220
221    #[test]
222    fn endpoint_squash() {
223        let endpoint = ExpectedUrl::builder()
224            .method(Method::PUT)
225            .endpoint("projects/simple%2Fproject/merge_requests/1/merge")
226            .content_type("application/x-www-form-urlencoded")
227            .body_str("squash=true")
228            .build()
229            .unwrap();
230        let client = SingleTestClient::new_raw(endpoint, "");
231
232        let endpoint = MergeMergeRequest::builder()
233            .project("simple/project")
234            .merge_request(1)
235            .squash(true)
236            .build()
237            .unwrap();
238        api::ignore(endpoint).query(&client).unwrap();
239    }
240
241    #[test]
242    fn endpoint_sha() {
243        let endpoint = ExpectedUrl::builder()
244            .method(Method::PUT)
245            .endpoint("projects/simple%2Fproject/merge_requests/1/merge")
246            .content_type("application/x-www-form-urlencoded")
247            .body_str("sha=blahblahblah")
248            .build()
249            .unwrap();
250        let client = SingleTestClient::new_raw(endpoint, "");
251
252        let endpoint = MergeMergeRequest::builder()
253            .project("simple/project")
254            .merge_request(1)
255            .sha("blahblahblah")
256            .build()
257            .unwrap();
258        api::ignore(endpoint).query(&client).unwrap();
259    }
260}