mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-28 12:36:43 +00:00
Send unilateral responses before sending OK
This commit is contained in:
@ -78,7 +78,7 @@ func (storeAddress *Address) createOrUpdateMailboxEvent(label *pmapi.Label) erro
|
||||
return err
|
||||
}
|
||||
storeAddress.mailboxes[label.ID] = mailbox
|
||||
mailbox.store.imapMailboxCreated(storeAddress.address, mailbox.labelName)
|
||||
mailbox.store.notifyMailboxCreated(storeAddress.address, mailbox.labelName)
|
||||
} else {
|
||||
mailbox.labelName = prefix + label.Path
|
||||
mailbox.color = label.Color
|
||||
|
||||
@ -18,119 +18,56 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/pkg/message"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
imap "github.com/emersion/go-imap"
|
||||
imapBackend "github.com/emersion/go-imap/backend"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// SetIMAPUpdateChannel sets the channel on which imap update messages will be sent. This should be the channel
|
||||
// on which the imap backend listens for imap updates.
|
||||
func (store *Store) SetIMAPUpdateChannel(updates chan imapBackend.Update) {
|
||||
store.log.Debug("Listening for IMAP updates")
|
||||
|
||||
if store.imapUpdates = updates; store.imapUpdates == nil {
|
||||
store.log.Error("The IMAP Updates channel is nil")
|
||||
}
|
||||
type ChangeNotifier interface {
|
||||
Notice(address, notice string)
|
||||
UpdateMessage(
|
||||
address, mailboxName string,
|
||||
uid, sequenceNumber uint32,
|
||||
msg *pmapi.Message, hasDeletedFlag bool)
|
||||
DeleteMessage(address, mailboxName string, sequenceNumber uint32)
|
||||
MailboxCreated(address, mailboxName string)
|
||||
MailboxStatus(address, mailboxName string, total, unread, unreadSeqNum uint32)
|
||||
}
|
||||
|
||||
func (store *Store) imapNotice(address, notice string) *imapBackend.StatusUpdate {
|
||||
update := new(imapBackend.StatusUpdate)
|
||||
update.Update = imapBackend.NewUpdate(address, "")
|
||||
update.StatusResp = &imap.StatusResp{
|
||||
Type: imap.StatusRespOk,
|
||||
Code: imap.CodeAlert,
|
||||
Info: notice,
|
||||
}
|
||||
store.imapSendUpdate(update)
|
||||
return update
|
||||
// SetChangeNotifier sets notifier to be called once mailbox or message changes.
|
||||
func (store *Store) SetChangeNotifier(notifier ChangeNotifier) {
|
||||
store.notifier = notifier
|
||||
}
|
||||
|
||||
func (store *Store) imapUpdateMessage(
|
||||
address, mailboxName string,
|
||||
uid, sequenceNumber uint32,
|
||||
msg *pmapi.Message, hasDeletedFlag bool,
|
||||
) *imapBackend.MessageUpdate {
|
||||
store.log.WithFields(logrus.Fields{
|
||||
"address": address,
|
||||
"mailbox": mailboxName,
|
||||
"seqNum": sequenceNumber,
|
||||
"uid": uid,
|
||||
"flags": message.GetFlags(msg),
|
||||
"deleted": hasDeletedFlag,
|
||||
}).Trace("IDLE update")
|
||||
update := new(imapBackend.MessageUpdate)
|
||||
update.Update = imapBackend.NewUpdate(address, mailboxName)
|
||||
update.Message = imap.NewMessage(sequenceNumber, []imap.FetchItem{imap.FetchFlags, imap.FetchUid})
|
||||
update.Message.Flags = message.GetFlags(msg)
|
||||
if hasDeletedFlag {
|
||||
update.Message.Flags = append(update.Message.Flags, imap.DeletedFlag)
|
||||
}
|
||||
update.Message.Uid = uid
|
||||
store.imapSendUpdate(update)
|
||||
return update
|
||||
}
|
||||
|
||||
func (store *Store) imapDeleteMessage(address, mailboxName string, sequenceNumber uint32) *imapBackend.ExpungeUpdate {
|
||||
store.log.WithFields(logrus.Fields{
|
||||
"address": address,
|
||||
"mailbox": mailboxName,
|
||||
"seqNum": sequenceNumber,
|
||||
}).Trace("IDLE delete")
|
||||
update := new(imapBackend.ExpungeUpdate)
|
||||
update.Update = imapBackend.NewUpdate(address, mailboxName)
|
||||
update.SeqNum = sequenceNumber
|
||||
store.imapSendUpdate(update)
|
||||
return update
|
||||
}
|
||||
|
||||
func (store *Store) imapMailboxCreated(address, mailboxName string) *imapBackend.MailboxInfoUpdate {
|
||||
store.log.WithFields(logrus.Fields{
|
||||
"address": address,
|
||||
"mailbox": mailboxName,
|
||||
}).Trace("IDLE mailbox info")
|
||||
update := new(imapBackend.MailboxInfoUpdate)
|
||||
update.Update = imapBackend.NewUpdate(address, "")
|
||||
update.MailboxInfo = &imap.MailboxInfo{
|
||||
Attributes: []string{imap.NoInferiorsAttr},
|
||||
Delimiter: PathDelimiter,
|
||||
Name: mailboxName,
|
||||
}
|
||||
store.imapSendUpdate(update)
|
||||
return update
|
||||
}
|
||||
|
||||
func (store *Store) imapMailboxStatus(address, mailboxName string, total, unread, unreadSeqNum uint) *imapBackend.MailboxUpdate {
|
||||
store.log.WithFields(logrus.Fields{
|
||||
"address": address,
|
||||
"mailbox": mailboxName,
|
||||
"total": total,
|
||||
"unread": unread,
|
||||
"unreadSeqNum": unreadSeqNum,
|
||||
}).Trace("IDLE status")
|
||||
update := new(imapBackend.MailboxUpdate)
|
||||
update.Update = imapBackend.NewUpdate(address, mailboxName)
|
||||
update.MailboxStatus = imap.NewMailboxStatus(mailboxName, []imap.StatusItem{imap.StatusMessages, imap.StatusUnseen})
|
||||
update.MailboxStatus.Messages = uint32(total)
|
||||
update.MailboxStatus.Unseen = uint32(unread)
|
||||
update.MailboxStatus.UnseenSeqNum = uint32(unreadSeqNum)
|
||||
store.imapSendUpdate(update)
|
||||
return update
|
||||
}
|
||||
|
||||
func (store *Store) imapSendUpdate(update imapBackend.Update) {
|
||||
if store.imapUpdates == nil {
|
||||
store.log.Trace("IMAP IDLE unavailable")
|
||||
func (store *Store) notifyNotice(address, notice string) {
|
||||
if store.notifier == nil {
|
||||
return
|
||||
}
|
||||
|
||||
select {
|
||||
case <-time.After(1 * time.Second):
|
||||
store.log.Warn("IMAP update could not be sent (timeout)")
|
||||
return
|
||||
case store.imapUpdates <- update:
|
||||
}
|
||||
store.notifier.Notice(address, notice)
|
||||
}
|
||||
|
||||
func (store *Store) notifyUpdateMessage(address, mailboxName string, uid, sequenceNumber uint32, msg *pmapi.Message, hasDeletedFlag bool) {
|
||||
if store.notifier == nil {
|
||||
return
|
||||
}
|
||||
store.notifier.UpdateMessage(address, mailboxName, uid, sequenceNumber, msg, hasDeletedFlag)
|
||||
}
|
||||
|
||||
func (store *Store) notifyDeleteMessage(address, mailboxName string, sequenceNumber uint32) {
|
||||
if store.notifier == nil {
|
||||
return
|
||||
}
|
||||
store.notifier.DeleteMessage(address, mailboxName, sequenceNumber)
|
||||
}
|
||||
|
||||
func (store *Store) notifyMailboxCreated(address, mailboxName string) {
|
||||
if store.notifier == nil {
|
||||
return
|
||||
}
|
||||
store.notifier.MailboxCreated(address, mailboxName)
|
||||
}
|
||||
|
||||
func (store *Store) notifyMailboxStatus(address, mailboxName string, total, unread, unreadSeqNum uint) {
|
||||
if store.notifier == nil {
|
||||
return
|
||||
}
|
||||
store.notifier.MailboxStatus(address, mailboxName, uint32(total), uint32(unread), uint32(unreadSeqNum))
|
||||
}
|
||||
|
||||
@ -21,52 +21,43 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
imapBackend "github.com/emersion/go-imap/backend"
|
||||
"github.com/golang/mock/gomock"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestCreateOrUpdateMessageIMAPUpdates(t *testing.T) {
|
||||
func TestNotifyChangeCreateOrUpdateMessage(t *testing.T) {
|
||||
m, clear := initMocks(t)
|
||||
defer clear()
|
||||
|
||||
updates := make(chan imapBackend.Update)
|
||||
m.changeNotifier.EXPECT().MailboxStatus(addr1, "All Mail", uint32(1), uint32(0), uint32(0))
|
||||
m.changeNotifier.EXPECT().MailboxStatus(addr1, "All Mail", uint32(2), uint32(0), uint32(0))
|
||||
m.changeNotifier.EXPECT().UpdateMessage(addr1, "All Mail", uint32(1), uint32(1), gomock.Any(), false)
|
||||
m.changeNotifier.EXPECT().UpdateMessage(addr1, "All Mail", uint32(2), uint32(2), gomock.Any(), false)
|
||||
|
||||
m.newStoreNoEvents(true)
|
||||
m.store.SetIMAPUpdateChannel(updates)
|
||||
|
||||
go checkIMAPUpdates(t, updates, []func(interface{}) bool{
|
||||
checkMessageUpdate(addr1, "All Mail", 1, 1),
|
||||
checkMessageUpdate(addr1, "All Mail", 2, 2),
|
||||
})
|
||||
m.store.SetChangeNotifier(m.changeNotifier)
|
||||
|
||||
insertMessage(t, m, "msg1", "Test message 1", addrID1, 0, []string{pmapi.AllMailLabel})
|
||||
insertMessage(t, m, "msg2", "Test message 2", addrID1, 0, []string{pmapi.AllMailLabel})
|
||||
|
||||
close(updates)
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateMessageIMAPUpdatesBulkUpdate(t *testing.T) {
|
||||
func TestNotifyChangeCreateOrUpdateMessages(t *testing.T) {
|
||||
m, clear := initMocks(t)
|
||||
defer clear()
|
||||
|
||||
updates := make(chan imapBackend.Update)
|
||||
m.changeNotifier.EXPECT().MailboxStatus(addr1, "All Mail", uint32(2), uint32(0), uint32(0))
|
||||
m.changeNotifier.EXPECT().UpdateMessage(addr1, "All Mail", uint32(1), uint32(1), gomock.Any(), false)
|
||||
m.changeNotifier.EXPECT().UpdateMessage(addr1, "All Mail", uint32(2), uint32(2), gomock.Any(), false)
|
||||
|
||||
m.newStoreNoEvents(true)
|
||||
m.store.SetIMAPUpdateChannel(updates)
|
||||
|
||||
go checkIMAPUpdates(t, updates, []func(interface{}) bool{
|
||||
checkMessageUpdate(addr1, "All Mail", 1, 1),
|
||||
checkMessageUpdate(addr1, "All Mail", 2, 2),
|
||||
})
|
||||
m.store.SetChangeNotifier(m.changeNotifier)
|
||||
|
||||
msg1 := getTestMessage("msg1", "Test message 1", addrID1, 0, []string{pmapi.AllMailLabel})
|
||||
msg2 := getTestMessage("msg2", "Test message 2", addrID1, 0, []string{pmapi.AllMailLabel})
|
||||
require.Nil(t, m.store.createOrUpdateMessagesEvent([]*pmapi.Message{msg1, msg2}))
|
||||
|
||||
close(updates)
|
||||
}
|
||||
|
||||
func TestDeleteMessageIMAPUpdate(t *testing.T) {
|
||||
func TestNotifyChangeDeleteMessage(t *testing.T) {
|
||||
m, clear := initMocks(t)
|
||||
defer clear()
|
||||
|
||||
@ -75,55 +66,10 @@ func TestDeleteMessageIMAPUpdate(t *testing.T) {
|
||||
insertMessage(t, m, "msg1", "Test message 1", addrID1, 0, []string{pmapi.AllMailLabel})
|
||||
insertMessage(t, m, "msg2", "Test message 2", addrID1, 0, []string{pmapi.AllMailLabel})
|
||||
|
||||
updates := make(chan imapBackend.Update)
|
||||
m.store.SetIMAPUpdateChannel(updates)
|
||||
go checkIMAPUpdates(t, updates, []func(interface{}) bool{
|
||||
checkMessageDelete(addr1, "All Mail", 2),
|
||||
checkMessageDelete(addr1, "All Mail", 1),
|
||||
})
|
||||
m.changeNotifier.EXPECT().DeleteMessage(addr1, "All Mail", uint32(2))
|
||||
m.changeNotifier.EXPECT().DeleteMessage(addr1, "All Mail", uint32(1))
|
||||
|
||||
m.store.SetChangeNotifier(m.changeNotifier)
|
||||
require.Nil(t, m.store.deleteMessageEvent("msg2"))
|
||||
require.Nil(t, m.store.deleteMessageEvent("msg1"))
|
||||
close(updates)
|
||||
}
|
||||
|
||||
func checkIMAPUpdates(t *testing.T, updates chan imapBackend.Update, checkFunctions []func(interface{}) bool) {
|
||||
idx := 0
|
||||
for update := range updates {
|
||||
if idx >= len(checkFunctions) {
|
||||
continue
|
||||
}
|
||||
if !checkFunctions[idx](update) {
|
||||
continue
|
||||
}
|
||||
idx++
|
||||
}
|
||||
require.True(t, idx == len(checkFunctions), "Less updates than expected: %+v of %+v", idx, len(checkFunctions))
|
||||
}
|
||||
|
||||
func checkMessageUpdate(username, mailbox string, seqNum, uid int) func(interface{}) bool { //nolint[unparam]
|
||||
return func(update interface{}) bool {
|
||||
switch u := update.(type) {
|
||||
case *imapBackend.MessageUpdate:
|
||||
return (u.Update.Username() == username &&
|
||||
u.Update.Mailbox() == mailbox &&
|
||||
u.Message.SeqNum == uint32(seqNum) &&
|
||||
u.Message.Uid == uint32(uid))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkMessageDelete(username, mailbox string, seqNum int) func(interface{}) bool { //nolint[unparam]
|
||||
return func(update interface{}) bool {
|
||||
switch u := update.(type) {
|
||||
case *imapBackend.ExpungeUpdate:
|
||||
return (u.Update.Username() == username &&
|
||||
u.Update.Mailbox() == mailbox &&
|
||||
u.SeqNum == uint32(seqNum))
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,7 +571,7 @@ func (loop *eventLoop) processNotices(l *logrus.Entry, notices []string) {
|
||||
for _, notice := range notices {
|
||||
l.Infof("Notice: %q", notice)
|
||||
for _, address := range loop.user.GetStoreAddresses() {
|
||||
loop.store.imapNotice(address, notice)
|
||||
loop.store.notifyNotice(address, notice)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,8 +18,6 @@
|
||||
package store
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -356,7 +354,7 @@ func (storeMailbox *Mailbox) txCreateOrUpdateMessages(tx *bolt.Tx, msgs []*pmapi
|
||||
}
|
||||
isMarkedAsDeleted := deletedBucket.Get([]byte(msg.ID)) != nil
|
||||
if seqErr == nil {
|
||||
storeMailbox.store.imapUpdateMessage(
|
||||
storeMailbox.store.notifyUpdateMessage(
|
||||
storeMailbox.storeAddress.address,
|
||||
storeMailbox.labelName,
|
||||
btoi(uidb),
|
||||
@ -390,7 +388,7 @@ func (storeMailbox *Mailbox) txCreateOrUpdateMessages(tx *bolt.Tx, msgs []*pmapi
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot get sequence number from UID")
|
||||
}
|
||||
storeMailbox.store.imapUpdateMessage(
|
||||
storeMailbox.store.notifyUpdateMessage(
|
||||
storeMailbox.storeAddress.address,
|
||||
storeMailbox.labelName,
|
||||
uid,
|
||||
@ -441,7 +439,7 @@ func (storeMailbox *Mailbox) txDeleteMessage(tx *bolt.Tx, apiID string) error {
|
||||
}
|
||||
|
||||
if seqNumErr == nil {
|
||||
storeMailbox.store.imapDeleteMessage(
|
||||
storeMailbox.store.notifyDeleteMessage(
|
||||
storeMailbox.storeAddress.address,
|
||||
storeMailbox.labelName,
|
||||
seqNum,
|
||||
@ -459,7 +457,7 @@ func (storeMailbox *Mailbox) txMailboxStatusUpdate(tx *bolt.Tx) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "cannot get counts for mailbox status update")
|
||||
}
|
||||
storeMailbox.store.imapMailboxStatus(
|
||||
storeMailbox.store.notifyMailboxStatus(
|
||||
storeMailbox.storeAddress.address,
|
||||
storeMailbox.labelName,
|
||||
total,
|
||||
@ -503,7 +501,7 @@ func (storeMailbox *Mailbox) txMarkMessagesAsDeleted(tx *bolt.Tx, apiIDs []strin
|
||||
|
||||
// In order to send flags in format
|
||||
// S: * 2 FETCH (FLAGS (\Deleted \Seen))
|
||||
update := storeMailbox.store.imapUpdateMessage(
|
||||
storeMailbox.store.notifyUpdateMessage(
|
||||
storeMailbox.storeAddress.address,
|
||||
storeMailbox.labelName,
|
||||
uid,
|
||||
@ -511,14 +509,6 @@ func (storeMailbox *Mailbox) txMarkMessagesAsDeleted(tx *bolt.Tx, apiIDs []strin
|
||||
msg,
|
||||
markAsDeleted,
|
||||
)
|
||||
|
||||
// txMarkMessagesAsDeleted is called only during processing request
|
||||
// from IMAP call (i.e., not from event loop) and in such cases we
|
||||
// have to wait to propagate update back before closing the response.
|
||||
select {
|
||||
case <-time.After(1 * time.Second):
|
||||
case <-update.Done():
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -1,14 +1,13 @@
|
||||
// Code generated by MockGen. DO NOT EDIT.
|
||||
// Source: github.com/ProtonMail/proton-bridge/internal/store (interfaces: PanicHandler,ClientManager,BridgeUser)
|
||||
// Source: github.com/ProtonMail/proton-bridge/internal/store (interfaces: PanicHandler,ClientManager,BridgeUser,ChangeNotifier)
|
||||
|
||||
// Package mocks is a generated GoMock package.
|
||||
package mocks
|
||||
|
||||
import (
|
||||
reflect "reflect"
|
||||
|
||||
pmapi "github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
gomock "github.com/golang/mock/gomock"
|
||||
reflect "reflect"
|
||||
)
|
||||
|
||||
// MockPanicHandler is a mock of PanicHandler interface
|
||||
@ -242,3 +241,86 @@ func (mr *MockBridgeUserMockRecorder) UpdateUser() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateUser", reflect.TypeOf((*MockBridgeUser)(nil).UpdateUser))
|
||||
}
|
||||
|
||||
// MockChangeNotifier is a mock of ChangeNotifier interface
|
||||
type MockChangeNotifier struct {
|
||||
ctrl *gomock.Controller
|
||||
recorder *MockChangeNotifierMockRecorder
|
||||
}
|
||||
|
||||
// MockChangeNotifierMockRecorder is the mock recorder for MockChangeNotifier
|
||||
type MockChangeNotifierMockRecorder struct {
|
||||
mock *MockChangeNotifier
|
||||
}
|
||||
|
||||
// NewMockChangeNotifier creates a new mock instance
|
||||
func NewMockChangeNotifier(ctrl *gomock.Controller) *MockChangeNotifier {
|
||||
mock := &MockChangeNotifier{ctrl: ctrl}
|
||||
mock.recorder = &MockChangeNotifierMockRecorder{mock}
|
||||
return mock
|
||||
}
|
||||
|
||||
// EXPECT returns an object that allows the caller to indicate expected use
|
||||
func (m *MockChangeNotifier) EXPECT() *MockChangeNotifierMockRecorder {
|
||||
return m.recorder
|
||||
}
|
||||
|
||||
// DeleteMessage mocks base method
|
||||
func (m *MockChangeNotifier) DeleteMessage(arg0, arg1 string, arg2 uint32) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "DeleteMessage", arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// DeleteMessage indicates an expected call of DeleteMessage
|
||||
func (mr *MockChangeNotifierMockRecorder) DeleteMessage(arg0, arg1, arg2 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteMessage", reflect.TypeOf((*MockChangeNotifier)(nil).DeleteMessage), arg0, arg1, arg2)
|
||||
}
|
||||
|
||||
// MailboxCreated mocks base method
|
||||
func (m *MockChangeNotifier) MailboxCreated(arg0, arg1 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "MailboxCreated", arg0, arg1)
|
||||
}
|
||||
|
||||
// MailboxCreated indicates an expected call of MailboxCreated
|
||||
func (mr *MockChangeNotifierMockRecorder) MailboxCreated(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MailboxCreated", reflect.TypeOf((*MockChangeNotifier)(nil).MailboxCreated), arg0, arg1)
|
||||
}
|
||||
|
||||
// MailboxStatus mocks base method
|
||||
func (m *MockChangeNotifier) MailboxStatus(arg0, arg1 string, arg2, arg3, arg4 uint32) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "MailboxStatus", arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// MailboxStatus indicates an expected call of MailboxStatus
|
||||
func (mr *MockChangeNotifierMockRecorder) MailboxStatus(arg0, arg1, arg2, arg3, arg4 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MailboxStatus", reflect.TypeOf((*MockChangeNotifier)(nil).MailboxStatus), arg0, arg1, arg2, arg3, arg4)
|
||||
}
|
||||
|
||||
// Notice mocks base method
|
||||
func (m *MockChangeNotifier) Notice(arg0, arg1 string) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "Notice", arg0, arg1)
|
||||
}
|
||||
|
||||
// Notice indicates an expected call of Notice
|
||||
func (mr *MockChangeNotifierMockRecorder) Notice(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Notice", reflect.TypeOf((*MockChangeNotifier)(nil).Notice), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpdateMessage mocks base method
|
||||
func (m *MockChangeNotifier) UpdateMessage(arg0, arg1 string, arg2, arg3 uint32, arg4 *pmapi.Message, arg5 bool) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "UpdateMessage", arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
}
|
||||
|
||||
// UpdateMessage indicates an expected call of UpdateMessage
|
||||
func (mr *MockChangeNotifierMockRecorder) UpdateMessage(arg0, arg1, arg2, arg3, arg4, arg5 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateMessage", reflect.TypeOf((*MockChangeNotifier)(nil).UpdateMessage), arg0, arg1, arg2, arg3, arg4, arg5)
|
||||
}
|
||||
|
||||
@ -26,7 +26,6 @@ import (
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
imapBackend "github.com/emersion/go-imap/backend"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -100,12 +99,12 @@ type Store struct {
|
||||
|
||||
log *logrus.Entry
|
||||
|
||||
cache *Cache
|
||||
filePath string
|
||||
db *bolt.DB
|
||||
lock *sync.RWMutex
|
||||
addresses map[string]*Address
|
||||
imapUpdates chan imapBackend.Update
|
||||
cache *Cache
|
||||
filePath string
|
||||
db *bolt.DB
|
||||
lock *sync.RWMutex
|
||||
addresses map[string]*Address
|
||||
notifier ChangeNotifier
|
||||
|
||||
isSyncRunning bool
|
||||
syncCooldown cooldown
|
||||
|
||||
@ -44,13 +44,14 @@ const (
|
||||
type mocksForStore struct {
|
||||
tb testing.TB
|
||||
|
||||
ctrl *gomock.Controller
|
||||
events *storemocks.MockListener
|
||||
user *storemocks.MockBridgeUser
|
||||
client *pmapimocks.MockClient
|
||||
clientManager *storemocks.MockClientManager
|
||||
panicHandler *storemocks.MockPanicHandler
|
||||
store *Store
|
||||
ctrl *gomock.Controller
|
||||
events *storemocks.MockListener
|
||||
user *storemocks.MockBridgeUser
|
||||
client *pmapimocks.MockClient
|
||||
clientManager *storemocks.MockClientManager
|
||||
panicHandler *storemocks.MockPanicHandler
|
||||
changeNotifier *storemocks.MockChangeNotifier
|
||||
store *Store
|
||||
|
||||
tmpDir string
|
||||
cache *Cache
|
||||
@ -59,13 +60,14 @@ type mocksForStore struct {
|
||||
func initMocks(tb testing.TB) (*mocksForStore, func()) {
|
||||
ctrl := gomock.NewController(tb)
|
||||
mocks := &mocksForStore{
|
||||
tb: tb,
|
||||
ctrl: ctrl,
|
||||
events: storemocks.NewMockListener(ctrl),
|
||||
user: storemocks.NewMockBridgeUser(ctrl),
|
||||
client: pmapimocks.NewMockClient(ctrl),
|
||||
clientManager: storemocks.NewMockClientManager(ctrl),
|
||||
panicHandler: storemocks.NewMockPanicHandler(ctrl),
|
||||
tb: tb,
|
||||
ctrl: ctrl,
|
||||
events: storemocks.NewMockListener(ctrl),
|
||||
user: storemocks.NewMockBridgeUser(ctrl),
|
||||
client: pmapimocks.NewMockClient(ctrl),
|
||||
clientManager: storemocks.NewMockClientManager(ctrl),
|
||||
panicHandler: storemocks.NewMockPanicHandler(ctrl),
|
||||
changeNotifier: storemocks.NewMockChangeNotifier(ctrl),
|
||||
}
|
||||
|
||||
// Called during clean-up.
|
||||
|
||||
Reference in New Issue
Block a user