1use std::borrow::Cow;
8use std::collections::BTreeSet;
9use std::iter;
10
11use chrono::{DateTime, Utc};
12use derive_builder::Builder;
13use http::Method;
14
15use crate::api::common::{CommaSeparatedList, NameOrId, SortOrder};
16use crate::api::helpers::{Labels, ReactionEmoji};
17use crate::api::{Endpoint, Pageable, QueryParams};
18
19use super::Assignee;
20use super::IssueDueDateFilter;
21use super::IssueEpic;
22use super::IssueHealthStatus;
23use super::IssueIteration;
24use super::IssueMilestone;
25use super::IssueOrderBy;
26use super::IssueScope;
27use super::IssueSearchScope;
28use super::IssueState;
29use super::IssueType;
30use super::IssueWeight;
31
32#[derive(Debug, Builder, Clone)]
36#[builder(setter(strip_option))]
37pub struct GroupIssues<'a> {
38 #[builder(setter(into))]
40 group: NameOrId<'a>,
41
42 #[builder(setter(name = "_iids"), default, private)]
44 iids: BTreeSet<u64>,
45 #[builder(default)]
47 state: Option<IssueState>,
48 #[builder(setter(name = "_labels"), default, private)]
50 labels: Option<Labels<'a>>,
51 #[builder(default)]
53 with_labels_details: Option<bool>,
54 #[builder(default)]
56 iteration: Option<IssueIteration<'a>>,
57 #[builder(default)]
59 milestone_id: Option<IssueMilestone<'a>>,
60 #[builder(default)]
62 scope: Option<IssueScope>,
63 #[builder(setter(into), default)]
65 author: Option<NameOrId<'a>>,
66 #[builder(setter(name = "_assignee"), default, private)]
68 assignee: Option<Assignee<'a>>,
69 #[builder(setter(name = "_my_reaction_emoji"), default, private)]
71 my_reaction_emoji: Option<ReactionEmoji<'a>>,
72 #[builder(default)]
74 non_archived: Option<bool>,
75 #[builder(default)]
77 weight: Option<IssueWeight>,
78 #[builder(setter(into), default)]
80 search: Option<Cow<'a, str>>,
81 #[builder(setter(name = "_search_in"), default, private)]
83 search_in: Option<CommaSeparatedList<IssueSearchScope>>,
84 #[builder(default)]
86 created_after: Option<DateTime<Utc>>,
87 #[builder(default)]
89 created_before: Option<DateTime<Utc>>,
90 #[builder(default)]
92 updated_after: Option<DateTime<Utc>>,
93 #[builder(default)]
95 updated_before: Option<DateTime<Utc>>,
96 #[builder(default)]
98 confidential: Option<bool>,
99 #[builder(default)]
101 due_date: Option<IssueDueDateFilter>,
102 #[builder(setter(into), default)]
104 epic_id: Option<IssueEpic>,
105 #[builder(default)]
107 issue_type: Option<IssueType>,
108 #[builder(default)]
110 health_status: Option<IssueHealthStatus>,
111
112 #[builder(default)]
116 order_by: Option<IssueOrderBy>,
117 #[builder(default)]
119 sort: Option<SortOrder>,
120}
121
122impl<'a> GroupIssues<'a> {
123 pub fn builder() -> GroupIssuesBuilder<'a> {
125 GroupIssuesBuilder::default()
126 }
127}
128
129impl<'a> GroupIssuesBuilder<'a> {
130 pub fn iid(&mut self, iid: u64) -> &mut Self {
132 self.iids.get_or_insert_with(BTreeSet::new).insert(iid);
133 self
134 }
135
136 pub fn iids<I>(&mut self, iter: I) -> &mut Self
138 where
139 I: Iterator<Item = u64>,
140 {
141 self.iids.get_or_insert_with(BTreeSet::new).extend(iter);
142 self
143 }
144
145 pub fn unlabeled(&mut self) -> &mut Self {
147 self.labels = Some(Some(Labels::None));
148 self
149 }
150
151 pub fn with_any_label(&mut self) -> &mut Self {
153 self.labels = Some(Some(Labels::Any));
154 self
155 }
156
157 pub fn label<L>(&mut self, label: L) -> &mut Self
159 where
160 L: Into<Cow<'a, str>>,
161 {
162 let label = label.into();
163 let labels = if let Some(Some(Labels::AllOf(mut set))) = self.labels.take() {
164 set.push(label);
165 set
166 } else {
167 iter::once(label).collect()
168 };
169 self.labels = Some(Some(Labels::AllOf(labels)));
170 self
171 }
172
173 pub fn labels<I, L>(&mut self, iter: I) -> &mut Self
175 where
176 I: IntoIterator<Item = L>,
177 L: Into<Cow<'a, str>>,
178 {
179 let iter = iter.into_iter().map(Into::into);
180 let labels = if let Some(Some(Labels::AllOf(mut set))) = self.labels.take() {
181 set.extend(iter);
182 set
183 } else {
184 iter.collect()
185 };
186 self.labels = Some(Some(Labels::AllOf(labels)));
187 self
188 }
189
190 pub fn unassigned(&mut self) -> &mut Self {
192 self.assignee = Some(Some(Assignee::Unassigned));
193 self
194 }
195
196 pub fn assigned(&mut self) -> &mut Self {
198 self.assignee = Some(Some(Assignee::Assigned));
199 self
200 }
201
202 pub fn assignee_id(&mut self, assignee: u64) -> &mut Self {
204 self.assignee = Some(Some(Assignee::Id(assignee)));
205 self
206 }
207
208 pub fn assignee<A>(&mut self, assignee: A) -> &mut Self
210 where
211 A: Into<Cow<'a, str>>,
212 {
213 let assignee = assignee.into();
214 let assignees = if let Some(Some(Assignee::Usernames(mut set))) = self.assignee.take() {
215 set.insert(assignee);
216 set
217 } else {
218 let mut set = BTreeSet::new();
219 set.insert(assignee);
220 set
221 };
222 self.assignee = Some(Some(Assignee::Usernames(assignees)));
223 self
224 }
225
226 pub fn assignees<I, A>(&mut self, iter: I) -> &mut Self
228 where
229 I: IntoIterator<Item = A>,
230 A: Into<Cow<'a, str>>,
231 {
232 let iter = iter.into_iter().map(Into::into);
233 let assignees = if let Some(Some(Assignee::Usernames(mut set))) = self.assignee.take() {
234 set.extend(iter);
235 set
236 } else {
237 iter.collect()
238 };
239 self.assignee = Some(Some(Assignee::Usernames(assignees)));
240 self
241 }
242
243 pub fn no_reaction(&mut self) -> &mut Self {
245 self.my_reaction_emoji = Some(Some(ReactionEmoji::None));
246 self
247 }
248
249 pub fn any_reaction(&mut self) -> &mut Self {
251 self.my_reaction_emoji = Some(Some(ReactionEmoji::Any));
252 self
253 }
254
255 pub fn my_reaction<E>(&mut self, emoji: E) -> &mut Self
257 where
258 E: Into<Cow<'a, str>>,
259 {
260 self.my_reaction_emoji = Some(Some(ReactionEmoji::Emoji(emoji.into())));
261 self
262 }
263
264 pub fn search_in(&mut self, scope: IssueSearchScope) -> &mut Self {
266 self.search_in
267 .get_or_insert(None)
268 .get_or_insert_with(CommaSeparatedList::new)
269 .push(scope);
270 self
271 }
272}
273
274impl Endpoint for GroupIssues<'_> {
275 fn method(&self) -> Method {
276 Method::GET
277 }
278
279 fn endpoint(&self) -> Cow<'static, str> {
280 format!("groups/{}/issues", self.group).into()
281 }
282
283 fn parameters(&self) -> QueryParams<'_> {
284 let mut params = QueryParams::default();
285
286 params
287 .extend(self.iids.iter().map(|&value| ("iids[]", value)))
288 .push_opt("state", self.state)
289 .push_opt("labels", self.labels.as_ref())
290 .push_opt("with_labels_details", self.with_labels_details)
291 .push_opt("scope", self.scope)
292 .push_opt("my_reaction_emoji", self.my_reaction_emoji.as_ref())
293 .push_opt("non_archived", self.non_archived)
294 .push_opt("weight", self.weight)
295 .push_opt("search", self.search.as_ref())
296 .push_opt("in", self.search_in.as_ref())
297 .push_opt("created_after", self.created_after)
298 .push_opt("created_before", self.created_before)
299 .push_opt("updated_after", self.updated_after)
300 .push_opt("updated_before", self.updated_before)
301 .push_opt("confidential", self.confidential)
302 .push_opt("due_date", self.due_date)
303 .push_opt("epic_id", self.epic_id)
304 .push_opt("issue_type", self.issue_type)
305 .push_opt("health_status", self.health_status)
306 .push_opt("order_by", self.order_by)
307 .push_opt("sort", self.sort);
308
309 if let Some(milestone_id) = self.milestone_id.as_ref() {
310 match milestone_id {
311 IssueMilestone::Named(name) => {
312 params.push("milestone", name);
313 },
314 milestone => {
315 params.push("milestone_id", milestone);
316 },
317 }
318 }
319 if let Some(author) = self.author.as_ref() {
320 match author {
321 NameOrId::Name(name) => {
322 params.push("author_username", name);
323 },
324 NameOrId::Id(id) => {
325 params.push("author_id", *id);
326 },
327 }
328 }
329 if let Some(iteration) = self.iteration.as_ref() {
330 iteration.add_params(&mut params);
331 }
332 if let Some(assignee) = self.assignee.as_ref() {
333 assignee.add_params(&mut params);
334 }
335
336 params
337 }
338}
339
340impl Pageable for GroupIssues<'_> {}
341
342#[cfg(test)]
343mod tests {
344 use chrono::{TimeZone, Utc};
345
346 use crate::api::common::SortOrder;
347 use crate::api::issues::{
348 groups::GroupIssues, groups::GroupIssuesBuilderError, IssueDueDateFilter, IssueEpic,
349 IssueHealthStatus, IssueIteration, IssueMilestone, IssueOrderBy, IssueScope,
350 IssueSearchScope, IssueState, IssueType, IssueWeight,
351 };
352 use crate::api::{self, Query};
353 use crate::test::client::{ExpectedUrl, SingleTestClient};
354
355 #[test]
356 fn group_is_needed() {
357 let err = GroupIssues::builder().build().unwrap_err();
358 crate::test::assert_missing_field!(err, GroupIssuesBuilderError, "group");
359 }
360
361 #[test]
362 fn group_is_sufficient() {
363 GroupIssues::builder().group(1).build().unwrap();
364 }
365
366 #[test]
367 fn endpoint() {
368 let endpoint = ExpectedUrl::builder()
369 .endpoint("groups/simple%2Fgroup/issues")
370 .build()
371 .unwrap();
372 let client = SingleTestClient::new_raw(endpoint, "");
373
374 let endpoint = GroupIssues::builder()
375 .group("simple/group")
376 .build()
377 .unwrap();
378 api::ignore(endpoint).query(&client).unwrap();
379 }
380
381 #[test]
382 fn endpoint_iids() {
383 let endpoint = ExpectedUrl::builder()
384 .endpoint("groups/simple%2Fgroup/issues")
385 .add_query_params(&[("iids[]", "1"), ("iids[]", "2")])
386 .build()
387 .unwrap();
388 let client = SingleTestClient::new_raw(endpoint, "");
389
390 let endpoint = GroupIssues::builder()
391 .group("simple/group")
392 .iid(1)
393 .iids([1, 2].iter().copied())
394 .build()
395 .unwrap();
396 api::ignore(endpoint).query(&client).unwrap();
397 }
398
399 #[test]
400 fn endpoint_state() {
401 let endpoint = ExpectedUrl::builder()
402 .endpoint("groups/simple%2Fgroup/issues")
403 .add_query_params(&[("state", "closed")])
404 .build()
405 .unwrap();
406 let client = SingleTestClient::new_raw(endpoint, "");
407
408 let endpoint = GroupIssues::builder()
409 .group("simple/group")
410 .state(IssueState::Closed)
411 .build()
412 .unwrap();
413 api::ignore(endpoint).query(&client).unwrap();
414 }
415
416 #[test]
417 fn endpoint_labels() {
418 let endpoint = ExpectedUrl::builder()
419 .endpoint("groups/simple%2Fgroup/issues")
420 .add_query_params(&[("labels", "label,label1,label2")])
421 .build()
422 .unwrap();
423 let client = SingleTestClient::new_raw(endpoint, "");
424
425 let endpoint = GroupIssues::builder()
426 .group("simple/group")
427 .label("label")
428 .labels(["label1", "label2"].iter().cloned())
429 .build()
430 .unwrap();
431 api::ignore(endpoint).query(&client).unwrap();
432 }
433
434 #[test]
435 fn endpoint_labels_unlabeled() {
436 let endpoint = ExpectedUrl::builder()
437 .endpoint("groups/simple%2Fgroup/issues")
438 .add_query_params(&[("labels", "None")])
439 .build()
440 .unwrap();
441 let client = SingleTestClient::new_raw(endpoint, "");
442
443 let endpoint = GroupIssues::builder()
444 .group("simple/group")
445 .unlabeled()
446 .build()
447 .unwrap();
448 api::ignore(endpoint).query(&client).unwrap();
449 }
450
451 #[test]
452 fn endpoint_labels_any() {
453 let endpoint = ExpectedUrl::builder()
454 .endpoint("groups/simple%2Fgroup/issues")
455 .add_query_params(&[("labels", "Any")])
456 .build()
457 .unwrap();
458 let client = SingleTestClient::new_raw(endpoint, "");
459
460 let endpoint = GroupIssues::builder()
461 .group("simple/group")
462 .with_any_label()
463 .build()
464 .unwrap();
465 api::ignore(endpoint).query(&client).unwrap();
466 }
467
468 #[test]
469 fn endpoint_with_labels_details() {
470 let endpoint = ExpectedUrl::builder()
471 .endpoint("groups/simple%2Fgroup/issues")
472 .add_query_params(&[("with_labels_details", "true")])
473 .build()
474 .unwrap();
475 let client = SingleTestClient::new_raw(endpoint, "");
476
477 let endpoint = GroupIssues::builder()
478 .group("simple/group")
479 .with_labels_details(true)
480 .build()
481 .unwrap();
482 api::ignore(endpoint).query(&client).unwrap();
483 }
484
485 #[test]
486 fn endpoint_epic_id() {
487 let endpoint = ExpectedUrl::builder()
488 .endpoint("groups/simple%2Fgroup/issues")
489 .add_query_params(&[("epic_id", "4")])
490 .build()
491 .unwrap();
492 let client = SingleTestClient::new_raw(endpoint, "");
493
494 let endpoint = GroupIssues::builder()
495 .group("simple/group")
496 .epic_id(4)
497 .build()
498 .unwrap();
499 api::ignore(endpoint).query(&client).unwrap();
500 }
501
502 #[test]
503 fn endpoint_epic_any() {
504 let endpoint = ExpectedUrl::builder()
505 .endpoint("groups/simple%2Fgroup/issues")
506 .add_query_params(&[("epic_id", "Any")])
507 .build()
508 .unwrap();
509 let client = SingleTestClient::new_raw(endpoint, "");
510
511 let endpoint = GroupIssues::builder()
512 .group("simple/group")
513 .epic_id(IssueEpic::Any)
514 .build()
515 .unwrap();
516 api::ignore(endpoint).query(&client).unwrap();
517 }
518
519 #[test]
520 fn endpoint_epic_none() {
521 let endpoint = ExpectedUrl::builder()
522 .endpoint("groups/simple%2Fgroup/issues")
523 .add_query_params(&[("epic_id", "None")])
524 .build()
525 .unwrap();
526 let client = SingleTestClient::new_raw(endpoint, "");
527
528 let endpoint = GroupIssues::builder()
529 .group("simple/group")
530 .epic_id(IssueEpic::None)
531 .build()
532 .unwrap();
533 api::ignore(endpoint).query(&client).unwrap();
534 }
535
536 #[test]
537 fn endpoint_issue_type() {
538 let endpoint = ExpectedUrl::builder()
539 .endpoint("groups/simple%2Fgroup/issues")
540 .add_query_params(&[("issue_type", "incident")])
541 .build()
542 .unwrap();
543 let client = SingleTestClient::new_raw(endpoint, "");
544
545 let endpoint = GroupIssues::builder()
546 .group("simple/group")
547 .issue_type(IssueType::Incident)
548 .build()
549 .unwrap();
550 api::ignore(endpoint).query(&client).unwrap();
551 }
552
553 #[test]
554 fn endpoint_health_status() {
555 let endpoint = ExpectedUrl::builder()
556 .endpoint("groups/simple%2Fgroup/issues")
557 .add_query_params(&[("health_status", "at_risk")])
558 .build()
559 .unwrap();
560 let client = SingleTestClient::new_raw(endpoint, "");
561
562 let endpoint = GroupIssues::builder()
563 .group("simple/group")
564 .health_status(IssueHealthStatus::AtRisk)
565 .build()
566 .unwrap();
567 api::ignore(endpoint).query(&client).unwrap();
568 }
569
570 #[test]
571 fn endpoint_iteration_none() {
572 let endpoint = ExpectedUrl::builder()
573 .endpoint("groups/simple%2Fgroup/issues")
574 .add_query_params(&[("iteration_id", "None")])
575 .build()
576 .unwrap();
577 let client = SingleTestClient::new_raw(endpoint, "");
578
579 let endpoint = GroupIssues::builder()
580 .group("simple/group")
581 .iteration(IssueIteration::None)
582 .build()
583 .unwrap();
584 api::ignore(endpoint).query(&client).unwrap();
585 }
586
587 #[test]
588 fn endpoint_iteration_any() {
589 let endpoint = ExpectedUrl::builder()
590 .endpoint("groups/simple%2Fgroup/issues")
591 .add_query_params(&[("iteration_id", "Any")])
592 .build()
593 .unwrap();
594 let client = SingleTestClient::new_raw(endpoint, "");
595
596 let endpoint = GroupIssues::builder()
597 .group("simple/group")
598 .iteration(IssueIteration::Any)
599 .build()
600 .unwrap();
601 api::ignore(endpoint).query(&client).unwrap();
602 }
603
604 #[test]
605 fn endpoint_iteration_id() {
606 let endpoint = ExpectedUrl::builder()
607 .endpoint("groups/simple%2Fgroup/issues")
608 .add_query_params(&[("iteration_id", "1")])
609 .build()
610 .unwrap();
611 let client = SingleTestClient::new_raw(endpoint, "");
612
613 let endpoint = GroupIssues::builder()
614 .group("simple/group")
615 .iteration(IssueIteration::Id(1))
616 .build()
617 .unwrap();
618 api::ignore(endpoint).query(&client).unwrap();
619 }
620
621 #[test]
622 fn endpoint_iteration_title() {
623 let endpoint = ExpectedUrl::builder()
624 .endpoint("groups/simple%2Fgroup/issues")
625 .add_query_params(&[("iteration_title", "title")])
626 .build()
627 .unwrap();
628 let client = SingleTestClient::new_raw(endpoint, "");
629
630 let endpoint = GroupIssues::builder()
631 .group("simple/group")
632 .iteration(IssueIteration::Title("title".into()))
633 .build()
634 .unwrap();
635 api::ignore(endpoint).query(&client).unwrap();
636 }
637
638 #[test]
639 fn endpoint_milestone_id() {
640 let endpoint = ExpectedUrl::builder()
641 .endpoint("groups/simple%2Fgroup/issues")
642 .add_query_params(&[("milestone_id", "Upcoming")])
643 .build()
644 .unwrap();
645 let client = SingleTestClient::new_raw(endpoint, "");
646
647 let endpoint = GroupIssues::builder()
648 .group("simple/group")
649 .milestone_id(IssueMilestone::Upcoming)
650 .build()
651 .unwrap();
652 api::ignore(endpoint).query(&client).unwrap();
653 }
654
655 #[test]
656 fn endpoint_milestone_id_named() {
657 let endpoint = ExpectedUrl::builder()
658 .endpoint("groups/simple%2Fgroup/issues")
659 .add_query_params(&[("milestone", "1.0")])
660 .build()
661 .unwrap();
662 let client = SingleTestClient::new_raw(endpoint, "");
663
664 let endpoint = GroupIssues::builder()
665 .group("simple/group")
666 .milestone_id(IssueMilestone::named("1.0"))
667 .build()
668 .unwrap();
669 api::ignore(endpoint).query(&client).unwrap();
670 }
671
672 #[test]
673 fn endpoint_scope() {
674 let endpoint = ExpectedUrl::builder()
675 .endpoint("groups/simple%2Fgroup/issues")
676 .add_query_params(&[("scope", "all")])
677 .build()
678 .unwrap();
679 let client = SingleTestClient::new_raw(endpoint, "");
680
681 let endpoint = GroupIssues::builder()
682 .group("simple/group")
683 .scope(IssueScope::All)
684 .build()
685 .unwrap();
686 api::ignore(endpoint).query(&client).unwrap();
687 }
688
689 #[test]
690 fn endpoint_author_id() {
691 let endpoint = ExpectedUrl::builder()
692 .endpoint("groups/simple%2Fgroup/issues")
693 .add_query_params(&[("author_id", "1")])
694 .build()
695 .unwrap();
696 let client = SingleTestClient::new_raw(endpoint, "");
697
698 let endpoint = GroupIssues::builder()
699 .group("simple/group")
700 .author(1)
701 .build()
702 .unwrap();
703 api::ignore(endpoint).query(&client).unwrap();
704 }
705
706 #[test]
707 fn endpoint_author_name() {
708 let endpoint = ExpectedUrl::builder()
709 .endpoint("groups/simple%2Fgroup/issues")
710 .add_query_params(&[("author_username", "name")])
711 .build()
712 .unwrap();
713 let client = SingleTestClient::new_raw(endpoint, "");
714
715 let endpoint = GroupIssues::builder()
716 .group("simple/group")
717 .author("name")
718 .build()
719 .unwrap();
720 api::ignore(endpoint).query(&client).unwrap();
721 }
722
723 #[test]
724 fn endpoint_assignee_unassigned() {
725 let endpoint = ExpectedUrl::builder()
726 .endpoint("groups/simple%2Fgroup/issues")
727 .add_query_params(&[("assignee_id", "None")])
728 .build()
729 .unwrap();
730 let client = SingleTestClient::new_raw(endpoint, "");
731
732 let endpoint = GroupIssues::builder()
733 .group("simple/group")
734 .unassigned()
735 .build()
736 .unwrap();
737 api::ignore(endpoint).query(&client).unwrap();
738 }
739
740 #[test]
741 fn endpoint_assignee_assigned() {
742 let endpoint = ExpectedUrl::builder()
743 .endpoint("groups/simple%2Fgroup/issues")
744 .add_query_params(&[("assignee_id", "Any")])
745 .build()
746 .unwrap();
747 let client = SingleTestClient::new_raw(endpoint, "");
748
749 let endpoint = GroupIssues::builder()
750 .group("simple/group")
751 .assigned()
752 .build()
753 .unwrap();
754 api::ignore(endpoint).query(&client).unwrap();
755 }
756
757 #[test]
758 fn endpoint_assignee_id() {
759 let endpoint = ExpectedUrl::builder()
760 .endpoint("groups/simple%2Fgroup/issues")
761 .add_query_params(&[("assignee_id", "1")])
762 .build()
763 .unwrap();
764 let client = SingleTestClient::new_raw(endpoint, "");
765
766 let endpoint = GroupIssues::builder()
767 .group("simple/group")
768 .assignee_id(1)
769 .build()
770 .unwrap();
771 api::ignore(endpoint).query(&client).unwrap();
772 }
773
774 #[test]
775 fn endpoint_assignee_user() {
776 let endpoint = ExpectedUrl::builder()
777 .endpoint("groups/simple%2Fgroup/issues")
778 .add_query_params(&[
779 ("assignee_username[]", "name1"),
780 ("assignee_username[]", "name2"),
781 ])
782 .build()
783 .unwrap();
784 let client = SingleTestClient::new_raw(endpoint, "");
785
786 let endpoint = GroupIssues::builder()
787 .group("simple/group")
788 .assignee("name1")
789 .assignees(["name1", "name2"].iter().copied())
790 .build()
791 .unwrap();
792 api::ignore(endpoint).query(&client).unwrap();
793 }
794
795 #[test]
796 fn endpoint_my_reaction_emoji() {
797 let endpoint = ExpectedUrl::builder()
798 .endpoint("groups/simple%2Fgroup/issues")
799 .add_query_params(&[("my_reaction_emoji", "tada")])
800 .build()
801 .unwrap();
802 let client = SingleTestClient::new_raw(endpoint, "");
803
804 let endpoint = GroupIssues::builder()
805 .group("simple/group")
806 .my_reaction("tada")
807 .build()
808 .unwrap();
809 api::ignore(endpoint).query(&client).unwrap();
810 }
811
812 #[test]
813 fn endpoint_my_reaction_emoji_no_reaction() {
814 let endpoint = ExpectedUrl::builder()
815 .endpoint("groups/simple%2Fgroup/issues")
816 .add_query_params(&[("my_reaction_emoji", "None")])
817 .build()
818 .unwrap();
819 let client = SingleTestClient::new_raw(endpoint, "");
820
821 let endpoint = GroupIssues::builder()
822 .group("simple/group")
823 .no_reaction()
824 .build()
825 .unwrap();
826 api::ignore(endpoint).query(&client).unwrap();
827 }
828
829 #[test]
830 fn endpoint_my_reaction_emoji_any_reaction() {
831 let endpoint = ExpectedUrl::builder()
832 .endpoint("groups/simple%2Fgroup/issues")
833 .add_query_params(&[("my_reaction_emoji", "Any")])
834 .build()
835 .unwrap();
836 let client = SingleTestClient::new_raw(endpoint, "");
837
838 let endpoint = GroupIssues::builder()
839 .group("simple/group")
840 .any_reaction()
841 .build()
842 .unwrap();
843 api::ignore(endpoint).query(&client).unwrap();
844 }
845
846 #[test]
847 fn endpoint_non_archived() {
848 let endpoint = ExpectedUrl::builder()
849 .endpoint("groups/simple%2Fgroup/issues")
850 .add_query_params(&[("non_archived", "true")])
851 .build()
852 .unwrap();
853 let client = SingleTestClient::new_raw(endpoint, "");
854
855 let endpoint = GroupIssues::builder()
856 .group("simple/group")
857 .non_archived(true)
858 .build()
859 .unwrap();
860 api::ignore(endpoint).query(&client).unwrap();
861 }
862
863 #[test]
864 fn endpoint_weight() {
865 let endpoint = ExpectedUrl::builder()
866 .endpoint("groups/simple%2Fgroup/issues")
867 .add_query_params(&[("weight", "Any")])
868 .build()
869 .unwrap();
870 let client = SingleTestClient::new_raw(endpoint, "");
871
872 let endpoint = GroupIssues::builder()
873 .group("simple/group")
874 .weight(IssueWeight::Any)
875 .build()
876 .unwrap();
877 api::ignore(endpoint).query(&client).unwrap();
878 }
879
880 #[test]
881 fn endpoint_search() {
882 let endpoint = ExpectedUrl::builder()
883 .endpoint("groups/simple%2Fgroup/issues")
884 .add_query_params(&[("search", "query")])
885 .build()
886 .unwrap();
887 let client = SingleTestClient::new_raw(endpoint, "");
888
889 let endpoint = GroupIssues::builder()
890 .group("simple/group")
891 .search("query")
892 .build()
893 .unwrap();
894 api::ignore(endpoint).query(&client).unwrap();
895 }
896
897 #[test]
898 fn endpoint_search_in() {
899 let endpoint = ExpectedUrl::builder()
900 .endpoint("groups/simple%2Fgroup/issues")
901 .add_query_params(&[("in", "title,description")])
902 .build()
903 .unwrap();
904 let client = SingleTestClient::new_raw(endpoint, "");
905
906 let endpoint = GroupIssues::builder()
907 .group("simple/group")
908 .search_in(IssueSearchScope::Title)
909 .search_in(IssueSearchScope::Description)
910 .build()
911 .unwrap();
912 api::ignore(endpoint).query(&client).unwrap();
913 }
914
915 #[test]
916 fn endpoint_created_after() {
917 let endpoint = ExpectedUrl::builder()
918 .endpoint("groups/simple%2Fgroup/issues")
919 .add_query_params(&[("created_after", "2020-01-01T00:00:00Z")])
920 .build()
921 .unwrap();
922 let client = SingleTestClient::new_raw(endpoint, "");
923
924 let endpoint = GroupIssues::builder()
925 .group("simple/group")
926 .created_after(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
927 .build()
928 .unwrap();
929 api::ignore(endpoint).query(&client).unwrap();
930 }
931
932 #[test]
933 fn endpoint_created_before() {
934 let endpoint = ExpectedUrl::builder()
935 .endpoint("groups/simple%2Fgroup/issues")
936 .add_query_params(&[("created_before", "2020-01-01T00:00:00Z")])
937 .build()
938 .unwrap();
939 let client = SingleTestClient::new_raw(endpoint, "");
940
941 let endpoint = GroupIssues::builder()
942 .group("simple/group")
943 .created_before(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
944 .build()
945 .unwrap();
946 api::ignore(endpoint).query(&client).unwrap();
947 }
948
949 #[test]
950 fn endpoint_updated_after() {
951 let endpoint = ExpectedUrl::builder()
952 .endpoint("groups/simple%2Fgroup/issues")
953 .add_query_params(&[("updated_after", "2020-01-01T00:00:00Z")])
954 .build()
955 .unwrap();
956 let client = SingleTestClient::new_raw(endpoint, "");
957
958 let endpoint = GroupIssues::builder()
959 .group("simple/group")
960 .updated_after(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
961 .build()
962 .unwrap();
963 api::ignore(endpoint).query(&client).unwrap();
964 }
965
966 #[test]
967 fn endpoint_updated_before() {
968 let endpoint = ExpectedUrl::builder()
969 .endpoint("groups/simple%2Fgroup/issues")
970 .add_query_params(&[("updated_before", "2020-01-01T00:00:00Z")])
971 .build()
972 .unwrap();
973 let client = SingleTestClient::new_raw(endpoint, "");
974
975 let endpoint = GroupIssues::builder()
976 .group("simple/group")
977 .updated_before(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
978 .build()
979 .unwrap();
980 api::ignore(endpoint).query(&client).unwrap();
981 }
982
983 #[test]
984 fn endpoint_confidential() {
985 let endpoint = ExpectedUrl::builder()
986 .endpoint("groups/simple%2Fgroup/issues")
987 .add_query_params(&[("confidential", "true")])
988 .build()
989 .unwrap();
990 let client = SingleTestClient::new_raw(endpoint, "");
991
992 let endpoint = GroupIssues::builder()
993 .group("simple/group")
994 .confidential(true)
995 .build()
996 .unwrap();
997 api::ignore(endpoint).query(&client).unwrap();
998 }
999
1000 #[test]
1001 fn endpoint_due_date() {
1002 let endpoint = ExpectedUrl::builder()
1003 .endpoint("groups/simple%2Fgroup/issues")
1004 .add_query_params(&[("due_date", "week")])
1005 .build()
1006 .unwrap();
1007 let client = SingleTestClient::new_raw(endpoint, "");
1008
1009 let endpoint = GroupIssues::builder()
1010 .group("simple/group")
1011 .due_date(IssueDueDateFilter::ThisWeek)
1012 .build()
1013 .unwrap();
1014 api::ignore(endpoint).query(&client).unwrap();
1015 }
1016
1017 #[test]
1018 fn endpoint_order_by() {
1019 let endpoint = ExpectedUrl::builder()
1020 .endpoint("groups/simple%2Fgroup/issues")
1021 .add_query_params(&[("order_by", "due_date")])
1022 .build()
1023 .unwrap();
1024 let client = SingleTestClient::new_raw(endpoint, "");
1025
1026 let endpoint = GroupIssues::builder()
1027 .group("simple/group")
1028 .order_by(IssueOrderBy::DueDate)
1029 .build()
1030 .unwrap();
1031 api::ignore(endpoint).query(&client).unwrap();
1032 }
1033
1034 #[test]
1035 fn endpoint_sort() {
1036 let endpoint = ExpectedUrl::builder()
1037 .endpoint("groups/simple%2Fgroup/issues")
1038 .add_query_params(&[("sort", "desc")])
1039 .build()
1040 .unwrap();
1041 let client = SingleTestClient::new_raw(endpoint, "");
1042
1043 let endpoint = GroupIssues::builder()
1044 .group("simple/group")
1045 .sort(SortOrder::Descending)
1046 .build()
1047 .unwrap();
1048 api::ignore(endpoint).query(&client).unwrap();
1049 }
1050}