Skip to content

Commit

Permalink
Feature:add unit tests
Browse files Browse the repository at this point in the history
* bump `github.com/quarksgroup.com` to `v1.0.0`.
* move http handlers to their own package `api/handlers`.
* generate interface mocks at `mocks`.
* add unit tests for package `github.com/rugwirobaker/helmes`, `github.com/rugwirobaker/helmes/api/handlers`
* add a new type `github.com/rugwirobaker/helmes/Health`
* rename `handlers.SMSHandler` to `handlers.SendService`
* rename `helmes.Service` to `helmes.SendService`
  • Loading branch information
rugwirobaker committed Oct 3, 2020
1 parent 4fa9efd commit 830ec3a
Show file tree
Hide file tree
Showing 12 changed files with 333 additions and 32 deletions.
11 changes: 6 additions & 5 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import (
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
helmes "github.com/rugwirobaker/helmes"
"github.com/rugwirobaker/helmes/api/handlers"
)

// Server ...
type Server struct {
Service helmes.Service
Service helmes.SendService
}

// New api Server instance
func New(svc helmes.Service) *Server {
func New(svc helmes.SendService) *Server {
return &Server{Service: svc}
}

Expand All @@ -31,9 +32,9 @@ func (s Server) Handler() http.Handler {
w.Write([]byte("Welcome to helmes"))
})

r.Get("/version", VersionHandler(s.Service))
r.Post("/send", SMSHandler(s.Service))
r.Get("/healthz", HealthHandler())
r.Get("/healthz", handlers.HealthHandler())
r.Get("/version", handlers.VersionHandler())
r.Post("/send", handlers.SendHandler(s.Service))

return r
}
25 changes: 9 additions & 16 deletions api/handlers.go → api/handlers/handlers.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package api
package handlers

