gitlab/api/groups/hooks/
create.rs

1// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
2// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
3// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
4// option. This file may not be copied, modified, or distributed
5// except according to those terms.
6
7use derive_builder::Builder;
8
9use crate::api::common::NameOrId;
10use crate::api::endpoint_prelude::*;
11use crate::api::projects::hooks::BranchFilterStrategy;
12
13/// Create a new webhook for a group.
14#[derive(Debug, Builder, Clone)]
15#[builder(setter(strip_option))]
16pub struct CreateHook<'a> {
17    /// The group to create a webhook within.
18    #[builder(setter(into))]
19    group: NameOrId<'a>,
20
21    /// The URL for the webhook to contact.
22    #[builder(setter(into))]
23    url: Cow<'a, str>,
24    /// The name of the hook.
25    #[builder(setter(into), default)]
26    name: Option<Cow<'a, str>>,
27    /// The description of the hook.
28    #[builder(setter(into), default)]
29    description: Option<Cow<'a, str>>,
30
31    /// Whether to send push events for this webhook or not.
32    #[builder(default)]
33    push_events: Option<bool>,
34    /// Filter which branches send push events for this webhook.
35    #[builder(setter(into), default)]
36    push_events_branch_filter: Option<Cow<'a, str>>,
37    /// The strategy to use for `push_events_branch_filter`.
38    #[builder(default)]
39    branch_filter_strategy: Option<BranchFilterStrategy>,
40    /// Whether to send issue events for this webhook or not.
41    #[builder(default)]
42    issues_events: Option<bool>,
43    /// Whether to send confidential issue events for this webhook or not.
44    #[builder(default)]
45    confidential_issues_events: Option<bool>,
46    /// Whether to send merge request events for this webhook or not.
47    #[builder(default)]
48    merge_requests_events: Option<bool>,
49    /// Whether to send tag events for this webhook or not.
50    #[builder(default)]
51    tag_push_events: Option<bool>,
52    /// Whether to send note (comment) events for this webhook or not.
53    #[builder(default)]
54    note_events: Option<bool>,
55    /// Whether to send confidential note (comment) events for this webhook or not.
56    #[builder(default)]
57    confidential_note_events: Option<bool>,
58    /// Whether to send job events for this webhook or not.
59    #[builder(default)]
60    job_events: Option<bool>,
61    /// Whether to send pipeline events for this webhook or not.
62    #[builder(default)]
63    pipeline_events: Option<bool>,
64    /// Whether to send wiki page events for this webhook or not.
65    #[builder(default)]
66    wiki_page_events: Option<bool>,
67    /// Whether to send deployment events for this webhook or not.
68    #[builder(default)]
69    deployment_events: Option<bool>,
70    /// Whether to send feature flag events for this webhook or not.
71    #[builder(default)]
72    feature_flag_events: Option<bool>,
73    /// Whether to send release events for this webhook or not.
74    #[builder(default)]
75    releases_events: Option<bool>,
76    /// Whether to send subgroup events for this webhook or not.
77    #[builder(default)]
78    subgroup_events: Option<bool>,
79    /// Whether to send member events for this webhook or not.
80    #[builder(default)]
81    member_events: Option<bool>,
82    /// Whether to send resource access token events for this webhook or not.
83    #[builder(default)]
84    resource_access_token_events: Option<bool>,
85    /// The template to use for the custom webhook.
86    #[builder(setter(into), default)]
87    custom_webhook_template: Option<Cow<'a, str>>,
88    /// Custom headers to send with the webhook.
89    #[builder(setter(name = "_custom_headers"), default, private)]
90    custom_headers: Vec<(Cow<'a, str>, Cow<'a, str>)>,
91
92    /// Whether to verify SSL/TLS certificates for the webhook endpoint or not.
93    #[builder(default)]
94    enable_ssl_verification: Option<bool>,
95    /// A secret token to include in webhook deliveries.
96    ///
97    /// This may be used to ensure that the webhook is actually coming from the GitLab instance.
98    #[builder(setter(into), default)]
99    token: Option<Cow<'a, str>>,
100}
101
102impl<'a> CreateHook<'a> {
103    /// Create a builder for the endpoint.
104    pub fn builder() -> CreateHookBuilder<'a> {
105        CreateHookBuilder::default()
106    }
107}
108
109impl<'a> CreateHookBuilder<'a> {
110    /// Add a single custom header.
111    pub fn custom_header<K, V>(&mut self, key: K, value: V) -> &mut Self
112    where
113        K: Into<Cow<'a, str>>,
114        V: Into<Cow<'a, str>>,
115    {
116        self.custom_headers
117            .get_or_insert_with(Vec::new)
118            .push((key.into(), value.into()));
119        self
120    }
121
122    /// Add multiple custom headers.
123    pub fn custom_headers<I, K, V>(&mut self, iter: I) -> &mut Self
124    where
125        I: Iterator<Item = (K, V)>,
126        K: Into<Cow<'a, str>>,
127        V: Into<Cow<'a, str>>,
128    {
129        self.custom_headers
130            .get_or_insert_with(Vec::new)
131            .extend(iter.map(|(k, v)| (k.into(), v.into())));
132        self
133    }
134}
135
136impl Endpoint for CreateHook<'_> {
137    fn method(&self) -> Method {
138        Method::POST
139    }
140
141    fn endpoint(&self) -> Cow<'static, str> {
142        format!("groups/{}/hooks", self.group).into()
143    }
144
145    fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
146        let mut params = FormParams::default();
147
148        params
149            .push("url", &self.url)
150            .push_opt("name", self.name.as_ref())
151            .push_opt("description", self.description.as_ref())
152            .push_opt("push_events", self.push_events)
153            .push_opt(
154                "push_events_branch_filter",
155                self.push_events_branch_filter.as_ref(),
156            )
157            .push_opt("branch_filter_strategy", self.branch_filter_strategy)
158            .push_opt("issues_events", self.issues_events)
159            .push_opt(
160                "confidential_issues_events",
161                self.confidential_issues_events,
162            )
163            .push_opt("merge_requests_events", self.merge_requests_events)
164            .push_opt("tag_push_events", self.tag_push_events)
165            .push_opt("note_events", self.note_events)
166            .push_opt("confidential_note_events", self.confidential_note_events)
167            .push_opt("job_events", self.job_events)
168            .push_opt("pipeline_events", self.pipeline_events)
169            .push_opt("wiki_page_events", self.wiki_page_events)
170            .push_opt("deployment_events", self.deployment_events)
171            .push_opt("feature_flag_events", self.feature_flag_events)
172            .push_opt("releases_events", self.releases_events)
173            .push_opt("subgroup_events", self.subgroup_events)
174            .push_opt("member_events", self.member_events)
175            .push_opt(
176                "resource_access_token_events",
177                self.resource_access_token_events,
178            )
179            .push_opt(
180                "custom_webhook_template",
181                self.custom_webhook_template.as_ref(),
182            )
183            .push_opt("enable_ssl_verification", self.enable_ssl_verification)
184            .push_opt("token", self.token.as_ref());
185
186        for (key, value) in &self.custom_headers {
187            params.push(format!("custom_headers[{}]", key), value);
188        }
189
190        params.into_body()
191    }
192}
193
194#[cfg(test)]
195mod tests {
196    use http::Method;
197
198    use crate::api::groups::hooks::{CreateHook, CreateHookBuilderError};
199    use crate::api::projects::hooks::BranchFilterStrategy;
200    use crate::api::{self, Query};
201    use crate::test::client::{ExpectedUrl, SingleTestClient};
202
203    #[test]
204    fn group_and_url_are_necessary() {
205        let err = CreateHook::builder().build().unwrap_err();
206        crate::test::assert_missing_field!(err, CreateHookBuilderError, "group");
207    }
208
209    #[test]
210    fn group_is_necessary() {
211        let err = CreateHook::builder().url("url").build().unwrap_err();
212        crate::test::assert_missing_field!(err, CreateHookBuilderError, "group");
213    }
214
215    #[test]
216    fn url_is_necessary() {
217        let err = CreateHook::builder().group("group").build().unwrap_err();
218        crate::test::assert_missing_field!(err, CreateHookBuilderError, "url");
219    }
220
221    #[test]
222    fn group_and_url_are_sufficient() {
223        CreateHook::builder()
224            .group("group")
225            .url("url")
226            .build()
227            .unwrap();
228    }
229
230    #[test]
231    fn endpoint() {
232        let endpoint = ExpectedUrl::builder()
233            .method(Method::POST)
234            .endpoint("groups/simple%2Fgroup/hooks")
235            .content_type("application/x-www-form-urlencoded")
236            .body_str("url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo")
237            .build()
238            .unwrap();
239        let client = SingleTestClient::new_raw(endpoint, "");
240
241        let endpoint = CreateHook::builder()
242            .group("simple/group")
243            .url("https://test.invalid/path?some=foo")
244            .build()
245            .unwrap();
246        api::ignore(endpoint).query(&client).unwrap();
247    }
248
249    #[test]
250    fn endpoint_name() {
251        let endpoint = ExpectedUrl::builder()
252            .method(Method::POST)
253            .endpoint("groups/simple%2Fgroup/hooks")
254            .content_type("application/x-www-form-urlencoded")
255            .body_str(concat!(
256                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
257                "&name=my-hook",
258            ))
259            .build()
260            .unwrap();
261        let client = SingleTestClient::new_raw(endpoint, "");
262
263        let endpoint = CreateHook::builder()
264            .group("simple/group")
265            .url("https://test.invalid/path?some=foo")
266            .name("my-hook")
267            .build()
268            .unwrap();
269        api::ignore(endpoint).query(&client).unwrap();
270    }
271
272    #[test]
273    fn endpoint_description() {
274        let endpoint = ExpectedUrl::builder()
275            .method(Method::POST)
276            .endpoint("groups/simple%2Fgroup/hooks")
277            .content_type("application/x-www-form-urlencoded")
278            .body_str(concat!(
279                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
280                "&description=A+test+hook",
281            ))
282            .build()
283            .unwrap();
284        let client = SingleTestClient::new_raw(endpoint, "");
285
286        let endpoint = CreateHook::builder()
287            .group("simple/group")
288            .url("https://test.invalid/path?some=foo")
289            .description("A test hook")
290            .build()
291            .unwrap();
292        api::ignore(endpoint).query(&client).unwrap();
293    }
294
295    #[test]
296    fn endpoint_push_events() {
297        let endpoint = ExpectedUrl::builder()
298            .method(Method::POST)
299            .endpoint("groups/simple%2Fgroup/hooks")
300            .content_type("application/x-www-form-urlencoded")
301            .body_str(concat!(
302                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
303                "&push_events=true",
304            ))
305            .build()
306            .unwrap();
307        let client = SingleTestClient::new_raw(endpoint, "");
308
309        let endpoint = CreateHook::builder()
310            .group("simple/group")
311            .url("https://test.invalid/path?some=foo")
312            .push_events(true)
313            .build()
314            .unwrap();
315        api::ignore(endpoint).query(&client).unwrap();
316    }
317
318    #[test]
319    fn endpoint_push_events_branch_filter() {
320        let endpoint = ExpectedUrl::builder()
321            .method(Method::POST)
322            .endpoint("groups/simple%2Fgroup/hooks")
323            .content_type("application/x-www-form-urlencoded")
324            .body_str(concat!(
325                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
326                "&push_events_branch_filter=branch%2F*%2Ffilter",
327            ))
328            .build()
329            .unwrap();
330        let client = SingleTestClient::new_raw(endpoint, "");
331
332        let endpoint = CreateHook::builder()
333            .group("simple/group")
334            .url("https://test.invalid/path?some=foo")
335            .push_events_branch_filter("branch/*/filter")
336            .build()
337            .unwrap();
338        api::ignore(endpoint).query(&client).unwrap();
339    }
340
341    #[test]
342    fn endpoint_branch_filter_strategy() {
343        let endpoint = ExpectedUrl::builder()
344            .method(Method::POST)
345            .endpoint("groups/simple%2Fgroup/hooks")
346            .content_type("application/x-www-form-urlencoded")
347            .body_str(concat!(
348                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
349                "&branch_filter_strategy=regex",
350            ))
351            .build()
352            .unwrap();
353        let client = SingleTestClient::new_raw(endpoint, "");
354
355        let endpoint = CreateHook::builder()
356            .group("simple/group")
357            .url("https://test.invalid/path?some=foo")
358            .branch_filter_strategy(BranchFilterStrategy::Regex)
359            .build()
360            .unwrap();
361        api::ignore(endpoint).query(&client).unwrap();
362    }
363
364    #[test]
365    fn endpoint_issues_events() {
366        let endpoint = ExpectedUrl::builder()
367            .method(Method::POST)
368            .endpoint("groups/simple%2Fgroup/hooks")
369            .content_type("application/x-www-form-urlencoded")
370            .body_str(concat!(
371                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
372                "&issues_events=false",
373            ))
374            .build()
375            .unwrap();
376        let client = SingleTestClient::new_raw(endpoint, "");
377
378        let endpoint = CreateHook::builder()
379            .group("simple/group")
380            .url("https://test.invalid/path?some=foo")
381            .issues_events(false)
382            .build()
383            .unwrap();
384        api::ignore(endpoint).query(&client).unwrap();
385    }
386
387    #[test]
388    fn endpoint_confidential_issues_events() {
389        let endpoint = ExpectedUrl::builder()
390            .method(Method::POST)
391            .endpoint("groups/simple%2Fgroup/hooks")
392            .content_type("application/x-www-form-urlencoded")
393            .body_str(concat!(
394                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
395                "&confidential_issues_events=false",
396            ))
397            .build()
398            .unwrap();
399        let client = SingleTestClient::new_raw(endpoint, "");
400
401        let endpoint = CreateHook::builder()
402            .group("simple/group")
403            .url("https://test.invalid/path?some=foo")
404            .confidential_issues_events(false)
405            .build()
406            .unwrap();
407        api::ignore(endpoint).query(&client).unwrap();
408    }
409
410    #[test]
411    fn endpoint_merge_requests_events() {
412        let endpoint = ExpectedUrl::builder()
413            .method(Method::POST)
414            .endpoint("groups/simple%2Fgroup/hooks")
415            .content_type("application/x-www-form-urlencoded")
416            .body_str(concat!(
417                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
418                "&merge_requests_events=false",
419            ))
420            .build()
421            .unwrap();
422        let client = SingleTestClient::new_raw(endpoint, "");
423
424        let endpoint = CreateHook::builder()
425            .group("simple/group")
426            .url("https://test.invalid/path?some=foo")
427            .merge_requests_events(false)
428            .build()
429            .unwrap();
430        api::ignore(endpoint).query(&client).unwrap();
431    }
432
433    #[test]
434    fn endpoint_tag_push_events() {
435        let endpoint = ExpectedUrl::builder()
436            .method(Method::POST)
437            .endpoint("groups/simple%2Fgroup/hooks")
438            .content_type("application/x-www-form-urlencoded")
439            .body_str(concat!(
440                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
441                "&tag_push_events=false",
442            ))
443            .build()
444            .unwrap();
445        let client = SingleTestClient::new_raw(endpoint, "");
446
447        let endpoint = CreateHook::builder()
448            .group("simple/group")
449            .url("https://test.invalid/path?some=foo")
450            .tag_push_events(false)
451            .build()
452            .unwrap();
453        api::ignore(endpoint).query(&client).unwrap();
454    }
455
456    #[test]
457    fn endpoint_note_events() {
458        let endpoint = ExpectedUrl::builder()
459            .method(Method::POST)
460            .endpoint("groups/simple%2Fgroup/hooks")
461            .content_type("application/x-www-form-urlencoded")
462            .body_str(concat!(
463                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
464                "&note_events=false",
465            ))
466            .build()
467            .unwrap();
468        let client = SingleTestClient::new_raw(endpoint, "");
469
470        let endpoint = CreateHook::builder()
471            .group("simple/group")
472            .url("https://test.invalid/path?some=foo")
473            .note_events(false)
474            .build()
475            .unwrap();
476        api::ignore(endpoint).query(&client).unwrap();
477    }
478
479    #[test]
480    fn endpoint_confidential_note_events() {
481        let endpoint = ExpectedUrl::builder()
482            .method(Method::POST)
483            .endpoint("groups/simple%2Fgroup/hooks")
484            .content_type("application/x-www-form-urlencoded")
485            .body_str(concat!(
486                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
487                "&confidential_note_events=false",
488            ))
489            .build()
490            .unwrap();
491        let client = SingleTestClient::new_raw(endpoint, "");
492
493        let endpoint = CreateHook::builder()
494            .group("simple/group")
495            .url("https://test.invalid/path?some=foo")
496            .confidential_note_events(false)
497            .build()
498            .unwrap();
499        api::ignore(endpoint).query(&client).unwrap();
500    }
501
502    #[test]
503    fn endpoint_job_events() {
504        let endpoint = ExpectedUrl::builder()
505            .method(Method::POST)
506            .endpoint("groups/simple%2Fgroup/hooks")
507            .content_type("application/x-www-form-urlencoded")
508            .body_str(concat!(
509                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
510                "&job_events=false",
511            ))
512            .build()
513            .unwrap();
514        let client = SingleTestClient::new_raw(endpoint, "");
515
516        let endpoint = CreateHook::builder()
517            .group("simple/group")
518            .url("https://test.invalid/path?some=foo")
519            .job_events(false)
520            .build()
521            .unwrap();
522        api::ignore(endpoint).query(&client).unwrap();
523    }
524
525    #[test]
526    fn endpoint_pipeline_events() {
527        let endpoint = ExpectedUrl::builder()
528            .method(Method::POST)
529            .endpoint("groups/simple%2Fgroup/hooks")
530            .content_type("application/x-www-form-urlencoded")
531            .body_str(concat!(
532                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
533                "&pipeline_events=false",
534            ))
535            .build()
536            .unwrap();
537        let client = SingleTestClient::new_raw(endpoint, "");
538
539        let endpoint = CreateHook::builder()
540            .group("simple/group")
541            .url("https://test.invalid/path?some=foo")
542            .pipeline_events(false)
543            .build()
544            .unwrap();
545        api::ignore(endpoint).query(&client).unwrap();
546    }
547
548    #[test]
549    fn endpoint_wiki_page_events() {
550        let endpoint = ExpectedUrl::builder()
551            .method(Method::POST)
552            .endpoint("groups/simple%2Fgroup/hooks")
553            .content_type("application/x-www-form-urlencoded")
554            .body_str(concat!(
555                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
556                "&wiki_page_events=false",
557            ))
558            .build()
559            .unwrap();
560        let client = SingleTestClient::new_raw(endpoint, "");
561
562        let endpoint = CreateHook::builder()
563            .group("simple/group")
564            .url("https://test.invalid/path?some=foo")
565            .wiki_page_events(false)
566            .build()
567            .unwrap();
568        api::ignore(endpoint).query(&client).unwrap();
569    }
570
571    #[test]
572    fn endpoint_deployment_events() {
573        let endpoint = ExpectedUrl::builder()
574            .method(Method::POST)
575            .endpoint("groups/simple%2Fgroup/hooks")
576            .content_type("application/x-www-form-urlencoded")
577            .body_str(concat!(
578                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
579                "&deployment_events=false",
580            ))
581            .build()
582            .unwrap();
583        let client = SingleTestClient::new_raw(endpoint, "");
584
585        let endpoint = CreateHook::builder()
586            .group("simple/group")
587            .url("https://test.invalid/path?some=foo")
588            .deployment_events(false)
589            .build()
590            .unwrap();
591        api::ignore(endpoint).query(&client).unwrap();
592    }
593
594    #[test]
595    fn endpoint_feature_flag_events() {
596        let endpoint = ExpectedUrl::builder()
597            .method(Method::POST)
598            .endpoint("groups/simple%2Fgroup/hooks")
599            .content_type("application/x-www-form-urlencoded")
600            .body_str(concat!(
601                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
602                "&feature_flag_events=true",
603            ))
604            .build()
605            .unwrap();
606        let client = SingleTestClient::new_raw(endpoint, "");
607
608        let endpoint = CreateHook::builder()
609            .group("simple/group")
610            .url("https://test.invalid/path?some=foo")
611            .feature_flag_events(true)
612            .build()
613            .unwrap();
614        api::ignore(endpoint).query(&client).unwrap();
615    }
616
617    #[test]
618    fn endpoint_releases_events() {
619        let endpoint = ExpectedUrl::builder()
620            .method(Method::POST)
621            .endpoint("groups/simple%2Fgroup/hooks")
622            .content_type("application/x-www-form-urlencoded")
623            .body_str(concat!(
624                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
625                "&releases_events=false",
626            ))
627            .build()
628            .unwrap();
629        let client = SingleTestClient::new_raw(endpoint, "");
630
631        let endpoint = CreateHook::builder()
632            .group("simple/group")
633            .url("https://test.invalid/path?some=foo")
634            .releases_events(false)
635            .build()
636            .unwrap();
637        api::ignore(endpoint).query(&client).unwrap();
638    }
639
640    #[test]
641    fn endpoint_subgroup_events() {
642        let endpoint = ExpectedUrl::builder()
643            .method(Method::POST)
644            .endpoint("groups/simple%2Fgroup/hooks")
645            .content_type("application/x-www-form-urlencoded")
646            .body_str(concat!(
647                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
648                "&subgroup_events=false",
649            ))
650            .build()
651            .unwrap();
652        let client = SingleTestClient::new_raw(endpoint, "");
653
654        let endpoint = CreateHook::builder()
655            .group("simple/group")
656            .url("https://test.invalid/path?some=foo")
657            .subgroup_events(false)
658            .build()
659            .unwrap();
660        api::ignore(endpoint).query(&client).unwrap();
661    }
662
663    #[test]
664    fn endpoint_member_events() {
665        let endpoint = ExpectedUrl::builder()
666            .method(Method::POST)
667            .endpoint("groups/simple%2Fgroup/hooks")
668            .content_type("application/x-www-form-urlencoded")
669            .body_str(concat!(
670                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
671                "&member_events=true",
672            ))
673            .build()
674            .unwrap();
675        let client = SingleTestClient::new_raw(endpoint, "");
676
677        let endpoint = CreateHook::builder()
678            .group("simple/group")
679            .url("https://test.invalid/path?some=foo")
680            .member_events(true)
681            .build()
682            .unwrap();
683        api::ignore(endpoint).query(&client).unwrap();
684    }
685
686    #[test]
687    fn endpoint_resource_access_token_events() {
688        let endpoint = ExpectedUrl::builder()
689            .method(Method::POST)
690            .endpoint("groups/simple%2Fgroup/hooks")
691            .content_type("application/x-www-form-urlencoded")
692            .body_str(concat!(
693                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
694                "&resource_access_token_events=true",
695            ))
696            .build()
697            .unwrap();
698        let client = SingleTestClient::new_raw(endpoint, "");
699
700        let endpoint = CreateHook::builder()
701            .group("simple/group")
702            .url("https://test.invalid/path?some=foo")
703            .resource_access_token_events(true)
704            .build()
705            .unwrap();
706        api::ignore(endpoint).query(&client).unwrap();
707    }
708
709    #[test]
710    fn endpoint_custom_webhook_template() {
711        let endpoint = ExpectedUrl::builder()
712            .method(Method::POST)
713            .endpoint("groups/simple%2Fgroup/hooks")
714            .content_type("application/x-www-form-urlencoded")
715            .body_str(concat!(
716                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
717                "&custom_webhook_template=my-template-content",
718            ))
719            .build()
720            .unwrap();
721        let client = SingleTestClient::new_raw(endpoint, "");
722
723        let endpoint = CreateHook::builder()
724            .group("simple/group")
725            .url("https://test.invalid/path?some=foo")
726            .custom_webhook_template("my-template-content")
727            .build()
728            .unwrap();
729        api::ignore(endpoint).query(&client).unwrap();
730    }
731
732    #[test]
733    fn endpoint_custom_headers() {
734        let endpoint = ExpectedUrl::builder()
735            .method(Method::POST)
736            .endpoint("groups/simple%2Fgroup/hooks")
737            .content_type("application/x-www-form-urlencoded")
738            .body_str(concat!(
739                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
740                "&custom_headers%5BX-Foo%5D=bar",
741                "&custom_headers%5BX-Another%5D=Value+With+Space",
742            ))
743            .build()
744            .unwrap();
745        let client = SingleTestClient::new_raw(endpoint, "");
746
747        let endpoint = CreateHook::builder()
748            .group("simple/group")
749            .url("https://test.invalid/path?some=foo")
750            .custom_header("X-Foo", "bar")
751            .custom_headers([("X-Another", "Value With Space")].iter().cloned())
752            .build()
753            .unwrap();
754        api::ignore(endpoint).query(&client).unwrap();
755    }
756
757    #[test]
758    fn endpoint_enable_ssl_verification() {
759        let endpoint = ExpectedUrl::builder()
760            .method(Method::POST)
761            .endpoint("groups/simple%2Fgroup/hooks")
762            .content_type("application/x-www-form-urlencoded")
763            .body_str(concat!(
764                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
765                "&enable_ssl_verification=false",
766            ))
767            .build()
768            .unwrap();
769        let client = SingleTestClient::new_raw(endpoint, "");
770
771        let endpoint = CreateHook::builder()
772            .group("simple/group")
773            .url("https://test.invalid/path?some=foo")
774            .enable_ssl_verification(false)
775            .build()
776            .unwrap();
777        api::ignore(endpoint).query(&client).unwrap();
778    }
779
780    #[test]
781    fn endpoint_token() {
782        let endpoint = ExpectedUrl::builder()
783            .method(Method::POST)
784            .endpoint("groups/simple%2Fgroup/hooks")
785            .content_type("application/x-www-form-urlencoded")
786            .body_str(concat!(
787                "url=https%3A%2F%2Ftest.invalid%2Fpath%3Fsome%3Dfoo",
788                "&token=secret",
789            ))
790            .build()
791            .unwrap();
792        let client = SingleTestClient::new_raw(endpoint, "");
793
794        let endpoint = CreateHook::builder()
795            .group("simple/group")
796            .url("https://test.invalid/path?some=foo")
797            .token("secret")
798            .build()
799            .unwrap();
800        api::ignore(endpoint).query(&client).unwrap();
801    }
802}