Skip to content

Commit

Permalink
fix handler tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nicpottier committed May 11, 2017
1 parent 67fb760 commit aba6186
Show file tree
Hide file tree
Showing 14 changed files with 61 additions and 39 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Courier [![Build Status](https://travis-ci.org/nyaruka/courier.svg?branch=master)](https://travis-ci.org/nyaruka/courier) [![Coverage Status](https://coveralls.io/repos/github/nyaruka/courier/badge.svg?branch=master)](https://coveralls.io/github/nyaruka/courier?branch=master)
# Courier [![Build Status](https://travis-ci.org/nyaruka/courier.svg?branch=master)](https://travis-ci.org/nyaruka/courier) [![Coverage Status](https://coveralls.io/repos/github/nyaruka/courier/badge.svg?branch=master)](https://coveralls.io/github/nyaruka/courier?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/nyaruka/courier)](https://goreportcard.com/report/github.com/nyaruka/courier)

Install Courier in your workspace with:

Expand Down
11 changes: 6 additions & 5 deletions handlers/africastalking/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ type handler struct {
handlers.BaseHandler
}

func NewHandler() *handler {
// NewHandler returns a new Africa's Talking handler
func NewHandler() courier.ChannelHandler {
return &handler{handlers.NewBaseHandler(courier.ChannelType("AT"), "Africas Talking")}
}

Expand Down Expand Up @@ -55,7 +56,7 @@ func (h *handler) Initialize(s courier.Server) error {
}

// ReceiveMessage is our HTTP handler function for incoming messages
func (h *handler) ReceiveMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *handler) ReceiveMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
// get our params
atMsg := &messageRequest{}
err := handlers.DecodeAndValidateForm(atMsg, r)
Expand All @@ -71,10 +72,10 @@ func (h *handler) ReceiveMessage(channel courier.Channel, w http.ResponseWriter,
}

// create our URN
urn := courier.NewTelURN(atMsg.From, channel.Country())
urn := courier.NewTelURN(atMsg.From, channel.Country)

// build our msg
msg := courier.NewMsg(channel, urn, atMsg.Text).WithExternalID(atMsg.ID).WithDate(date)
msg := courier.NewMsg(channel, urn, atMsg.Text).WithExternalID(atMsg.ID).WithReceivedOn(date)
defer msg.Release()

// and finally queue our message
Expand All @@ -87,7 +88,7 @@ func (h *handler) ReceiveMessage(channel courier.Channel, w http.ResponseWriter,
}

// StatusMessage is our HTTP handler function for status updates
func (h *handler) StatusMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *handler) StatusMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
// get our params
atStatus := &statusRequest{}
err := handlers.DecodeAndValidateForm(atStatus, r)
Expand Down
2 changes: 1 addition & 1 deletion handlers/africastalking/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
. "github.com/nyaruka/courier/handlers"
)

