Skip to content
This repository has been archived by the owner on Jun 6, 2023. It is now read-only.

Commit

Permalink
Merge pull request #14 from RobotsAndPencils/valid
Browse files Browse the repository at this point in the history
Payload and device token validations
  • Loading branch information
curtisallen committed Jan 9, 2016
2 parents cbda86f + 947f5b8 commit b70e6fa
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 3 deletions.
14 changes: 13 additions & 1 deletion payload/aps.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// Package payload serializes a JSON payload to push.
package payload

import (
Expand Down Expand Up @@ -88,3 +87,16 @@ func (a *APS) Map() map[string]interface{} {
func (a APS) MarshalJSON() ([]byte, error) {
return json.Marshal(a.Map())
}

// Validate APS payload.
func (a *APS) Validate() error {
if a == nil {
return ErrIncomplete
}

// must have a body or a badge (or custom data)
if len(a.Alert.Body) == 0 && a.Badge == badge.Preserve {
return ErrIncomplete
}
return nil
}
28 changes: 28 additions & 0 deletions payload/aps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,31 @@ func TestCustomArray(t *testing.T) {
expected := []byte(`{"acme2":["bang","whiz"],"aps":{"alert":"Message received from Bob"}}`)
testPayload(t, pm, expected)
}

func TestValidAPS(t *testing.T) {
tests := []payload.APS{
{Alert: payload.Alert{Body: "You got your emails."}},
{Badge: badge.New(9)},
{Badge: badge.Clear},
}

for _, p := range tests {
if err := p.Validate(); err != nil {
t.Errorf("Expected no error, got %v.", err)
}
}
}

func TestInvalidAPS(t *testing.T) {
tests := []*payload.APS{
{Sound: "bingbong.aiff"},
{},
nil,
}

for _, p := range tests {
if err := p.Validate(); err != payload.ErrIncomplete {
t.Errorf("Expected err %v, got %v.", payload.ErrIncomplete, err)
}
}
}
17 changes: 15 additions & 2 deletions payload/browser.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,20 @@ type BrowserAlert struct {
}

// MarshalJSON allows you to json.Marshal(browser) directly.
func (b Browser) MarshalJSON() ([]byte, error) {
aps := map[string]interface{}{"alert": b.Alert, "url-args": b.URLArgs}
func (p Browser) MarshalJSON() ([]byte, error) {
aps := map[string]interface{}{"alert": p.Alert, "url-args": p.URLArgs}
return json.Marshal(map[string]interface{}{"aps": aps})
}

// Validate browser payload.
func (p *Browser) Validate() error {
if p == nil {
return ErrIncomplete
}

// must have both a title and body. action and url-args are optional.
if len(p.Alert.Title) == 0 || len(p.Alert.Body) == 0 {
return ErrIncomplete
}
return nil
}
28 changes: 28 additions & 0 deletions payload/browser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,31 @@ func TestBrowser(t *testing.T) {
expected := []byte(`{"aps":{"alert":{"title":"Flight A998 Now Boarding","body":"Boarding has begun for Flight A998.","action":"View"},"url-args":["boarding","A998"]}}`)
testPayload(t, p, expected)
}

func TestValidBrowser(t *testing.T) {
p := payload.Browser{
Alert: payload.BrowserAlert{
Title: "Flight A998 Now Boarding",
Body: "Boarding has begun for Flight A998.",
},
}
if err := p.Validate(); err != nil {
t.Errorf("Expected no error, got %v.", err)
}
}

func TestInvalidBrowser(t *testing.T) {
tests := []*payload.Browser{
{
Alert: payload.BrowserAlert{Action: "View"},
},
{},
nil,
}

for _, p := range tests {
if err := p.Validate(); err != payload.ErrIncomplete {
t.Errorf("Expected err %v, got %v.", payload.ErrIncomplete, err)
}
}
}
13 changes: 13 additions & 0 deletions payload/mdm.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,16 @@ package payload
type MDM struct {
Token string `json:"mdm"`
}

// Validate MDM payload.
func (p *MDM) Validate() error {
if p == nil {
return ErrIncomplete
}

// must have a token.
if len(p.Token) == 0 {
return ErrIncomplete
}
return nil
}
20 changes: 20 additions & 0 deletions payload/mdm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,23 @@ func TestMDM(t *testing.T) {
expected := []byte(`{"mdm":"00000000-1111-3333-4444-555555555555"}`)
testPayload(t, p, expected)
}

func TestValidMDM(t *testing.T) {
p := payload.MDM{"00000000-1111-3333-4444-555555555555"}
if err := p.Validate(); err != nil {
t.Errorf("Expected no error, got %v.", err)
}
}

func TestInvalidMDM(t *testing.T) {
tests := []*payload.MDM{
{},
nil,
}

for _, p := range tests {
if err := p.Validate(); err != payload.ErrIncomplete {
t.Errorf("Expected err %v, got %v.", payload.ErrIncomplete, err)
}
}
}
9 changes: 9 additions & 0 deletions payload/payload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Package payload serializes a JSON payload to push.
package payload

import "errors"

// validation errors
var (
ErrIncomplete = errors.New("payload does not contain necessary fields")
)
13 changes: 13 additions & 0 deletions push/device_token.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package push

import "encoding/hex"

// IsDeviceTokenValid checks if s is a hexadecimal token of the correct length.
func IsDeviceTokenValid(s string) bool {
// TODO: In 2016, they may be growing up to 100 bytes (200 hexadecimal digits).
if len(s) != 64 {
return false
}
_, err := hex.DecodeString(s)
return err == nil
}
35 changes: 35 additions & 0 deletions push/device_token_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package push_test

import (
"testing"

"github.com/RobotsAndPencils/buford/push"
)

func TestInvalidDeviceTokens(t *testing.T) {
tokens := []string{
"invalid-token",
"f00f",
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl",
"50c4afb5 9197d2ba d1794be4 e63f2532 ee18c660 0ee655fa 38b0b380 94fd8847",
"<50c4afb5 9197d2ba d1794be4 e63f2532 ee18c660 0ee655fa 38b0b380 94fd8847>",
}

for _, token := range tokens {
if push.IsDeviceTokenValid(token) {
t.Errorf("Expected device token %q to be invalid.", token)
}
}
}

func TestValidDeviceToken(t *testing.T) {
tokens := []string{
"c2732227a1d8021cfaf781d71fb2f908c61f5861079a00954a5453f1d0281433",
}

for _, token := range tokens {
if !push.IsDeviceTokenValid(token) {
t.Errorf("Expected device token %q to be valid.", token)
}
}
}

0 comments on commit b70e6fa

Please sign in to comment.