From 4aaeeb6ebfbfa4ac78db131ee62a1d6b2dd74ac2 Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Mon, 9 Oct 2017 19:21:56 +0300 Subject: [PATCH 01/16] Extract notification into separete package and interface --- geth/api/api.go | 35 ++------------ geth/api/backend.go | 5 +- geth/common/notification.go | 16 +++++++ geth/notification/fcm_client.go | 21 +++++++++ geth/notification/fcm_client_test.go | 1 + geth/notification/notification.go | 45 ++++++++++++++++++ geth/notification/notification_test.go | 1 + static/bindata.go | 64 +++++++++++++------------- 8 files changed, 123 insertions(+), 65 deletions(-) create mode 100644 geth/common/notification.go create mode 100644 geth/notification/fcm_client.go create mode 100644 geth/notification/fcm_client_test.go create mode 100644 geth/notification/notification.go create mode 100644 geth/notification/notification_test.go diff --git a/geth/api/api.go b/geth/api/api.go index 5dd4de511..da6b41b07 100644 --- a/geth/api/api.go +++ b/geth/api/api.go @@ -3,18 +3,12 @@ package api import ( "context" - "github.com/NaySoftware/go-fcm" "github.com/ethereum/go-ethereum/accounts/keystore" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/status-im/status-go/geth/common" - "github.com/status-im/status-go/geth/log" "github.com/status-im/status-go/geth/params" ) -const ( - serverKey = "AAAAxwa-r08:APA91bFtMIToDVKGAmVCm76iEXtA4dn9MPvLdYKIZqAlNpLJbd12EgdBI9DSDSXKdqvIAgLodepmRhGVaWvhxnXJzVpE6MoIRuKedDV3kfHSVBhWFqsyoLTwXY4xeufL9Sdzb581U-lx" -) - // StatusAPI provides API to access Status related functionality. type StatusAPI struct { b *StatusBackend @@ -199,33 +193,10 @@ func (api *StatusAPI) JailBaseJS(js string) { api.b.jailManager.BaseJS(js) } -// Notify sends a push notification to the device with the given token. -// TODO(oskarth): API package this stuff +// Notify and send message func (api *StatusAPI) Notify(token string) string { - log.Debug("Notify", "token", token) - - var NP fcm.NotificationPayload - NP.Title = "Status - new message" - NP.Body = "ping" - - // TODO(oskarth): Experiment with this - data := map[string]string{ - "msg": "Hello World1", - "sum": "Happy Day", - } - - ids := []string{ - token, - } - - c := fcm.NewFcmClient(serverKey) - c.NewFcmRegIdsMsg(ids, data) - c.SetNotificationPayload(&NP) - - _, err := c.Send() - if err != nil { - log.Error("Notify failed:", err) - } + api.b.notification.Notify(token) + api.b.notification.Send() return token } diff --git a/geth/api/backend.go b/geth/api/backend.go index 508defcc7..02764474d 100644 --- a/geth/api/backend.go +++ b/geth/api/backend.go @@ -10,6 +10,7 @@ import ( "github.com/status-im/status-go/geth/jail" "github.com/status-im/status-go/geth/log" "github.com/status-im/status-go/geth/node" + "github.com/status-im/status-go/geth/notification" "github.com/status-im/status-go/geth/params" "github.com/status-im/status-go/geth/signal" "github.com/status-im/status-go/geth/txqueue" @@ -23,7 +24,7 @@ type StatusBackend struct { accountManager common.AccountManager txQueueManager common.TxQueueManager jailManager common.JailManager - // TODO(oskarth): notifer here + notification common.Notification } // NewStatusBackend create a new NewStatusBackend instance @@ -34,12 +35,14 @@ func NewStatusBackend() *StatusBackend { accountManager := account.NewManager(nodeManager) txQueueManager := txqueue.NewManager(nodeManager, accountManager) jailManager := jail.New(nodeManager) + notificationManager := notification.New(notification.NewFCMClient()) return &StatusBackend{ nodeManager: nodeManager, accountManager: accountManager, jailManager: jailManager, txQueueManager: txQueueManager, + notification: notificationManager, } } diff --git a/geth/common/notification.go b/geth/common/notification.go new file mode 100644 index 000000000..b1a9c7088 --- /dev/null +++ b/geth/common/notification.go @@ -0,0 +1,16 @@ +package common + +import "github.com/NaySoftware/go-fcm" + +// Notification manages Push Notifications and send messages +type Notification interface { + Notify(token string) string + Send() error +} + +// Messaging manages send/notification messaging clients +type Messaging interface { + NewFcmRegIdsMsg(list []string, body interface{}) *fcm.FcmClient + Send() (*fcm.FcmResponseStatus, error) + SetNotificationPayload(payload *fcm.NotificationPayload) *fcm.FcmClient +} diff --git a/geth/notification/fcm_client.go b/geth/notification/fcm_client.go new file mode 100644 index 000000000..e25d07c1c --- /dev/null +++ b/geth/notification/fcm_client.go @@ -0,0 +1,21 @@ +package notification + +import "github.com/NaySoftware/go-fcm" + +const ( + //todo(jeka): should be removed + fcmServerKey = "AAAAxwa-r08:APA91bFtMIToDVKGAmVCm76iEXtA4dn9MPvLdYKIZqAlNpLJbd12EgdBI9DSDSXKdqvIAgLodepmRhGVaWvhxnXJzVpE6MoIRuKedDV3kfHSVBhWFqsyoLTwXY4xeufL9Sdzb581U-lx" +) + +// NewFCMClient Firebase Cloud Messaging client constructor +func NewFCMClient() *fcm.FcmClient { + return fcm.NewFcmClient(fcmServerKey).SetNotificationPayload(getNotificationPayload()) +} + +// only for feature testing +func getNotificationPayload() *fcm.NotificationPayload { + return &fcm.NotificationPayload{ + Title: "Status - new message", + Body: "ping", + } +} diff --git a/geth/notification/fcm_client_test.go b/geth/notification/fcm_client_test.go new file mode 100644 index 000000000..4306c87f1 --- /dev/null +++ b/geth/notification/fcm_client_test.go @@ -0,0 +1 @@ +package notification diff --git a/geth/notification/notification.go b/geth/notification/notification.go new file mode 100644 index 000000000..e24d7f0d6 --- /dev/null +++ b/geth/notification/notification.go @@ -0,0 +1,45 @@ +package notification + +import ( + "github.com/status-im/status-go/geth/common" + "github.com/status-im/status-go/geth/log" +) + +// Manager of push notifications +type Manager struct { + messaging common.Messaging +} + +// New notifications manager +func New(messaging common.Messaging) *Manager { + return &Manager{ + messaging, + } +} + +// Notify registers notification +func (n *Manager) Notify(token string) string { + log.Debug("Notify", "token", token) + + n.messaging.NewFcmRegIdsMsg([]string{token}, n.getMessage) + + return token +} + +// Send prepared message +func (n *Manager) Send() error { + _, err := n.messaging.Send() + if err != nil { + log.Error("Notify failed:", err) + } + + return err +} + +func (n *Manager) getMessage() interface{} { + // TODO(oskarth): Experiment with this + return map[string]string{ + "msg": "Hello World1", + "sum": "Happy Day", + } +} diff --git a/geth/notification/notification_test.go b/geth/notification/notification_test.go new file mode 100644 index 000000000..4306c87f1 --- /dev/null +++ b/geth/notification/notification_test.go @@ -0,0 +1 @@ +package notification diff --git a/static/bindata.go b/static/bindata.go index 70e1f7650..04681d3bd 100644 --- a/static/bindata.go +++ b/static/bindata.go @@ -518,25 +518,25 @@ func AssetNames() []string { // _bindata is a table, holding each asset generator, mapped to its name. var _bindata = map[string]func() (*asset, error){ - "scripts/README.md": scriptsReadmeMd, - "scripts/web3.js": scriptsWeb3Js, - "config/cht.json": configChtJson, - "config/linter_exclude_list.txt": configLinter_exclude_listTxt, - "config/status-chain-genesis.json": configStatusChainGenesisJson, - "config/test-data.json": configTestDataJson, - "keys/firebaseauthkey": keysFirebaseauthkey, - "keys/test-account1-before-eip55.pk": keysTestAccount1BeforeEip55Pk, - "keys/test-account1.pk": keysTestAccount1Pk, - "keys/test-account2.pk": keysTestAccount2Pk, - "keys/wnodekey": keysWnodekey, - "keys/wnodepassword": keysWnodepassword, - "testdata/jail/commands.js": testdataJailCommandsJs, - "testdata/jail/status.js": testdataJailStatusJs, - "testdata/jail/tx-send/context-no-message-id.js": testdataJailTxSendContextNoMessageIdJs, - "testdata/jail/tx-send/message-id-no-context.js": testdataJailTxSendMessageIdNoContextJs, + "scripts/README.md": scriptsReadmeMd, + "scripts/web3.js": scriptsWeb3Js, + "config/cht.json": configChtJson, + "config/linter_exclude_list.txt": configLinter_exclude_listTxt, + "config/status-chain-genesis.json": configStatusChainGenesisJson, + "config/test-data.json": configTestDataJson, + "keys/firebaseauthkey": keysFirebaseauthkey, + "keys/test-account1-before-eip55.pk": keysTestAccount1BeforeEip55Pk, + "keys/test-account1.pk": keysTestAccount1Pk, + "keys/test-account2.pk": keysTestAccount2Pk, + "keys/wnodekey": keysWnodekey, + "keys/wnodepassword": keysWnodepassword, + "testdata/jail/commands.js": testdataJailCommandsJs, + "testdata/jail/status.js": testdataJailStatusJs, + "testdata/jail/tx-send/context-no-message-id.js": testdataJailTxSendContextNoMessageIdJs, + "testdata/jail/tx-send/message-id-no-context.js": testdataJailTxSendMessageIdNoContextJs, "testdata/jail/tx-send/no-message-id-or-context.js": testdataJailTxSendNoMessageIdOrContextJs, - "testdata/jail/tx-send/tx-send.js": testdataJailTxSendTxSendJs, - "testdata/node/test.sol": testdataNodeTestSol, + "testdata/jail/tx-send/tx-send.js": testdataJailTxSendTxSendJs, + "testdata/node/test.sol": testdataNodeTestSol, } // AssetDir returns the file names below a certain @@ -578,34 +578,35 @@ type bintree struct { Func func() (*asset, error) Children map[string]*bintree } + var _bintree = &bintree{nil, map[string]*bintree{ "config": &bintree{nil, map[string]*bintree{ - "cht.json": &bintree{configChtJson, map[string]*bintree{}}, - "linter_exclude_list.txt": &bintree{configLinter_exclude_listTxt, map[string]*bintree{}}, + "cht.json": &bintree{configChtJson, map[string]*bintree{}}, + "linter_exclude_list.txt": &bintree{configLinter_exclude_listTxt, map[string]*bintree{}}, "status-chain-genesis.json": &bintree{configStatusChainGenesisJson, map[string]*bintree{}}, - "test-data.json": &bintree{configTestDataJson, map[string]*bintree{}}, + "test-data.json": &bintree{configTestDataJson, map[string]*bintree{}}, }}, "keys": &bintree{nil, map[string]*bintree{ - "firebaseauthkey": &bintree{keysFirebaseauthkey, map[string]*bintree{}}, + "firebaseauthkey": &bintree{keysFirebaseauthkey, map[string]*bintree{}}, "test-account1-before-eip55.pk": &bintree{keysTestAccount1BeforeEip55Pk, map[string]*bintree{}}, - "test-account1.pk": &bintree{keysTestAccount1Pk, map[string]*bintree{}}, - "test-account2.pk": &bintree{keysTestAccount2Pk, map[string]*bintree{}}, - "wnodekey": &bintree{keysWnodekey, map[string]*bintree{}}, - "wnodepassword": &bintree{keysWnodepassword, map[string]*bintree{}}, + "test-account1.pk": &bintree{keysTestAccount1Pk, map[string]*bintree{}}, + "test-account2.pk": &bintree{keysTestAccount2Pk, map[string]*bintree{}}, + "wnodekey": &bintree{keysWnodekey, map[string]*bintree{}}, + "wnodepassword": &bintree{keysWnodepassword, map[string]*bintree{}}, }}, "scripts": &bintree{nil, map[string]*bintree{ "README.md": &bintree{scriptsReadmeMd, map[string]*bintree{}}, - "web3.js": &bintree{scriptsWeb3Js, map[string]*bintree{}}, + "web3.js": &bintree{scriptsWeb3Js, map[string]*bintree{}}, }}, "testdata": &bintree{nil, map[string]*bintree{ "jail": &bintree{nil, map[string]*bintree{ "commands.js": &bintree{testdataJailCommandsJs, map[string]*bintree{}}, - "status.js": &bintree{testdataJailStatusJs, map[string]*bintree{}}, + "status.js": &bintree{testdataJailStatusJs, map[string]*bintree{}}, "tx-send": &bintree{nil, map[string]*bintree{ - "context-no-message-id.js": &bintree{testdataJailTxSendContextNoMessageIdJs, map[string]*bintree{}}, - "message-id-no-context.js": &bintree{testdataJailTxSendMessageIdNoContextJs, map[string]*bintree{}}, + "context-no-message-id.js": &bintree{testdataJailTxSendContextNoMessageIdJs, map[string]*bintree{}}, + "message-id-no-context.js": &bintree{testdataJailTxSendMessageIdNoContextJs, map[string]*bintree{}}, "no-message-id-or-context.js": &bintree{testdataJailTxSendNoMessageIdOrContextJs, map[string]*bintree{}}, - "tx-send.js": &bintree{testdataJailTxSendTxSendJs, map[string]*bintree{}}, + "tx-send.js": &bintree{testdataJailTxSendTxSendJs, map[string]*bintree{}}, }}, }}, "node": &bintree{nil, map[string]*bintree{ @@ -660,4 +661,3 @@ func _filePath(dir, name string) string { cannonicalName := strings.Replace(name, "\\", "/", -1) return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...) } - From acd1c1527cb9a41f3987b7f95e15be4682cb31df Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Mon, 9 Oct 2017 19:23:09 +0300 Subject: [PATCH 02/16] Basic unit testing for notification service --- Makefile | 1 + geth/common/notification_mock.go | 118 +++++++++++++++++++++++++ geth/notification/fcm_client_test.go | 22 +++++ geth/notification/notification_test.go | 56 ++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 geth/common/notification_mock.go diff --git a/Makefile b/Makefile index 3060b9ebe..a98511928 100644 --- a/Makefile +++ b/Makefile @@ -135,6 +135,7 @@ mock-install: ##@other Install mocking tools mock: ##@other Regenerate mocks mockgen -source=geth/common/types.go -destination=geth/common/types_mock.go -package=common + mockgen -source=geth/common/notification.go -destination=geth/common/notification_mock.go -package=common -imports fcm=github.com/NaySoftware/go-fcm test: ##@tests Run unit and integration tests build/env.sh go test $(UNIT_TEST_PACKAGES) diff --git a/geth/common/notification_mock.go b/geth/common/notification_mock.go new file mode 100644 index 000000000..8d57147f1 --- /dev/null +++ b/geth/common/notification_mock.go @@ -0,0 +1,118 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: geth/common/notification.go + +// Package common is a generated GoMock package. +package common + +import ( + go_fcm "github.com/NaySoftware/go-fcm" + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockNotification is a mock of Notification interface +type MockNotification struct { + ctrl *gomock.Controller + recorder *MockNotificationMockRecorder +} + +// MockNotificationMockRecorder is the mock recorder for MockNotification +type MockNotificationMockRecorder struct { + mock *MockNotification +} + +// NewMockNotification creates a new mock instance +func NewMockNotification(ctrl *gomock.Controller) *MockNotification { + mock := &MockNotification{ctrl: ctrl} + mock.recorder = &MockNotificationMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockNotification) EXPECT() *MockNotificationMockRecorder { + return m.recorder +} + +// Notify mocks base method +func (m *MockNotification) Notify(token string) string { + ret := m.ctrl.Call(m, "Notify", token) + ret0, _ := ret[0].(string) + return ret0 +} + +// Notify indicates an expected call of Notify +func (mr *MockNotificationMockRecorder) Notify(token interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notify", reflect.TypeOf((*MockNotification)(nil).Notify), token) +} + +// Send mocks base method +func (m *MockNotification) Send() error { + ret := m.ctrl.Call(m, "Send") + ret0, _ := ret[0].(error) + return ret0 +} + +// Send indicates an expected call of Send +func (mr *MockNotificationMockRecorder) Send() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockNotification)(nil).Send)) +} + +// MockMessaging is a mock of Messaging interface +type MockMessaging struct { + ctrl *gomock.Controller + recorder *MockMessagingMockRecorder +} + +// MockMessagingMockRecorder is the mock recorder for MockMessaging +type MockMessagingMockRecorder struct { + mock *MockMessaging +} + +// NewMockMessaging creates a new mock instance +func NewMockMessaging(ctrl *gomock.Controller) *MockMessaging { + mock := &MockMessaging{ctrl: ctrl} + mock.recorder = &MockMessagingMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockMessaging) EXPECT() *MockMessagingMockRecorder { + return m.recorder +} + +// NewFcmRegIdsMsg mocks base method +func (m *MockMessaging) NewFcmRegIdsMsg(list []string, body interface{}) *go_fcm.FcmClient { + ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", list, body) + ret0, _ := ret[0].(*go_fcm.FcmClient) + return ret0 +} + +// NewFcmRegIdsMsg indicates an expected call of NewFcmRegIdsMsg +func (mr *MockMessagingMockRecorder) NewFcmRegIdsMsg(list, body interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockMessaging)(nil).NewFcmRegIdsMsg), list, body) +} + +// Send mocks base method +func (m *MockMessaging) Send() (*go_fcm.FcmResponseStatus, error) { + ret := m.ctrl.Call(m, "Send") + ret0, _ := ret[0].(*go_fcm.FcmResponseStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Send indicates an expected call of Send +func (mr *MockMessagingMockRecorder) Send() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockMessaging)(nil).Send)) +} + +// SetNotificationPayload mocks base method +func (m *MockMessaging) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient { + ret := m.ctrl.Call(m, "SetNotificationPayload", payload) + ret0, _ := ret[0].(*go_fcm.FcmClient) + return ret0 +} + +// SetNotificationPayload indicates an expected call of SetNotificationPayload +func (mr *MockMessagingMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockMessaging)(nil).SetNotificationPayload), payload) +} diff --git a/geth/notification/fcm_client_test.go b/geth/notification/fcm_client_test.go index 4306c87f1..7b017799f 100644 --- a/geth/notification/fcm_client_test.go +++ b/geth/notification/fcm_client_test.go @@ -1 +1,23 @@ package notification + +import ( + "testing" + + "github.com/NaySoftware/go-fcm" + t "github.com/status-im/status-go/geth/testing" + "github.com/stretchr/testify/suite" +) + +func TestFCMClientTestSuite(t *testing.T) { + suite.Run(t, new(FCMClientTestSuite)) +} + +type FCMClientTestSuite struct { + t.BaseTestSuite +} + +func (s *FCMClientTestSuite) TestNewFCMClient() { + fcmClient := NewFCMClient() + s.Require().NotNil(fcmClient) + s.Require().IsType(&fcm.FcmClient{}, fcmClient) +} diff --git a/geth/notification/notification_test.go b/geth/notification/notification_test.go index 4306c87f1..a5fe7336b 100644 --- a/geth/notification/notification_test.go +++ b/geth/notification/notification_test.go @@ -1 +1,57 @@ package notification + +import ( + "testing" + + "github.com/golang/mock/gomock" + "github.com/status-im/status-go/geth/common" + t "github.com/status-im/status-go/geth/testing" + "github.com/stretchr/testify/suite" +) + +func TestNotificationTestSuite(t *testing.T) { + suite.Run(t, new(NotificationTestSuite)) +} + +type NotificationTestSuite struct { + t.BaseTestSuite + messagingMock *common.MockMessaging + messagingMockCtrl *gomock.Controller +} + +func (s *NotificationTestSuite) SetupTest() { + s.messagingMockCtrl = gomock.NewController(s.T()) + s.messagingMock = common.NewMockMessaging(s.messagingMockCtrl) +} + +func (s *NotificationTestSuite) TearDownTest() { + s.messagingMockCtrl.Finish() +} + +func (s *NotificationTestSuite) TestNewNotification() { + manager := New(nil) + s.Require().NotNil(manager) + s.Require().IsType(&Manager{}, manager) +} + +func (s *NotificationTestSuite) TestNotify() { + token := "test" + s.messagingMock.EXPECT().NewFcmRegIdsMsg([]string{token}, map[string]string{ + "msg": "Hello World1", + "sum": "Happy Day", + }) + + manager := New(s.messagingMock) + res := manager.Notify(token) + + s.Require().Equal(token, res) +} + +func (s *NotificationTestSuite) TestSend() { + s.messagingMock.EXPECT().Send().Times(1).Return(nil) + + manager := New(s.messagingMock) + err := manager.Send() + + s.Require().NoError(err) +} From 9c1aff3655e3dd208ef0b351803dc3c2e8577b73 Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Tue, 10 Oct 2017 14:18:15 +0300 Subject: [PATCH 03/16] Unnecessary test checks removed --- geth/notification/fcm_client_test.go | 5 ++--- geth/notification/notification_test.go | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/geth/notification/fcm_client_test.go b/geth/notification/fcm_client_test.go index 7b017799f..362d78fd7 100644 --- a/geth/notification/fcm_client_test.go +++ b/geth/notification/fcm_client_test.go @@ -3,7 +3,6 @@ package notification import ( "testing" - "github.com/NaySoftware/go-fcm" t "github.com/status-im/status-go/geth/testing" "github.com/stretchr/testify/suite" ) @@ -18,6 +17,6 @@ type FCMClientTestSuite struct { func (s *FCMClientTestSuite) TestNewFCMClient() { fcmClient := NewFCMClient() + s.Require().NotNil(fcmClient) - s.Require().IsType(&fcm.FcmClient{}, fcmClient) -} +} \ No newline at end of file diff --git a/geth/notification/notification_test.go b/geth/notification/notification_test.go index a5fe7336b..10912c99e 100644 --- a/geth/notification/notification_test.go +++ b/geth/notification/notification_test.go @@ -31,7 +31,6 @@ func (s *NotificationTestSuite) TearDownTest() { func (s *NotificationTestSuite) TestNewNotification() { manager := New(nil) s.Require().NotNil(manager) - s.Require().IsType(&Manager{}, manager) } func (s *NotificationTestSuite) TestNotify() { From 7195fe3f9293aebdf0dff1c56651953a0b057c00 Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Tue, 10 Oct 2017 18:30:56 +0300 Subject: [PATCH 04/16] Create message provider interface --- geth/api/api.go | 18 ++++++-- geth/api/backend.go | 8 +++- geth/common/notification.go | 19 ++++++-- geth/notification/fcm_client.go | 21 --------- geth/notification/fcm_provider.go | 46 +++++++++++++++++++ ...cm_client_test.go => fcm_provider_test.go} | 0 geth/notification/message/message.go | 7 +++ geth/notification/message/payload.go | 12 +++++ geth/notification/notification.go | 33 +++++-------- 9 files changed, 112 insertions(+), 52 deletions(-) delete mode 100644 geth/notification/fcm_client.go create mode 100644 geth/notification/fcm_provider.go rename geth/notification/{fcm_client_test.go => fcm_provider_test.go} (100%) create mode 100644 geth/notification/message/message.go create mode 100644 geth/notification/message/payload.go diff --git a/geth/api/api.go b/geth/api/api.go index da6b41b07..13d4969d7 100644 --- a/geth/api/api.go +++ b/geth/api/api.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/status-im/status-go/geth/common" + "github.com/status-im/status-go/geth/notification/message" "github.com/status-im/status-go/geth/params" ) @@ -193,10 +194,21 @@ func (api *StatusAPI) JailBaseJS(js string) { api.b.jailManager.BaseJS(js) } -// Notify and send message +// Notify and send message. func (api *StatusAPI) Notify(token string) string { - api.b.notification.Notify(token) - api.b.notification.Send() + // TODO(oskarth): Experiment with this + msg := &message.Message{ + Body: map[string]string{ + "msg": "Hello World1", + "sum": "Happy Day", + }, + Payload: &message.Payload{ + Title: "Status - new message", + Body: "ping", + }, + } + + api.b.notification.Notify(token, msg) return token } diff --git a/geth/api/backend.go b/geth/api/backend.go index 02764474d..3dca45068 100644 --- a/geth/api/backend.go +++ b/geth/api/backend.go @@ -14,6 +14,12 @@ import ( "github.com/status-im/status-go/geth/params" "github.com/status-im/status-go/geth/signal" "github.com/status-im/status-go/geth/txqueue" + "github.com/NaySoftware/go-fcm" +) + +const ( + //todo(jeka): should be removed + fcmServerKey = "AAAAxwa-r08:APA91bFtMIToDVKGAmVCm76iEXtA4dn9MPvLdYKIZqAlNpLJbd12EgdBI9DSDSXKdqvIAgLodepmRhGVaWvhxnXJzVpE6MoIRuKedDV3kfHSVBhWFqsyoLTwXY4xeufL9Sdzb581U-lx" ) // StatusBackend implements Status.im service @@ -35,7 +41,7 @@ func NewStatusBackend() *StatusBackend { accountManager := account.NewManager(nodeManager) txQueueManager := txqueue.NewManager(nodeManager, accountManager) jailManager := jail.New(nodeManager) - notificationManager := notification.New(notification.NewFCMClient()) + notificationManager := notification.New(notification.NewFCMProvider(fcm.NewFcmClient(fcmServerKey))) return &StatusBackend{ nodeManager: nodeManager, diff --git a/geth/common/notification.go b/geth/common/notification.go index b1a9c7088..fec73f77d 100644 --- a/geth/common/notification.go +++ b/geth/common/notification.go @@ -1,15 +1,24 @@ package common -import "github.com/NaySoftware/go-fcm" +import ( + "github.com/NaySoftware/go-fcm" + "github.com/status-im/status-go/geth/notification/message" +) -// Notification manages Push Notifications and send messages +// Notification manages Push Notifications and send messages. type Notification interface { - Notify(token string) string + Notify(token string, msg *message.Message) (string, error) +} + +// MessagingProvider manages send/notification messaging clients. +type MessagingProvider interface { + SetMessage(ids []string, body interface{}) + SetPayload(payload *message.Payload) Send() error } -// Messaging manages send/notification messaging clients -type Messaging interface { +// FirebaseClient is a copy of "go-fcm" client methods. +type FirebaseClient interface { NewFcmRegIdsMsg(list []string, body interface{}) *fcm.FcmClient Send() (*fcm.FcmResponseStatus, error) SetNotificationPayload(payload *fcm.NotificationPayload) *fcm.FcmClient diff --git a/geth/notification/fcm_client.go b/geth/notification/fcm_client.go deleted file mode 100644 index e25d07c1c..000000000 --- a/geth/notification/fcm_client.go +++ /dev/null @@ -1,21 +0,0 @@ -package notification - -import "github.com/NaySoftware/go-fcm" - -const ( - //todo(jeka): should be removed - fcmServerKey = "AAAAxwa-r08:APA91bFtMIToDVKGAmVCm76iEXtA4dn9MPvLdYKIZqAlNpLJbd12EgdBI9DSDSXKdqvIAgLodepmRhGVaWvhxnXJzVpE6MoIRuKedDV3kfHSVBhWFqsyoLTwXY4xeufL9Sdzb581U-lx" -) - -// NewFCMClient Firebase Cloud Messaging client constructor -func NewFCMClient() *fcm.FcmClient { - return fcm.NewFcmClient(fcmServerKey).SetNotificationPayload(getNotificationPayload()) -} - -// only for feature testing -func getNotificationPayload() *fcm.NotificationPayload { - return &fcm.NotificationPayload{ - Title: "Status - new message", - Body: "ping", - } -} diff --git a/geth/notification/fcm_provider.go b/geth/notification/fcm_provider.go new file mode 100644 index 000000000..bd9f63b51 --- /dev/null +++ b/geth/notification/fcm_provider.go @@ -0,0 +1,46 @@ +package notification + +import ( + "github.com/NaySoftware/go-fcm" + "github.com/status-im/status-go/geth/notification/message" + "github.com/status-im/status-go/geth/common" +) + +// FCMProvider represents messaging provider for notifications. +type FCMProvider struct { + common.FirebaseClient +} + +// NewFCMProvider Firebase Cloud Messaging client constructor. +func NewFCMProvider(fcmClient common.FirebaseClient) *FCMProvider { + return &FCMProvider{fcmClient} +} + +// SetMessage to send for given ids. +func (p *FCMProvider) SetMessage(ids []string, body interface{}) { + p.NewFcmRegIdsMsg(ids, body) +} + +// SetPayload sets payload message information. +func (p *FCMProvider) SetPayload(payload *message.Payload) { + fcmPayload := p.toFCMPayload(payload) + p.SetNotificationPayload(fcmPayload) +} + +// Send message. +func (p *FCMProvider) Send() error { + _, err := p.FirebaseClient.Send() + return err +} + +func (p *FCMProvider) toFCMPayload(payload *message.Payload) *fcm.NotificationPayload { + return &fcm.NotificationPayload{ + Title: payload.Title, + Body: payload.Body, + Icon: payload.Icon, + Sound: payload.Sound, + Badge: payload.Badge, + Tag: payload.Tag, + Color: payload.Color, + } +} diff --git a/geth/notification/fcm_client_test.go b/geth/notification/fcm_provider_test.go similarity index 100% rename from geth/notification/fcm_client_test.go rename to geth/notification/fcm_provider_test.go diff --git a/geth/notification/message/message.go b/geth/notification/message/message.go new file mode 100644 index 000000000..9e5c841e9 --- /dev/null +++ b/geth/notification/message/message.go @@ -0,0 +1,7 @@ +package message + +// Message with data and payload +type Message struct { + Body interface{} + Payload *Payload +} diff --git a/geth/notification/message/payload.go b/geth/notification/message/payload.go new file mode 100644 index 000000000..c856e5c5e --- /dev/null +++ b/geth/notification/message/payload.go @@ -0,0 +1,12 @@ +package message + +// Payload data of message. +type Payload struct { + Title string + Body string + Icon string + Sound string + Badge string + Tag string + Color string +} diff --git a/geth/notification/notification.go b/geth/notification/notification.go index e24d7f0d6..6b77220be 100644 --- a/geth/notification/notification.go +++ b/geth/notification/notification.go @@ -3,43 +3,32 @@ package notification import ( "github.com/status-im/status-go/geth/common" "github.com/status-im/status-go/geth/log" + "github.com/status-im/status-go/geth/notification/message" ) -// Manager of push notifications +// Manager of push notifications. type Manager struct { - messaging common.Messaging + messaging common.MessagingProvider } -// New notifications manager -func New(messaging common.Messaging) *Manager { +// New notifications manager. +func New(messaging common.MessagingProvider) *Manager { return &Manager{ messaging, } } -// Notify registers notification -func (n *Manager) Notify(token string) string { +// Notify makes send message and notification. +func (n *Manager) Notify(token string, msg *message.Message) (string, error) { log.Debug("Notify", "token", token) - n.messaging.NewFcmRegIdsMsg([]string{token}, n.getMessage) + n.messaging.SetMessage([]string{token}, msg.Body) + n.messaging.SetPayload(msg.Payload) - return token -} - -// Send prepared message -func (n *Manager) Send() error { - _, err := n.messaging.Send() + err := n.messaging.Send() if err != nil { log.Error("Notify failed:", err) } - return err -} - -func (n *Manager) getMessage() interface{} { - // TODO(oskarth): Experiment with this - return map[string]string{ - "msg": "Hello World1", - "sum": "Happy Day", - } + return token, err } From c36a51d0cf657cf7449a6584e77f8ca23caaa5a7 Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Tue, 10 Oct 2017 18:33:12 +0300 Subject: [PATCH 05/16] Firebase provider tests --- geth/common/notification_mock.go | 101 ++++++++++++++++++------- geth/notification/fcm_provider_test.go | 69 +++++++++++++++-- geth/notification/notification_test.go | 54 +++++++++---- 3 files changed, 175 insertions(+), 49 deletions(-) diff --git a/geth/common/notification_mock.go b/geth/common/notification_mock.go index 8d57147f1..618d949a4 100644 --- a/geth/common/notification_mock.go +++ b/geth/common/notification_mock.go @@ -7,6 +7,7 @@ package common import ( go_fcm "github.com/NaySoftware/go-fcm" gomock "github.com/golang/mock/gomock" + message "github.com/status-im/status-go/geth/notification/message" reflect "reflect" ) @@ -34,66 +35,110 @@ func (m *MockNotification) EXPECT() *MockNotificationMockRecorder { } // Notify mocks base method -func (m *MockNotification) Notify(token string) string { - ret := m.ctrl.Call(m, "Notify", token) +func (m *MockNotification) Notify(token string, msg *message.Message) (string, error) { + ret := m.ctrl.Call(m, "Notify", token, msg) ret0, _ := ret[0].(string) - return ret0 + ret1, _ := ret[1].(error) + return ret0, ret1 } // Notify indicates an expected call of Notify -func (mr *MockNotificationMockRecorder) Notify(token interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notify", reflect.TypeOf((*MockNotification)(nil).Notify), token) +func (mr *MockNotificationMockRecorder) Notify(token, msg interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notify", reflect.TypeOf((*MockNotification)(nil).Notify), token, msg) +} + +// MockMessagingProvider is a mock of MessagingProvider interface +type MockMessagingProvider struct { + ctrl *gomock.Controller + recorder *MockMessagingProviderMockRecorder +} + +// MockMessagingProviderMockRecorder is the mock recorder for MockMessagingProvider +type MockMessagingProviderMockRecorder struct { + mock *MockMessagingProvider +} + +// NewMockMessagingProvider creates a new mock instance +func NewMockMessagingProvider(ctrl *gomock.Controller) *MockMessagingProvider { + mock := &MockMessagingProvider{ctrl: ctrl} + mock.recorder = &MockMessagingProviderMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockMessagingProvider) EXPECT() *MockMessagingProviderMockRecorder { + return m.recorder +} + +// SetMessage mocks base method +func (m *MockMessagingProvider) SetMessage(ids []string, body interface{}) { + m.ctrl.Call(m, "SetMessage", ids, body) +} + +// SetMessage indicates an expected call of SetMessage +func (mr *MockMessagingProviderMockRecorder) SetMessage(ids, body interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMessage", reflect.TypeOf((*MockMessagingProvider)(nil).SetMessage), ids, body) +} + +// SetPayload mocks base method +func (m *MockMessagingProvider) SetPayload(payload *message.Payload) { + m.ctrl.Call(m, "SetPayload", payload) +} + +// SetPayload indicates an expected call of SetPayload +func (mr *MockMessagingProviderMockRecorder) SetPayload(payload interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPayload", reflect.TypeOf((*MockMessagingProvider)(nil).SetPayload), payload) } // Send mocks base method -func (m *MockNotification) Send() error { +func (m *MockMessagingProvider) Send() error { ret := m.ctrl.Call(m, "Send") ret0, _ := ret[0].(error) return ret0 } // Send indicates an expected call of Send -func (mr *MockNotificationMockRecorder) Send() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockNotification)(nil).Send)) +func (mr *MockMessagingProviderMockRecorder) Send() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockMessagingProvider)(nil).Send)) } -// MockMessaging is a mock of Messaging interface -type MockMessaging struct { +// MockFirebaseClient is a mock of FirebaseClient interface +type MockFirebaseClient struct { ctrl *gomock.Controller - recorder *MockMessagingMockRecorder + recorder *MockFirebaseClientMockRecorder } -// MockMessagingMockRecorder is the mock recorder for MockMessaging -type MockMessagingMockRecorder struct { - mock *MockMessaging +// MockFirebaseClientMockRecorder is the mock recorder for MockFirebaseClient +type MockFirebaseClientMockRecorder struct { + mock *MockFirebaseClient } -// NewMockMessaging creates a new mock instance -func NewMockMessaging(ctrl *gomock.Controller) *MockMessaging { - mock := &MockMessaging{ctrl: ctrl} - mock.recorder = &MockMessagingMockRecorder{mock} +// NewMockFirebaseClient creates a new mock instance +func NewMockFirebaseClient(ctrl *gomock.Controller) *MockFirebaseClient { + mock := &MockFirebaseClient{ctrl: ctrl} + mock.recorder = &MockFirebaseClientMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use -func (m *MockMessaging) EXPECT() *MockMessagingMockRecorder { +func (m *MockFirebaseClient) EXPECT() *MockFirebaseClientMockRecorder { return m.recorder } // NewFcmRegIdsMsg mocks base method -func (m *MockMessaging) NewFcmRegIdsMsg(list []string, body interface{}) *go_fcm.FcmClient { +func (m *MockFirebaseClient) NewFcmRegIdsMsg(list []string, body interface{}) *go_fcm.FcmClient { ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", list, body) ret0, _ := ret[0].(*go_fcm.FcmClient) return ret0 } // NewFcmRegIdsMsg indicates an expected call of NewFcmRegIdsMsg -func (mr *MockMessagingMockRecorder) NewFcmRegIdsMsg(list, body interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockMessaging)(nil).NewFcmRegIdsMsg), list, body) +func (mr *MockFirebaseClientMockRecorder) NewFcmRegIdsMsg(list, body interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockFirebaseClient)(nil).NewFcmRegIdsMsg), list, body) } // Send mocks base method -func (m *MockMessaging) Send() (*go_fcm.FcmResponseStatus, error) { +func (m *MockFirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) { ret := m.ctrl.Call(m, "Send") ret0, _ := ret[0].(*go_fcm.FcmResponseStatus) ret1, _ := ret[1].(error) @@ -101,18 +146,18 @@ func (m *MockMessaging) Send() (*go_fcm.FcmResponseStatus, error) { } // Send indicates an expected call of Send -func (mr *MockMessagingMockRecorder) Send() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockMessaging)(nil).Send)) +func (mr *MockFirebaseClientMockRecorder) Send() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockFirebaseClient)(nil).Send)) } // SetNotificationPayload mocks base method -func (m *MockMessaging) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient { +func (m *MockFirebaseClient) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient { ret := m.ctrl.Call(m, "SetNotificationPayload", payload) ret0, _ := ret[0].(*go_fcm.FcmClient) return ret0 } // SetNotificationPayload indicates an expected call of SetNotificationPayload -func (mr *MockMessagingMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockMessaging)(nil).SetNotificationPayload), payload) +func (mr *MockFirebaseClientMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockFirebaseClient)(nil).SetNotificationPayload), payload) } diff --git a/geth/notification/fcm_provider_test.go b/geth/notification/fcm_provider_test.go index 362d78fd7..d59a5beff 100644 --- a/geth/notification/fcm_provider_test.go +++ b/geth/notification/fcm_provider_test.go @@ -1,22 +1,81 @@ package notification import ( + "errors" "testing" + "github.com/NaySoftware/go-fcm" + "github.com/golang/mock/gomock" + "github.com/status-im/status-go/geth/common" + "github.com/status-im/status-go/geth/notification/message" t "github.com/status-im/status-go/geth/testing" "github.com/stretchr/testify/suite" ) func TestFCMClientTestSuite(t *testing.T) { - suite.Run(t, new(FCMClientTestSuite)) + suite.Run(t, new(FCMProviderTestSuite)) } -type FCMClientTestSuite struct { +type FCMProviderTestSuite struct { t.BaseTestSuite + + fcmClientMock *common.MockFirebaseClient + fcmClientMockCtrl *gomock.Controller } -func (s *FCMClientTestSuite) TestNewFCMClient() { - fcmClient := NewFCMClient() +func (s *FCMProviderTestSuite) SetupTest() { + s.fcmClientMockCtrl = gomock.NewController(s.T()) + s.fcmClientMock = common.NewMockFirebaseClient(s.fcmClientMockCtrl) +} + +func (s *FCMProviderTestSuite) TearDownTest() { + s.fcmClientMockCtrl.Finish() +} + +func (s *FCMProviderTestSuite) TestNewFCMClient() { + fcmClient := NewFCMProvider(s.fcmClientMock) s.Require().NotNil(fcmClient) -} \ No newline at end of file +} + +func (s *FCMProviderTestSuite) TestSetMessage() { + ids := []string{"1"} + body := interface{}("body") + + s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) + fcmClient := NewFCMProvider(s.fcmClientMock) + + fcmClient.SetMessage(ids, body) +} + +func (s *FCMProviderTestSuite) TestSetPayload() { + title := "title" + body := "body" + payload := &message.Payload{Title: title, Body: body} + fcmPayload := &fcm.NotificationPayload{Title: title, Body: body} + + s.fcmClientMock.EXPECT().SetNotificationPayload(fcmPayload).Times(1) + fcmClient := NewFCMProvider(s.fcmClientMock) + + fcmClient.SetPayload(payload) +} + +func (s *FCMProviderTestSuite) TestSendSuccess() { + s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1) + fcmClient := NewFCMProvider(s.fcmClientMock) + + err := fcmClient.Send() + + s.Require().NoError(err) +} + +func (s *FCMProviderTestSuite) TestSendError() { + expectedError := errors.New("error") + + s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1) + fcmClient := NewFCMProvider(s.fcmClientMock) + + err := fcmClient.Send() + + s.Require().Equal(expectedError, err) +} diff --git a/geth/notification/notification_test.go b/geth/notification/notification_test.go index 10912c99e..099d8d1cb 100644 --- a/geth/notification/notification_test.go +++ b/geth/notification/notification_test.go @@ -3,8 +3,10 @@ package notification import ( "testing" + "errors" "github.com/golang/mock/gomock" "github.com/status-im/status-go/geth/common" + "github.com/status-im/status-go/geth/notification/message" t "github.com/status-im/status-go/geth/testing" "github.com/stretchr/testify/suite" ) @@ -15,13 +17,13 @@ func TestNotificationTestSuite(t *testing.T) { type NotificationTestSuite struct { t.BaseTestSuite - messagingMock *common.MockMessaging + messagingMock *common.MockMessagingProvider messagingMockCtrl *gomock.Controller } func (s *NotificationTestSuite) SetupTest() { s.messagingMockCtrl = gomock.NewController(s.T()) - s.messagingMock = common.NewMockMessaging(s.messagingMockCtrl) + s.messagingMock = common.NewMockMessagingProvider(s.messagingMockCtrl) } func (s *NotificationTestSuite) TearDownTest() { @@ -33,24 +35,44 @@ func (s *NotificationTestSuite) TestNewNotification() { s.Require().NotNil(manager) } -func (s *NotificationTestSuite) TestNotify() { +func (s *NotificationTestSuite) TestNotifySuccess() { token := "test" - s.messagingMock.EXPECT().NewFcmRegIdsMsg([]string{token}, map[string]string{ - "msg": "Hello World1", - "sum": "Happy Day", - }) + msg := getMessage() + + s.messagingMock.EXPECT().SetMessage([]string{token}, msg.Body).Times(1) + s.messagingMock.EXPECT().SetPayload(msg.Payload).Times(1) + s.messagingMock.EXPECT().Send().Return(nil).Times(1) manager := New(s.messagingMock) - res := manager.Notify(token) + res, err := manager.Notify(token, msg) s.Require().Equal(token, res) -} - -func (s *NotificationTestSuite) TestSend() { - s.messagingMock.EXPECT().Send().Times(1).Return(nil) - - manager := New(s.messagingMock) - err := manager.Send() - s.Require().NoError(err) } + +func (s *NotificationTestSuite) TestNotifyError() { + token := "test" + msg := getMessage() + expectedError := errors.New("error") + + s.messagingMock.EXPECT().SetMessage([]string{token}, msg.Body).Times(1) + s.messagingMock.EXPECT().SetPayload(msg.Payload).Times(1) + s.messagingMock.EXPECT().Send().Return(expectedError).Times(1) + + manager := New(s.messagingMock) + _, err := manager.Notify(token, msg) + + s.Require().Equal(expectedError, err) +} + +func getMessage() *message.Message { + return &message.Message{ + Body: map[string]string{ + "msg": "Hello World1", + "sum": "Happy Day", + }, + Payload: &message.Payload{ + Title: "test notification", + }, + } +} From 804ed7c10c613baa637c6d6c21c60fa3c7f9283a Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Wed, 11 Oct 2017 16:51:43 +0300 Subject: [PATCH 06/16] Remove provider interface --- geth/api/api.go | 21 +++-- geth/api/backend.go | 7 +- geth/common/notification.go | 25 +----- geth/notification/fcm/client.go | 10 +++ geth/notification/fcm/notifier.go | 52 +++++++++++++ .../notifier_test.go} | 54 ++++++------- geth/notification/fcm_provider.go | 46 ----------- geth/notification/message/message.go | 7 -- geth/notification/notification.go | 34 -------- geth/notification/notification_test.go | 78 ------------------- geth/notification/{message => }/payload.go | 2 +- 11 files changed, 102 insertions(+), 234 deletions(-) create mode 100644 geth/notification/fcm/client.go create mode 100644 geth/notification/fcm/notifier.go rename geth/notification/{fcm_provider_test.go => fcm/notifier_test.go} (52%) delete mode 100644 geth/notification/fcm_provider.go delete mode 100644 geth/notification/message/message.go delete mode 100644 geth/notification/notification.go delete mode 100644 geth/notification/notification_test.go rename geth/notification/{message => }/payload.go (87%) diff --git a/geth/api/api.go b/geth/api/api.go index 13d4969d7..5ecfdad05 100644 --- a/geth/api/api.go +++ b/geth/api/api.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/go-ethereum/accounts/keystore" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/status-im/status-go/geth/common" - "github.com/status-im/status-go/geth/notification/message" + "github.com/status-im/status-go/geth/log" "github.com/status-im/status-go/geth/params" ) @@ -196,19 +196,18 @@ func (api *StatusAPI) JailBaseJS(js string) { // Notify and send message. func (api *StatusAPI) Notify(token string) string { + log.Debug("Notify", "token", token) + // TODO(oskarth): Experiment with this - msg := &message.Message{ - Body: map[string]string{ - "msg": "Hello World1", - "sum": "Happy Day", - }, - Payload: &message.Payload{ - Title: "Status - new message", - Body: "ping", - }, + msg := map[string]string{ + "msg": "Hello World1", + "sum": "Happy Day", } - api.b.notification.Notify(token, msg) + err := api.b.notification.Notify(msg, token) + if err != nil { + log.Error("Notify failed:", err) + } return token } diff --git a/geth/api/backend.go b/geth/api/backend.go index 3dca45068..b47365f30 100644 --- a/geth/api/backend.go +++ b/geth/api/backend.go @@ -10,11 +10,10 @@ import ( "github.com/status-im/status-go/geth/jail" "github.com/status-im/status-go/geth/log" "github.com/status-im/status-go/geth/node" - "github.com/status-im/status-go/geth/notification" + "github.com/status-im/status-go/geth/notification/fcm" "github.com/status-im/status-go/geth/params" "github.com/status-im/status-go/geth/signal" "github.com/status-im/status-go/geth/txqueue" - "github.com/NaySoftware/go-fcm" ) const ( @@ -30,7 +29,7 @@ type StatusBackend struct { accountManager common.AccountManager txQueueManager common.TxQueueManager jailManager common.JailManager - notification common.Notification + notification common.Notifier } // NewStatusBackend create a new NewStatusBackend instance @@ -41,7 +40,7 @@ func NewStatusBackend() *StatusBackend { accountManager := account.NewManager(nodeManager) txQueueManager := txqueue.NewManager(nodeManager, accountManager) jailManager := jail.New(nodeManager) - notificationManager := notification.New(notification.NewFCMProvider(fcm.NewFcmClient(fcmServerKey))) + notificationManager := fcm.NewNotifier(fcmServerKey) return &StatusBackend{ nodeManager: nodeManager, diff --git a/geth/common/notification.go b/geth/common/notification.go index fec73f77d..ead1c5462 100644 --- a/geth/common/notification.go +++ b/geth/common/notification.go @@ -1,25 +1,6 @@ package common -import ( - "github.com/NaySoftware/go-fcm" - "github.com/status-im/status-go/geth/notification/message" -) - -// Notification manages Push Notifications and send messages. -type Notification interface { - Notify(token string, msg *message.Message) (string, error) -} - -// MessagingProvider manages send/notification messaging clients. -type MessagingProvider interface { - SetMessage(ids []string, body interface{}) - SetPayload(payload *message.Payload) - Send() error -} - -// FirebaseClient is a copy of "go-fcm" client methods. -type FirebaseClient interface { - NewFcmRegIdsMsg(list []string, body interface{}) *fcm.FcmClient - Send() (*fcm.FcmResponseStatus, error) - SetNotificationPayload(payload *fcm.NotificationPayload) *fcm.FcmClient +// Notifier manages Push Notifications. +type Notifier interface { + Notify(body interface{}, tokens ...string) error } diff --git a/geth/notification/fcm/client.go b/geth/notification/fcm/client.go new file mode 100644 index 000000000..73aa21c9a --- /dev/null +++ b/geth/notification/fcm/client.go @@ -0,0 +1,10 @@ +package fcm + +import "github.com/NaySoftware/go-fcm" + +// FirebaseClient is a copy of "go-fcm" client methods. +type FirebaseClient interface { + NewFcmRegIdsMsg(tokens []string, body interface{}) *fcm.FcmClient + Send() (*fcm.FcmResponseStatus, error) + SetNotificationPayload(payload *fcm.NotificationPayload) *fcm.FcmClient +} \ No newline at end of file diff --git a/geth/notification/fcm/notifier.go b/geth/notification/fcm/notifier.go new file mode 100644 index 000000000..7f91d65e3 --- /dev/null +++ b/geth/notification/fcm/notifier.go @@ -0,0 +1,52 @@ +package fcm + +import ( + "github.com/NaySoftware/go-fcm" + "github.com/status-im/status-go/geth/notification" +) + +// Notifier represents messaging provider for notifications. +type Notifier struct { + FirebaseClient +} + +// NewNotifier Firebase Cloud Messaging client constructor. +func NewNotifier(key string) *Notifier { + return &Notifier{fcm.NewFcmClient(key)} +} + +// Notify preparation and send to the tokens list. +func (p *Notifier) Notify(body interface{}, tokens ...string) error { + p.setPayload(¬ification.Payload{ + Title: "Status - new message", + Body: "ping", + }) + + p.setMessage(body, tokens...) + _, err := p.FirebaseClient.Send() + + return err +} + +// SetMessage to send for given the tokens list. +func (p *Notifier) setMessage(body interface{}, tokens ...string) { + p.NewFcmRegIdsMsg(tokens, body) +} + +// SetPayload sets payload message information. +func (p *Notifier) setPayload(payload *notification.Payload) { + fcmPayload := p.toFCMPayload(payload) + p.SetNotificationPayload(fcmPayload) +} + +func (p *Notifier) toFCMPayload(payload *notification.Payload) *fcm.NotificationPayload { + return &fcm.NotificationPayload{ + Title: payload.Title, + Body: payload.Body, + Icon: payload.Icon, + Sound: payload.Sound, + Badge: payload.Badge, + Tag: payload.Tag, + Color: payload.Color, + } +} diff --git a/geth/notification/fcm_provider_test.go b/geth/notification/fcm/notifier_test.go similarity index 52% rename from geth/notification/fcm_provider_test.go rename to geth/notification/fcm/notifier_test.go index d59a5beff..61950a57c 100644 --- a/geth/notification/fcm_provider_test.go +++ b/geth/notification/fcm/notifier_test.go @@ -1,4 +1,4 @@ -package notification +package fcm import ( "errors" @@ -6,8 +6,6 @@ import ( "github.com/NaySoftware/go-fcm" "github.com/golang/mock/gomock" - "github.com/status-im/status-go/geth/common" - "github.com/status-im/status-go/geth/notification/message" t "github.com/status-im/status-go/geth/testing" "github.com/stretchr/testify/suite" ) @@ -19,13 +17,13 @@ func TestFCMClientTestSuite(t *testing.T) { type FCMProviderTestSuite struct { t.BaseTestSuite - fcmClientMock *common.MockFirebaseClient + fcmClientMock *MockFirebaseClient fcmClientMockCtrl *gomock.Controller } func (s *FCMProviderTestSuite) SetupTest() { s.fcmClientMockCtrl = gomock.NewController(s.T()) - s.fcmClientMock = common.NewMockFirebaseClient(s.fcmClientMockCtrl) + s.fcmClientMock = NewMockFirebaseClient(s.fcmClientMockCtrl) } func (s *FCMProviderTestSuite) TearDownTest() { @@ -33,49 +31,43 @@ func (s *FCMProviderTestSuite) TearDownTest() { } func (s *FCMProviderTestSuite) TestNewFCMClient() { - fcmClient := NewFCMProvider(s.fcmClientMock) + fcmClient := Notifier{s.fcmClientMock} s.Require().NotNil(fcmClient) } -func (s *FCMProviderTestSuite) TestSetMessage() { +func (s *FCMProviderTestSuite) TestNotifySuccess() { + fcmPayload := getPayload() ids := []string{"1"} body := interface{}("body") - s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) - fcmClient := NewFCMProvider(s.fcmClientMock) - - fcmClient.SetMessage(ids, body) -} - -func (s *FCMProviderTestSuite) TestSetPayload() { - title := "title" - body := "body" - payload := &message.Payload{Title: title, Body: body} - fcmPayload := &fcm.NotificationPayload{Title: title, Body: body} - s.fcmClientMock.EXPECT().SetNotificationPayload(fcmPayload).Times(1) - fcmClient := NewFCMProvider(s.fcmClientMock) - - fcmClient.SetPayload(payload) -} - -func (s *FCMProviderTestSuite) TestSendSuccess() { + s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1) - fcmClient := NewFCMProvider(s.fcmClientMock) + fcmClient := Notifier{s.fcmClientMock} - err := fcmClient.Send() + err := fcmClient.Notify(body, ids...) s.Require().NoError(err) } -func (s *FCMProviderTestSuite) TestSendError() { +func (s *FCMProviderTestSuite) TestNotifyError() { expectedError := errors.New("error") - s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1) - fcmClient := NewFCMProvider(s.fcmClientMock) + fcmPayload := getPayload() + ids := []string{"1"} + body := interface{}("body") - err := fcmClient.Send() + s.fcmClientMock.EXPECT().SetNotificationPayload(fcmPayload).Times(1) + s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) + s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1) + fcmClient := Notifier{s.fcmClientMock} + + err := fcmClient.Notify(body, ids...) s.Require().Equal(expectedError, err) } + +func getPayload() *fcm.NotificationPayload { + return &fcm.NotificationPayload{Title: "Status - new message", Body: "ping"} +} diff --git a/geth/notification/fcm_provider.go b/geth/notification/fcm_provider.go deleted file mode 100644 index bd9f63b51..000000000 --- a/geth/notification/fcm_provider.go +++ /dev/null @@ -1,46 +0,0 @@ -package notification - -import ( - "github.com/NaySoftware/go-fcm" - "github.com/status-im/status-go/geth/notification/message" - "github.com/status-im/status-go/geth/common" -) - -// FCMProvider represents messaging provider for notifications. -type FCMProvider struct { - common.FirebaseClient -} - -// NewFCMProvider Firebase Cloud Messaging client constructor. -func NewFCMProvider(fcmClient common.FirebaseClient) *FCMProvider { - return &FCMProvider{fcmClient} -} - -// SetMessage to send for given ids. -func (p *FCMProvider) SetMessage(ids []string, body interface{}) { - p.NewFcmRegIdsMsg(ids, body) -} - -// SetPayload sets payload message information. -func (p *FCMProvider) SetPayload(payload *message.Payload) { - fcmPayload := p.toFCMPayload(payload) - p.SetNotificationPayload(fcmPayload) -} - -// Send message. -func (p *FCMProvider) Send() error { - _, err := p.FirebaseClient.Send() - return err -} - -func (p *FCMProvider) toFCMPayload(payload *message.Payload) *fcm.NotificationPayload { - return &fcm.NotificationPayload{ - Title: payload.Title, - Body: payload.Body, - Icon: payload.Icon, - Sound: payload.Sound, - Badge: payload.Badge, - Tag: payload.Tag, - Color: payload.Color, - } -} diff --git a/geth/notification/message/message.go b/geth/notification/message/message.go deleted file mode 100644 index 9e5c841e9..000000000 --- a/geth/notification/message/message.go +++ /dev/null @@ -1,7 +0,0 @@ -package message - -// Message with data and payload -type Message struct { - Body interface{} - Payload *Payload -} diff --git a/geth/notification/notification.go b/geth/notification/notification.go deleted file mode 100644 index 6b77220be..000000000 --- a/geth/notification/notification.go +++ /dev/null @@ -1,34 +0,0 @@ -package notification - -import ( - "github.com/status-im/status-go/geth/common" - "github.com/status-im/status-go/geth/log" - "github.com/status-im/status-go/geth/notification/message" -) - -// Manager of push notifications. -type Manager struct { - messaging common.MessagingProvider -} - -// New notifications manager. -func New(messaging common.MessagingProvider) *Manager { - return &Manager{ - messaging, - } -} - -// Notify makes send message and notification. -func (n *Manager) Notify(token string, msg *message.Message) (string, error) { - log.Debug("Notify", "token", token) - - n.messaging.SetMessage([]string{token}, msg.Body) - n.messaging.SetPayload(msg.Payload) - - err := n.messaging.Send() - if err != nil { - log.Error("Notify failed:", err) - } - - return token, err -} diff --git a/geth/notification/notification_test.go b/geth/notification/notification_test.go deleted file mode 100644 index 099d8d1cb..000000000 --- a/geth/notification/notification_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package notification - -import ( - "testing" - - "errors" - "github.com/golang/mock/gomock" - "github.com/status-im/status-go/geth/common" - "github.com/status-im/status-go/geth/notification/message" - t "github.com/status-im/status-go/geth/testing" - "github.com/stretchr/testify/suite" -) - -func TestNotificationTestSuite(t *testing.T) { - suite.Run(t, new(NotificationTestSuite)) -} - -type NotificationTestSuite struct { - t.BaseTestSuite - messagingMock *common.MockMessagingProvider - messagingMockCtrl *gomock.Controller -} - -func (s *NotificationTestSuite) SetupTest() { - s.messagingMockCtrl = gomock.NewController(s.T()) - s.messagingMock = common.NewMockMessagingProvider(s.messagingMockCtrl) -} - -func (s *NotificationTestSuite) TearDownTest() { - s.messagingMockCtrl.Finish() -} - -func (s *NotificationTestSuite) TestNewNotification() { - manager := New(nil) - s.Require().NotNil(manager) -} - -func (s *NotificationTestSuite) TestNotifySuccess() { - token := "test" - msg := getMessage() - - s.messagingMock.EXPECT().SetMessage([]string{token}, msg.Body).Times(1) - s.messagingMock.EXPECT().SetPayload(msg.Payload).Times(1) - s.messagingMock.EXPECT().Send().Return(nil).Times(1) - - manager := New(s.messagingMock) - res, err := manager.Notify(token, msg) - - s.Require().Equal(token, res) - s.Require().NoError(err) -} - -func (s *NotificationTestSuite) TestNotifyError() { - token := "test" - msg := getMessage() - expectedError := errors.New("error") - - s.messagingMock.EXPECT().SetMessage([]string{token}, msg.Body).Times(1) - s.messagingMock.EXPECT().SetPayload(msg.Payload).Times(1) - s.messagingMock.EXPECT().Send().Return(expectedError).Times(1) - - manager := New(s.messagingMock) - _, err := manager.Notify(token, msg) - - s.Require().Equal(expectedError, err) -} - -func getMessage() *message.Message { - return &message.Message{ - Body: map[string]string{ - "msg": "Hello World1", - "sum": "Happy Day", - }, - Payload: &message.Payload{ - Title: "test notification", - }, - } -} diff --git a/geth/notification/message/payload.go b/geth/notification/payload.go similarity index 87% rename from geth/notification/message/payload.go rename to geth/notification/payload.go index c856e5c5e..0dc787a4a 100644 --- a/geth/notification/message/payload.go +++ b/geth/notification/payload.go @@ -1,4 +1,4 @@ -package message +package notification // Payload data of message. type Payload struct { From c304d3e7ae0ea3802d2a17a68183d6095370be1a Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Wed, 11 Oct 2017 16:52:11 +0300 Subject: [PATCH 07/16] Update PN tests --- Makefile | 1 + geth/common/notification_mock.go | 155 ++++--------------------- geth/notification/fcm/client_mock.go | 71 +++++++++++ geth/notification/fcm/notifier_test.go | 23 ++-- 4 files changed, 101 insertions(+), 149 deletions(-) create mode 100644 geth/notification/fcm/client_mock.go diff --git a/Makefile b/Makefile index a98511928..bc1e7a824 100644 --- a/Makefile +++ b/Makefile @@ -136,6 +136,7 @@ mock-install: ##@other Install mocking tools mock: ##@other Regenerate mocks mockgen -source=geth/common/types.go -destination=geth/common/types_mock.go -package=common mockgen -source=geth/common/notification.go -destination=geth/common/notification_mock.go -package=common -imports fcm=github.com/NaySoftware/go-fcm + mockgen -source=geth/notification/fcm/client.go -destination=geth/notification/fcm/client_mock.go -package=fcm -imports fcm=github.com/NaySoftware/go-fcm test: ##@tests Run unit and integration tests build/env.sh go test $(UNIT_TEST_PACKAGES) diff --git a/geth/common/notification_mock.go b/geth/common/notification_mock.go index 618d949a4..acb145e76 100644 --- a/geth/common/notification_mock.go +++ b/geth/common/notification_mock.go @@ -5,159 +5,46 @@ package common import ( - go_fcm "github.com/NaySoftware/go-fcm" gomock "github.com/golang/mock/gomock" - message "github.com/status-im/status-go/geth/notification/message" reflect "reflect" ) -// MockNotification is a mock of Notification interface -type MockNotification struct { +// MockNotifier is a mock of Notifier interface +type MockNotifier struct { ctrl *gomock.Controller - recorder *MockNotificationMockRecorder + recorder *MockNotifierMockRecorder } -// MockNotificationMockRecorder is the mock recorder for MockNotification -type MockNotificationMockRecorder struct { - mock *MockNotification +// MockNotifierMockRecorder is the mock recorder for MockNotifier +type MockNotifierMockRecorder struct { + mock *MockNotifier } -// NewMockNotification creates a new mock instance -func NewMockNotification(ctrl *gomock.Controller) *MockNotification { - mock := &MockNotification{ctrl: ctrl} - mock.recorder = &MockNotificationMockRecorder{mock} +// NewMockNotifier creates a new mock instance +func NewMockNotifier(ctrl *gomock.Controller) *MockNotifier { + mock := &MockNotifier{ctrl: ctrl} + mock.recorder = &MockNotifierMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use -func (m *MockNotification) EXPECT() *MockNotificationMockRecorder { +func (m *MockNotifier) EXPECT() *MockNotifierMockRecorder { return m.recorder } // Notify mocks base method -func (m *MockNotification) Notify(token string, msg *message.Message) (string, error) { - ret := m.ctrl.Call(m, "Notify", token, msg) - ret0, _ := ret[0].(string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Notify indicates an expected call of Notify -func (mr *MockNotificationMockRecorder) Notify(token, msg interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notify", reflect.TypeOf((*MockNotification)(nil).Notify), token, msg) -} - -// MockMessagingProvider is a mock of MessagingProvider interface -type MockMessagingProvider struct { - ctrl *gomock.Controller - recorder *MockMessagingProviderMockRecorder -} - -// MockMessagingProviderMockRecorder is the mock recorder for MockMessagingProvider -type MockMessagingProviderMockRecorder struct { - mock *MockMessagingProvider -} - -// NewMockMessagingProvider creates a new mock instance -func NewMockMessagingProvider(ctrl *gomock.Controller) *MockMessagingProvider { - mock := &MockMessagingProvider{ctrl: ctrl} - mock.recorder = &MockMessagingProviderMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockMessagingProvider) EXPECT() *MockMessagingProviderMockRecorder { - return m.recorder -} - -// SetMessage mocks base method -func (m *MockMessagingProvider) SetMessage(ids []string, body interface{}) { - m.ctrl.Call(m, "SetMessage", ids, body) -} - -// SetMessage indicates an expected call of SetMessage -func (mr *MockMessagingProviderMockRecorder) SetMessage(ids, body interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMessage", reflect.TypeOf((*MockMessagingProvider)(nil).SetMessage), ids, body) -} - -// SetPayload mocks base method -func (m *MockMessagingProvider) SetPayload(payload *message.Payload) { - m.ctrl.Call(m, "SetPayload", payload) -} - -// SetPayload indicates an expected call of SetPayload -func (mr *MockMessagingProviderMockRecorder) SetPayload(payload interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetPayload", reflect.TypeOf((*MockMessagingProvider)(nil).SetPayload), payload) -} - -// Send mocks base method -func (m *MockMessagingProvider) Send() error { - ret := m.ctrl.Call(m, "Send") +func (m *MockNotifier) Notify(body interface{}, tokens ...string) error { + varargs := []interface{}{body} + for _, a := range tokens { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Notify", varargs...) ret0, _ := ret[0].(error) return ret0 } -// Send indicates an expected call of Send -func (mr *MockMessagingProviderMockRecorder) Send() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockMessagingProvider)(nil).Send)) -} - -// MockFirebaseClient is a mock of FirebaseClient interface -type MockFirebaseClient struct { - ctrl *gomock.Controller - recorder *MockFirebaseClientMockRecorder -} - -// MockFirebaseClientMockRecorder is the mock recorder for MockFirebaseClient -type MockFirebaseClientMockRecorder struct { - mock *MockFirebaseClient -} - -// NewMockFirebaseClient creates a new mock instance -func NewMockFirebaseClient(ctrl *gomock.Controller) *MockFirebaseClient { - mock := &MockFirebaseClient{ctrl: ctrl} - mock.recorder = &MockFirebaseClientMockRecorder{mock} - return mock -} - -// EXPECT returns an object that allows the caller to indicate expected use -func (m *MockFirebaseClient) EXPECT() *MockFirebaseClientMockRecorder { - return m.recorder -} - -// NewFcmRegIdsMsg mocks base method -func (m *MockFirebaseClient) NewFcmRegIdsMsg(list []string, body interface{}) *go_fcm.FcmClient { - ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", list, body) - ret0, _ := ret[0].(*go_fcm.FcmClient) - return ret0 -} - -// NewFcmRegIdsMsg indicates an expected call of NewFcmRegIdsMsg -func (mr *MockFirebaseClientMockRecorder) NewFcmRegIdsMsg(list, body interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockFirebaseClient)(nil).NewFcmRegIdsMsg), list, body) -} - -// Send mocks base method -func (m *MockFirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) { - ret := m.ctrl.Call(m, "Send") - ret0, _ := ret[0].(*go_fcm.FcmResponseStatus) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Send indicates an expected call of Send -func (mr *MockFirebaseClientMockRecorder) Send() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockFirebaseClient)(nil).Send)) -} - -// SetNotificationPayload mocks base method -func (m *MockFirebaseClient) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient { - ret := m.ctrl.Call(m, "SetNotificationPayload", payload) - ret0, _ := ret[0].(*go_fcm.FcmClient) - return ret0 -} - -// SetNotificationPayload indicates an expected call of SetNotificationPayload -func (mr *MockFirebaseClientMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockFirebaseClient)(nil).SetNotificationPayload), payload) +// Notify indicates an expected call of Notify +func (mr *MockNotifierMockRecorder) Notify(body interface{}, tokens ...interface{}) *gomock.Call { + varargs := append([]interface{}{body}, tokens...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notify", reflect.TypeOf((*MockNotifier)(nil).Notify), varargs...) } diff --git a/geth/notification/fcm/client_mock.go b/geth/notification/fcm/client_mock.go new file mode 100644 index 000000000..ab25372fc --- /dev/null +++ b/geth/notification/fcm/client_mock.go @@ -0,0 +1,71 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: geth/notification/fcm/client.go + +// Package fcm is a generated GoMock package. +package fcm + +import ( + go_fcm "github.com/NaySoftware/go-fcm" + gomock "github.com/golang/mock/gomock" + reflect "reflect" +) + +// MockFirebaseClient is a mock of FirebaseClient interface +type MockFirebaseClient struct { + ctrl *gomock.Controller + recorder *MockFirebaseClientMockRecorder +} + +// MockFirebaseClientMockRecorder is the mock recorder for MockFirebaseClient +type MockFirebaseClientMockRecorder struct { + mock *MockFirebaseClient +} + +// NewMockFirebaseClient creates a new mock instance +func NewMockFirebaseClient(ctrl *gomock.Controller) *MockFirebaseClient { + mock := &MockFirebaseClient{ctrl: ctrl} + mock.recorder = &MockFirebaseClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockFirebaseClient) EXPECT() *MockFirebaseClientMockRecorder { + return m.recorder +} + +// NewFcmRegIdsMsg mocks base method +func (m *MockFirebaseClient) NewFcmRegIdsMsg(tokens []string, body interface{}) *go_fcm.FcmClient { + ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", tokens, body) + ret0, _ := ret[0].(*go_fcm.FcmClient) + return ret0 +} + +// NewFcmRegIdsMsg indicates an expected call of NewFcmRegIdsMsg +func (mr *MockFirebaseClientMockRecorder) NewFcmRegIdsMsg(tokens, body interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockFirebaseClient)(nil).NewFcmRegIdsMsg), tokens, body) +} + +// Send mocks base method +func (m *MockFirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) { + ret := m.ctrl.Call(m, "Send") + ret0, _ := ret[0].(*go_fcm.FcmResponseStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Send indicates an expected call of Send +func (mr *MockFirebaseClientMockRecorder) Send() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockFirebaseClient)(nil).Send)) +} + +// SetNotificationPayload mocks base method +func (m *MockFirebaseClient) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient { + ret := m.ctrl.Call(m, "SetNotificationPayload", payload) + ret0, _ := ret[0].(*go_fcm.FcmClient) + return ret0 +} + +// SetNotificationPayload indicates an expected call of SetNotificationPayload +func (mr *MockFirebaseClientMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockFirebaseClient)(nil).SetNotificationPayload), payload) +} diff --git a/geth/notification/fcm/notifier_test.go b/geth/notification/fcm/notifier_test.go index 61950a57c..3016fe3e4 100644 --- a/geth/notification/fcm/notifier_test.go +++ b/geth/notification/fcm/notifier_test.go @@ -11,32 +11,26 @@ import ( ) func TestFCMClientTestSuite(t *testing.T) { - suite.Run(t, new(FCMProviderTestSuite)) + suite.Run(t, new(NotifierTestSuite)) } -type FCMProviderTestSuite struct { +type NotifierTestSuite struct { t.BaseTestSuite fcmClientMock *MockFirebaseClient fcmClientMockCtrl *gomock.Controller } -func (s *FCMProviderTestSuite) SetupTest() { +func (s *NotifierTestSuite) SetupTest() { s.fcmClientMockCtrl = gomock.NewController(s.T()) s.fcmClientMock = NewMockFirebaseClient(s.fcmClientMockCtrl) } -func (s *FCMProviderTestSuite) TearDownTest() { +func (s *NotifierTestSuite) TearDownTest() { s.fcmClientMockCtrl.Finish() } -func (s *FCMProviderTestSuite) TestNewFCMClient() { - fcmClient := Notifier{s.fcmClientMock} - - s.Require().NotNil(fcmClient) -} - -func (s *FCMProviderTestSuite) TestNotifySuccess() { +func (s *NotifierTestSuite) TestNotifySuccess() { fcmPayload := getPayload() ids := []string{"1"} body := interface{}("body") @@ -48,12 +42,11 @@ func (s *FCMProviderTestSuite) TestNotifySuccess() { err := fcmClient.Notify(body, ids...) - s.Require().NoError(err) + s.NoError(err) } -func (s *FCMProviderTestSuite) TestNotifyError() { +func (s *NotifierTestSuite) TestNotifyError() { expectedError := errors.New("error") - fcmPayload := getPayload() ids := []string{"1"} body := interface{}("body") @@ -65,7 +58,7 @@ func (s *FCMProviderTestSuite) TestNotifyError() { err := fcmClient.Notify(body, ids...) - s.Require().Equal(expectedError, err) + s.Equal(expectedError, err) } func getPayload() *fcm.NotificationPayload { From 390495342c05fe854913c2589003fba1ac5f5774 Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Wed, 11 Oct 2017 16:59:58 +0300 Subject: [PATCH 08/16] Make FCM client interface private --- geth/notification/fcm/client.go | 4 +-- geth/notification/fcm/client_mock.go | 40 +++++++++++++------------- geth/notification/fcm/notifier.go | 4 +-- geth/notification/fcm/notifier_test.go | 4 +-- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/geth/notification/fcm/client.go b/geth/notification/fcm/client.go index 73aa21c9a..00a46879f 100644 --- a/geth/notification/fcm/client.go +++ b/geth/notification/fcm/client.go @@ -2,8 +2,8 @@ package fcm import "github.com/NaySoftware/go-fcm" -// FirebaseClient is a copy of "go-fcm" client methods. -type FirebaseClient interface { +// firebaseClient is a copy of "go-fcm" client methods. +type firebaseClient interface { NewFcmRegIdsMsg(tokens []string, body interface{}) *fcm.FcmClient Send() (*fcm.FcmResponseStatus, error) SetNotificationPayload(payload *fcm.NotificationPayload) *fcm.FcmClient diff --git a/geth/notification/fcm/client_mock.go b/geth/notification/fcm/client_mock.go index ab25372fc..3d80c7560 100644 --- a/geth/notification/fcm/client_mock.go +++ b/geth/notification/fcm/client_mock.go @@ -10,43 +10,43 @@ import ( reflect "reflect" ) -// MockFirebaseClient is a mock of FirebaseClient interface -type MockFirebaseClient struct { +// MockfirebaseClient is a mock of firebaseClient interface +type MockfirebaseClient struct { ctrl *gomock.Controller - recorder *MockFirebaseClientMockRecorder + recorder *MockfirebaseClientMockRecorder } -// MockFirebaseClientMockRecorder is the mock recorder for MockFirebaseClient -type MockFirebaseClientMockRecorder struct { - mock *MockFirebaseClient +// MockfirebaseClientMockRecorder is the mock recorder for MockfirebaseClient +type MockfirebaseClientMockRecorder struct { + mock *MockfirebaseClient } -// NewMockFirebaseClient creates a new mock instance -func NewMockFirebaseClient(ctrl *gomock.Controller) *MockFirebaseClient { - mock := &MockFirebaseClient{ctrl: ctrl} - mock.recorder = &MockFirebaseClientMockRecorder{mock} +// NewMockfirebaseClient creates a new mock instance +func NewMockfirebaseClient(ctrl *gomock.Controller) *MockfirebaseClient { + mock := &MockfirebaseClient{ctrl: ctrl} + mock.recorder = &MockfirebaseClientMockRecorder{mock} return mock } // EXPECT returns an object that allows the caller to indicate expected use -func (m *MockFirebaseClient) EXPECT() *MockFirebaseClientMockRecorder { +func (m *MockfirebaseClient) EXPECT() *MockfirebaseClientMockRecorder { return m.recorder } // NewFcmRegIdsMsg mocks base method -func (m *MockFirebaseClient) NewFcmRegIdsMsg(tokens []string, body interface{}) *go_fcm.FcmClient { +func (m *MockfirebaseClient) NewFcmRegIdsMsg(tokens []string, body interface{}) *go_fcm.FcmClient { ret := m.ctrl.Call(m, "NewFcmRegIdsMsg", tokens, body) ret0, _ := ret[0].(*go_fcm.FcmClient) return ret0 } // NewFcmRegIdsMsg indicates an expected call of NewFcmRegIdsMsg -func (mr *MockFirebaseClientMockRecorder) NewFcmRegIdsMsg(tokens, body interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockFirebaseClient)(nil).NewFcmRegIdsMsg), tokens, body) +func (mr *MockfirebaseClientMockRecorder) NewFcmRegIdsMsg(tokens, body interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewFcmRegIdsMsg", reflect.TypeOf((*MockfirebaseClient)(nil).NewFcmRegIdsMsg), tokens, body) } // Send mocks base method -func (m *MockFirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) { +func (m *MockfirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) { ret := m.ctrl.Call(m, "Send") ret0, _ := ret[0].(*go_fcm.FcmResponseStatus) ret1, _ := ret[1].(error) @@ -54,18 +54,18 @@ func (m *MockFirebaseClient) Send() (*go_fcm.FcmResponseStatus, error) { } // Send indicates an expected call of Send -func (mr *MockFirebaseClientMockRecorder) Send() *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockFirebaseClient)(nil).Send)) +func (mr *MockfirebaseClientMockRecorder) Send() *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockfirebaseClient)(nil).Send)) } // SetNotificationPayload mocks base method -func (m *MockFirebaseClient) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient { +func (m *MockfirebaseClient) SetNotificationPayload(payload *go_fcm.NotificationPayload) *go_fcm.FcmClient { ret := m.ctrl.Call(m, "SetNotificationPayload", payload) ret0, _ := ret[0].(*go_fcm.FcmClient) return ret0 } // SetNotificationPayload indicates an expected call of SetNotificationPayload -func (mr *MockFirebaseClientMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call { - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockFirebaseClient)(nil).SetNotificationPayload), payload) +func (mr *MockfirebaseClientMockRecorder) SetNotificationPayload(payload interface{}) *gomock.Call { + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetNotificationPayload", reflect.TypeOf((*MockfirebaseClient)(nil).SetNotificationPayload), payload) } diff --git a/geth/notification/fcm/notifier.go b/geth/notification/fcm/notifier.go index 7f91d65e3..2f94e6dac 100644 --- a/geth/notification/fcm/notifier.go +++ b/geth/notification/fcm/notifier.go @@ -7,7 +7,7 @@ import ( // Notifier represents messaging provider for notifications. type Notifier struct { - FirebaseClient + firebaseClient } // NewNotifier Firebase Cloud Messaging client constructor. @@ -23,7 +23,7 @@ func (p *Notifier) Notify(body interface{}, tokens ...string) error { }) p.setMessage(body, tokens...) - _, err := p.FirebaseClient.Send() + _, err := p.firebaseClient.Send() return err } diff --git a/geth/notification/fcm/notifier_test.go b/geth/notification/fcm/notifier_test.go index 3016fe3e4..38fa2fe0c 100644 --- a/geth/notification/fcm/notifier_test.go +++ b/geth/notification/fcm/notifier_test.go @@ -17,13 +17,13 @@ func TestFCMClientTestSuite(t *testing.T) { type NotifierTestSuite struct { t.BaseTestSuite - fcmClientMock *MockFirebaseClient + fcmClientMock *MockfirebaseClient fcmClientMockCtrl *gomock.Controller } func (s *NotifierTestSuite) SetupTest() { s.fcmClientMockCtrl = gomock.NewController(s.T()) - s.fcmClientMock = NewMockFirebaseClient(s.fcmClientMockCtrl) + s.fcmClientMock = NewMockfirebaseClient(s.fcmClientMockCtrl) } func (s *NotifierTestSuite) TearDownTest() { From 4f9788a1585acac387cedb1fbf5ba10c4a0e22a7 Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Thu, 12 Oct 2017 17:31:14 +0300 Subject: [PATCH 09/16] Fix tests and rename field in Notifier --- geth/notification/fcm/notifier.go | 29 ++++++++++++++------------ geth/notification/fcm/notifier_test.go | 3 +-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/geth/notification/fcm/notifier.go b/geth/notification/fcm/notifier.go index 2f94e6dac..f43e2d59e 100644 --- a/geth/notification/fcm/notifier.go +++ b/geth/notification/fcm/notifier.go @@ -2,44 +2,47 @@ package fcm import ( "github.com/NaySoftware/go-fcm" + "github.com/status-im/status-go/geth/common" "github.com/status-im/status-go/geth/notification" ) // Notifier represents messaging provider for notifications. type Notifier struct { - firebaseClient + client firebaseClient } // NewNotifier Firebase Cloud Messaging client constructor. -func NewNotifier(key string) *Notifier { - return &Notifier{fcm.NewFcmClient(key)} +func NewNotifier(key string) func() common.Notifier { + return func() common.Notifier { + return &Notifier{fcm.NewFcmClient(key)} + } } // Notify preparation and send to the tokens list. -func (p *Notifier) Notify(body interface{}, tokens ...string) error { - p.setPayload(¬ification.Payload{ +func (n *Notifier) Notify(body interface{}, tokens ...string) error { + n.setPayload(¬ification.Payload{ Title: "Status - new message", Body: "ping", }) - p.setMessage(body, tokens...) - _, err := p.firebaseClient.Send() + n.setMessage(body, tokens...) + _, err := n.client.Send() return err } // SetMessage to send for given the tokens list. -func (p *Notifier) setMessage(body interface{}, tokens ...string) { - p.NewFcmRegIdsMsg(tokens, body) +func (n *Notifier) setMessage(body interface{}, tokens ...string) { + n.client.NewFcmRegIdsMsg(tokens, body) } // SetPayload sets payload message information. -func (p *Notifier) setPayload(payload *notification.Payload) { - fcmPayload := p.toFCMPayload(payload) - p.SetNotificationPayload(fcmPayload) +func (n *Notifier) setPayload(payload *notification.Payload) { + fcmPayload := n.toFCMPayload(payload) + n.client.SetNotificationPayload(fcmPayload) } -func (p *Notifier) toFCMPayload(payload *notification.Payload) *fcm.NotificationPayload { +func (n *Notifier) toFCMPayload(payload *notification.Payload) *fcm.NotificationPayload { return &fcm.NotificationPayload{ Title: payload.Title, Body: payload.Body, diff --git a/geth/notification/fcm/notifier_test.go b/geth/notification/fcm/notifier_test.go index 38fa2fe0c..320fd6798 100644 --- a/geth/notification/fcm/notifier_test.go +++ b/geth/notification/fcm/notifier_test.go @@ -6,7 +6,6 @@ import ( "github.com/NaySoftware/go-fcm" "github.com/golang/mock/gomock" - t "github.com/status-im/status-go/geth/testing" "github.com/stretchr/testify/suite" ) @@ -15,7 +14,7 @@ func TestFCMClientTestSuite(t *testing.T) { } type NotifierTestSuite struct { - t.BaseTestSuite + suite.Suite fcmClientMock *MockfirebaseClient fcmClientMockCtrl *gomock.Controller From 42cb6446b95fadb37d85975240e65359e690bf80 Mon Sep 17 00:00:00 2001 From: Eugene <6655321@bk.ru> Date: Thu, 12 Oct 2017 17:31:39 +0300 Subject: [PATCH 10/16] Return error for notify --- cmd/statusd/library.go | 23 +++++++++++++++++++++-- geth/api/api.go | 6 +++--- geth/api/backend.go | 4 ++-- geth/common/notification.go | 3 +++ geth/common/types.go | 6 ++++++ 5 files changed, 35 insertions(+), 7 deletions(-) diff --git a/cmd/statusd/library.go b/cmd/statusd/library.go index 22668809c..f65506b60 100644 --- a/cmd/statusd/library.go +++ b/cmd/statusd/library.go @@ -376,6 +376,25 @@ func makeJSONResponse(err error) *C.char { // Notify sends push notification by given token //export Notify func Notify(token *C.char) *C.char { - res := statusAPI.Notify(C.GoString(token)) - return C.CString(res) + err := statusAPI.Notify(C.GoString(token)) + + res := true + errString := "" + if err != nil { + res = false + errString = err.Error() + } + + out := common.NotifyResult{ + Status: res, + Error: errString, + } + + outBytes, err := json.Marshal(&out) + if err != nil { + log.Error("failed to marshal Notify output", "error", err.Error()) + return makeJSONResponse(err) + } + + return C.CString(string(outBytes)) } diff --git a/geth/api/api.go b/geth/api/api.go index 5ecfdad05..377a46a5f 100644 --- a/geth/api/api.go +++ b/geth/api/api.go @@ -195,7 +195,7 @@ func (api *StatusAPI) JailBaseJS(js string) { } // Notify and send message. -func (api *StatusAPI) Notify(token string) string { +func (api *StatusAPI) Notify(token string) error { log.Debug("Notify", "token", token) // TODO(oskarth): Experiment with this @@ -204,10 +204,10 @@ func (api *StatusAPI) Notify(token string) string { "sum": "Happy Day", } - err := api.b.notification.Notify(msg, token) + err := api.b.notifier().Notify(msg, token) if err != nil { log.Error("Notify failed:", err) } - return token + return err } diff --git a/geth/api/backend.go b/geth/api/backend.go index b47365f30..d52b25aa9 100644 --- a/geth/api/backend.go +++ b/geth/api/backend.go @@ -29,7 +29,7 @@ type StatusBackend struct { accountManager common.AccountManager txQueueManager common.TxQueueManager jailManager common.JailManager - notification common.Notifier + notifier common.NotifierConstructor } // NewStatusBackend create a new NewStatusBackend instance @@ -47,7 +47,7 @@ func NewStatusBackend() *StatusBackend { accountManager: accountManager, jailManager: jailManager, txQueueManager: txQueueManager, - notification: notificationManager, + notifier: notificationManager, } } diff --git a/geth/common/notification.go b/geth/common/notification.go index ead1c5462..dcd67ccd4 100644 --- a/geth/common/notification.go +++ b/geth/common/notification.go @@ -4,3 +4,6 @@ package common type Notifier interface { Notify(body interface{}, tokens ...string) error } + +// NotifierConstructor returns constructor of configured instance Notifier interface. +type NotifierConstructor func() Notifier diff --git a/geth/common/types.go b/geth/common/types.go index fe91c5327..1a7c9f884 100644 --- a/geth/common/types.go +++ b/geth/common/types.go @@ -395,6 +395,12 @@ type TestConfig struct { } } +// NotifyResult is a JSON returned from notify message +type NotifyResult struct { + Status bool `json:"status"` + Error string `json:"error"` +} + // LoadTestConfig loads test configuration values from disk func LoadTestConfig() (*TestConfig, error) { var testConfig TestConfig From f159ea85a0d48e9d18fa327a6a16038934300420 Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Wed, 18 Oct 2017 23:03:05 +0300 Subject: [PATCH 11/16] References for marshal library responces removed --- cmd/statusd/library.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/cmd/statusd/library.go b/cmd/statusd/library.go index f65506b60..67d3b0a79 100644 --- a/cmd/statusd/library.go +++ b/cmd/statusd/library.go @@ -22,7 +22,7 @@ func GenerateConfig(datadir *C.char, networkID C.int, devMode C.int) *C.char { return makeJSONResponse(err) } - outBytes, err := json.Marshal(&config) + outBytes, err := json.Marshal(config) if err != nil { return makeJSONResponse(err) } @@ -124,7 +124,7 @@ func CreateAccount(password *C.char) *C.char { Mnemonic: mnemonic, Error: errString, } - outBytes, _ := json.Marshal(&out) + outBytes, _ := json.Marshal(out) return C.CString(string(outBytes)) } @@ -144,7 +144,7 @@ func CreateChildAccount(parentAddress, password *C.char) *C.char { PubKey: pubKey, Error: errString, } - outBytes, _ := json.Marshal(&out) + outBytes, _ := json.Marshal(out) return C.CString(string(outBytes)) } @@ -165,7 +165,7 @@ func RecoverAccount(password, mnemonic *C.char) *C.char { Mnemonic: C.GoString(mnemonic), Error: errString, } - outBytes, _ := json.Marshal(&out) + outBytes, _ := json.Marshal(out) return C.CString(string(outBytes)) } @@ -207,7 +207,7 @@ func CompleteTransaction(id, password *C.char) *C.char { Hash: txHash.Hex(), Error: errString, } - outBytes, err := json.Marshal(&out) + outBytes, err := json.Marshal(out) if err != nil { log.Error("failed to marshal CompleteTransaction output", "error", err.Error()) return makeJSONResponse(err) @@ -246,7 +246,7 @@ func CompleteTransactions(ids, password *C.char) *C.char { } } - outBytes, err := json.Marshal(&out) + outBytes, err := json.Marshal(out) if err != nil { log.Error("failed to marshal CompleteTransactions output", "error", err.Error()) return makeJSONResponse(err) @@ -270,7 +270,7 @@ func DiscardTransaction(id *C.char) *C.char { ID: C.GoString(id), Error: errString, } - outBytes, err := json.Marshal(&out) + outBytes, err := json.Marshal(out) if err != nil { log.Error("failed to marshal DiscardTransaction output", "error", err.Error()) return makeJSONResponse(err) @@ -308,7 +308,7 @@ func DiscardTransactions(ids *C.char) *C.char { } } - outBytes, err := json.Marshal(&out) + outBytes, err := json.Marshal(out) if err != nil { log.Error("failed to marshal DiscardTransactions output", "error", err.Error()) return makeJSONResponse(err) @@ -368,7 +368,7 @@ func makeJSONResponse(err error) *C.char { out := common.APIResponse{ Error: errString, } - outBytes, _ := json.Marshal(&out) + outBytes, _ := json.Marshal(out) return C.CString(string(outBytes)) } @@ -390,7 +390,7 @@ func Notify(token *C.char) *C.char { Error: errString, } - outBytes, err := json.Marshal(&out) + outBytes, err := json.Marshal(out) if err != nil { log.Error("failed to marshal Notify output", "error", err.Error()) return makeJSONResponse(err) From 9efed591dab6f0bcaa316e3a5f54f5ce1b795b3a Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Wed, 18 Oct 2017 23:17:40 +0300 Subject: [PATCH 12/16] Notifier constructor renamed --- geth/api/api.go | 2 +- geth/api/backend.go | 22 +++++++++++----------- geth/common/notification.go | 6 +++--- geth/common/notification_mock.go | 12 ++++++------ geth/notification/fcm/notifier.go | 6 +++--- geth/notification/fcm/notifier_test.go | 4 ++-- 6 files changed, 26 insertions(+), 26 deletions(-) diff --git a/geth/api/api.go b/geth/api/api.go index 377a46a5f..be639abbf 100644 --- a/geth/api/api.go +++ b/geth/api/api.go @@ -204,7 +204,7 @@ func (api *StatusAPI) Notify(token string) error { "sum": "Happy Day", } - err := api.b.notifier().Notify(msg, token) + err := api.b.newNotification().Send(msg, token) if err != nil { log.Error("Notify failed:", err) } diff --git a/geth/api/backend.go b/geth/api/backend.go index d52b25aa9..b4fc458da 100644 --- a/geth/api/backend.go +++ b/geth/api/backend.go @@ -24,12 +24,12 @@ const ( // StatusBackend implements Status.im service type StatusBackend struct { sync.Mutex - nodeReady chan struct{} // channel to wait for when node is fully ready - nodeManager common.NodeManager - accountManager common.AccountManager - txQueueManager common.TxQueueManager - jailManager common.JailManager - notifier common.NotifierConstructor + nodeReady chan struct{} // channel to wait for when node is fully ready + nodeManager common.NodeManager + accountManager common.AccountManager + txQueueManager common.TxQueueManager + jailManager common.JailManager + newNotification common.NotificationConstructor } // NewStatusBackend create a new NewStatusBackend instance @@ -43,11 +43,11 @@ func NewStatusBackend() *StatusBackend { notificationManager := fcm.NewNotifier(fcmServerKey) return &StatusBackend{ - nodeManager: nodeManager, - accountManager: accountManager, - jailManager: jailManager, - txQueueManager: txQueueManager, - notifier: notificationManager, + nodeManager: nodeManager, + accountManager: accountManager, + jailManager: jailManager, + txQueueManager: txQueueManager, + newNotification: notificationManager, } } diff --git a/geth/common/notification.go b/geth/common/notification.go index dcd67ccd4..34ba674c7 100644 --- a/geth/common/notification.go +++ b/geth/common/notification.go @@ -2,8 +2,8 @@ package common // Notifier manages Push Notifications. type Notifier interface { - Notify(body interface{}, tokens ...string) error + Send(body interface{}, tokens ...string) error } -// NotifierConstructor returns constructor of configured instance Notifier interface. -type NotifierConstructor func() Notifier +// NotificationConstructor returns constructor of configured instance Notifier interface. +type NotificationConstructor func() Notifier diff --git a/geth/common/notification_mock.go b/geth/common/notification_mock.go index acb145e76..accbd8cd8 100644 --- a/geth/common/notification_mock.go +++ b/geth/common/notification_mock.go @@ -32,19 +32,19 @@ func (m *MockNotifier) EXPECT() *MockNotifierMockRecorder { return m.recorder } -// Notify mocks base method -func (m *MockNotifier) Notify(body interface{}, tokens ...string) error { +// Send mocks base method +func (m *MockNotifier) Send(body interface{}, tokens ...string) error { varargs := []interface{}{body} for _, a := range tokens { varargs = append(varargs, a) } - ret := m.ctrl.Call(m, "Notify", varargs...) + ret := m.ctrl.Call(m, "Send", varargs...) ret0, _ := ret[0].(error) return ret0 } -// Notify indicates an expected call of Notify -func (mr *MockNotifierMockRecorder) Notify(body interface{}, tokens ...interface{}) *gomock.Call { +// Send indicates an expected call of Send +func (mr *MockNotifierMockRecorder) Send(body interface{}, tokens ...interface{}) *gomock.Call { varargs := append([]interface{}{body}, tokens...) - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notify", reflect.TypeOf((*MockNotifier)(nil).Notify), varargs...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockNotifier)(nil).Send), varargs...) } diff --git a/geth/notification/fcm/notifier.go b/geth/notification/fcm/notifier.go index f43e2d59e..7ebcfe280 100644 --- a/geth/notification/fcm/notifier.go +++ b/geth/notification/fcm/notifier.go @@ -12,14 +12,14 @@ type Notifier struct { } // NewNotifier Firebase Cloud Messaging client constructor. -func NewNotifier(key string) func() common.Notifier { +func NewNotifier(key string) common.NotificationConstructor { return func() common.Notifier { return &Notifier{fcm.NewFcmClient(key)} } } -// Notify preparation and send to the tokens list. -func (n *Notifier) Notify(body interface{}, tokens ...string) error { +// Send send to the tokens list. +func (n *Notifier) Send(body interface{}, tokens ...string) error { n.setPayload(¬ification.Payload{ Title: "Status - new message", Body: "ping", diff --git a/geth/notification/fcm/notifier_test.go b/geth/notification/fcm/notifier_test.go index 320fd6798..91cbbe551 100644 --- a/geth/notification/fcm/notifier_test.go +++ b/geth/notification/fcm/notifier_test.go @@ -39,7 +39,7 @@ func (s *NotifierTestSuite) TestNotifySuccess() { s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1) fcmClient := Notifier{s.fcmClientMock} - err := fcmClient.Notify(body, ids...) + err := fcmClient.Send(body, ids...) s.NoError(err) } @@ -55,7 +55,7 @@ func (s *NotifierTestSuite) TestNotifyError() { s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1) fcmClient := Notifier{s.fcmClientMock} - err := fcmClient.Notify(body, ids...) + err := fcmClient.Send(body, ids...) s.Equal(expectedError, err) } From d22cdc5cbb4870ae5273934bf9b81bee367374f9 Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Wed, 18 Oct 2017 23:29:23 +0300 Subject: [PATCH 13/16] NotifyResult doesnt return error field if success --- cmd/statusd/library.go | 4 +--- geth/common/types.go | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/statusd/library.go b/cmd/statusd/library.go index 67d3b0a79..d0ae27ad7 100644 --- a/cmd/statusd/library.go +++ b/cmd/statusd/library.go @@ -378,15 +378,13 @@ func makeJSONResponse(err error) *C.char { func Notify(token *C.char) *C.char { err := statusAPI.Notify(C.GoString(token)) - res := true errString := "" if err != nil { - res = false errString = err.Error() } out := common.NotifyResult{ - Status: res, + Status: err == nil, Error: errString, } diff --git a/geth/common/types.go b/geth/common/types.go index 1a7c9f884..5ecccf2d9 100644 --- a/geth/common/types.go +++ b/geth/common/types.go @@ -398,7 +398,7 @@ type TestConfig struct { // NotifyResult is a JSON returned from notify message type NotifyResult struct { Status bool `json:"status"` - Error string `json:"error"` + Error string `json:"error,omitempty"` } // LoadTestConfig loads test configuration values from disk From c823acfd04c4330b026de11f8f8f0bf9a7a56e95 Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Wed, 18 Oct 2017 23:56:39 +0300 Subject: [PATCH 14/16] All notifiers remaned into notification --- geth/api/backend.go | 2 +- .../fcm/{notifier.go => notification.go} | 18 +++++++++--------- .../{notifier_test.go => notification_test.go} | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) rename geth/notification/fcm/{notifier.go => notification.go} (59%) rename geth/notification/fcm/{notifier_test.go => notification_test.go} (94%) diff --git a/geth/api/backend.go b/geth/api/backend.go index b4fc458da..328d77039 100644 --- a/geth/api/backend.go +++ b/geth/api/backend.go @@ -40,7 +40,7 @@ func NewStatusBackend() *StatusBackend { accountManager := account.NewManager(nodeManager) txQueueManager := txqueue.NewManager(nodeManager, accountManager) jailManager := jail.New(nodeManager) - notificationManager := fcm.NewNotifier(fcmServerKey) + notificationManager := fcm.NewNotification(fcmServerKey) return &StatusBackend{ nodeManager: nodeManager, diff --git a/geth/notification/fcm/notifier.go b/geth/notification/fcm/notification.go similarity index 59% rename from geth/notification/fcm/notifier.go rename to geth/notification/fcm/notification.go index 7ebcfe280..62101ece1 100644 --- a/geth/notification/fcm/notifier.go +++ b/geth/notification/fcm/notification.go @@ -6,20 +6,20 @@ import ( "github.com/status-im/status-go/geth/notification" ) -// Notifier represents messaging provider for notifications. -type Notifier struct { +// Notification represents messaging provider for notifications. +type Notification struct { client firebaseClient } -// NewNotifier Firebase Cloud Messaging client constructor. -func NewNotifier(key string) common.NotificationConstructor { +// NewNotification Firebase Cloud Messaging client constructor. +func NewNotification(key string) common.NotificationConstructor { return func() common.Notifier { - return &Notifier{fcm.NewFcmClient(key)} + return &Notification{fcm.NewFcmClient(key)} } } // Send send to the tokens list. -func (n *Notifier) Send(body interface{}, tokens ...string) error { +func (n *Notification) Send(body interface{}, tokens ...string) error { n.setPayload(¬ification.Payload{ Title: "Status - new message", Body: "ping", @@ -32,17 +32,17 @@ func (n *Notifier) Send(body interface{}, tokens ...string) error { } // SetMessage to send for given the tokens list. -func (n *Notifier) setMessage(body interface{}, tokens ...string) { +func (n *Notification) setMessage(body interface{}, tokens ...string) { n.client.NewFcmRegIdsMsg(tokens, body) } // SetPayload sets payload message information. -func (n *Notifier) setPayload(payload *notification.Payload) { +func (n *Notification) setPayload(payload *notification.Payload) { fcmPayload := n.toFCMPayload(payload) n.client.SetNotificationPayload(fcmPayload) } -func (n *Notifier) toFCMPayload(payload *notification.Payload) *fcm.NotificationPayload { +func (n *Notification) toFCMPayload(payload *notification.Payload) *fcm.NotificationPayload { return &fcm.NotificationPayload{ Title: payload.Title, Body: payload.Body, diff --git a/geth/notification/fcm/notifier_test.go b/geth/notification/fcm/notification_test.go similarity index 94% rename from geth/notification/fcm/notifier_test.go rename to geth/notification/fcm/notification_test.go index 91cbbe551..f9c1789b4 100644 --- a/geth/notification/fcm/notifier_test.go +++ b/geth/notification/fcm/notification_test.go @@ -37,7 +37,7 @@ func (s *NotifierTestSuite) TestNotifySuccess() { s.fcmClientMock.EXPECT().SetNotificationPayload(fcmPayload).Times(1) s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1) - fcmClient := Notifier{s.fcmClientMock} + fcmClient := Notification{s.fcmClientMock} err := fcmClient.Send(body, ids...) @@ -53,7 +53,7 @@ func (s *NotifierTestSuite) TestNotifyError() { s.fcmClientMock.EXPECT().SetNotificationPayload(fcmPayload).Times(1) s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1) - fcmClient := Notifier{s.fcmClientMock} + fcmClient := Notification{s.fcmClientMock} err := fcmClient.Send(body, ids...) From a3bca52f513c4f0cf06fe59f9328c152fe0333d6 Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Sun, 22 Oct 2017 15:53:24 +0300 Subject: [PATCH 15/16] Fmt --- geth/notification/fcm/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geth/notification/fcm/client.go b/geth/notification/fcm/client.go index 00a46879f..bc2ae434b 100644 --- a/geth/notification/fcm/client.go +++ b/geth/notification/fcm/client.go @@ -7,4 +7,4 @@ type firebaseClient interface { NewFcmRegIdsMsg(tokens []string, body interface{}) *fcm.FcmClient Send() (*fcm.FcmResponseStatus, error) SetNotificationPayload(payload *fcm.NotificationPayload) *fcm.FcmClient -} \ No newline at end of file +} From 0e72e3d6b4812bf40f4cc1ba2cac7f11c6294e9f Mon Sep 17 00:00:00 2001 From: Evgeny Danienko <6655321@bk.ru> Date: Mon, 23 Oct 2017 18:46:51 +0300 Subject: [PATCH 16/16] Update notify interface and mark old one as deprecated --- cmd/statusd/library.go | 55 +++++++++++++++++----- geth/api/api.go | 25 +++++++--- geth/common/notification.go | 4 +- geth/common/notification_mock.go | 9 ++-- geth/notification/fcm/notification.go | 54 +++++++++------------ geth/notification/fcm/notification_test.go | 26 ++++++---- 6 files changed, 108 insertions(+), 65 deletions(-) diff --git a/cmd/statusd/library.go b/cmd/statusd/library.go index d0ae27ad7..23aae1d76 100644 --- a/cmd/statusd/library.go +++ b/cmd/statusd/library.go @@ -6,12 +6,12 @@ import ( "fmt" "os" - "gopkg.in/go-playground/validator.v9" - + "github.com/NaySoftware/go-fcm" "github.com/status-im/status-go/geth/common" "github.com/status-im/status-go/geth/log" "github.com/status-im/status-go/geth/params" "github.com/status-im/status-go/helpers/profiling" + "gopkg.in/go-playground/validator.v9" ) //GenerateConfig for status node @@ -374,25 +374,56 @@ func makeJSONResponse(err error) *C.char { } // Notify sends push notification by given token +// @deprecated //export Notify func Notify(token *C.char) *C.char { - err := statusAPI.Notify(C.GoString(token)) + res := statusAPI.Notify(C.GoString(token)) + return C.CString(res) +} +// NotifyUsers sends push notifications by given tokens. +//export NotifyUsers +func NotifyUsers(message, payloadJSON, tokensArray *C.char) (outCBytes *C.char) { + var ( + err error + outBytes []byte + ) errString := "" + + defer func() { + out := common.NotifyResult{ + Status: err == nil, + Error: errString, + } + + outBytes, err = json.Marshal(out) + if err != nil { + log.Error("failed to marshal Notify output", "error", err.Error()) + outCBytes = makeJSONResponse(err) + return + } + + outCBytes = C.CString(string(outBytes)) + }() + + tokens, err := common.ParseJSONArray(C.GoString(tokensArray)) if err != nil { errString = err.Error() + return } - out := common.NotifyResult{ - Status: err == nil, - Error: errString, - } - - outBytes, err := json.Marshal(out) + var payload fcm.NotificationPayload + err = json.Unmarshal([]byte(C.GoString(payloadJSON)), &payload) if err != nil { - log.Error("failed to marshal Notify output", "error", err.Error()) - return makeJSONResponse(err) + errString = err.Error() + return } - return C.CString(string(outBytes)) + err = statusAPI.NotifyUsers(C.GoString(message), payload, tokens...) + if err != nil { + errString = err.Error() + return + } + + return } diff --git a/geth/api/api.go b/geth/api/api.go index be639abbf..f6bcf3e2a 100644 --- a/geth/api/api.go +++ b/geth/api/api.go @@ -3,6 +3,7 @@ package api import ( "context" + "github.com/NaySoftware/go-fcm" "github.com/ethereum/go-ethereum/accounts/keystore" gethcommon "github.com/ethereum/go-ethereum/common" "github.com/status-im/status-go/geth/common" @@ -194,17 +195,27 @@ func (api *StatusAPI) JailBaseJS(js string) { api.b.jailManager.BaseJS(js) } -// Notify and send message. -func (api *StatusAPI) Notify(token string) error { +// Notify sends a push notification to the device with the given token. +// @deprecated +func (api *StatusAPI) Notify(token string) string { log.Debug("Notify", "token", token) + message := "Hello World1" - // TODO(oskarth): Experiment with this - msg := map[string]string{ - "msg": "Hello World1", - "sum": "Happy Day", + tokens := []string{token} + + err := api.b.newNotification().Send(message, fcm.NotificationPayload{}, tokens...) + if err != nil { + log.Error("Notify failed:", err) } - err := api.b.newNotification().Send(msg, token) + return token +} + +// NotifyUsers send notifications to users. +func (api *StatusAPI) NotifyUsers(message string, payload fcm.NotificationPayload, tokens ...string) error { + log.Debug("Notify", "tokens", tokens) + + err := api.b.newNotification().Send(message, payload, tokens...) if err != nil { log.Error("Notify failed:", err) } diff --git a/geth/common/notification.go b/geth/common/notification.go index 34ba674c7..e30920547 100644 --- a/geth/common/notification.go +++ b/geth/common/notification.go @@ -1,8 +1,10 @@ package common +import "github.com/NaySoftware/go-fcm" + // Notifier manages Push Notifications. type Notifier interface { - Send(body interface{}, tokens ...string) error + Send(body string, payload fcm.NotificationPayload, tokens ...string) error } // NotificationConstructor returns constructor of configured instance Notifier interface. diff --git a/geth/common/notification_mock.go b/geth/common/notification_mock.go index accbd8cd8..70dd0682a 100644 --- a/geth/common/notification_mock.go +++ b/geth/common/notification_mock.go @@ -5,6 +5,7 @@ package common import ( + go_fcm "github.com/NaySoftware/go-fcm" gomock "github.com/golang/mock/gomock" reflect "reflect" ) @@ -33,8 +34,8 @@ func (m *MockNotifier) EXPECT() *MockNotifierMockRecorder { } // Send mocks base method -func (m *MockNotifier) Send(body interface{}, tokens ...string) error { - varargs := []interface{}{body} +func (m *MockNotifier) Send(body string, payload go_fcm.NotificationPayload, tokens ...string) error { + varargs := []interface{}{body, payload} for _, a := range tokens { varargs = append(varargs, a) } @@ -44,7 +45,7 @@ func (m *MockNotifier) Send(body interface{}, tokens ...string) error { } // Send indicates an expected call of Send -func (mr *MockNotifierMockRecorder) Send(body interface{}, tokens ...interface{}) *gomock.Call { - varargs := append([]interface{}{body}, tokens...) +func (mr *MockNotifierMockRecorder) Send(body, payload interface{}, tokens ...interface{}) *gomock.Call { + varargs := append([]interface{}{body, payload}, tokens...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Send", reflect.TypeOf((*MockNotifier)(nil).Send), varargs...) } diff --git a/geth/notification/fcm/notification.go b/geth/notification/fcm/notification.go index 62101ece1..99fdcd1b6 100644 --- a/geth/notification/fcm/notification.go +++ b/geth/notification/fcm/notification.go @@ -1,9 +1,10 @@ package fcm import ( + "fmt" + "github.com/NaySoftware/go-fcm" "github.com/status-im/status-go/geth/common" - "github.com/status-im/status-go/geth/notification" ) // Notification represents messaging provider for notifications. @@ -14,42 +15,33 @@ type Notification struct { // NewNotification Firebase Cloud Messaging client constructor. func NewNotification(key string) common.NotificationConstructor { return func() common.Notifier { - return &Notification{fcm.NewFcmClient(key)} + client := fcm.NewFcmClient(key). + SetDelayWhileIdle(true). + SetContentAvailable(true). + SetTimeToLive(fcm.MAX_TTL) + + return &Notification{client} } } // Send send to the tokens list. -func (n *Notification) Send(body interface{}, tokens ...string) error { - n.setPayload(¬ification.Payload{ - Title: "Status - new message", - Body: "ping", - }) +func (n *Notification) Send(body string, payload fcm.NotificationPayload, tokens ...string) error { + data := map[string]string{ + "msg": body, + } - n.setMessage(body, tokens...) + if payload.Title == "" { + payload.Title = "Status - new message" + } + if payload.Body == "" { + payload.Body = "ping" + } + + fmt.Println(payload.Title, payload.Body) + + n.client.NewFcmRegIdsMsg(tokens, data) + n.client.SetNotificationPayload(&payload) _, err := n.client.Send() return err } - -// SetMessage to send for given the tokens list. -func (n *Notification) setMessage(body interface{}, tokens ...string) { - n.client.NewFcmRegIdsMsg(tokens, body) -} - -// SetPayload sets payload message information. -func (n *Notification) setPayload(payload *notification.Payload) { - fcmPayload := n.toFCMPayload(payload) - n.client.SetNotificationPayload(fcmPayload) -} - -func (n *Notification) toFCMPayload(payload *notification.Payload) *fcm.NotificationPayload { - return &fcm.NotificationPayload{ - Title: payload.Title, - Body: payload.Body, - Icon: payload.Icon, - Sound: payload.Sound, - Badge: payload.Badge, - Tag: payload.Tag, - Color: payload.Color, - } -} diff --git a/geth/notification/fcm/notification_test.go b/geth/notification/fcm/notification_test.go index f9c1789b4..6c429dd5a 100644 --- a/geth/notification/fcm/notification_test.go +++ b/geth/notification/fcm/notification_test.go @@ -32,14 +32,17 @@ func (s *NotifierTestSuite) TearDownTest() { func (s *NotifierTestSuite) TestNotifySuccess() { fcmPayload := getPayload() ids := []string{"1"} - body := interface{}("body") + payload := fcmPayload + msg := make(map[string]string) + body := "body" + msg["msg"] = body - s.fcmClientMock.EXPECT().SetNotificationPayload(fcmPayload).Times(1) - s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) + s.fcmClientMock.EXPECT().SetNotificationPayload(&fcmPayload).Times(1) + s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, msg).Times(1) s.fcmClientMock.EXPECT().Send().Return(nil, nil).Times(1) fcmClient := Notification{s.fcmClientMock} - err := fcmClient.Send(body, ids...) + err := fcmClient.Send(body, payload, ids...) s.NoError(err) } @@ -48,18 +51,21 @@ func (s *NotifierTestSuite) TestNotifyError() { expectedError := errors.New("error") fcmPayload := getPayload() ids := []string{"1"} - body := interface{}("body") + payload := fcmPayload + msg := make(map[string]string) + body := "body" + msg["msg"] = body - s.fcmClientMock.EXPECT().SetNotificationPayload(fcmPayload).Times(1) - s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, body).Times(1) + s.fcmClientMock.EXPECT().SetNotificationPayload(&fcmPayload).Times(1) + s.fcmClientMock.EXPECT().NewFcmRegIdsMsg(ids, msg).Times(1) s.fcmClientMock.EXPECT().Send().Return(nil, expectedError).Times(1) fcmClient := Notification{s.fcmClientMock} - err := fcmClient.Send(body, ids...) + err := fcmClient.Send(body, payload, ids...) s.Equal(expectedError, err) } -func getPayload() *fcm.NotificationPayload { - return &fcm.NotificationPayload{Title: "Status - new message", Body: "ping"} +func getPayload() fcm.NotificationPayload { + return fcm.NotificationPayload{Title: "Status - new message", Body: "sum"} }