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("scope", self.scope)
307 .push_opt("my_reaction_emoji", self.my_reaction_emoji.as_ref())
308 .push_opt("non_archived", self.non_archived)
309 .push_opt("weight", self.weight)
310 .push_opt("search", self.search.as_ref())
311 .push_opt("in", self.search_in.as_ref())
312 .push_opt("created_after", self.created_after)
313 .push_opt("created_before", self.created_before)
314 .push_opt("updated_after", self.updated_after)
315 .push_opt("updated_before", self.updated_before)
316 .push_opt("confidential", self.confidential)
317 .push_opt("due_date", self.due_date)
318 .push_opt("epic_id", self.epic_id)
319 .push_opt("issue_type", self.issue_type)
320 .push_opt("health_status", self.health_status)
321 .push_opt("order_by", self.order_by)
322 .push_opt("sort", self.sort);
323
324 if let Some(milestone_id) = self.milestone_id.as_ref() {
325 match milestone_id {
326 IssueMilestone::Named(name) => {
327 params.push("milestone", name);
328 },
329 milestone => {
330 params.push("milestone_id", milestone);
331 },
332 }
333 }
334 if let Some(author) = self.author.as_ref() {
335 match author {
336 NameOrId::Name(name) => {
337 params.push("author_username", name);
338 },
339 NameOrId::Id(id) => {
340 params.push("author_id", *id);
341 },
342 }
343 }
344 if let Some(iteration) = self.iteration.as_ref() {
345 iteration.add_params(&mut params);
346 }
347 if let Some(assignee) = self.assignee.as_ref() {
348 assignee.add_params(&mut params);
349 }
350
351 params
352 }
353}
354
355impl Pageable for GroupIssues<'_> {}
356
357#[cfg(test)]
358mod tests {
359 use chrono::{TimeZone, Utc};
360
361 use crate::api::common::SortOrder;
362 use crate::api::issues::{
363 groups::GroupIssues, groups::GroupIssuesBuilderError, IssueDueDateFilter, IssueEpic,
364 IssueHealthStatus, IssueIteration, IssueMilestone, IssueOrderBy, IssueScope,
365 IssueSearchScope, IssueState, IssueType, IssueWeight,
366 };
367 use crate::api::{self, Query};
368 use crate::test::client::{ExpectedUrl, SingleTestClient};
369
370 #[test]
371 fn group_is_needed() {
372 let err = GroupIssues::builder().build().unwrap_err();
373 crate::test::assert_missing_field!(err, GroupIssuesBuilderError, "group");
374 }
375
376 #[test]
377 fn group_is_sufficient() {
378 GroupIssues::builder().group(1).build().unwrap();
379 }
380
381 #[test]
382 fn endpoint() {
383 let endpoint = ExpectedUrl::builder()
384 .endpoint("groups/simple%2Fgroup/issues")
385 .build()
386 .unwrap();
387 let client = SingleTestClient::new_raw(endpoint, "");
388
389 let endpoint = GroupIssues::builder()
390 .group("simple/group")
391 .build()
392 .unwrap();
393 api::ignore(endpoint).query(&client).unwrap();
394 }
395
396 #[test]
397 fn endpoint_iids() {
398 let endpoint = ExpectedUrl::builder()
399 .endpoint("groups/simple%2Fgroup/issues")
400 .add_query_params(&[("iids[]", "1"), ("iids[]", "2")])
401 .build()
402 .unwrap();
403 let client = SingleTestClient::new_raw(endpoint, "");
404
405 let endpoint = GroupIssues::builder()
406 .group("simple/group")
407 .iid(1)
408 .iids([1, 2].iter().copied())
409 .build()
410 .unwrap();
411 api::ignore(endpoint).query(&client).unwrap();
412 }
413
414 #[test]
415 fn endpoint_state() {
416 let endpoint = ExpectedUrl::builder()
417 .endpoint("groups/simple%2Fgroup/issues")
418 .add_query_params(&[("state", "closed")])
419 .build()
420 .unwrap();
421 let client = SingleTestClient::new_raw(endpoint, "");
422
423 let endpoint = GroupIssues::builder()
424 .group("simple/group")
425 .state(IssueState::Closed)
426 .build()
427 .unwrap();
428 api::ignore(endpoint).query(&client).unwrap();
429 }
430
431 #[test]
432 fn endpoint_labels() {
433 let endpoint = ExpectedUrl::builder()
434 .endpoint("groups/simple%2Fgroup/issues")
435 .add_query_params(&[("labels", "label,label1,label2")])
436 .build()
437 .unwrap();
438 let client = SingleTestClient::new_raw(endpoint, "");
439
440 let endpoint = GroupIssues::builder()
441 .group("simple/group")
442 .label("label")
443 .labels(["label1", "label2"].iter().cloned())
444 .build()
445 .unwrap();
446 api::ignore(endpoint).query(&client).unwrap();
447 }
448
449 #[test]
450 fn endpoint_labels_unlabeled() {
451 let endpoint = ExpectedUrl::builder()
452 .endpoint("groups/simple%2Fgroup/issues")
453 .add_query_params(&[("labels", "None")])
454 .build()
455 .unwrap();
456 let client = SingleTestClient::new_raw(endpoint, "");
457
458 let endpoint = GroupIssues::builder()
459 .group("simple/group")
460 .unlabeled()
461 .build()
462 .unwrap();
463 api::ignore(endpoint).query(&client).unwrap();
464 }
465
466 #[test]
467 fn endpoint_labels_any() {
468 let endpoint = ExpectedUrl::builder()
469 .endpoint("groups/simple%2Fgroup/issues")
470 .add_query_params(&[("labels", "Any")])
471 .build()
472 .unwrap();
473 let client = SingleTestClient::new_raw(endpoint, "");
474
475 let endpoint = GroupIssues::builder()
476 .group("simple/group")
477 .with_any_label()
478 .build()
479 .unwrap();
480 api::ignore(endpoint).query(&client).unwrap();
481 }
482
483 #[test]
484 fn endpoint_with_labels_details() {
485 let endpoint = ExpectedUrl::builder()
486 .endpoint("groups/simple%2Fgroup/issues")
487 .add_query_params(&[("with_labels_details", "true")])
488 .build()
489 .unwrap();
490 let client = SingleTestClient::new_raw(endpoint, "");
491
492 let endpoint = GroupIssues::builder()
493 .group("simple/group")
494 .with_labels_details(true)
495 .build()
496 .unwrap();
497 api::ignore(endpoint).query(&client).unwrap();
498 }
499
500 #[test]
501 fn endpoint_epic_id() {
502 let endpoint = ExpectedUrl::builder()
503 .endpoint("groups/simple%2Fgroup/issues")
504 .add_query_params(&[("epic_id", "4")])
505 .build()
506 .unwrap();
507 let client = SingleTestClient::new_raw(endpoint, "");
508
509 let endpoint = GroupIssues::builder()
510 .group("simple/group")
511 .epic_id(IssueEpic::Id(4))
512 .build()
513 .unwrap();
514 api::ignore(endpoint).query(&client).unwrap();
515 }
516
517 #[test]
518 fn endpoint_issue_type() {
519 let endpoint = ExpectedUrl::builder()
520 .endpoint("groups/simple%2Fgroup/issues")
521 .add_query_params(&[("issue_type", "incident")])
522 .build()
523 .unwrap();
524 let client = SingleTestClient::new_raw(endpoint, "");
525
526 let endpoint = GroupIssues::builder()
527 .group("simple/group")
528 .issue_type(IssueType::Incident)
529 .build()
530 .unwrap();
531 api::ignore(endpoint).query(&client).unwrap();
532 }
533
534 #[test]
535 fn endpoint_health_status() {
536 let endpoint = ExpectedUrl::builder()
537 .endpoint("groups/simple%2Fgroup/issues")
538 .add_query_params(&[("health_status", "at_risk")])
539 .build()
540 .unwrap();
541 let client = SingleTestClient::new_raw(endpoint, "");
542
543 let endpoint = GroupIssues::builder()
544 .group("simple/group")
545 .health_status(IssueHealthStatus::AtRisk)
546 .build()
547 .unwrap();
548 api::ignore(endpoint).query(&client).unwrap();
549 }
550
551 #[test]
552 fn endpoint_iteration_none() {
553 let endpoint = ExpectedUrl::builder()
554 .endpoint("groups/simple%2Fgroup/issues")
555 .add_query_params(&[("iteration_id", "None")])
556 .build()
557 .unwrap();
558 let client = SingleTestClient::new_raw(endpoint, "");
559
560 let endpoint = GroupIssues::builder()
561 .group("simple/group")
562 .iteration(IssueIteration::None)
563 .build()
564 .unwrap();
565 api::ignore(endpoint).query(&client).unwrap();
566 }
567
568 #[test]
569 fn endpoint_iteration_any() {
570 let endpoint = ExpectedUrl::builder()
571 .endpoint("groups/simple%2Fgroup/issues")
572 .add_query_params(&[("iteration_id", "Any")])
573 .build()
574 .unwrap();
575 let client = SingleTestClient::new_raw(endpoint, "");
576
577 let endpoint = GroupIssues::builder()
578 .group("simple/group")
579 .iteration(IssueIteration::Any)
580 .build()
581 .unwrap();
582 api::ignore(endpoint).query(&client).unwrap();
583 }
584
585 #[test]
586 fn endpoint_iteration_id() {
587 let endpoint = ExpectedUrl::builder()
588 .endpoint("groups/simple%2Fgroup/issues")
589 .add_query_params(&[("iteration_id", "1")])
590 .build()
591 .unwrap();
592 let client = SingleTestClient::new_raw(endpoint, "");
593
594 let endpoint = GroupIssues::builder()
595 .group("simple/group")
596 .iteration(IssueIteration::Id(1))
597 .build()
598 .unwrap();
599 api::ignore(endpoint).query(&client).unwrap();
600 }
601
602 #[test]
603 fn endpoint_iteration_title() {
604 let endpoint = ExpectedUrl::builder()
605 .endpoint("groups/simple%2Fgroup/issues")
606 .add_query_params(&[("iteration_title", "title")])
607 .build()
608 .unwrap();
609 let client = SingleTestClient::new_raw(endpoint, "");
610
611 let endpoint = GroupIssues::builder()
612 .group("simple/group")
613 .iteration(IssueIteration::Title("title".into()))
614 .build()
615 .unwrap();
616 api::ignore(endpoint).query(&client).unwrap();
617 }
618
619 #[test]
620 fn endpoint_milestone_id() {
621 let endpoint = ExpectedUrl::builder()
622 .endpoint("groups/simple%2Fgroup/issues")
623 .add_query_params(&[("milestone_id", "Upcoming")])
624 .build()
625 .unwrap();
626 let client = SingleTestClient::new_raw(endpoint, "");
627
628 let endpoint = GroupIssues::builder()
629 .group("simple/group")
630 .milestone_id(IssueMilestone::Upcoming)
631 .build()
632 .unwrap();
633 api::ignore(endpoint).query(&client).unwrap();
634 }
635
636 #[test]
637 fn endpoint_milestone_id_named() {
638 let endpoint = ExpectedUrl::builder()
639 .endpoint("groups/simple%2Fgroup/issues")
640 .add_query_params(&[("milestone", "1.0")])
641 .build()
642 .unwrap();
643 let client = SingleTestClient::new_raw(endpoint, "");
644
645 let endpoint = GroupIssues::builder()
646 .group("simple/group")
647 .milestone_id(IssueMilestone::named("1.0"))
648 .build()
649 .unwrap();
650 api::ignore(endpoint).query(&client).unwrap();
651 }
652
653 #[test]
654 #[allow(deprecated)]
655 fn endpoint_milestone_any() {
656 let endpoint = ExpectedUrl::builder()
657 .endpoint("groups/simple%2Fgroup/issues")
658 .add_query_params(&[("milestone_id", "Any")])
659 .build()
660 .unwrap();
661 let client = SingleTestClient::new_raw(endpoint, "");
662
663 let endpoint = GroupIssues::builder()
664 .group("simple/group")
665 .any_milestone()
666 .build()
667 .unwrap();
668 api::ignore(endpoint).query(&client).unwrap();
669 }
670
671 #[test]
672 #[allow(deprecated)]
673 fn endpoint_milestone_none() {
674 let endpoint = ExpectedUrl::builder()
675 .endpoint("groups/simple%2Fgroup/issues")
676 .add_query_params(&[("milestone_id", "None")])
677 .build()
678 .unwrap();
679 let client = SingleTestClient::new_raw(endpoint, "");
680
681 let endpoint = GroupIssues::builder()
682 .group("simple/group")
683 .without_milestone()
684 .build()
685 .unwrap();
686 api::ignore(endpoint).query(&client).unwrap();
687 }
688
689 #[test]
690 #[allow(deprecated)]
691 fn endpoint_milestone_name() {
692 let endpoint = ExpectedUrl::builder()
693 .endpoint("groups/simple%2Fgroup/issues")
694 .add_query_params(&[("milestone", "1.0")])
695 .build()
696 .unwrap();
697 let client = SingleTestClient::new_raw(endpoint, "");
698
699 let endpoint = GroupIssues::builder()
700 .group("simple/group")
701 .milestone("1.0")
702 .build()
703 .unwrap();
704 api::ignore(endpoint).query(&client).unwrap();
705 }
706
707 #[test]
708 fn endpoint_scope() {
709 let endpoint = ExpectedUrl::builder()
710 .endpoint("groups/simple%2Fgroup/issues")
711 .add_query_params(&[("scope", "all")])
712 .build()
713 .unwrap();
714 let client = SingleTestClient::new_raw(endpoint, "");
715
716 let endpoint = GroupIssues::builder()
717 .group("simple/group")
718 .scope(IssueScope::All)
719 .build()
720 .unwrap();
721 api::ignore(endpoint).query(&client).unwrap();
722 }
723
724 #[test]
725 fn endpoint_author_id() {
726 let endpoint = ExpectedUrl::builder()
727 .endpoint("groups/simple%2Fgroup/issues")
728 .add_query_params(&[("author_id", "1")])
729 .build()
730 .unwrap();
731 let client = SingleTestClient::new_raw(endpoint, "");
732
733 let endpoint = GroupIssues::builder()
734 .group("simple/group")
735 .author(1)
736 .build()
737 .unwrap();
738 api::ignore(endpoint).query(&client).unwrap();
739 }
740
741 #[test]
742 fn endpoint_author_name() {
743 let endpoint = ExpectedUrl::builder()
744 .endpoint("groups/simple%2Fgroup/issues")
745 .add_query_params(&[("author_username", "name")])
746 .build()
747 .unwrap();
748 let client = SingleTestClient::new_raw(endpoint, "");
749
750 let endpoint = GroupIssues::builder()
751 .group("simple/group")
752 .author("name")
753 .build()
754 .unwrap();
755 api::ignore(endpoint).query(&client).unwrap();
756 }
757
758 #[test]
759 fn endpoint_assignee_unassigned() {
760 let endpoint = ExpectedUrl::builder()
761 .endpoint("groups/simple%2Fgroup/issues")
762 .add_query_params(&[("assignee_id", "None")])
763 .build()
764 .unwrap();
765 let client = SingleTestClient::new_raw(endpoint, "");
766
767 let endpoint = GroupIssues::builder()
768 .group("simple/group")
769 .unassigned()
770 .build()
771 .unwrap();
772 api::ignore(endpoint).query(&client).unwrap();
773 }
774
775 #[test]
776 fn endpoint_assignee_assigned() {
777 let endpoint = ExpectedUrl::builder()
778 .endpoint("groups/simple%2Fgroup/issues")
779 .add_query_params(&[("assignee_id", "Any")])
780 .build()
781 .unwrap();
782 let client = SingleTestClient::new_raw(endpoint, "");
783
784 let endpoint = GroupIssues::builder()
785 .group("simple/group")
786 .assigned()
787 .build()
788 .unwrap();
789 api::ignore(endpoint).query(&client).unwrap();
790 }
791
792 #[test]
793 fn endpoint_assignee_id() {
794 let endpoint = ExpectedUrl::builder()
795 .endpoint("groups/simple%2Fgroup/issues")
796 .add_query_params(&[("assignee_id", "1")])
797 .build()
798 .unwrap();
799 let client = SingleTestClient::new_raw(endpoint, "");
800
801 let endpoint = GroupIssues::builder()
802 .group("simple/group")
803 .assignee_id(1)
804 .build()
805 .unwrap();
806 api::ignore(endpoint).query(&client).unwrap();
807 }
808
809 #[test]
810 fn endpoint_assignee_user() {
811 let endpoint = ExpectedUrl::builder()
812 .endpoint("groups/simple%2Fgroup/issues")
813 .add_query_params(&[
814 ("assignee_username[]", "name1"),
815 ("assignee_username[]", "name2"),
816 ])
817 .build()
818 .unwrap();
819 let client = SingleTestClient::new_raw(endpoint, "");
820
821 let endpoint = GroupIssues::builder()
822 .group("simple/group")
823 .assignee("name1")
824 .assignees(["name1", "name2"].iter().copied())
825 .build()
826 .unwrap();
827 api::ignore(endpoint).query(&client).unwrap();
828 }
829
830 #[test]
831 fn endpoint_my_reaction_emoji() {
832 let endpoint = ExpectedUrl::builder()
833 .endpoint("groups/simple%2Fgroup/issues")
834 .add_query_params(&[("my_reaction_emoji", "tada")])
835 .build()
836 .unwrap();
837 let client = SingleTestClient::new_raw(endpoint, "");
838
839 let endpoint = GroupIssues::builder()
840 .group("simple/group")
841 .my_reaction("tada")
842 .build()
843 .unwrap();
844 api::ignore(endpoint).query(&client).unwrap();
845 }
846
847 #[test]
848 fn endpoint_my_reaction_emoji_no_reaction() {
849 let endpoint = ExpectedUrl::builder()
850 .endpoint("groups/simple%2Fgroup/issues")
851 .add_query_params(&[("my_reaction_emoji", "None")])
852 .build()
853 .unwrap();
854 let client = SingleTestClient::new_raw(endpoint, "");
855
856 let endpoint = GroupIssues::builder()
857 .group("simple/group")
858 .no_reaction()
859 .build()
860 .unwrap();
861 api::ignore(endpoint).query(&client).unwrap();
862 }
863
864 #[test]
865 fn endpoint_my_reaction_emoji_any_reaction() {
866 let endpoint = ExpectedUrl::builder()
867 .endpoint("groups/simple%2Fgroup/issues")
868 .add_query_params(&[("my_reaction_emoji", "Any")])
869 .build()
870 .unwrap();
871 let client = SingleTestClient::new_raw(endpoint, "");
872
873 let endpoint = GroupIssues::builder()
874 .group("simple/group")
875 .any_reaction()
876 .build()
877 .unwrap();
878 api::ignore(endpoint).query(&client).unwrap();
879 }
880
881 #[test]
882 fn endpoint_non_archived() {
883 let endpoint = ExpectedUrl::builder()
884 .endpoint("groups/simple%2Fgroup/issues")
885 .add_query_params(&[("non_archived", "true")])
886 .build()
887 .unwrap();
888 let client = SingleTestClient::new_raw(endpoint, "");
889
890 let endpoint = GroupIssues::builder()
891 .group("simple/group")
892 .non_archived(true)
893 .build()
894 .unwrap();
895 api::ignore(endpoint).query(&client).unwrap();
896 }
897
898 #[test]
899 fn endpoint_weight() {
900 let endpoint = ExpectedUrl::builder()
901 .endpoint("groups/simple%2Fgroup/issues")
902 .add_query_params(&[("weight", "Any")])
903 .build()
904 .unwrap();
905 let client = SingleTestClient::new_raw(endpoint, "");
906
907 let endpoint = GroupIssues::builder()
908 .group("simple/group")
909 .weight(IssueWeight::Any)
910 .build()
911 .unwrap();
912 api::ignore(endpoint).query(&client).unwrap();
913 }
914
915 #[test]
916 fn endpoint_search() {
917 let endpoint = ExpectedUrl::builder()
918 .endpoint("groups/simple%2Fgroup/issues")
919 .add_query_params(&[("search", "query")])
920 .build()
921 .unwrap();
922 let client = SingleTestClient::new_raw(endpoint, "");
923
924 let endpoint = GroupIssues::builder()
925 .group("simple/group")
926 .search("query")
927 .build()
928 .unwrap();
929 api::ignore(endpoint).query(&client).unwrap();
930 }
931
932 #[test]
933 fn endpoint_search_in() {
934 let endpoint = ExpectedUrl::builder()
935 .endpoint("groups/simple%2Fgroup/issues")
936 .add_query_params(&[("in", "title,description")])
937 .build()
938 .unwrap();
939 let client = SingleTestClient::new_raw(endpoint, "");
940
941 let endpoint = GroupIssues::builder()
942 .group("simple/group")
943 .search_in(IssueSearchScope::Title)
944 .search_in(IssueSearchScope::Description)
945 .build()
946 .unwrap();
947 api::ignore(endpoint).query(&client).unwrap();
948 }
949
950 #[test]
951 fn endpoint_created_after() {
952 let endpoint = ExpectedUrl::builder()
953 .endpoint("groups/simple%2Fgroup/issues")
954 .add_query_params(&[("created_after", "2020-01-01T00:00:00Z")])
955 .build()
956 .unwrap();
957 let client = SingleTestClient::new_raw(endpoint, "");
958
959 let endpoint = GroupIssues::builder()
960 .group("simple/group")
961 .created_after(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
962 .build()
963 .unwrap();
964 api::ignore(endpoint).query(&client).unwrap();
965 }
966
967 #[test]
968 fn endpoint_created_before() {
969 let endpoint = ExpectedUrl::builder()
970 .endpoint("groups/simple%2Fgroup/issues")
971 .add_query_params(&[("created_before", "2020-01-01T00:00:00Z")])
972 .build()
973 .unwrap();
974 let client = SingleTestClient::new_raw(endpoint, "");
975
976 let endpoint = GroupIssues::builder()
977 .group("simple/group")
978 .created_before(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
979 .build()
980 .unwrap();
981 api::ignore(endpoint).query(&client).unwrap();
982 }
983
984 #[test]
985 fn endpoint_updated_after() {
986 let endpoint = ExpectedUrl::builder()
987 .endpoint("groups/simple%2Fgroup/issues")
988 .add_query_params(&[("updated_after", "2020-01-01T00:00:00Z")])
989 .build()
990 .unwrap();
991 let client = SingleTestClient::new_raw(endpoint, "");
992
993 let endpoint = GroupIssues::builder()
994 .group("simple/group")
995 .updated_after(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
996 .build()
997 .unwrap();
998 api::ignore(endpoint).query(&client).unwrap();
999 }
1000
1001 #[test]
1002 fn endpoint_updated_before() {
1003 let endpoint = ExpectedUrl::builder()
1004 .endpoint("groups/simple%2Fgroup/issues")
1005 .add_query_params(&[("updated_before", "2020-01-01T00:00:00Z")])
1006 .build()
1007 .unwrap();
1008 let client = SingleTestClient::new_raw(endpoint, "");
1009
1010 let endpoint = GroupIssues::builder()
1011 .group("simple/group")
1012 .updated_before(Utc.with_ymd_and_hms(2020, 1, 1, 0, 0, 0).unwrap())
1013 .build()
1014 .unwrap();
1015 api::ignore(endpoint).query(&client).unwrap();
1016 }
1017
1018 #[test]
1019 fn endpoint_confidential() {
1020 let endpoint = ExpectedUrl::builder()
1021 .endpoint("groups/simple%2Fgroup/issues")
1022 .add_query_params(&[("confidential", "true")])
1023 .build()
1024 .unwrap();
1025 let client = SingleTestClient::new_raw(endpoint, "");
1026
1027 let endpoint = GroupIssues::builder()
1028 .group("simple/group")
1029 .confidential(true)
1030 .build()
1031 .unwrap();
1032 api::ignore(endpoint).query(&client).unwrap();
1033 }
1034
1035 #[test]
1036 fn endpoint_due_date() {
1037 let endpoint = ExpectedUrl::builder()
1038 .endpoint("groups/simple%2Fgroup/issues")
1039 .add_query_params(&[("due_date", "week")])
1040 .build()
1041 .unwrap();
1042 let client = SingleTestClient::new_raw(endpoint, "");
1043
1044 let endpoint = GroupIssues::builder()
1045 .group("simple/group")
1046 .due_date(IssueDueDateFilter::ThisWeek)
1047 .build()
1048 .unwrap();
1049 api::ignore(endpoint).query(&client).unwrap();
1050 }
1051
1052 #[test]
1053 fn endpoint_order_by() {
1054 let endpoint = ExpectedUrl::builder()
1055 .endpoint("groups/simple%2Fgroup/issues")
1056 .add_query_params(&[("order_by", "due_date")])
1057 .build()
1058 .unwrap();
1059 let client = SingleTestClient::new_raw(endpoint, "");
1060
1061 let endpoint = GroupIssues::builder()
1062 .group("simple/group")
1063 .order_by(IssueOrderBy::DueDate)
1064 .build()
1065 .unwrap();
1066 api::ignore(endpoint).query(&client).unwrap();
1067 }
1068
1069 #[test]
1070 fn endpoint_sort() {
1071 let endpoint = ExpectedUrl::builder()
1072 .endpoint("groups/simple%2Fgroup/issues")
1073 .add_query_params(&[("sort", "desc")])
1074 .build()
1075 .unwrap();
1076 let client = SingleTestClient::new_raw(endpoint, "");
1077
1078 let endpoint = GroupIssues::builder()
1079 .group("simple/group")
1080 .sort(SortOrder::Descending)
1081 .build()
1082 .unwrap();
1083 api::ignore(endpoint).query(&client).unwrap();
1084 }
1085}