1use std::collections::BTreeSet;
8use std::iter;
9
10use chrono::{DateTime, Utc};
11use derive_builder::Builder;
12
13use crate::api::common::{NameOrId, SortOrder, YesNo};
14use crate::api::endpoint_prelude::*;
15use crate::api::helpers::{Labels, ReactionEmoji};
16use crate::api::merge_requests::{
17 ApproverIds, Assignee, MergeRequestMilestone, MergeRequestOrderBy, MergeRequestScope,
18 MergeRequestState, MergeRequestView,
19};
20
21#[derive(Debug, Clone)]
22#[non_exhaustive]
23enum ApprovedBy<'a> {
24 Any,
25 None,
26 AllOfIds(BTreeSet<u64>),
27 AllOfUsernames(BTreeSet<Cow<'a, str>>),
28}
29
30impl ApprovedBy<'_> {
31 fn add_params<'b>(&'b self, params: &mut QueryParams<'b>) {
32 match self {
33 ApprovedBy::Any => {
34 params.push("approved_by_ids", "Any");
35 },
36 ApprovedBy::None => {
37 params.push("approved_by_ids", "None");
38 },
39 ApprovedBy::AllOfIds(ids) => {
40 params.extend(ids.iter().map(|&id| ("approved_by_ids[]", id)));
41 },
42 ApprovedBy::AllOfUsernames(usernames) => {
43 params.extend(
44 usernames
45 .iter()
46 .map(|username| ("approved_by_usernames[]", username)),
47 );
48 },
49 }
50 }
51}
52
53#[derive(Debug, Builder, Clone)]
57#[builder(setter(strip_option))]
58pub struct MergeRequests<'a> {
59 #[builder(setter(into))]
61 project: NameOrId<'a>,
62
63 #[builder(setter(name = "_iids"), default, private)]
65 iids: BTreeSet<u64>,
66 #[builder(default)]
68 state: Option<MergeRequestState>,
69 #[builder(setter(name = "_milestone"), default, private)]
71 milestone: Option<MergeRequestMilestone<'a>>,
72 #[builder(default)]
76 view: Option<MergeRequestView>,
77 #[builder(setter(name = "_labels"), default, private)]
79 labels: Option<Labels<'a>>,
80 #[builder(default)]
82 with_labels_details: Option<bool>,
83 #[builder(default)]
85 with_merge_status_recheck: Option<bool>,
86 #[builder(default)]
88 created_after: Option<DateTime<Utc>>,
89 #[builder(default)]
91 created_before: Option<DateTime<Utc>>,
92 #[builder(default)]
94 updated_after: Option<DateTime<Utc>>,
95 #[builder(default)]
97 updated_before: Option<DateTime<Utc>>,
98 #[builder(default)]
100 scope: Option<MergeRequestScope>,
101 #[builder(setter(into), default)]
103 author: Option<NameOrId<'a>>,
104 #[builder(setter(name = "_assignee"), default, private)]
106 assignee: Option<Assignee>,
107 #[builder(setter(name = "_approver_ids"), default, private)]
109 approver_ids: Option<ApproverIds>,
110 #[builder(setter(name = "_approved_by"), default, private)]
112 approved_by: Option<ApprovedBy<'a>>,
113 #[builder(default, setter(into))]
115 approved: Option<YesNo>,
116 #[builder(setter(into), default)]
118 reviewer: Option<NameOrId<'a>>,
119 #[builder(setter(name = "_my_reaction_emoji"), default, private)]
121 my_reaction_emoji: Option<ReactionEmoji<'a>>,
122 #[builder(setter(into), default)]
124 source_branch: Option<Cow<'a, str>>,
125 #[builder(setter(into), default)]
127 target_branch: Option<Cow<'a, str>>,
128 #[builder(setter(into), default)]
130 wip: Option<YesNo>,
131 #[builder(setter(into), default)]
133 environment: Option<Cow<'a, str>>,
134 #[builder(default)]
136 deployed_after: Option<DateTime<Utc>>,
137 #[builder(default)]
139 deployed_before: Option<DateTime<Utc>>,
140
141 #[builder(setter(into), default)]
144 search: Option<Cow<'a, str>>,
145
146 #[builder(default)]
148 order_by: Option<MergeRequestOrderBy>,
149 #[builder(default)]
151 sort: Option<SortOrder>,
152}
153
154impl<'a> MergeRequests<'a> {
155 pub fn builder() -> MergeRequestsBuilder<'a> {
157 MergeRequestsBuilder::default()
158 }
159}
160
161impl<'a> MergeRequestsBuilder<'a> {
162 pub fn iid(&mut self, iid: u64) -> &mut Self {
164 self.iids.get_or_insert_with(BTreeSet::new).insert(iid);
165 self
166 }
167
168 pub fn iids<I>(&mut self, iter: I) -> &mut Self
170 where
171 I: Iterator<Item = u64>,
172 {
173 self.iids.get_or_insert_with(BTreeSet::new).extend(iter);
174 self
175 }
176
177 pub fn unlabeled(&mut self) -> &mut Self {
179 self.labels = Some(Some(Labels::None));
180 self
181 }
182
183 pub fn with_any_label(&mut self) -> &mut Self {
185 self.labels = Some(Some(Labels::Any));
186 self
187 }
188
189 pub fn label<L>(&mut self, label: L) -> &mut Self
191 where
192 L: Into<Cow<'a, str>>,
193 {
194 let label = label.into();
195 let labels = if let Some(Some(Labels::AllOf(mut set))) = self.labels.take() {
196 set.push(label);
197 set
198 } else {
199 iter::once(label).collect()
200 };
201 self.labels = Some(Some(Labels::AllOf(labels)));
202 self
203 }
204
205 pub fn labels<I, L>(&mut self, iter: I) -> &mut Self
207 where
208 I: IntoIterator<Item = L>,
209 L: Into<Cow<'a, str>>,
210 {
211 let iter = iter.into_iter().map(Into::into);
212 let labels = if let Some(Some(Labels::AllOf(mut set))) = self.labels.take() {
213 set.extend(iter);
214 set
215 } else {
216 iter.collect()
217 };
218 self.labels = Some(Some(Labels::AllOf(labels)));
219 self
220 }
221
222 pub fn without_milestone(&mut self) -> &mut Self {
224 self.milestone = Some(Some(MergeRequestMilestone::None));
225 self
226 }
227
228 pub fn any_milestone(&mut self) -> &mut Self {
230 self.milestone = Some(Some(MergeRequestMilestone::Any));
231 self
232 }
233
234 pub fn milestone<M>(&mut self, milestone: M) -> &mut Self
236 where
237 M: Into<Cow<'a, str>>,
238 {
239 self.milestone = Some(Some(MergeRequestMilestone::Named(milestone.into())));
240 self
241 }
242
243 pub fn unassigned(&mut self) -> &mut Self {
245 self.assignee = Some(Some(Assignee::Unassigned));
246 self
247 }
248
249 pub fn assigned(&mut self) -> &mut Self {
251 self.assignee = Some(Some(Assignee::Assigned));
252 self
253 }
254
255 pub fn assignee_id(&mut self, assignee: u64) -> &mut Self {
257 self.assignee = Some(Some(Assignee::Id(assignee)));
258 self
259 }
260
261 pub fn no_approvers(&mut self) -> &mut Self {
263 self.approver_ids = Some(Some(ApproverIds::None));
264 self
265 }
266
267 pub fn any_approvers(&mut self) -> &mut Self {
269 self.approver_ids = Some(Some(ApproverIds::Any));
270 self
271 }
272
273 pub fn approver_id(&mut self, approver: u64) -> &mut Self {
275 let approver_ids = if let Some(Some(ApproverIds::AllOf(mut set))) = self.approver_ids.take()
276 {
277 set.insert(approver);
278 set
279 } else {
280 [approver].iter().copied().collect()
281 };
282 self.approver_ids = Some(Some(ApproverIds::AllOf(approver_ids)));
283 self
284 }
285
286 pub fn approver_ids<I>(&mut self, iter: I) -> &mut Self
288 where
289 I: Iterator<Item = u64>,
290 {
291 let approver_ids = if let Some(Some(ApproverIds::AllOf(mut set))) = self.approver_ids.take()
292 {
293 set.extend(iter);
294 set
295 } else {
296 iter.collect()
297 };
298 self.approver_ids = Some(Some(ApproverIds::AllOf(approver_ids)));
299 self
300 }
301
302 pub fn no_approvals(&mut self) -> &mut Self {
304 self.approved_by = Some(Some(ApprovedBy::None));
305 self
306 }
307
308 pub fn any_approvals(&mut self) -> &mut Self {
310 self.approved_by = Some(Some(ApprovedBy::Any));
311 self
312 }
313
314 pub fn approved_by_id(&mut self, approved_by: u64) -> &mut Self {
318 let approved_by = if let Some(Some(ApprovedBy::AllOfIds(mut set))) = self.approved_by.take()
319 {
320 set.insert(approved_by);
321 set
322 } else {
323 [approved_by].iter().copied().collect()
324 };
325 self.approved_by = Some(Some(ApprovedBy::AllOfIds(approved_by)));
326 self
327 }
328
329 pub fn approved_by_ids<I>(&mut self, iter: I) -> &mut Self
333 where
334 I: Iterator<Item = u64>,
335 {
336 let approved_by_ids =
337 if let Some(Some(ApprovedBy::AllOfIds(mut set))) = self.approved_by.take() {
338 set.extend(iter);
339 set
340 } else {
341 iter.collect()
342 };
343 self.approved_by = Some(Some(ApprovedBy::AllOfIds(approved_by_ids)));
344 self
345 }
346
347 pub fn approved_by_username<U>(&mut self, username: U) -> &mut Self
351 where
352 U: Into<Cow<'a, str>>,
353 {
354 let approved_by_usernames =
355 if let Some(Some(ApprovedBy::AllOfUsernames(mut set))) = self.approved_by.take() {
356 set.insert(username.into());
357 set
358 } else {
359 [username.into()].iter().cloned().collect()
360 };
361 self.approved_by = Some(Some(ApprovedBy::AllOfUsernames(approved_by_usernames)));
362 self
363 }
364
365 pub fn approved_by_usernames<I, U>(&mut self, iter: I) -> &mut Self
369 where
370 I: Iterator<Item = U>,
371 U: Into<Cow<'a, str>>,
372 {
373 let approved_by_usernames =
374 if let Some(Some(ApprovedBy::AllOfUsernames(mut set))) = self.approved_by.take() {
375 set.extend(iter.map(Into::into));
376 set
377 } else {
378 iter.map(Into::into).collect()
379 };
380 self.approved_by = Some(Some(ApprovedBy::AllOfUsernames(approved_by_usernames)));
381 self
382 }
383
384 pub fn no_reaction(&mut self) -> &mut Self {
386 self.my_reaction_emoji = Some(Some(ReactionEmoji::None));
387 self
388 }
389
390 pub fn any_reaction(&mut self) -> &mut Self {
392 self.my_reaction_emoji = Some(Some(ReactionEmoji::Any));
393 self
394 }
395
396 pub fn my_reaction<E>(&mut self, emoji: E) -> &mut Self
398 where
399 E: Into<Cow<'a, str>>,
400 {
401 self.my_reaction_emoji = Some(Some(ReactionEmoji::Emoji(emoji.into())));
402 self
403 }
404}
405
406impl Endpoint for MergeRequests<'_> {
407 fn method(&self) -> Method {
408 Method::GET
409 }
410
411 fn endpoint(&self) -> Cow<'static, str> {
412 format!("projects/{}/merge_requests", self.project).into()
413 }
414
415 fn parameters(&self) -> QueryParams {
416 let mut params = QueryParams::default();
417
418 params
419 .extend(self.iids.iter().map(|&value| ("iids[]", value)))
420 .push_opt("state", self.state)
421 .push_opt("milestone", self.milestone.as_ref())
422 .push_opt("view", self.view)
423 .push_opt("labels", self.labels.as_ref())
424 .push_opt("with_labels_details", self.with_labels_details)
425 .push_opt("with_merge_status_recheck", self.with_merge_status_recheck)
426 .push_opt("created_after", self.created_after)
427 .push_opt("created_before", self.created_before)
428 .push_opt("updated_after", self.updated_after)
429 .push_opt("updated_before", self.updated_before)
430 .push_opt("scope", self.scope)
431 .push_opt("approved", self.approved)
432 .push_opt("my_reaction_emoji", self.my_reaction_emoji.as_ref())
433 .push_opt("source_branch", self.source_branch.as_ref())
434 .push_opt("target_branch", self.target_branch.as_ref())
435 .push_opt("search", self.search.as_ref())
436 .push_opt("wip", self.wip)
437 .push_opt("environment", self.environment.as_ref())
438 .push_opt("deployed_after", self.deployed_after)
439 .push_opt("deployed_before", self.deployed_before)
440 .push_opt("order_by", self.order_by)
441 .push_opt("sort", self.sort);
442
443 if let Some(author) = self.author.as_ref() {
444 match author {
445 NameOrId::Name(name) => {
446 params.push("author_username", name);
447 },
448 NameOrId::Id(id) => {
449 params.push("author_id", *id);
450 },
451 }
452 }
453 if let Some(assignee) = self.assignee.as_ref() {
454 assignee.add_params(&mut params);
455 }
456 if let Some(approver_ids) = self.approver_ids.as_ref() {
457 approver_ids.add_params(&mut params);
458 }
459 if let Some(approved_by) = self.approved_by.as_ref() {
460 approved_by.add_params(&mut params);
461 }
462 if let Some(reviewer) = self.reviewer.as_ref() {
463 match reviewer {
464 NameOrId::Name(name) => {
465 params.push("reviewer_username", name);
466 },
467 NameOrId::Id(id) => {
468 params.push("reviewer_id", *id);
469 },
470 }
471 }
472
473 params
474 }
475}
476
477impl Pageable for MergeRequests<'_> {}
478
479#[cfg(test)]
480mod tests {
481 use chrono::{TimeZone, Utc};
482
483 use crate::api::common::{SortOrder, YesNo};
484 use crate::api::projects::merge_requests::{
485 MergeRequestOrderBy, MergeRequestScope, MergeRequestState, MergeRequestView, MergeRequests,
486 MergeRequestsBuilderError,
487 };
488 use crate::api::{self, Query};
489 use crate::test::client::{ExpectedUrl, SingleTestClient};
490
491 #[test]
492 fn project_is_needed() {
493 let err = MergeRequests::builder().build().unwrap_err();
494 crate::test::assert_missing_field!(err, MergeRequestsBuilderError, "project");
495 }
496
497 #[test]
498 fn project_is_sufficient() {
499 MergeRequests::builder().project(1).build().unwrap();
500 }
501
502 #[test]
503 fn endpoint() {
504 let endpoint = ExpectedUrl::builder()
505 .endpoint("projects/simple%2Fproject/merge_requests")
506 .build()
507 .unwrap();
508 let client = SingleTestClient::new_raw(endpoint, "");
509
510 let endpoint = MergeRequests::builder()
511 .project("simple/project")
512 .build()
513 .unwrap();
514 api::ignore(endpoint).query(&client).unwrap();
515 }
516
517 #[test]
518 fn endpoint_iids() {
519 let endpoint = ExpectedUrl::builder()
520 .endpoint("projects/simple%2Fproject/merge_requests")
521 .add_query_params(&[("iids[]", "1"), ("iids[]", "2")])
522 .build()
523 .unwrap();
524 let client = SingleTestClient::new_raw(endpoint, "");
525
526 let endpoint = MergeRequests::builder()
527 .project("simple/project")
528 .iid(1)
529 .iids([1, 2].iter().copied())
530 .build()
531 .unwrap();
532 api::ignore(endpoint).query(&client).unwrap();
533 }
534
535 #[test]
536 fn endpoint_state() {
537 let endpoint = ExpectedUrl::builder()
538 .endpoint("projects/simple%2Fproject/merge_requests")
539 .add_query_params(&[("state", "locked")])
540 .build()
541 .unwrap();
542 let client = SingleTestClient::new_raw(endpoint, "");
543
544 let endpoint = MergeRequests::builder()
545 .project("simple/project")
546 .state(MergeRequestState::Locked)
547 .build()
548 .unwrap();
549 api::ignore(endpoint).query(&client).unwrap();
550 }
551
552 #[test]
553 fn endpoint_milestone_none() {
554 let endpoint = ExpectedUrl::builder()
555 .endpoint("projects/simple%2Fproject/merge_requests")
556 .add_query_params(&[("milestone", "None")])
557 .build()
558 .unwrap();
559 let client = SingleTestClient::new_raw(endpoint, "");
560
561 let endpoint = MergeRequests::builder()
562 .project("simple/project")
563 .without_milestone()
564 .build()
565 .unwrap();
566 api::ignore(endpoint).query(&client).unwrap();
567 }
568
569 #[test]
570 fn endpoint_milestone_any() {
571 let endpoint = ExpectedUrl::builder()
572 .endpoint("projects/simple%2Fproject/merge_requests")
573 .add_query_params(&[("milestone", "Any")])
574 .build()
575 .unwrap();
576 let client = SingleTestClient::new_raw(endpoint, "");
577
578 let endpoint = MergeRequests::builder()
579 .project("simple/project")
580 .any_milestone()
581 .build()
582 .unwrap();
583 api::ignore(endpoint).query(&client).unwrap();
584 }
585
586 #[test]
587 fn endpoint_milestone() {
588 let endpoint = ExpectedUrl::builder()
589 .endpoint("projects/simple%2Fproject/merge_requests")
590 .add_query_params(&[("milestone", "1.0")])
591 .build()
592 .unwrap();
593 let client = SingleTestClient::new_raw(endpoint, "");
594
595 let endpoint = MergeRequests::builder()
596 .project("simple/project")
597 .milestone("1.0")
598 .build()
599 .unwrap();
600 api::ignore(endpoint).query(&client).unwrap();
601 }
602
603 #[test]
604 fn endpoint_view() {
605 let endpoint = ExpectedUrl::builder()
606 .endpoint("projects/simple%2Fproject/merge_requests")
607 .add_query_params(&[("view", "simple")])
608 .build()
609 .unwrap();
610 let client = SingleTestClient::new_raw(endpoint, "");
611
612 let endpoint = MergeRequests::builder()
613 .project("simple/project")
614 .view(MergeRequestView::Simple)
615 .build()
616 .unwrap();
617 api::ignore(endpoint).query(&client).unwrap();
618 }
619
620 #[test]
621 fn endpoint_labels() {
622 let endpoint = ExpectedUrl::builder()
623 .endpoint("projects/simple%2Fproject/merge_requests")
624 .add_query_params(&[("labels", "label,label1,label2")])
625 .build()
626 .unwrap();
627 let client = SingleTestClient::new_raw(endpoint, "");
628
629 let endpoint = MergeRequests::builder()
630 .project("simple/project")
631 .label("label")
632 .labels(["label1", "label2"].iter().cloned())
633 .build()
634 .unwrap();
635 api::ignore(endpoint).query(&client).unwrap();
636 }
637
638 #[test]
639 fn endpoint_labels_unlabeled() {
640 let endpoint = ExpectedUrl::builder()
641 .endpoint("projects/simple%2Fproject/merge_requests")
642 .add_query_params(&[("labels", "None")])
643 .build()
644 .unwrap();
645 let client = SingleTestClient::new_raw(endpoint, "");
646
647 let endpoint = MergeRequests::builder()
648 .project("simple/project")
649 .unlabeled()
650 .build()
651 .unwrap();
652 api::ignore(endpoint).query(&client).unwrap();
653 }
654
655 #[test]
656 fn endpoint_labels_any() {
657 let endpoint = ExpectedUrl::builder()
658 .endpoint("projects/simple%2Fproject/merge_requests")
659 .add_query_params(&[("labels", "Any")])
660 .build()
661 .unwrap();
662 let client = SingleTestClient::new_raw(endpoint, "");
663
664 let endpoint = MergeRequests::builder()
665 .project("simple/project")
666 .with_any_label()
667 .build()
668 .unwrap();
669 api::ignore(endpoint).query(&client).unwrap();
670 }
671
672 #[test]
673 fn endpoint_with_labels_details() {
674 let endpoint = ExpectedUrl::builder()
675 .endpoint("projects/simple%2Fproject/merge_requests")
676 .add_query_params(&[("with_labels_details", "true")])
677 .build()
678 .unwrap();
679 let client = SingleTestClient::new_raw(endpoint, "");
680
681 let endpoint = MergeRequests::builder()
682 .project("simple/project")
683 .with_labels_details(true)
684 .build()
685 .unwrap();
686 api::ignore(endpoint).query(&client).unwrap();
687 }
688
689 #[test]
690 fn endpoint_with_merge_status_recheck() {
691 let endpoint = ExpectedUrl::builder()
692 .endpoint("projects/simple%2Fproject/merge_requests")
693 .add_query_params(&[("with_merge_status_recheck", "true")])
694 .build()
695 .unwrap();
696 let client = SingleTestClient::new_raw(endpoint, "");
697
698 let endpoint = MergeRequests::builder()
699 .project("simple/project")
700 .with_merge_status_recheck(true)
701 .build()
702 .unwrap();
703 api::ignore(endpoint).query(&client).unwrap();
704 }
705
706 #[test]
707 fn endpoint_created_after() {
708 let endpoint = ExpectedUrl::builder()
709 .endpoint("projects/simple%2Fproject/merge_requests")
710 .add_query_params(&[("created_after", "2020-01-01T00:00:00Z")])
711 .build()
712 .unwrap();
713 let client = SingleTestClient::new_raw(endpoint, "");
714
715 let endpoint = MergeRequests::builder()
716 .project("simple/project")
717 .created_after(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
718 .build()
719 .unwrap();
720 api::ignore(endpoint).query(&client).unwrap();
721 }
722
723 #[test]
724 fn endpoint_created_before() {
725 let endpoint = ExpectedUrl::builder()
726 .endpoint("projects/simple%2Fproject/merge_requests")
727 .add_query_params(&[("created_before", "2020-01-01T00:00:00Z")])
728 .build()
729 .unwrap();
730 let client = SingleTestClient::new_raw(endpoint, "");
731
732 let endpoint = MergeRequests::builder()
733 .project("simple/project")
734 .created_before(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
735 .build()
736 .unwrap();
737 api::ignore(endpoint).query(&client).unwrap();
738 }
739
740 #[test]
741 fn endpoint_updated_after() {
742 let endpoint = ExpectedUrl::builder()
743 .endpoint("projects/simple%2Fproject/merge_requests")
744 .add_query_params(&[("updated_after", "2020-01-01T00:00:00Z")])
745 .build()
746 .unwrap();
747 let client = SingleTestClient::new_raw(endpoint, "");
748
749 let endpoint = MergeRequests::builder()
750 .project("simple/project")
751 .updated_after(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
752 .build()
753 .unwrap();
754 api::ignore(endpoint).query(&client).unwrap();
755 }
756
757 #[test]
758 fn endpoint_updated_before() {
759 let endpoint = ExpectedUrl::builder()
760 .endpoint("projects/simple%2Fproject/merge_requests")
761 .add_query_params(&[("updated_before", "2020-01-01T00:00:00Z")])
762 .build()
763 .unwrap();
764 let client = SingleTestClient::new_raw(endpoint, "");
765
766 let endpoint = MergeRequests::builder()
767 .project("simple/project")
768 .updated_before(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
769 .build()
770 .unwrap();
771 api::ignore(endpoint).query(&client).unwrap();
772 }
773
774 #[test]
775 fn endpoint_scope() {
776 let endpoint = ExpectedUrl::builder()
777 .endpoint("projects/simple%2Fproject/merge_requests")
778 .add_query_params(&[("scope", "all")])
779 .build()
780 .unwrap();
781 let client = SingleTestClient::new_raw(endpoint, "");
782
783 let endpoint = MergeRequests::builder()
784 .project("simple/project")
785 .scope(MergeRequestScope::All)
786 .build()
787 .unwrap();
788 api::ignore(endpoint).query(&client).unwrap();
789 }
790
791 #[test]
792 fn endpoint_author() {
793 let endpoint = ExpectedUrl::builder()
794 .endpoint("projects/simple%2Fproject/merge_requests")
795 .add_query_params(&[("author_id", "1")])
796 .build()
797 .unwrap();
798 let client = SingleTestClient::new_raw(endpoint, "");
799
800 let endpoint = MergeRequests::builder()
801 .project("simple/project")
802 .author(1)
803 .build()
804 .unwrap();
805 api::ignore(endpoint).query(&client).unwrap();
806 }
807
808 #[test]
809 fn endpoint_author_name() {
810 let endpoint = ExpectedUrl::builder()
811 .endpoint("projects/simple%2Fproject/merge_requests")
812 .add_query_params(&[("author_username", "name")])
813 .build()
814 .unwrap();
815 let client = SingleTestClient::new_raw(endpoint, "");
816
817 let endpoint = MergeRequests::builder()
818 .project("simple/project")
819 .author("name")
820 .build()
821 .unwrap();
822 api::ignore(endpoint).query(&client).unwrap();
823 }
824
825 #[test]
826 fn endpoint_assignee_unassigned() {
827 let endpoint = ExpectedUrl::builder()
828 .endpoint("projects/simple%2Fproject/merge_requests")
829 .add_query_params(&[("assignee_id", "None")])
830 .build()
831 .unwrap();
832 let client = SingleTestClient::new_raw(endpoint, "");
833
834 let endpoint = MergeRequests::builder()
835 .project("simple/project")
836 .unassigned()
837 .build()
838 .unwrap();
839 api::ignore(endpoint).query(&client).unwrap();
840 }
841
842 #[test]
843 fn endpoint_assignee_assigned() {
844 let endpoint = ExpectedUrl::builder()
845 .endpoint("projects/simple%2Fproject/merge_requests")
846 .add_query_params(&[("assignee_id", "Any")])
847 .build()
848 .unwrap();
849 let client = SingleTestClient::new_raw(endpoint, "");
850
851 let endpoint = MergeRequests::builder()
852 .project("simple/project")
853 .assigned()
854 .build()
855 .unwrap();
856 api::ignore(endpoint).query(&client).unwrap();
857 }
858
859 #[test]
860 fn endpoint_assignee_id() {
861 let endpoint = ExpectedUrl::builder()
862 .endpoint("projects/simple%2Fproject/merge_requests")
863 .add_query_params(&[("assignee_id", "1")])
864 .build()
865 .unwrap();
866 let client = SingleTestClient::new_raw(endpoint, "");
867
868 let endpoint = MergeRequests::builder()
869 .project("simple/project")
870 .assignee_id(1)
871 .build()
872 .unwrap();
873 api::ignore(endpoint).query(&client).unwrap();
874 }
875
876 #[test]
877 fn endpoint_approvers_none() {
878 let endpoint = ExpectedUrl::builder()
879 .endpoint("projects/simple%2Fproject/merge_requests")
880 .add_query_params(&[("approver_ids", "None")])
881 .build()
882 .unwrap();
883 let client = SingleTestClient::new_raw(endpoint, "");
884
885 let endpoint = MergeRequests::builder()
886 .project("simple/project")
887 .no_approvers()
888 .build()
889 .unwrap();
890 api::ignore(endpoint).query(&client).unwrap();
891 }
892
893 #[test]
894 fn endpoint_approvers_any() {
895 let endpoint = ExpectedUrl::builder()
896 .endpoint("projects/simple%2Fproject/merge_requests")
897 .add_query_params(&[("approver_ids", "Any")])
898 .build()
899 .unwrap();
900 let client = SingleTestClient::new_raw(endpoint, "");
901
902 let endpoint = MergeRequests::builder()
903 .project("simple/project")
904 .any_approvers()
905 .build()
906 .unwrap();
907 api::ignore(endpoint).query(&client).unwrap();
908 }
909
910 #[test]
911 fn endpoint_approver_ids() {
912 let endpoint = ExpectedUrl::builder()
913 .endpoint("projects/simple%2Fproject/merge_requests")
914 .add_query_params(&[("approver_ids[]", "1"), ("approver_ids[]", "2")])
915 .build()
916 .unwrap();
917 let client = SingleTestClient::new_raw(endpoint, "");
918
919 let endpoint = MergeRequests::builder()
920 .project("simple/project")
921 .approver_id(1)
922 .approver_ids([1, 2].iter().copied())
923 .build()
924 .unwrap();
925 api::ignore(endpoint).query(&client).unwrap();
926 }
927
928 #[test]
929 fn endpoint_approvals_none() {
930 let endpoint = ExpectedUrl::builder()
931 .endpoint("projects/simple%2Fproject/merge_requests")
932 .add_query_params(&[("approved_by_ids", "None")])
933 .build()
934 .unwrap();
935 let client = SingleTestClient::new_raw(endpoint, "");
936
937 let endpoint = MergeRequests::builder()
938 .project("simple/project")
939 .no_approvals()
940 .build()
941 .unwrap();
942 api::ignore(endpoint).query(&client).unwrap();
943 }
944
945 #[test]
946 fn endpoint_approvals_any() {
947 let endpoint = ExpectedUrl::builder()
948 .endpoint("projects/simple%2Fproject/merge_requests")
949 .add_query_params(&[("approved_by_ids", "Any")])
950 .build()
951 .unwrap();
952 let client = SingleTestClient::new_raw(endpoint, "");
953
954 let endpoint = MergeRequests::builder()
955 .project("simple/project")
956 .any_approvals()
957 .build()
958 .unwrap();
959 api::ignore(endpoint).query(&client).unwrap();
960 }
961
962 #[test]
963 fn endpoint_approved_by_ids() {
964 let endpoint = ExpectedUrl::builder()
965 .endpoint("projects/simple%2Fproject/merge_requests")
966 .add_query_params(&[("approved_by_ids[]", "1"), ("approved_by_ids[]", "2")])
967 .build()
968 .unwrap();
969 let client = SingleTestClient::new_raw(endpoint, "");
970
971 let endpoint = MergeRequests::builder()
972 .project("simple/project")
973 .approved_by_id(1)
974 .approved_by_ids([1, 2].iter().copied())
975 .build()
976 .unwrap();
977 api::ignore(endpoint).query(&client).unwrap();
978 }
979
980 #[test]
981 fn endpoint_approved_by_usernames() {
982 let endpoint = ExpectedUrl::builder()
983 .endpoint("projects/simple%2Fproject/merge_requests")
984 .add_query_params(&[
985 ("approved_by_usernames[]", "thing1"),
986 ("approved_by_usernames[]", "thing2"),
987 ])
988 .build()
989 .unwrap();
990 let client = SingleTestClient::new_raw(endpoint, "");
991
992 let endpoint = MergeRequests::builder()
993 .project("simple/project")
994 .approved_by_username("thing1")
995 .approved_by_usernames(["thing1", "thing2"].iter().copied())
996 .build()
997 .unwrap();
998 api::ignore(endpoint).query(&client).unwrap();
999 }
1000
1001 #[test]
1002 fn endpoint_approved() {
1003 let endpoint = ExpectedUrl::builder()
1004 .endpoint("projects/simple%2Fproject/merge_requests")
1005 .add_query_params(&[("approved", "yes")])
1006 .build()
1007 .unwrap();
1008 let client = SingleTestClient::new_raw(endpoint, "");
1009
1010 let endpoint = MergeRequests::builder()
1011 .project("simple/project")
1012 .approved(true)
1013 .build()
1014 .unwrap();
1015 api::ignore(endpoint).query(&client).unwrap();
1016 }
1017
1018 #[test]
1019 fn endpoint_reviewer() {
1020 let endpoint = ExpectedUrl::builder()
1021 .endpoint("projects/simple%2Fproject/merge_requests")
1022 .add_query_params(&[("reviewer_id", "1")])
1023 .build()
1024 .unwrap();
1025 let client = SingleTestClient::new_raw(endpoint, "");
1026
1027 let endpoint = MergeRequests::builder()
1028 .project("simple/project")
1029 .reviewer(1)
1030 .build()
1031 .unwrap();
1032 api::ignore(endpoint).query(&client).unwrap();
1033 }
1034
1035 #[test]
1036 fn endpoint_reviewer_name() {
1037 let endpoint = ExpectedUrl::builder()
1038 .endpoint("projects/simple%2Fproject/merge_requests")
1039 .add_query_params(&[("reviewer_username", "name")])
1040 .build()
1041 .unwrap();
1042 let client = SingleTestClient::new_raw(endpoint, "");
1043
1044 let endpoint = MergeRequests::builder()
1045 .project("simple/project")
1046 .reviewer("name")
1047 .build()
1048 .unwrap();
1049 api::ignore(endpoint).query(&client).unwrap();
1050 }
1051
1052 #[test]
1053 fn endpoint_my_reaction_emoji() {
1054 let endpoint = ExpectedUrl::builder()
1055 .endpoint("projects/simple%2Fproject/merge_requests")
1056 .add_query_params(&[("my_reaction_emoji", "tada")])
1057 .build()
1058 .unwrap();
1059 let client = SingleTestClient::new_raw(endpoint, "");
1060
1061 let endpoint = MergeRequests::builder()
1062 .project("simple/project")
1063 .my_reaction("tada")
1064 .build()
1065 .unwrap();
1066 api::ignore(endpoint).query(&client).unwrap();
1067 }
1068
1069 #[test]
1070 fn endpoint_my_reaction_emoji_no_reaction() {
1071 let endpoint = ExpectedUrl::builder()
1072 .endpoint("projects/simple%2Fproject/merge_requests")
1073 .add_query_params(&[("my_reaction_emoji", "None")])
1074 .build()
1075 .unwrap();
1076 let client = SingleTestClient::new_raw(endpoint, "");
1077
1078 let endpoint = MergeRequests::builder()
1079 .project("simple/project")
1080 .no_reaction()
1081 .build()
1082 .unwrap();
1083 api::ignore(endpoint).query(&client).unwrap();
1084 }
1085
1086 #[test]
1087 fn endpoint_my_reaction_emoji_any_reaction() {
1088 let endpoint = ExpectedUrl::builder()
1089 .endpoint("projects/simple%2Fproject/merge_requests")
1090 .add_query_params(&[("my_reaction_emoji", "Any")])
1091 .build()
1092 .unwrap();
1093 let client = SingleTestClient::new_raw(endpoint, "");
1094
1095 let endpoint = MergeRequests::builder()
1096 .project("simple/project")
1097 .any_reaction()
1098 .build()
1099 .unwrap();
1100 api::ignore(endpoint).query(&client).unwrap();
1101 }
1102
1103 #[test]
1104 fn endpoint_target_branch() {
1105 let endpoint = ExpectedUrl::builder()
1106 .endpoint("projects/simple%2Fproject/merge_requests")
1107 .add_query_params(&[("target_branch", "target/branch")])
1108 .build()
1109 .unwrap();
1110 let client = SingleTestClient::new_raw(endpoint, "");
1111
1112 let endpoint = MergeRequests::builder()
1113 .project("simple/project")
1114 .target_branch("target/branch")
1115 .build()
1116 .unwrap();
1117 api::ignore(endpoint).query(&client).unwrap();
1118 }
1119
1120 #[test]
1121 fn endpoint_wip() {
1122 let endpoint = ExpectedUrl::builder()
1123 .endpoint("projects/simple%2Fproject/merge_requests")
1124 .add_query_params(&[("wip", "yes")])
1125 .build()
1126 .unwrap();
1127 let client = SingleTestClient::new_raw(endpoint, "");
1128
1129 let endpoint = MergeRequests::builder()
1130 .project("simple/project")
1131 .wip(YesNo::Yes)
1132 .build()
1133 .unwrap();
1134 api::ignore(endpoint).query(&client).unwrap();
1135 }
1136
1137 #[test]
1138 fn endpoint_environment() {
1139 let endpoint = ExpectedUrl::builder()
1140 .endpoint("projects/simple%2Fproject/merge_requests")
1141 .add_query_params(&[("environment", "env")])
1142 .build()
1143 .unwrap();
1144 let client = SingleTestClient::new_raw(endpoint, "");
1145
1146 let endpoint = MergeRequests::builder()
1147 .project("simple/project")
1148 .environment("env")
1149 .build()
1150 .unwrap();
1151 api::ignore(endpoint).query(&client).unwrap();
1152 }
1153
1154 #[test]
1155 fn endpoint_deployed_before() {
1156 let endpoint = ExpectedUrl::builder()
1157 .endpoint("projects/simple%2Fproject/merge_requests")
1158 .add_query_params(&[("deployed_before", "2020-01-01T00:00:00Z")])
1159 .build()
1160 .unwrap();
1161 let client = SingleTestClient::new_raw(endpoint, "");
1162
1163 let endpoint = MergeRequests::builder()
1164 .project("simple/project")
1165 .deployed_before(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
1166 .build()
1167 .unwrap();
1168 api::ignore(endpoint).query(&client).unwrap();
1169 }
1170
1171 #[test]
1172 fn endpoint_deployed_after() {
1173 let endpoint = ExpectedUrl::builder()
1174 .endpoint("projects/simple%2Fproject/merge_requests")
1175 .add_query_params(&[("deployed_after", "2020-01-01T00:00:00Z")])
1176 .build()
1177 .unwrap();
1178 let client = SingleTestClient::new_raw(endpoint, "");
1179
1180 let endpoint = MergeRequests::builder()
1181 .project("simple/project")
1182 .deployed_after(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
1183 .build()
1184 .unwrap();
1185 api::ignore(endpoint).query(&client).unwrap();
1186 }
1187
1188 #[test]
1189 fn endpoint_search() {
1190 let endpoint = ExpectedUrl::builder()
1191 .endpoint("projects/simple%2Fproject/merge_requests")
1192 .add_query_params(&[("search", "query")])
1193 .build()
1194 .unwrap();
1195 let client = SingleTestClient::new_raw(endpoint, "");
1196
1197 let endpoint = MergeRequests::builder()
1198 .project("simple/project")
1199 .search("query")
1200 .build()
1201 .unwrap();
1202 api::ignore(endpoint).query(&client).unwrap();
1203 }
1204
1205 #[test]
1206 fn endpoint_order_by() {
1207 let endpoint = ExpectedUrl::builder()
1208 .endpoint("projects/simple%2Fproject/merge_requests")
1209 .add_query_params(&[("order_by", "created_at")])
1210 .build()
1211 .unwrap();
1212 let client = SingleTestClient::new_raw(endpoint, "");
1213
1214 let endpoint = MergeRequests::builder()
1215 .project("simple/project")
1216 .order_by(MergeRequestOrderBy::CreatedAt)
1217 .build()
1218 .unwrap();
1219 api::ignore(endpoint).query(&client).unwrap();
1220 }
1221
1222 #[test]
1223 fn endpoint_sort() {
1224 let endpoint = ExpectedUrl::builder()
1225 .endpoint("projects/simple%2Fproject/merge_requests")
1226 .add_query_params(&[("sort", "desc")])
1227 .build()
1228 .unwrap();
1229 let client = SingleTestClient::new_raw(endpoint, "");
1230
1231 let endpoint = MergeRequests::builder()
1232 .project("simple/project")
1233 .sort(SortOrder::Descending)
1234 .build()
1235 .unwrap();
1236 api::ignore(endpoint).query(&client).unwrap();
1237 }
1238}