Skip to content

Commit

Permalink
feat(opsgenie): Add support for setting priority in Opsgenie notifica…
Browse files Browse the repository at this point in the history
…tion (#267)

* feat(opsgenie): Add support for setting priority in Opsgenie notifications

Signed-off-by: Bofa Alsarah <[email protected]>

* test(opsgenie): Add unit tests for opsgenie.go

Signed-off-by: Bofa Alsarah <[email protected]>

* test(opsgenie): Add test coverage for GetTemplater function

Signed-off-by: Bofa Alsarah <[email protected]>

---------

Signed-off-by: Bofa Alsarah <[email protected]>
Co-authored-by: Mustafa Mabrook <[email protected]>
  • Loading branch information
bofaalsarah and Mustafa Mabrook authored Feb 8, 2024
1 parent c0913e2 commit 4222fe0
Show file tree
Hide file tree
Showing 2 changed files with 242 additions and 0 deletions.
13 changes: 13 additions & 0 deletions pkg/services/opsgenie.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type OpsgenieOptions struct {

type OpsgenieNotification struct {
Description string `json:"description"`
Priority string `json:"priority,omitempty"`
}

func (n *OpsgenieNotification) GetTemplater(name string, f texttemplate.FuncMap) (Templater, error) {
Expand Down Expand Up @@ -63,13 +64,25 @@ func (s *opsgenieService) Send(notification Notification, dest Destination) erro
},
})
description := ""
priority := ""
if notification.Opsgenie != nil {
if notification.Opsgenie.Description == "" {
return fmt.Errorf("Opsgenie notification description is missing")
}

description = notification.Opsgenie.Description

if notification.Opsgenie.Priority != "" {
priority = notification.Opsgenie.Priority
}
}

alertPriority := alert.Priority(priority)

