Skip to content

Commit

Permalink
adds an alerts client
Browse files Browse the repository at this point in the history
BACK-2500
  • Loading branch information
ewollesen committed Nov 2, 2023
1 parent 82d9259 commit a5ca88f
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 1 deletion.
80 changes: 80 additions & 0 deletions alerts/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package alerts

import (
"context"
"net/http"

"github.com/kelseyhightower/envconfig"

"github.com/tidepool-org/platform/client"
"github.com/tidepool-org/platform/platform"
)

// Client for managing alerts configs.
type Client struct {
client *platform.Client
}

// NewClient builds an alerts client.
func NewClient(cfg *ClientConfig) (*Client, error) {
client, err := platform.NewClient(cfg.Config, platform.AuthorizeAsService)
if err != nil {
return nil, err
}

return &Client{
client: client,
}, nil
}

// Upsert updates cfg in the service if it exists, or creates it if it doesn't.
func (c *Client) Upsert(ctx context.Context, cfg *Config) error {
url := c.client.ConstructURL("v1", "alerts", cfg.UserID, cfg.FollowedUserID)
return c.client.RequestData(ctx, http.MethodPost, url, nil, cfg, nil)
}

// Delete the alerts config.
func (c *Client) Delete(ctx context.Context, cfg *Config) error {
url := c.client.ConstructURL("v1", "alerts", cfg.UserID, cfg.FollowedUserID)
return c.client.RequestData(ctx, http.MethodDelete, url, nil, nil, nil)
}

// ClientConfig leverages platform.Config for the alerts client.
type ClientConfig struct {
*platform.Config
Address string `envconfig:"TIDEPOOL_DATA_CLIENT_ADDRESS"`
}

// ConfigLoader abstracts the method by which config values are loaded.
type ConfigLoader interface {
Load(cfg *ClientConfig) error
}

// envconfigLoader adapts envconfig to implement ConfigLoader.
type envconfigLoader struct {
ConfigLoader platform.ConfigLoader
}

// NewEnvconfigLoader loads values via envconfig.
//
// If loader is nil, it defaults to envconfig for platform values.
func NewEnvconfigLoader(loader platform.ConfigLoader) *envconfigLoader {
if loader == nil {
loader = platform.NewEnvconfigLoader(nil)
}
return &envconfigLoader{
ConfigLoader: loader,
}
}

// Load implements ConfigLoader.
func (l *envconfigLoader) Load(cfg *ClientConfig) error {
if err := l.ConfigLoader.Load(cfg.Config); err != nil {
return err
}
if err := envconfig.Process(client.EnvconfigEmptyPrefix, cfg); err != nil {
return err
}
cfg.Config.Address = cfg.Address
return nil
}
78 changes: 78 additions & 0 deletions alerts/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package alerts

import (
"context"
"net/http"
"net/http/httptest"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"github.com/tidepool-org/platform/client"
"github.com/tidepool-org/platform/log"
"github.com/tidepool-org/platform/log/null"
"github.com/tidepool-org/platform/platform"
)

var _ = Describe("Client", func() {
test404Server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
}))
GinkgoT().Cleanup(test404Server.Close)
test200Server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.Error(w, http.StatusText(http.StatusOK), http.StatusOK)
}))
GinkgoT().Cleanup(test200Server.Close)

Context("Delete", func() {
It("returns an error on non-200 responses", func() {
client, ctx := newAlertsClientTest(test404Server)
err := client.Delete(ctx, &Config{})
Expect(err).Should(HaveOccurred())
Expect(err).To(MatchError(ContainSubstring("resource not found")))
})

It("returns nil on success", func() {
client, ctx := newAlertsClientTest(test200Server)
err := client.Delete(ctx, &Config{})
Expect(err).ShouldNot(HaveOccurred())
})
})

Context("Upsert", func() {
It("returns an error on non-200 responses", func() {
client, ctx := newAlertsClientTest(test404Server)
err := client.Upsert(ctx, &Config{})
Expect(err).Should(HaveOccurred())
Expect(err).To(MatchError(ContainSubstring("resource not found")))
})

It("returns nil on success", func() {
client, ctx := newAlertsClientTest(test200Server)
err := client.Upsert(ctx, &Config{})
Expect(err).ShouldNot(HaveOccurred())
})
})

})

func buildTestClient(s *httptest.Server) *Client {
pCfg := &platform.Config{
ServiceSecret: "foo",
Config: &client.Config{
Address: s.URL,
UserAgent: "foo",
},
}
client, err := NewClient(&ClientConfig{Address: s.URL, Config: pCfg})
Expect(err).ShouldNot(HaveOccurred())
return client
}

func newAlertsClientTest(server *httptest.Server) (*Client, context.Context) {
return buildTestClient(server), contextWithNullLogger()
}

func contextWithNullLogger() context.Context {
return log.NewContextWithLogger(context.Background(), null.NewLogger())
}
1 change: 0 additions & 1 deletion alerts/repo.go

This file was deleted.

0 comments on commit a5ca88f

Please sign in to comment.