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