Skip to content

Commit

Permalink
feature: add outbound-ips implementation
Browse files Browse the repository at this point in the history
ReadMe's API now includes an endpoint for retrieving a list of their
outbound IP addresses for use with webhooks and the API explorer.

This is a simple single GET call with a very simple data model.

See https://docs.readme.com/main/reference/getoutboundips for more
information.
  • Loading branch information
joshbeard committed Jan 18, 2024
1 parent f111db4 commit 21fab31
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 0 deletions.
47 changes: 47 additions & 0 deletions readme/outbound_ips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package readme

// OutboundIPEndpoint is the ReadMe API URL endpoint for retrieving ReadMe's outbound IP addresses.
const OutboundIPEndpoint = "/outbound-ips"

// OutboundIPService is an interface for using the outbound IPs endpoint of the ReadMe.com API.
//
// API Reference: https://docs.readme.com/main/reference/getoutboundips
type OutboundIPService interface {
// Get all of ReadMe’s IP addresses used for outbound webhook requests and the “Try It!” button on the API Explorer.
//
// Although ReadMe’s outbound IP addresses may change, the IPs in this API
// response will be valid for at least 7 days. If you configure your API or
// webhooks to limit access based on these IPs, you should refresh the IP list
// from this endpoint weekly.
//
// API Reference: https://docs.readme.com/main/reference/getproject
Get() ([]OutboundIP, *APIResponse, error)
}

// OutboundIPClient handles communication with the OutboundIP related methods of the ReadMe.com API.
type OutboundIPClient struct {
client *Client
}

// OutboundIP represents the response from the ReadMe API when returning outbound IP addresses.
type OutboundIP struct {
IPAddress string `json:"ipAddress"`
}

var _ OutboundIPService = &OutboundIPClient{}

// Get all of ReadMe’s IP addresses used for outbound webhook requests and the “Try It!” button on the API Explorer.
//
// API Reference: https://docs.readme.com/main/reference/getproject
func (c OutboundIPClient) Get() ([]OutboundIP, *APIResponse, error) {
ipList := []OutboundIP{}
apiResponse, err := c.client.APIRequest(&APIRequest{
Method: "GET",
Endpoint: OutboundIPEndpoint,
UseAuth: false,
OkStatusCode: []int{200},
Response: &ipList,
})

return ipList, apiResponse, err
}
47 changes: 47 additions & 0 deletions readme/outbound_ips_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package readme_test

import (
"testing"

"github.com/h2non/gock"
"github.com/liveoaklabs/readme-api-go-client/tests/testdata"
"github.com/stretchr/testify/assert"
)

func Test_OutboundIPs_Get(t *testing.T) {
t.Run("when API responds with 200", func(t *testing.T) {
// Arrange
expect := testdata.OutboundIPs
gock.New(TestClient.APIURL).
Get("/outbound-ips").
Reply(200).
JSON(expect)
defer gock.Off()

// Act
got, _, err := TestClient.OutboundIP.Get()

// Assert
assert.NoError(t, err, "it does not return an error")
assert.Equal(t, expect, got, "it returns expected Project struct")
assert.True(t, gock.IsDone(), "it makes the expected API call")
})

t.Run("when API response cannot be parsed", func(t *testing.T) {
// Arrange
gock.New(TestClient.APIURL).
Get("/outbound-ips").
Reply(200).
JSON(`[{"invalid":invalid"}]`)
defer gock.Off()

// Act
_, _, err := TestClient.OutboundIP.Get()

// Assert
assert.ErrorContains(t, err,
"unable to parse API response: invalid character",
"it returns the expected error")
assert.True(t, gock.IsDone(), "it makes the expected API call")
})
}
3 changes: 3 additions & 0 deletions readme/readme.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ type Client struct {
Doc DocService
// Image implements the ReadMe Image API for uploading images.
Image ImageService
// OutboundIP implements the ReadMe OutboundIP API for retrieving outbound IP addresses.
OutboundIP OutboundIPService
// Project implements the ReadMe Project API for retrieving metadata about the project.
Project ProjectService
// Version implements the ReadMe Version API for managing versions.
Expand Down Expand Up @@ -174,6 +176,7 @@ func NewClient(token string, apiURL ...string) (*Client, error) {
client.CustomPage = &CustomPageClient{client: client}
client.Doc = &DocClient{client: client}
client.Image = &ImageClient{client: client}
client.OutboundIP = &OutboundIPClient{client: client}
client.Project = &ProjectClient{client: client}
client.Version = &VersionClient{client: client}

Expand Down
101 changes: 101 additions & 0 deletions tests/mocks/mock_OutboundIPService.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions tests/testdata/outbound_ips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package testdata

import "github.com/liveoaklabs/readme-api-go-client/readme"

var OutboundIPs = []readme.OutboundIP{
{
IPAddress: "127.0.0.1",
},
{
IPAddress: "10.0.1.2",
},
{
IPAddress: "10.10.9.8",
},
}

0 comments on commit 21fab31

Please sign in to comment.