_, err := alertClient.Create(context.TODO(), &alert.CreateAlertRequest{
Message: notification.Message,
Description: description,
Priority: alertPriority,
Responders: []alert.Responder{
{
Type: "team",
Expand Down
229 changes: 229 additions & 0 deletions pkg/services/opsgenie_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
package services

import (
"errors"
"net/http"
"net/http/httptest"
"testing"
texttemplate "text/template"

"github.com/stretchr/testify/assert"
)

// Mock Opsgenie service for testing purposes
type mockOpsgenieService struct {
options OpsgenieOptions
client *http.Client
}

func NewOpsgenieServiceWithClient(options OpsgenieOptions, client *http.Client) *mockOpsgenieService {
return &mockOpsgenieService{
options: options,
client: client,
}
}

func (s *mockOpsgenieService) Send(notification Notification, destination Destination) error {
// Simulate the behavior of the Opsgenie service
if notification.Opsgenie == nil || notification.Opsgenie.Description == "" {
return errors.New("Description is missing")
}
if _, ok := s.options.ApiKeys[destination.Recipient]; !ok {
return errors.New("No API key configured for recipient")
}
// Return nil to simulate successful sending of notification
return nil
}
func TestOpsgenieNotification_GetTemplater(t *testing.T) {
// Prepare test data
name := "testTemplate"
descriptionTemplate := "Test Opsgenie alert: {{.foo}}"
f := texttemplate.FuncMap{}

t.Run("ValidTemplate", func(t *testing.T) {
// Create a new OpsgenieNotification instance
notification := OpsgenieNotification{
Description: descriptionTemplate,
}

// Call the GetTemplater method
templater, err := notification.GetTemplater(name, f)

// Assert that no error occurred during the call
assert.NoError(t, err)

// Prepare mock data for the Templater function
mockNotification := &Notification{}
vars := map[string]interface{}{
"foo": "bar",
}

// Call the Templater function returned by GetTemplater
err = templater(mockNotification, vars)

// Assert that no error occurred during the execution of the Templater function
assert.NoError(t, err)

// Assert that the OpsgenieNotification's description field was correctly updated
assert.Equal(t, "Test Opsgenie alert: bar", mockNotification.Opsgenie.Description)
})

t.Run("InvalidTemplate", func(t *testing.T) {
// Create a new OpsgenieNotification instance with an invalid description template
notification := OpsgenieNotification{
Description: "{{.invalid", // Invalid template syntax
}

// Call the GetTemplater method with the invalid template
_, err := notification.GetTemplater(name, f)

// Assert that an error occurred during the call
assert.Error(t, err)
})
}

func TestOpsgenie_SendNotification_MissingAPIKey(t *testing.T) {
// Create a mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server.Close()

// Replace the HTTP client in the Opsgenie service with a mock client
mockClient := &http.Client{
Transport: &http.Transport{},
}
service := NewOpsgenieServiceWithClient(OpsgenieOptions{
ApiUrl: server.URL,
ApiKeys: map[string]string{}}, mockClient)

// Prepare test data
recipient := "testRecipient"
message := "Test message"
descriptionTemplate := "Test Opsgenie alert: {{.foo}}"

// Create test notification with description
notification := Notification{
Message: message,
Opsgenie: &OpsgenieNotification{
Description: descriptionTemplate,
},
}

// Execute the service method with missing API Key
err := service.Send(notification, Destination{Recipient: recipient, Service: "opsgenie"})

// Assert the result for missing API Key
assert.Error(t, err)
assert.Contains(t, err.Error(), "No API key configured for recipient")
}
func TestOpsgenie_SendNotification_MissingDescriptionAndPriority(t *testing.T) {
// Create a mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server.Close()

// Replace the HTTP client in the Opsgenie service with a mock client
mockClient := &http.Client{
Transport: &http.Transport{},
}
service := NewOpsgenieServiceWithClient(OpsgenieOptions{
ApiUrl: server.URL,
ApiKeys: map[string]string{
"testRecipient": "testApiKey",
}}, mockClient)

// Prepare test data
recipient := "testRecipient"
message := "Test message"

// Create test notification with missing description and priority
notification := Notification{
Message: message,
}

// Execute the service method with missing description and priority
err := service.Send(notification, Destination{Recipient: recipient, Service: "opsgenie"})

// Assert the result for missing description and priority
assert.Error(t, err)
assert.Contains(t, err.Error(), "Description is missing")
}

func TestOpsgenie_SendNotification_WithDescriptionOnly(t *testing.T) {
// Create a mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server.Close()

// Replace the HTTP client in the Opsgenie service with a mock client
mockClient := &http.Client{
Transport: &http.Transport{},
}
service := NewOpsgenieServiceWithClient(OpsgenieOptions{
ApiUrl: server.URL,
ApiKeys: map[string]string{
"testRecipient": "testApiKey",
},
}, mockClient)

// Prepare test data
recipient := "testRecipient"
message := "Test message"
descriptionTemplate := "Test Opsgenie alert: {{.foo}}"

// Create test notification with description only
notification := Notification{
Message: message,
Opsgenie: &OpsgenieNotification{
Description: descriptionTemplate,
},
}

// Execute the service method with description only
err := service.Send(notification, Destination{Recipient: recipient, Service: "opsgenie"})

// Assert the result for description present and no priority
assert.NoError(t, err) // Expect no error
}

func TestOpsgenie_SendNotification_WithDescriptionAndPriority(t *testing.T) {
// Create a mock HTTP server
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}))
defer server.Close()

// Replace the HTTP client in the Opsgenie service with a mock client
mockClient := &http.Client{
Transport: &http.Transport{},
}
service := NewOpsgenieServiceWithClient(OpsgenieOptions{
ApiUrl: server.URL,
ApiKeys: map[string]string{
"testRecipient": "testApiKey",
}}, mockClient)

// Prepare test data
recipient := "testRecipient"
message := "Test message"
descriptionTemplate := "Test Opsgenie alert: {{.foo}}"
priority := "P1"

// Create test notification with description and priority
notification := Notification{
Message: message,
Opsgenie: &OpsgenieNotification{
Description: descriptionTemplate,
Priority: priority,
},
}

// Execute the service method with description and priority
err := service.Send(notification, Destination{Recipient: recipient, Service: "opsgenie"})

// Assert the result for description and priority present
assert.NoError(t, err) // Expect no error
}

0 comments on commit 4222fe0

Please sign in to comment.