1
1
use anyhow:: { anyhow, Result } ;
2
2
use reqwest:: { blocking:: Client , header, StatusCode as Status } ;
3
3
4
+ #[ cfg( test) ]
5
+ use mockito;
6
+
4
7
#[ derive( serde:: Serialize , Debug ) ]
5
8
#[ serde( rename_all = "snake_case" , tag = "event_type" ) ]
6
9
pub enum Event {
@@ -25,11 +28,17 @@ impl Event {
25
28
/// If the variant is `Trigger`, this will page whoever is on call
26
29
/// (potentially waking them up at 3 AM).
27
30
pub fn send ( self ) -> Result < ( ) > {
31
+ #[ cfg( not( test) ) ]
32
+ let base_url = "https://events.pagerduty.com" ;
33
+ #[ cfg( test) ]
34
+ let base_url = mockito:: server_url ( ) ;
35
+
28
36
let api_token = dotenv:: var ( "PAGERDUTY_API_TOKEN" ) ?;
29
37
let service_key = dotenv:: var ( "PAGERDUTY_INTEGRATION_KEY" ) ?;
30
38
39
+ let url = format ! ( "{}/generic/2010-04-15/create_event.json" , base_url) ;
31
40
let response = Client :: new ( )
32
- . post ( "https://events.pagerduty.com/generic/2010-04-15/create_event.json" )
41
+ . post ( & url )
33
42
. header ( header:: ACCEPT , "application/vnd.pagerduty+json;version=2" )
34
43
. header ( header:: AUTHORIZATION , format ! ( "Token token={}" , api_token) )
35
44
. json ( & FullEvent {
@@ -66,3 +75,75 @@ struct InvalidEvent {
66
75
message : String ,
67
76
errors : Vec < String > ,
68
77
}
78
+
79
+ #[ cfg( test) ]
80
+ mod tests {
81
+ use super :: Event ;
82
+ use mockito:: { mock, Matcher } ;
83
+ use std:: env;
84
+
85
+ #[ test]
86
+ fn test_send ( ) {
87
+ // set environment variables for this test
88
+ env:: set_var ( "PAGERDUTY_API_TOKEN" , "secret123" ) ;
89
+ env:: set_var ( "PAGERDUTY_INTEGRATION_KEY" , "crates-io-service-key" ) ;
90
+
91
+ // setup the pagerduty API endpoint mock
92
+ let response_body = json ! ( {
93
+ "description" : "possible spam attack underway" ,
94
+ "event_type" : "trigger" ,
95
+ "incident_key" : "spam_attack" ,
96
+ "service_key" : "crates-io-service-key"
97
+ } ) ;
98
+
99
+ let mock = mock ( "POST" , "/generic/2010-04-15/create_event.json" )
100
+ . match_header ( "Accept" , "application/vnd.pagerduty+json;version=2" )
101
+ . match_header ( "Authorization" , "Token token=secret123" )
102
+ . match_header ( "Content-Type" , "application/json" )
103
+ . match_body ( Matcher :: Json ( response_body) )
104
+ . with_status ( 200 )
105
+ . create ( ) ;
106
+
107
+ // create and send the event
108
+ let event = Event :: Trigger {
109
+ incident_key : Some ( "spam_attack" . into ( ) ) ,
110
+ description : "possible spam attack underway" . into ( ) ,
111
+ } ;
112
+
113
+ let result = event. send ( ) ;
114
+
115
+ // check that the mock endpoint was triggered
116
+ mock. assert ( ) ;
117
+ assert_ok ! ( result) ;
118
+ }
119
+
120
+ #[ test]
121
+ fn test_send_with_400_error ( ) {
122
+ // set environment variables for this test
123
+ env:: set_var ( "PAGERDUTY_API_TOKEN" , "secret123" ) ;
124
+ env:: set_var ( "PAGERDUTY_INTEGRATION_KEY" , "crates-io-service-key" ) ;
125
+
126
+ // setup the pagerduty API endpoint mock
127
+ let request_body = json ! ( {
128
+ "message" : "oops" ,
129
+ "errors" : [ "something" , "went" , "wrong" ] ,
130
+ } ) ;
131
+
132
+ let mock = mock ( "POST" , "/generic/2010-04-15/create_event.json" )
133
+ . with_status ( 400 )
134
+ . with_body ( request_body. to_string ( ) )
135
+ . create ( ) ;
136
+
137
+ // create and send the event
138
+ let event = Event :: Trigger {
139
+ incident_key : Some ( "spam_attack" . into ( ) ) ,
140
+ description : "possible spam attack underway" . into ( ) ,
141
+ } ;
142
+
143
+ let result = event. send ( ) ;
144
+
145
+ // check that the mock endpoint was triggered
146
+ mock. assert ( ) ;
147
+ assert_err ! ( result) ;
148
+ }
149
+ }
0 commit comments