Skip to content

Commit

Permalink
finish test builds for regions and region
Browse files Browse the repository at this point in the history
  • Loading branch information
efuchsman committed Jan 19, 2024
1 parent be94bef commit a7f356e
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 21 deletions.
2 changes: 1 addition & 1 deletion distilleries_of_scotland.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func main() {
}

// Seed regions to the database
dis := distilleries.NewClient(db)
dis := distilleries.NewDistilleriesClient(db)
filePath := "data/regions.json"
if err = dis.SeedRegions(filePath); err != nil {
log.Fatalf("Error seeding regions to the database: %v", err)
Expand Down
16 changes: 6 additions & 10 deletions handlers/regions/regions.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package regions

import (
"encoding/json"
"net/http"
"strings"

Expand All @@ -12,10 +11,10 @@ import (
)

type Handler struct {
dis *distilleries.Client
dis distilleries.Client
}

func NewHandler(dis *distilleries.Client) *Handler {
func NewHandler(dis distilleries.Client) *Handler {
return &Handler{
dis: dis,
}
Expand All @@ -26,13 +25,11 @@ func (h *Handler) GetRegions(w http.ResponseWriter, r *http.Request) {
regions, err := h.dis.GetRegions()
if err != nil {
log.Errorf("%+v", err)
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
apiresponses.InternalError500(w, "region", err)
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(regions)
apiresponses.OK200(w, regions)
}

func (h *Handler) GetRegion(w http.ResponseWriter, r *http.Request) {
Expand All @@ -51,7 +48,6 @@ func (h *Handler) GetRegion(w http.ResponseWriter, r *http.Request) {
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(region)
log.Printf("Region Data: %+v", region)
apiresponses.OK200(w, region)
}
129 changes: 129 additions & 0 deletions handlers/regions/regions_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
package regions

import (
"errors"
"fmt"
"net/http/httptest"
"path/filepath"
"runtime"
"testing"

"github.com/efuchsman/distilleries_of_scotland/internal/distilleries"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert"
)

var (
projectRoot = ".."
testRegion1 = &distilleries.Region{
RegionName: "test1",
Description: "test1",
}
testRegion2 = &distilleries.Region{
RegionName: "test2",
Description: "test2",
}

testRegions = &distilleries.Regions{
Regions: []*distilleries.Region{
testRegion1,
testRegion2,
},
}
)

func init() {
_, currentFile, _, ok := runtime.Caller(0)
if ok {
projectRoot = filepath.Join(filepath.Dir(currentFile), "..", "..")
}

configPath := filepath.Join(projectRoot, "config", "config_test.yml")
viper.SetConfigFile(configPath)

if err := viper.ReadInConfig(); err != nil {
panic("Error reading testing configuration file: " + err.Error())
}
}

func TestGetRegions(t *testing.T) {
testCases := []struct {
description string
disClient *distilleries.TestClient
expectedCode int
expectedBody string
}{
{
description: "Success: Region is returned",
disClient: &distilleries.TestClient{
GetRegionsData: testRegions,
},
expectedCode: 200,
expectedBody: `{"regions":[{"region_name":"test1","description":"test1"},{"region_name":"test2","description":"test2"}]}` + "\n",
},
{
description: "Error: Internal Error",
disClient: &distilleries.TestClient{
GetRegionsErr: errors.New("Internal Error"),
},
expectedCode: 500,
expectedBody: `{"message":"INTERNAL_ERROR","resource":"region","description":"An internal error occurred."}` + "\n",
},
}
for i, tc := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
t.Log(tc.description)
t.Parallel()

h := NewHandler(tc.disClient)

r := httptest.NewRequest("GET", "/regions", nil)
w := httptest.NewRecorder()
h.GetRegions(w, r)

assert.Equal(t, tc.expectedCode, w.Code)
assert.Equal(t, tc.expectedBody, w.Body.String())
})
}
}

func TestGetRegion(t *testing.T) {
testCases := []struct {
description string
disClient *distilleries.TestClient
expectedCode int
expectedBody string
}{
{
description: "Success: Region is returned",
disClient: &distilleries.TestClient{
GetRegionByNameData: testRegion1,
},
expectedCode: 200,
expectedBody: `{"region_name":"test1","description":"test1"}` + "\n",
},
{
description: "Error: Region is cannot be found",
disClient: &distilleries.TestClient{
GetRegionByNameErr: errors.New("Error fetching region"),
},
expectedCode: 404,
expectedBody: `{"message":"NOT_FOUND","resource":"region","description":"What you are looking for cannot be found."}` + "\n",
},
}
for i, tc := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
t.Log(tc.description)
t.Parallel()

h := NewHandler(tc.disClient)

r := httptest.NewRequest("GET", "/regions/test1", nil)
w := httptest.NewRecorder()
h.GetRegion(w, r)

assert.Equal(t, tc.expectedCode, w.Code)
assert.Equal(t, tc.expectedBody, w.Body.String())
})
}
}
6 changes: 6 additions & 0 deletions internal/apiresponses/apiresponses.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ func write(w http.ResponseWriter, code int, data interface{}) {

if data != nil {
enc := json.NewEncoder(w)
enc.SetIndent("", "")
enc.SetEscapeHTML(false)
if err := enc.Encode(data); err != nil {
fields := log.Fields{"data": data, "code": code}
log.WithFields(fields).Errorf("%+v", err)
Expand Down Expand Up @@ -149,3 +151,7 @@ func BadRequest400(w http.ResponseWriter, resource, field string) {
func NotFound404(w http.ResponseWriter, resource string) {
Err(w, NewNotFoundError(resource), 404)
}

func InternalError500(w http.ResponseWriter, resource string, err error) {
Err(w, NewInternalError(resource), 500)
}
8 changes: 4 additions & 4 deletions internal/distilleries/distilleries.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ import (
disdb "github.com/efuchsman/distilleries_of_scotland/internal/distilleriesdb"
)

type Service interface {
type Client interface {
SeedRegions(filePath string) error
GetRegions() (*Regions, error)
GetRegionByName(regionName string) (*Region, error)
}

type Client struct {
type DistilleriesClient struct {
db disdb.Client
}

func NewClient(db disdb.Client) *Client {
return &Client{
func NewDistilleriesClient(db disdb.Client) *DistilleriesClient {
return &DistilleriesClient{
db: db,
}
}
8 changes: 4 additions & 4 deletions internal/distilleries/regions.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type Regions struct {
Regions []*Region `json:"regions"`
}

func (c *Client) AddRegion(regionName string, regionDescription string) (*Region, error) {
func (c *DistilleriesClient) AddRegion(regionName string, regionDescription string) (*Region, error) {
fields := log.Fields{"Region Name": regionName, "Region Description": regionDescription}

region, err := c.db.CreateRegion(regionName, regionDescription)
Expand Down Expand Up @@ -50,7 +50,7 @@ func buildRegions(filePath string) ([]*Region, error) {
return regions, nil
}

func (c *Client) SeedRegions(filePath string) error {
func (c *DistilleriesClient) SeedRegions(filePath string) error {
regions, err := buildRegions(filePath)
if err != nil {
log.Errorf("Error seeding Regions: %v", err)
Expand All @@ -77,7 +77,7 @@ func (c *Client) SeedRegions(filePath string) error {
return nil
}

func (c *Client) GetRegionByName(regionName string) (*Region, error) {
func (c *DistilleriesClient) GetRegionByName(regionName string) (*Region, error) {
fields := log.Fields{"Region Name": regionName}

region, err := c.db.GetRegionByName(regionName)
Expand All @@ -94,7 +94,7 @@ func (c *Client) GetRegionByName(regionName string) (*Region, error) {
return distilleryRegion, nil
}

func (c *Client) GetRegions() (*Regions, error) {
func (c *DistilleriesClient) GetRegions() (*Regions, error) {
regions, err := c.db.GetRegions()
if err != nil {
log.Errorf("Error fetching regions: %+v", err)
Expand Down
50 changes: 48 additions & 2 deletions internal/distilleries/regions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ func TestAddRegion(t *testing.T) {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
t.Log(tc.description)
t.Parallel()
c := NewClient(tc.dbclient)
c := NewDistilleriesClient(tc.dbclient)

newRegion, err := c.AddRegion(tc.regionName, tc.regionDescription)
if tc.expectedErr != nil {
Expand Down Expand Up @@ -122,6 +122,52 @@ func TestBuildRegions(t *testing.T) {
}
}

func TestGetRegions(t *testing.T) {
testCases := []struct {
description string
dbclient distilleriesdb.TestClient
expectedCount int
expectedErr error
}{
{
description: "Success: Region is returned",
dbclient: distilleriesdb.TestClient{
GetRegionsData: []distilleriesdb.Region{
*testDbRegion,
},
},
expectedCount: 1,
expectedErr: nil,
},

{
description: "Failure: Region cannot be found",
dbclient: distilleriesdb.TestClient{
GetRegionsErr: distilleriesdb.ErrNoRows,
},
expectedCount: 0,
expectedErr: distilleriesdb.ErrNoRows,
},
}
for i, tc := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
t.Log(tc.description)
t.Parallel()

c := NewDistilleriesClient(tc.dbclient)

regions, err := c.GetRegions()
if tc.expectedErr != nil {
assert.Error(t, err, tc.description)
return
}

assert.NoError(t, err, tc.description)
assert.Equal(t, tc.expectedCount, len(regions.Regions))
})
}
}

func TestGetRegionByName(t *testing.T) {
testCases := []struct {
description string
Expand Down Expand Up @@ -155,7 +201,7 @@ func TestGetRegionByName(t *testing.T) {
t.Log(tc.description)
t.Parallel()

c := NewClient(tc.dbclient)
c := NewDistilleriesClient(tc.dbclient)

newRegion, err := c.GetRegionByName(tc.regionName)
if tc.expectedErr != nil {
Expand Down
1 change: 1 addition & 0 deletions internal/distilleries/testclient.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package distilleries

type TestClient struct {
DistilleriesClient
GetRegionByNameData *Region
GetRegionByNameErr error

Expand Down

0 comments on commit a7f356e

Please sign in to comment.