import (
"encoding/json"
Expand All @@ -12,8 +12,8 @@ import (

var startTime = time.Now()

// SMSHandler ...
func SMSHandler(svc helmes.Service) http.HandlerFunc {
// SendHandler ...
func SendHandler(svc helmes.SendService) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {

in := new(helmes.SMS)
Expand All @@ -35,25 +35,18 @@ func SMSHandler(svc helmes.Service) http.HandlerFunc {
}
}

// VersionHandler ...
func VersionHandler(svc helmes.Service) http.HandlerFunc {
// VersionHandler handles version reporting
func VersionHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
build, err := svc.Version(r.Context())
if err != nil {
http.Error(w, err.Error(), 500)
}
JSON(w, build, http.StatusOK)
res := helmes.Data()
JSON(w, res, http.StatusOK)
}
}

// HealthHandler reports the health of the application
// HealthHandler handles application health reporting
func HealthHandler() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
res := struct {
GitRev string `json:"git_rev"`
Uptime float64 `json:"uptime"`
Goroutines int `json:"goroutines"`
}{
res := &helmes.Health{
GitRev: helmes.Data().Version,
Uptime: time.Since(startTime).Seconds(),
Goroutines: runtime.NumGoroutine(),
Expand Down
81 changes: 81 additions & 0 deletions api/handlers/handlers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package handlers_test

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/golang/mock/gomock"
"github.com/google/go-cmp/cmp"
"github.com/rugwirobaker/helmes"
"github.com/rugwirobaker/helmes/api/handlers"
"github.com/rugwirobaker/helmes/mock"
)

var (
dummyMessage = &helmes.SMS{
Payload: "Hello",
Recipient: "User_Phone",
}
dummyReport = &helmes.Report{
ID: "message id",
Cost: 1,
}
)

func TestSendHander(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()

sender := mock.NewMockSendService(controller)
sender.EXPECT().Send(gomock.Any(), gomock.Any()).Return(dummyReport, nil)

in := new(bytes.Buffer)

_ = json.NewEncoder(in).Encode(dummyMessage)

w := httptest.NewRecorder()
r := httptest.NewRequest("POST", "/", in)

handlers.SendHandler(sender).ServeHTTP(w, r)
if got, want := w.Code, http.StatusOK; want != got {
t.Errorf("Want response code %d, got %d", want, got)
}

got, want := &helmes.Report{}, dummyReport
json.NewDecoder(w.Body).Decode(got)
if diff := cmp.Diff(got, want); len(diff) != 0 {
t.Errorf(diff)
}

}

func TestHealthHandler(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/healthz", nil)

handlers.HealthHandler().ServeHTTP(w, r)

if got, want := w.Code, 200; want != got {
t.Errorf("Want response code %d, got %d", want, got)
}
}

func TestVersionHandler(t *testing.T) {
w := httptest.NewRecorder()
r := httptest.NewRequest("GET", "/version", nil)

handlers.VersionHandler().ServeHTTP(w, r)

if got, want := w.Code, 200; want != got {
t.Errorf("Want response code %d, got %d", want, got)
}

got, want := &helmes.Build{}, helmes.Data()
json.NewDecoder(w.Body).Decode(got)
if diff := cmp.Diff(got, want); len(diff) != 0 {
t.Errorf(diff)
}
}
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ go 1.14

require (
github.com/go-chi/chi v4.1.2+incompatible
github.com/golang/mock v1.4.4
github.com/google/go-cmp v0.5.1
github.com/google/uuid v1.1.2
github.com/quarksgroup/sms-client v0.0.0-20200916024156-cec3c804e5f8
github.com/quarksgroup/sms-client v1.0.0
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
)
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec=
github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
Expand All @@ -18,19 +20,24 @@ github.com/quarksgroup/sms-client v0.0.0-20200911144732-8cbf6e85ed3a h1:Prr/Ac/a
github.com/quarksgroup/sms-client v0.0.0-20200911144732-8cbf6e85ed3a/go.mod h1:XcPDoSKQvB0PT2pXePS3pqVd7uCHTBhZ/zBdnSFBYOw=
github.com/quarksgroup/sms-client v0.0.0-20200916024156-cec3c804e5f8 h1:AehGo7q3SYg9btSTVFPAUx0ToP3vWu1k6qccpHs+vzk=
github.com/quarksgroup/sms-client v0.0.0-20200916024156-cec3c804e5f8/go.mod h1:XcPDoSKQvB0PT2pXePS3pqVd7uCHTBhZ/zBdnSFBYOw=
github.com/quarksgroup/sms-client v1.0.0 h1:JKKsozedN6vbsAvqciC7A4SnnrMiNX2xSTknKjn1TA8=
github.com/quarksgroup/sms-client v1.0.0/go.mod h1:XcPDoSKQvB0PT2pXePS3pqVd7uCHTBhZ/zBdnSFBYOw=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
Expand Down
8 changes: 8 additions & 0 deletions health.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package helmes

// Health report
type Health struct {
GitRev string `json:"git_rev"`
Uptime float64 `json:"uptime"`
Goroutines int `json:"goroutines"`
}
14 changes: 4 additions & 10 deletions helmes.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,10 @@ type Report struct {
Cost int64 `json:"cost"`
}

// Service defines the capabilties of helmes
type Service interface {
// SendService defines the capabilties of helmes
type SendService interface {
// Send an sms message and return it's
Send(context.Context, *SMS) (*Report, error)

//Version returns helmes's current running version
Version(context.Context) (*Build, error)
}

type service struct {
Expand All @@ -36,7 +33,7 @@ type service struct {
}

// New instance of service
func New(cli *sms.Client, id, secret, sender, callback string) (Service, error) {
func New(cli *sms.Client, id, secret, sender, callback string) (SendService, error) {
token, _, err := cli.Auth.Login(context.Background(), id, secret)
if err != nil {
return nil, err
Expand All @@ -54,6 +51,7 @@ func (s *service) Send(ctx context.Context, message *SMS) (*Report, error) {
if err != nil {
return nil, err
}
s.token = token
ctx = context.WithValue(ctx, sms.TokenKey{}, &sms.Token{
Token: token.Token,
Refresh: token.Refresh,
Expand All @@ -74,10 +72,6 @@ func (s *service) Send(ctx context.Context, message *SMS) (*Report, error) {
return convertReport(report), nil
}

func (s *service) Version(ctx context.Context) (*Build, error) {
return Data(), nil
}

func convertReport(report *sms.Report) *Report {
return &Report{
ID: report.ID,
Expand Down
53 changes: 53 additions & 0 deletions helmes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package helmes_test

import (
"context"
"testing"

"github.com/golang/mock/gomock"
"github.com/google/go-cmp/cmp"
"github.com/quarksgroup/sms-client/sms"
"github.com/rugwirobaker/helmes"
"github.com/rugwirobaker/helmes/mock/mocksmc"
)

var noContext = context.Background()

func TestSend(t *testing.T) {
controller := gomock.NewController(t)
defer controller.Finish()

mockReport := &sms.Report{
ID: "fake_id",
Cost: 1,
}
mockToken := &sms.Token{}
mockSMS := &helmes.SMS{}

mockSendService := mocksmc.NewMockSendService(controller)
mockSendService.EXPECT().Send(gomock.Any(), gomock.Any()).Return(mockReport, nil, nil)

mockAuthService := mocksmc.NewMockAuthService(controller)
mockAuthService.EXPECT().Refresh(gomock.Any(), gomock.Any(), false).Return(mockToken, nil, nil)
mockAuthService.EXPECT().Login(gomock.Any(), "id", "secret").Return(mockToken, nil, nil)

client := new(sms.Client)
client.Message = mockSendService
client.Auth = mockAuthService

service, _ := helmes.New(client, "id", "secret", "sender", "callback")

want := &helmes.Report{
ID: "fake_id",
Cost: 1,
}

got, err := service.Send(noContext, mockSMS)
if err != nil {
t.Error(err)
}
if diff := cmp.Diff(got, want); diff != "" {
t.Errorf(diff)
}

}
3 changes: 3 additions & 0 deletions mock/mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package mock

//go:generate mockgen -package=mock -destination=mock_gen.go github.com/rugwirobaker/helmes SendService
50 changes: 50 additions & 0 deletions mock/mock_gen.go

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

3 changes: 3 additions & 0 deletions mock/mocksmc/mock.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package mocksmc

//go:generate mockgen -package=mocksmc -destination=mock_gen.go github.com/quarksgroup/sms-client/sms SendService,AuthService
Loading

0 comments on commit 830ec3a

Please sign in to comment.