var testChannels = []courier.Channel{
var testChannels = []*courier.Channel{
courier.NewMockChannel("8eb23e93-5ecb-45ba-b726-3b064e0c56ab", "AT", "2020", "US", nil),
}

Expand Down
24 changes: 18 additions & 6 deletions handlers/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,24 @@ import (
var base64Regex, _ = regexp.Compile("^([a-zA-Z0-9+/=]{4})+$")
var base64Encoding = base64.StdEncoding.Strict()

// BaseHandler is the base class for most handlers, it just stored the server, name and channel type for the handler
type BaseHandler struct {
channelType courier.ChannelType
name string
server courier.Server
}

// NewBaseHandler returns a newly constructed BaseHandler with the passed in parameters
func NewBaseHandler(channelType courier.ChannelType, name string) BaseHandler {
return BaseHandler{channelType: channelType, name: name}
}

// SetServer can be used to change the server on a BaseHandler
func (h *BaseHandler) SetServer(server courier.Server) {
h.server = server
}

// Server returns the server instance on the BaseHandler
func (h *BaseHandler) Server() courier.Server {
return h.server
}
Expand All @@ -57,6 +61,8 @@ func init() {
decoder.SetAliasTag("name")
}

// NameFromFirstLastUsername is a utility function to build a contact's name from the passed
// in values, all of which can be empty
func NameFromFirstLastUsername(first string, last string, username string) string {
if first != "" && last != "" {
return fmt.Sprintf("%s %s", first, last)
Expand All @@ -70,41 +76,47 @@ func NameFromFirstLastUsername(first string, last string, username string) strin
return ""
}

func DecodeAndValidateForm(data interface{}, r *http.Request) error {
// DecodeAndValidateForm takes the passed in form and attempts to parse and validate it from the
// POST parameters of the passed in request
func DecodeAndValidateForm(form interface{}, r *http.Request) error {
err := r.ParseForm()
if err != nil {
return err
}

err = decoder.Decode(data, r.Form)
err = decoder.Decode(form, r.Form)
if err != nil {
return err
}

// check our input is valid
err = validate.Struct(data)
err = validate.Struct(form)
if err != nil {
return err
}

return nil
}

func DecodeAndValidateQueryParams(data interface{}, r *http.Request) error {
err := decoder.Decode(data, r.URL.Query())
// DecodeAndValidateQueryParams takes the passed in form and attempts to parse and validate it from the
// GET parameters of the passed in request
func DecodeAndValidateQueryParams(form interface{}, r *http.Request) error {
err := decoder.Decode(form, r.URL.Query())
if err != nil {
return err
}

// check our input is valid
err = validate.Struct(data)
err = validate.Struct(form)
if err != nil {
return err
}

return nil
}

// DecodeAndValidateJSON takes the passed in envelope and tries to unmarshal it from the body
// of the passed in request, then validating it
func DecodeAndValidateJSON(envelope interface{}, r *http.Request) error {
// read our body
body, err := ioutil.ReadAll(io.LimitReader(r.Body, 100000))
Expand Down
9 changes: 5 additions & 4 deletions handlers/blackmyna/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ type bmHandler struct {
handlers.BaseHandler
}

func NewHandler() *bmHandler {
// NewHandler returns a new Blackmyna Handler
func NewHandler() courier.ChannelHandler {
return &bmHandler{handlers.NewBaseHandler(courier.ChannelType("BM"), "Blackmyna")}
}

Expand All @@ -33,7 +34,7 @@ func (h *bmHandler) Initialize(s courier.Server) error {
}

// ReceiveMessage is our HTTP handler function for incoming messages
func (h *bmHandler) ReceiveMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *bmHandler) ReceiveMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
// get our params
bmMsg := &bmMessage{}
err := handlers.DecodeAndValidateForm(bmMsg, r)
Expand All @@ -42,7 +43,7 @@ func (h *bmHandler) ReceiveMessage(channel courier.Channel, w http.ResponseWrite
}

// create our URN
urn := courier.NewTelURN(bmMsg.From, channel.Country())
urn := courier.NewTelURN(bmMsg.From, channel.Country)

// build our msg
msg := courier.NewMsg(channel, urn, bmMsg.Text)
Expand Down Expand Up @@ -71,7 +72,7 @@ var bmStatusMapping = map[int]courier.MsgStatus{
}

// StatusMessage is our HTTP handler function for status updates
func (h *bmHandler) StatusMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *bmHandler) StatusMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
// get our params
bmStatus := &bmStatus{}
err := handlers.DecodeAndValidateForm(bmStatus, r)
Expand Down
2 changes: 1 addition & 1 deletion handlers/blackmyna/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
. "github.com/nyaruka/courier/handlers"
)

var testChannels = []courier.Channel{
var testChannels = []*courier.Channel{
courier.NewMockChannel("8eb23e93-5ecb-45ba-b726-3b064e0c56ab", "BM", "2020", "US", nil),
}

Expand Down
11 changes: 6 additions & 5 deletions handlers/kannel/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ type kannelHandler struct {
handlers.BaseHandler
}

func NewHandler() *kannelHandler {
// NewHandler returns a new KannelHandler
func NewHandler() courier.ChannelHandler {
return &kannelHandler{handlers.NewBaseHandler(courier.ChannelType("KN"), "Kannel")}
}

Expand All @@ -34,7 +35,7 @@ func (h *kannelHandler) Initialize(s courier.Server) error {
}

// ReceiveMessage is our HTTP handler function for incoming messages
func (h *kannelHandler) ReceiveMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *kannelHandler) ReceiveMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
// get our params
kannelMsg := &kannelMessage{}
err := handlers.DecodeAndValidateQueryParams(kannelMsg, r)
Expand All @@ -46,10 +47,10 @@ func (h *kannelHandler) ReceiveMessage(channel courier.Channel, w http.ResponseW
date := time.Unix(kannelMsg.Timestamp, 0).UTC()

// create our URN
urn := courier.NewTelURN(kannelMsg.Sender, channel.Country())
urn := courier.NewTelURN(kannelMsg.Sender, channel.Country)

// build our msg
msg := courier.NewMsg(channel, urn, kannelMsg.Message).WithExternalID(fmt.Sprintf("%d", kannelMsg.ID)).WithDate(date)
msg := courier.NewMsg(channel, urn, kannelMsg.Message).WithExternalID(fmt.Sprintf("%d", kannelMsg.ID)).WithReceivedOn(date)
defer msg.Release()

// and finally queue our message
Expand Down Expand Up @@ -77,7 +78,7 @@ var kannelStatusMapping = map[int]courier.MsgStatus{
}

// StatusMessage is our HTTP handler function for status updates
func (h *kannelHandler) StatusMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *kannelHandler) StatusMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
// get our params
kannelStatus := &kannelStatus{}
err := handlers.DecodeAndValidateQueryParams(kannelStatus, r)
Expand Down
2 changes: 1 addition & 1 deletion handlers/kannel/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var (
statusInvalidStatus = "/c/kn/8eb23e93-5ecb-45ba-b726-3b064e0c56ab/status/?id=12345&status=66"
)

var testChannels = []courier.Channel{
var testChannels = []*courier.Channel{
courier.NewMockChannel("8eb23e93-5ecb-45ba-b726-3b064e0c56ab", "KN", "2020", "US", nil),
}

Expand Down
9 changes: 5 additions & 4 deletions handlers/telegram/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ type telegramHandler struct {
handlers.BaseHandler
}

func NewHandler() *telegramHandler {
// NewHandler returns a new TelegramHandler ready to be registered
func NewHandler() courier.ChannelHandler {
return &telegramHandler{handlers.NewBaseHandler(courier.ChannelType("TG"), "Telegram")}
}

Expand All @@ -34,7 +35,7 @@ func (h *telegramHandler) Initialize(s courier.Server) error {
}

// ReceiveMessage is our HTTP handler function for incoming messages
func (h *telegramHandler) ReceiveMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *telegramHandler) ReceiveMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
te := &telegramEnvelope{}
err := handlers.DecodeAndValidateJSON(te, r)
if err != nil {
Expand Down Expand Up @@ -101,7 +102,7 @@ func (h *telegramHandler) ReceiveMessage(channel courier.Channel, w http.Respons
}

// build our msg
msg := courier.NewMsg(channel, urn, text).WithDate(date).WithExternalID(fmt.Sprintf("%d", te.Message.MessageID)).WithName(name)
msg := courier.NewMsg(channel, urn, text).WithReceivedOn(date).WithExternalID(fmt.Sprintf("%d", te.Message.MessageID)).WithContactName(name)
defer msg.Release()

if mediaURL != "" {
Expand All @@ -119,7 +120,7 @@ func (h *telegramHandler) ReceiveMessage(channel courier.Channel, w http.Respons

var telegramAPIURL = "https://api.telegram.org"

func resolveFileID(channel courier.Channel, fileID string) (string, error) {
func resolveFileID(channel *courier.Channel, fileID string) (string, error) {
authToken := channel.GetConfig(courier.ConfigAuthToken)
fileURL := fmt.Sprintf("%s/bot%s/getFile", telegramAPIURL, authToken)

Expand Down
2 changes: 1 addition & 1 deletion handlers/telegram/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
. "github.com/nyaruka/courier/handlers"
)

var testChannels = []courier.Channel{
var testChannels = []*courier.Channel{
courier.NewMockChannel("8eb23e93-5ecb-45ba-b726-3b064e0c568c", "TG", "2020", "US", nil),
}

Expand Down
13 changes: 9 additions & 4 deletions handlers/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ import (

"fmt"

_ "github.com/lib/pq"
_ "github.com/lib/pq" // postgres driver
"github.com/nyaruka/courier"
"github.com/stretchr/testify/require"
)

// RequestPrepFunc is our type for a hook for tests to use before a request is fired in a test
type RequestPrepFunc func(*http.Request)

// ChannelTestCase defines the test values for a particular test case
type ChannelTestCase struct {
Label string

Expand All @@ -35,17 +37,18 @@ type ChannelTestCase struct {
PrepRequest RequestPrepFunc
}

// GetMediaURLs returns the media urls that are expected for this test case
func (c ChannelTestCase) GetMediaURLs() []string {
if c.MediaURL != nil {
return []string{*c.MediaURL}
}
return c.MediaURLs
}

// utility method to get the pointer to the passed in string
// Sp is a utility method to get the pointer to the passed in string
func Sp(str string) *string { return &str }

// utility method to get the pointer to the pased in time
// Tp is utility method to get the pointer to the passed in time
func Tp(tm time.Time) *time.Time { return &tm }

// utility method to make sure the passed in host is up, prevents races with our test server
Expand Down Expand Up @@ -99,6 +102,7 @@ func testHandlerRequest(tb testing.TB, s *courier.MockServer, url string, data s
return body
}

// RunChannelTestCases runs all the passed in tests cases for the passed in channel configurations
func RunChannelTestCases(t *testing.T, channels []*courier.Channel, handler courier.ChannelHandler, testCases []ChannelTestCase) {
s := courier.NewMockServer()
for _, ch := range channels {
Expand Down Expand Up @@ -135,7 +139,7 @@ func RunChannelTestCases(t *testing.T, channels []*courier.Channel, handler cour
require.Equal(*testCase.External, msg.ExternalID)
}
if testCase.MediaURL != nil || len(testCase.MediaURLs) > 0 {
require.Equal(testCase.GetMediaURLs(), msg.MediaURLs)
require.Equal(testCase.MediaURLs, msg.MediaURLs)
}
if testCase.Date != nil {
require.Equal(*testCase.Date, msg.SentOn)
Expand All @@ -161,6 +165,7 @@ func RunChannelTestCases(t *testing.T, channels []*courier.Channel, handler cour
})
}

// RunChannelBenchmarks runs all the passed in test cases for the passed in channels
func RunChannelBenchmarks(b *testing.B, channels []*courier.Channel, handler courier.ChannelHandler, testCases []ChannelTestCase) {
s := courier.NewMockServer()
for _, ch := range channels {
Expand Down
9 changes: 5 additions & 4 deletions handlers/twilio/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ type twHandler struct {
handlers.BaseHandler
}

func NewHandler() *twHandler {
// NewHandler returns a new TwilioHandler ready to be registered
func NewHandler() courier.ChannelHandler {
return &twHandler{handlers.NewBaseHandler(courier.ChannelType("TW"), "Twilio")}
}

Expand Down Expand Up @@ -78,7 +79,7 @@ var twStatusMapping = map[string]courier.MsgStatus{
}

// ReceiveMessage is our HTTP handler function for incoming messages
func (h *twHandler) ReceiveMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *twHandler) ReceiveMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
err := h.validateSignature(channel, r)
if err != nil {
return err
Expand Down Expand Up @@ -119,7 +120,7 @@ func (h *twHandler) ReceiveMessage(channel courier.Channel, w http.ResponseWrite
}

// StatusMessage is our HTTP handler function for status updates
func (h *twHandler) StatusMessage(channel courier.Channel, w http.ResponseWriter, r *http.Request) error {
func (h *twHandler) StatusMessage(channel *courier.Channel, w http.ResponseWriter, r *http.Request) error {
err := h.validateSignature(channel, r)
if err != nil {
return err
Expand Down Expand Up @@ -157,7 +158,7 @@ func (h *twHandler) writeReceiveSuccess(w http.ResponseWriter) error {
}

// see https://www.twilio.com/docs/api/security
func (h *twHandler) validateSignature(channel courier.Channel, r *http.Request) error {
func (h *twHandler) validateSignature(channel *courier.Channel, r *http.Request) error {
if err := r.ParseForm(); err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion handlers/twilio/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
. "github.com/nyaruka/courier/handlers"
)

var testChannels = []courier.Channel{
var testChannels = []*courier.Channel{
courier.NewMockChannel("8eb23e93-5ecb-45ba-b726-3b064e0c56ab", "TW", "2020", "US", map[string]string{"auth_token": "6789"}),
}

Expand Down
Loading

0 comments on commit aba6186

Please sign in to comment.