github.com/newrelic/newrelic-client-go@v1.1.0/pkg/alerts/channels_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package alerts
     5  
     6  import (
     7  	"net/http"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/newrelic/newrelic-client-go/internal/serialization"
    13  )
    14  
    15  var (
    16  	testListChannelsResponseJSON = `{
    17  		"channels": [
    18  			{
    19  				"id": 2803426,
    20  				"name": "unit-test-alert-channel",
    21  				"type": "user",
    22  				"configuration": {
    23  					"user_id": "2680539"
    24  				},
    25  				"links": {
    26  					"policy_ids": []
    27  				}
    28  			},
    29  			{
    30  				"id": 2932511,
    31  				"name": "test@testing.com",
    32  				"type": "email",
    33  				"configuration": {
    34  					"include_json_attachment": "true",
    35  					"recipients": "test@testing.com"
    36  				},
    37  				"links": {
    38  					"policy_ids": []
    39  				}
    40  			}
    41  		]
    42  	}`
    43  
    44  	testCreateChannelResponseJSON = `{
    45  		"channels": [
    46  			{
    47  				"id": 2932701,
    48  				"name": "test@example.com",
    49  				"type": "email",
    50  				"configuration": {
    51  					"include_json_attachment": "true",
    52  					"recipients": "test@example.com"
    53  				},
    54  				"links": {
    55  					"policy_ids": []
    56  				}
    57  			}
    58  		],
    59  		"links": {
    60  			"channel.policy_ids": "/v2/policies/{policy_id}"
    61  		}
    62  	}`
    63  
    64  	testDeleteChannelResponseJSON = `{
    65  		"channel": {
    66  			"id": 2932511,
    67  			"name": "test@example.com",
    68  			"type": "email",
    69  			"configuration": {
    70  				"include_json_attachment": "true",
    71  				"recipients": "test@example.com"
    72  			},
    73  			"links": {
    74  				"policy_ids": []
    75  			}
    76  		},
    77  		"links": {
    78  			"channel.policy_ids": "/v2/policies/{policy_id}"
    79  		}
    80  	}`
    81  
    82  	// Tests serialization of complex `headers` and `payload` fields
    83  	testWebhookComplexHeadersAndPayloadResponseJSON = `{
    84  		"channels": [
    85  			{
    86  				"id": 1,
    87  				"name": "webhook-EMPTY-headers-and-payload",
    88  				"type": "webhook",
    89  				"configuration": {
    90  					"base_url": "http://example.com",
    91  					"headers": "",
    92  					"payload": "",
    93  					"payload_type": ""
    94  				},
    95  				"links": {
    96  					"policy_ids": []
    97  				}
    98  			},
    99  			{
   100  				"id": 2,
   101  				"name": "webhook-ESCAPED-STRING-headers-and-payload",
   102  				"type": "webhook",
   103  				"configuration": {
   104  					"base_url": "http://example.com",
   105  					"headers": "{\"key\":\"value\"}",
   106  					"payload": "{\"key\":\"value\"}",
   107  					"payload_type": "application/json"
   108  				},
   109  				"links": {
   110  					"policy_ids": []
   111  				}
   112  			},
   113  			{
   114  				"id": 3,
   115  				"name": "webhook-WEIRD-headers-and-payload",
   116  				"type": "webhook",
   117  				"configuration": {
   118  					"base_url": "http://example.com",
   119  					"headers": {
   120  						"": ""
   121  					},
   122  					"payload": {
   123  						"": ""
   124  					},
   125  					"payload_type": "application/json"
   126  				},
   127  				"links": {
   128  					"policy_ids": []
   129  				}
   130  			},
   131  			{
   132  				"id": 4,
   133  				"name": "webhook-COMPLEX-payload",
   134  				"type": "webhook",
   135  				"configuration": {
   136  					"base_url": "http://example.com",
   137  					"headers": {
   138  						"key": "value",
   139  						"invalidHeader": {
   140  							"is": "allowed by the API"
   141  						}
   142  					},
   143  					"payload": {
   144  						"array": ["test", 1],
   145  						"object": {
   146  							"key": "value"
   147  						}
   148  					},
   149  					"payload_type": "application/json"
   150  				},
   151  				"links": {
   152  					"policy_ids": []
   153  				}
   154  			}
   155  		]
   156  	}`
   157  )
   158  
   159  func TestListChannels(t *testing.T) {
   160  	t.Parallel()
   161  	alerts := newMockResponse(t, testListChannelsResponseJSON, http.StatusOK)
   162  
   163  	expected := []*Channel{
   164  		{
   165  			ID:   2803426,
   166  			Name: "unit-test-alert-channel",
   167  			Type: ChannelTypes.User,
   168  			Configuration: ChannelConfiguration{
   169  				UserID: "2680539",
   170  			},
   171  			Links: ChannelLinks{
   172  				PolicyIDs: []int{},
   173  			},
   174  		},
   175  		{
   176  			ID:   2932511,
   177  			Name: "test@testing.com",
   178  			Type: ChannelTypes.Email,
   179  			Configuration: ChannelConfiguration{
   180  				Recipients:            "test@testing.com",
   181  				IncludeJSONAttachment: "true",
   182  			},
   183  			Links: ChannelLinks{
   184  				PolicyIDs: []int{},
   185  			},
   186  		},
   187  	}
   188  
   189  	actual, err := alerts.ListChannels()
   190  
   191  	assert.NoError(t, err)
   192  	assert.NotNil(t, actual)
   193  	assert.Equal(t, expected, actual)
   194  }
   195  
   196  func TestListChannelsWebhookWithComplexHeadersAndPayload(t *testing.T) {
   197  	t.Parallel()
   198  	alerts := newMockResponse(t, testWebhookComplexHeadersAndPayloadResponseJSON, http.StatusOK)
   199  
   200  	expected := []*Channel{
   201  		{
   202  			ID:   1,
   203  			Name: "webhook-EMPTY-headers-and-payload",
   204  			Type: ChannelTypes.Webhook,
   205  			Configuration: ChannelConfiguration{
   206  				BaseURL:     "http://example.com",
   207  				PayloadType: "",
   208  			},
   209  			Links: ChannelLinks{
   210  				PolicyIDs: []int{},
   211  			},
   212  		},
   213  		{
   214  			ID:   2,
   215  			Name: "webhook-ESCAPED-STRING-headers-and-payload",
   216  			Type: ChannelTypes.Webhook,
   217  			Configuration: ChannelConfiguration{
   218  				BaseURL:     "http://example.com",
   219  				PayloadType: "application/json",
   220  				Headers: serialization.MapStringInterface{
   221  					"key": "value",
   222  				},
   223  				Payload: serialization.MapStringInterface{
   224  					"key": "value",
   225  				},
   226  			},
   227  			Links: ChannelLinks{
   228  				PolicyIDs: []int{},
   229  			},
   230  		},
   231  		{
   232  			ID:   3,
   233  			Name: "webhook-WEIRD-headers-and-payload",
   234  			Type: ChannelTypes.Webhook,
   235  			Configuration: ChannelConfiguration{
   236  				BaseURL: "http://example.com",
   237  				Headers: serialization.MapStringInterface{
   238  					"": "",
   239  				},
   240  				Payload: serialization.MapStringInterface{
   241  					"": "",
   242  				},
   243  				PayloadType: "application/json",
   244  			},
   245  			Links: ChannelLinks{
   246  				PolicyIDs: []int{},
   247  			},
   248  		},
   249  		{
   250  			ID:   4,
   251  			Name: "webhook-COMPLEX-payload",
   252  			Type: ChannelTypes.Webhook,
   253  			Configuration: ChannelConfiguration{
   254  				BaseURL: "http://example.com",
   255  				Headers: serialization.MapStringInterface{
   256  					"key": "value",
   257  					"invalidHeader": map[string]interface{}{
   258  						"is": "allowed by the API",
   259  					},
   260  				},
   261  				Payload: serialization.MapStringInterface{
   262  					"array": []interface{}{"test", float64(1)},
   263  					"object": map[string]interface{}{
   264  						"key": "value",
   265  					},
   266  				},
   267  				PayloadType: "application/json",
   268  			},
   269  			Links: ChannelLinks{
   270  				PolicyIDs: []int{},
   271  			},
   272  		},
   273  	}
   274  
   275  	actual, err := alerts.ListChannels()
   276  
   277  	assert.NoError(t, err)
   278  	assert.NotNil(t, actual)
   279  	assert.Equal(t, expected, actual)
   280  }
   281  
   282  func TestGetChannel(t *testing.T) {
   283  	t.Parallel()
   284  	alerts := newMockResponse(t, testListChannelsResponseJSON, http.StatusOK)
   285  
   286  	expected := &Channel{
   287  		ID:   2803426,
   288  		Name: "unit-test-alert-channel",
   289  		Type: ChannelTypes.User,
   290  		Configuration: ChannelConfiguration{
   291  			UserID: "2680539",
   292  		},
   293  		Links: ChannelLinks{
   294  			PolicyIDs: []int{},
   295  		},
   296  	}
   297  
   298  	actual, err := alerts.GetChannel(2803426)
   299  
   300  	assert.NoError(t, err)
   301  	assert.NotNil(t, actual)
   302  	assert.Equal(t, expected, actual)
   303  }
   304  
   305  func TestGetChannelNotFound(t *testing.T) {
   306  	t.Parallel()
   307  	alerts := newMockResponse(t, testListChannelsResponseJSON, http.StatusOK)
   308  
   309  	actual, err := alerts.GetChannel(0)
   310  
   311  	assert.Error(t, err)
   312  	assert.Nil(t, actual)
   313  	assert.Equal(t, "no channel found for id 0", err.Error())
   314  }
   315  
   316  func TestCreateChannel(t *testing.T) {
   317  	t.Parallel()
   318  	alerts := newMockResponse(t, testCreateChannelResponseJSON, http.StatusCreated)
   319  
   320  	channel := Channel{
   321  		Name: "test@example.com",
   322  		Type: ChannelTypes.Email,
   323  		Configuration: ChannelConfiguration{
   324  			Recipients:            "test@example.com",
   325  			IncludeJSONAttachment: "true",
   326  		},
   327  	}
   328  
   329  	expected := &Channel{
   330  		ID:   2932701,
   331  		Name: "test@example.com",
   332  		Type: ChannelTypes.Email,
   333  		Configuration: ChannelConfiguration{
   334  			Recipients:            "test@example.com",
   335  			IncludeJSONAttachment: "true",
   336  		},
   337  		Links: ChannelLinks{
   338  			PolicyIDs: []int{},
   339  		},
   340  	}
   341  
   342  	actual, err := alerts.CreateChannel(channel)
   343  
   344  	assert.NoError(t, err)
   345  	assert.NotNil(t, actual)
   346  	assert.Equal(t, expected, actual)
   347  }
   348  
   349  func TestCreateChannelInvalidChannelType(t *testing.T) {
   350  	t.Parallel()
   351  	alerts := newMockResponse(t, `{
   352  		"error": {
   353  			"title": "Invalid channel type"
   354  		}
   355  	}`, http.StatusUnprocessableEntity)
   356  
   357  	channel := Channel{
   358  		Name:          "string",
   359  		Type:          "string",
   360  		Configuration: ChannelConfiguration{},
   361  	}
   362  
   363  	actual, err := alerts.CreateChannel(channel)
   364  
   365  	assert.Error(t, err)
   366  	assert.Nil(t, actual)
   367  }
   368  
   369  func TestDeleteChannel(t *testing.T) {
   370  	t.Parallel()
   371  	alerts := newMockResponse(t, testDeleteChannelResponseJSON, http.StatusOK)
   372  
   373  	expected := &Channel{
   374  		ID:   2932511,
   375  		Name: "test@example.com",
   376  		Type: ChannelTypes.Email,
   377  		Configuration: ChannelConfiguration{
   378  			Recipients:            "test@example.com",
   379  			IncludeJSONAttachment: "true",
   380  		},
   381  		Links: ChannelLinks{
   382  			PolicyIDs: []int{},
   383  		},
   384  	}
   385  
   386  	actual, err := alerts.DeleteChannel(2932511)
   387  
   388  	assert.NoError(t, err)
   389  	assert.NotNil(t, actual)
   390  	assert.Equal(t, expected, actual)
   391  }