From bbfc058d05d69a8f31a2789fe27a8c5256d353da Mon Sep 17 00:00:00 2001 From: Bo-Yi Wu Date: Sun, 10 Apr 2016 11:36:49 +0800 Subject: [PATCH] support multiple notification request. Signed-off-by: Bo-Yi Wu --- Makefile | 3 + gorush/log.go | 2 +- gorush/notification.go | 45 +++++++---- gorush/notification_test.go | 149 +++++++++++++++++++++++++++++++++--- 4 files changed, 172 insertions(+), 27 deletions(-) diff --git a/Makefile b/Makefile index 0f62656..0d11ab2 100644 --- a/Makefile +++ b/Makefile @@ -17,5 +17,8 @@ docker_build: clean tar -zxvf bin.tar.gz -rm -rf bin.tar.gz build.tar.gz +test: + cd gopush && go test -v -covermode=count -coverprofile=coverage.out + clean: rm -rf build.tar.gz bin.tar.gz bin/* diff --git a/gorush/log.go b/gorush/log.go index 749d5ce..ce9e6f4 100644 --- a/gorush/log.go +++ b/gorush/log.go @@ -174,7 +174,7 @@ func typeForPlatForm(platform int) string { } } -func LogPush(status, token string, req RequestPushNotification, errPush error) { +func LogPush(status, token string, req PushNotification, errPush error) { var plat, platColor, output string platColor = colorForPlatForm(req.Platform) diff --git a/gorush/notification.go b/gorush/notification.go index e84d5e6..dcb0e71 100644 --- a/gorush/notification.go +++ b/gorush/notification.go @@ -41,7 +41,11 @@ type Alert struct { TitleLocKey string `json:"title-loc-key,omitempty"` } -type RequestPushNotification struct { +type RequestPush struct { + Notifications []PushNotification `json:"notifications"` +} + +type PushNotification struct { // Common Tokens []string `json:"tokens" binding:"required"` Platform int `json:"platform" binding:"required"` @@ -114,26 +118,33 @@ func InitAPNSClient() error { return nil } -func pushNotification(notification RequestPushNotification) bool { - switch notification.Platform { - case PlatFormIos: - if !PushConf.Ios.Enabled { - return false +func SendNotification(req RequestPush) int { + var count int + for _, notification := range req.Notifications { + switch notification.Platform { + case PlatFormIos: + if !PushConf.Ios.Enabled { + continue + } + + count += 1 + go PushToIOS(notification) + case PlatFormAndroid: + if !PushConf.Android.Enabled { + continue + } + + count += 1 + go PushToAndroid(notification) } - go PushToIOS(notification) - case PlatFormAndroid: - if !PushConf.Android.Enabled { - return false - } - go PushToAndroid(notification) } - return true + return count } // The iOS Notification Payload // ref: https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/TheNotificationPayload.html -func GetIOSNotification(req RequestPushNotification) *apns.Notification { +func GetIOSNotification(req PushNotification) *apns.Notification { notification := &apns.Notification{} if len(req.ApnsID) > 0 { @@ -225,7 +236,7 @@ func GetIOSNotification(req RequestPushNotification) *apns.Notification { return notification } -func PushToIOS(req RequestPushNotification) bool { +func PushToIOS(req PushNotification) bool { notification := GetIOSNotification(req) @@ -260,7 +271,7 @@ func PushToIOS(req RequestPushNotification) bool { // HTTP Connection Server Reference for Android // https://developers.google.com/cloud-messaging/http-server-ref -func GetAndroidNotification(req RequestPushNotification) gcm.HttpMessage { +func GetAndroidNotification(req PushNotification) gcm.HttpMessage { notification := gcm.HttpMessage{} notification.RegistrationIds = req.Tokens @@ -311,7 +322,7 @@ func GetAndroidNotification(req RequestPushNotification) gcm.HttpMessage { return notification } -func PushToAndroid(req RequestPushNotification) bool { +func PushToAndroid(req PushNotification) bool { var apiKey string notification := GetAndroidNotification(req) diff --git a/gorush/notification_test.go b/gorush/notification_test.go index c4c45b0..6444ab3 100644 --- a/gorush/notification_test.go +++ b/gorush/notification_test.go @@ -5,6 +5,7 @@ import ( "github.com/buger/jsonparser" "github.com/google/go-gcm" "github.com/stretchr/testify/assert" + "github.com/sideshow/apns2" "log" "os" "testing" @@ -64,7 +65,7 @@ func TestIOSNotificationStructure(t *testing.T) { test := "test" message := "Welcome notification Server" - req := RequestPushNotification{ + req := PushNotification{ ApnsID: test, Topic: test, Expiration: time.Now().Unix(), @@ -126,7 +127,7 @@ func TestIOSAlertNotificationStructure(t *testing.T) { var dat map[string]interface{} test := "test" - req := RequestPushNotification{ + req := PushNotification{ Alert: Alert{ Action: test, ActionLocKey: test, @@ -178,7 +179,7 @@ func TestIOSAlertNotificationStructure(t *testing.T) { func TestAndroidNotificationStructure(t *testing.T) { test := "test" - req := RequestPushNotification{ + req := PushNotification{ Tokens: []string{"a", "b"}, Message: "Welcome", To: test, @@ -219,7 +220,7 @@ func TestPushToIOS(t *testing.T) { PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" InitAPNSClient() - req := RequestPushNotification{ + req := PushNotification{ Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"}, Platform: 1, Message: "Welcome", @@ -235,7 +236,7 @@ func TestPushToAndroidWrongAPIKey(t *testing.T) { PushConf.Android.Enabled = true PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + "a" - req := RequestPushNotification{ + req := PushNotification{ Tokens: []string{"aaaaaa", "bbbbb"}, Platform: 2, Message: "Welcome", @@ -251,7 +252,7 @@ func TestPushToAndroidWrongToken(t *testing.T) { PushConf.Android.Enabled = true PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") - req := RequestPushNotification{ + req := PushNotification{ Tokens: []string{"aaaaaa", "bbbbb"}, Platform: 2, Message: "Welcome", @@ -271,7 +272,7 @@ func TestPushToAndroidRightTokenForJSONLog(t *testing.T) { android_token := os.Getenv("ANDROID_TEST_TOKEN") - req := RequestPushNotification{ + req := PushNotification{ Tokens: []string{android_token, "bbbbb"}, Platform: 2, Message: "Welcome", @@ -289,7 +290,7 @@ func TestPushToAndroidRightTokenForStringLog(t *testing.T) { android_token := os.Getenv("ANDROID_TEST_TOKEN") - req := RequestPushNotification{ + req := PushNotification{ Tokens: []string{android_token, "bbbbb"}, Platform: 2, Message: "Welcome", @@ -307,7 +308,7 @@ func TestOverwriteAndroidApiKey(t *testing.T) { android_token := os.Getenv("ANDROID_TEST_TOKEN") - req := RequestPushNotification{ + req := PushNotification{ Tokens: []string{android_token, "bbbbb"}, Platform: 2, Message: "Welcome", @@ -318,3 +319,133 @@ func TestOverwriteAndroidApiKey(t *testing.T) { success := PushToAndroid(req) assert.False(t, success) } + +func TestSenMultipleNotifications(t *testing.T) { + PushConf = BuildDefaultPushConf() + + PushConf.Ios.Enabled = true + PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" + InitAPNSClient() + + PushConf.Android.Enabled = true + PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + + android_token := os.Getenv("ANDROID_TEST_TOKEN") + + req := RequestPush{ + Notifications: []PushNotification{ + //ios + PushNotification{ + Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"}, + Platform: 1, + Message: "Welcome", + }, + // android + PushNotification{ + Tokens: []string{android_token, "bbbbb"}, + Platform: 2, + Message: "Welcome", + }, + }, + } + + count := SendNotification(req) + assert.Equal(t, 2, count) +} + +func TestDisabledAndroidNotifications(t *testing.T) { + PushConf = BuildDefaultPushConf() + + PushConf.Ios.Enabled = true + PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" + InitAPNSClient() + + PushConf.Android.Enabled = false + PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + + android_token := os.Getenv("ANDROID_TEST_TOKEN") + + req := RequestPush{ + Notifications: []PushNotification{ + //ios + PushNotification{ + Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"}, + Platform: 1, + Message: "Welcome", + }, + // android + PushNotification{ + Tokens: []string{android_token, "bbbbb"}, + Platform: 2, + Message: "Welcome", + }, + }, + } + + count := SendNotification(req) + assert.Equal(t, 1, count) +} + +func TestDisabledIosNotifications(t *testing.T) { + PushConf = BuildDefaultPushConf() + + PushConf.Ios.Enabled = false + PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" + InitAPNSClient() + + PushConf.Android.Enabled = true + PushConf.Android.ApiKey = os.Getenv("ANDROID_API_KEY") + + android_token := os.Getenv("ANDROID_TEST_TOKEN") + + req := RequestPush{ + Notifications: []PushNotification{ + //ios + PushNotification{ + Tokens: []string{"11aa01229f15f0f0c52029d8cf8cd0aeaf2365fe4cebc4af26cd6d76b7919ef7"}, + Platform: 1, + Message: "Welcome", + }, + // android + PushNotification{ + Tokens: []string{android_token, "bbbbb"}, + Platform: 2, + Message: "Welcome", + }, + }, + } + + count := SendNotification(req) + assert.Equal(t, 1, count) +} + +func TestMissingIosCertificate(t *testing.T) { + PushConf = BuildDefaultPushConf() + + PushConf.Ios.Enabled = true + PushConf.Ios.PemKeyPath = "test" + err := InitAPNSClient() + + assert.Error(t, err) +} + +func TestAPNSClientDevHost(t *testing.T) { + PushConf = BuildDefaultPushConf() + + PushConf.Ios.Enabled = true + PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" + InitAPNSClient() + + assert.Equal(t, apns2.HostDevelopment, ApnsClient.Host) +} + +func TestAPNSClientProdHost(t *testing.T) { + PushConf = BuildDefaultPushConf() + + PushConf.Ios.Enabled = true + PushConf.Ios.Production = true + PushConf.Ios.PemKeyPath = "../certificate/certificate-valid.pem" + InitAPNSClient() + + assert.Equal(t, apns2.HostProduction, ApnsClient.Host) +}