Skip to content

Commit

Permalink
Support adding conference bridge when creating or managing incidents
Browse files Browse the repository at this point in the history
Up until now you could view the conference bridge associated with an incident
when viewing its details via this package, but you could not add a conference
bridge to a new or existing incident. This change adds the ability to include a
conference bridge when creating a new incident, or when you're updating an
existing one.

Closes #373
  • Loading branch information
theckman committed Nov 14, 2021
1 parent f86153a commit dbeea63
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 19 deletions.
47 changes: 28 additions & 19 deletions incident.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,15 @@ type ListIncidentsOptions struct {

// ConferenceBridge is a struct for the conference_bridge object on an incident
type ConferenceBridge struct {
// ConferenceNumber is the phone number of the conference call for the
// conference bridge. Phone numbers should be formatted like
// +1 415-555-1212,,,,1234#, where a comma (,) represents a one-second
// wait and pound (#) completes access code input.
ConferenceNumber string `json:"conference_number,omitempty"`
ConferenceURL string `json:"conference_url,omitempty"`

// ConferenceURL is the URL for the conference bridge. This could be a link
// to a video conference or Slack channel.
ConferenceURL string `json:"conference_url,omitempty"`
}

// ListIncidents lists existing incidents.
Expand Down Expand Up @@ -152,28 +159,30 @@ type createIncidentResponse struct {

// CreateIncidentOptions is the structure used when POSTing to the CreateIncident API endpoint.
type CreateIncidentOptions struct {
Type string `json:"type"`
Title string `json:"title"`
Service *APIReference `json:"service"`
Priority *APIReference `json:"priority"`
Urgency string `json:"urgency,omitempty"`
IncidentKey string `json:"incident_key,omitempty"`
Body *APIDetails `json:"body,omitempty"`
EscalationPolicy *APIReference `json:"escalation_policy,omitempty"`
Assignments []Assignee `json:"assignments,omitempty"`
Type string `json:"type"`
Title string `json:"title"`
Service *APIReference `json:"service"`
Priority *APIReference `json:"priority"`
Urgency string `json:"urgency,omitempty"`
IncidentKey string `json:"incident_key,omitempty"`
Body *APIDetails `json:"body,omitempty"`
EscalationPolicy *APIReference `json:"escalation_policy,omitempty"`
Assignments []Assignee `json:"assignments,omitempty"`
ConferenceBridge *ConferenceBridge `json:"conference_bridge,omitempty"`
}

// ManageIncidentsOptions is the structure used when PUTing updates to incidents to the ManageIncidents func
type ManageIncidentsOptions struct {
ID string `json:"id"`
Type string `json:"type"`
Status string `json:"status,omitempty"`
Title string `json:"title,omitempty"`
Priority *APIReference `json:"priority,omitempty"`
Assignments []Assignee `json:"assignments,omitempty"`
EscalationLevel uint `json:"escalation_level,omitempty"`
EscalationPolicy *APIReference `json:"escalation_policy,omitempty"`
Resolution string `json:"resolution,omitempty"`
ID string `json:"id"`
Type string `json:"type"`
Status string `json:"status,omitempty"`
Title string `json:"title,omitempty"`
Priority *APIReference `json:"priority,omitempty"`
Assignments []Assignee `json:"assignments,omitempty"`
EscalationLevel uint `json:"escalation_level,omitempty"`
EscalationPolicy *APIReference `json:"escalation_policy,omitempty"`
Resolution string `json:"resolution,omitempty"`
ConferenceBridge *ConferenceBridge `json:"conference_bridge,omitempty"`
}

// MergeIncidentsOptions is the structure used when merging incidents with MergeIncidents func
Expand Down
84 changes: 84 additions & 0 deletions incident_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,90 @@ func TestIncident_Manage_assignments(t *testing.T) {
testEqual(t, want, res)
}

func TestIncident_Manage_conference_bridge(t *testing.T) {
setup()
defer teardown()

wantFrom := "foo@bar.com"

mux.HandleFunc("/incidents", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "PUT")

if gotFrom := r.Header.Get("From"); gotFrom != wantFrom {
t.Errorf("From HTTP header = %q, want %q", gotFrom, wantFrom)
}

body, err := ioutil.ReadAll(r.Body)
if err != nil {
t.Fatal(err)
}

var data map[string][]ManageIncidentsOptions
testErrCheck(t, "json.Unmarshal()", "", json.Unmarshal(body, &data))

if len(data["incidents"]) == 0 {
t.Fatalf("no incidents, expect 1")
}

const (
wantNum = "42"
wantURL = "http://example.org/bridge"
)

inc := data["incidents"][0]

if inc.ConferenceBridge == nil {
t.Fatalf("inc.ConferenceBridge = <nil>")
}

if got := inc.ConferenceBridge.ConferenceNumber; got != wantNum {
t.Fatalf("inc.ConferenceBridge.ConferenceNumber = %q, want %q", got, wantNum)
}

if got := inc.ConferenceBridge.ConferenceURL; got != wantURL {
t.Fatalf("inc.ConferenceBridge.ConferenceNumber = %q, want %q", got, wantURL)
}

_, _ = w.Write([]byte(`{"incidents": [{"title": "foo", "id": "1","conference_bridge":{"conference_number":"42","conference_url":"http://example.org/bridge"}}]}`))
})

client := defaultTestClient(server.URL, "foo")

input := []ManageIncidentsOptions{
{
ID: "1",
Type: "incident",
ConferenceBridge: &ConferenceBridge{
ConferenceNumber: "42",
ConferenceURL: "http://example.org/bridge",
},
},
}

want := &ListIncidentsResponse{
APIListObject: APIListObject{Limit: 0, Offset: 0, More: false, Total: 0},
Incidents: []Incident{
{
APIObject: APIObject{
ID: "1",
},
Title: "foo",
ConferenceBridge: &ConferenceBridge{
ConferenceNumber: "42",
ConferenceURL: "http://example.org/bridge",
},
},
},
}

got, err := client.ManageIncidents(wantFrom, input)
if err != nil {
t.Fatal(err)
}

testEqual(t, want, got)
}

func TestIncident_Manage_esclation_level(t *testing.T) {
setup()
defer teardown()
Expand Down

0 comments on commit dbeea63

Please sign in to comment.