Tests and final touches

This commit is contained in:
Michal Horejsek
2021-01-04 15:03:49 +01:00
parent 8ab852277c
commit 6ef2bb254d
24 changed files with 316 additions and 93 deletions

View File

@ -82,22 +82,92 @@ func TestEventLoopUpdateMessageFromLoop(t *testing.T) {
Subject: subject,
})
testEvent(t, m, &pmapi.Event{
EventID: "event1",
Messages: []*pmapi.EventMessage{{
EventItem: pmapi.EventItem{
ID: "msg1",
Action: pmapi.EventUpdate,
},
Updated: &pmapi.EventMessageUpdated{
ID: "msg1",
Subject: &newSubject,
},
}},
})
msg, err := m.store.getMessageFromDB("msg1")
require.NoError(t, err)
require.Equal(t, newSubject, msg.Subject)
}
func TestEventLoopDeletionNotPaused(t *testing.T) {
m, clear := initMocks(t)
defer clear()
m.newStoreNoEvents(true, &pmapi.Message{
ID: "msg1",
Subject: "subject",
LabelIDs: []string{"label"},
})
m.changeNotifier.EXPECT().CanDelete("label").Return(true, func() {})
m.store.SetChangeNotifier(m.changeNotifier)
testEvent(t, m, &pmapi.Event{
EventID: "event1",
Messages: []*pmapi.EventMessage{{
EventItem: pmapi.EventItem{
ID: "msg1",
Action: pmapi.EventDelete,
},
}},
})
_, err := m.store.getMessageFromDB("msg1")
require.Error(t, err)
}
func TestEventLoopDeletionPaused(t *testing.T) {
m, clear := initMocks(t)
defer clear()
m.newStoreNoEvents(true, &pmapi.Message{
ID: "msg1",
Subject: "subject",
LabelIDs: []string{"label"},
})
delay := 5 * time.Second
m.changeNotifier.EXPECT().CanDelete("label").Return(false, func() {
time.Sleep(delay)
})
m.changeNotifier.EXPECT().CanDelete("label").Return(true, func() {})
m.store.SetChangeNotifier(m.changeNotifier)
start := time.Now()
testEvent(t, m, &pmapi.Event{
EventID: "event1",
Messages: []*pmapi.EventMessage{{
EventItem: pmapi.EventItem{
ID: "msg1",
Action: pmapi.EventDelete,
},
}},
})
_, err := m.store.getMessageFromDB("msg1")
require.Error(t, err)
require.True(t, time.Since(start) > delay)
}
func testEvent(t *testing.T, m *mocksForStore, event *pmapi.Event) {
eventReceived := make(chan struct{})
m.client.EXPECT().GetEvent("latestEventID").DoAndReturn(func(eventID string) (*pmapi.Event, error) {
defer close(eventReceived)
return &pmapi.Event{
EventID: "event1",
Messages: []*pmapi.EventMessage{{
EventItem: pmapi.EventItem{
ID: "msg1",
Action: pmapi.EventUpdate,
},
Updated: &pmapi.EventMessageUpdated{
ID: "msg1",
Subject: &newSubject,
},
}},
}, nil
return event, nil
})
// Event loop runs in goroutine started during store creation (newStoreNoEvents).
@ -109,10 +179,6 @@ func TestEventLoopUpdateMessageFromLoop(t *testing.T) {
case <-time.After(5 * time.Second):
require.Fail(t, "latestEventID was not processed")
}
msg, err := m.store.getMessageFromDB("msg1")
require.NoError(t, err)
require.Equal(t, newSubject, msg.Subject)
}
func TestEventLoopUpdateMessage(t *testing.T) {

View File

@ -20,7 +20,7 @@ package store
import (
"net/mail"
backendMessage "github.com/ProtonMail/proton-bridge/pkg/message"
pkgMsg "github.com/ProtonMail/proton-bridge/pkg/message"
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
bolt "go.etcd.io/bbolt"
)
@ -121,8 +121,8 @@ func (message *Message) SetContentTypeAndHeader(mimeType string, header mail.Hea
return message.store.db.Update(txUpdate)
}
// SetBodyStructure stores serialized body structure in database
func (message *Message) SetBodyStructure(bs *backendMessage.BodyStructure) error {
// SetBodyStructure stores serialized body structure in database.
func (message *Message) SetBodyStructure(bs *pkgMsg.BodyStructure) error {
txUpdate := func(tx *bolt.Tx) error {
return message.store.txPutBodyStructure(
tx.Bucket(bodystructureBucket),
@ -132,10 +132,10 @@ func (message *Message) SetBodyStructure(bs *backendMessage.BodyStructure) error
return message.store.db.Update(txUpdate)
}
// GetBodyStructure deserialize body structure from database. If body structure
// GetBodyStructure deserializes body structure from database. If body structure
// is not in database it returns nil error and nil body structure. If error
// occurs it returns nil body structure.
func (message *Message) GetBodyStructure() (bs *backendMessage.BodyStructure, err error) {
func (message *Message) GetBodyStructure() (bs *pkgMsg.BodyStructure, err error) {
txRead := func(tx *bolt.Tx) error {
bs, err = message.store.txGetBodyStructure(
tx.Bucket(bodystructureBucket),

View File

@ -51,6 +51,8 @@ var (
// Database structure:
// * metadata
// * {messageID} -> message data (subject, from, to, time, headers, body size, ...)
// * bodystructure
// * {messageID} -> message body structure
// * counts
// * {mailboxID} -> mailboxCounts: totalOnAPI, unreadOnAPI, labelName, labelColor, labelIsExclusive
// * address_info

View File

@ -103,7 +103,7 @@ func (mocks *mocksForStore) newStoreNoEvents(combinedMode bool, msgs ...*pmapi.M
{ID: addrID1, Email: addr1, Type: pmapi.OriginalAddress, Receive: pmapi.CanReceive},
{ID: addrID2, Email: addr2, Type: pmapi.AliasAddress, Receive: pmapi.CanReceive},
})
mocks.client.EXPECT().ListLabels()
mocks.client.EXPECT().ListLabels().AnyTimes()
mocks.client.EXPECT().CountMessages("")
// Call to get latest event ID and then to process first event.

View File

@ -27,7 +27,7 @@ import (
"strings"
"github.com/ProtonMail/gopenpgp/v2/crypto"
backendMessage "github.com/ProtonMail/proton-bridge/pkg/message"
pkgMsg "github.com/ProtonMail/proton-bridge/pkg/message"
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -171,7 +171,7 @@ func (store *Store) txPutMessage(metaBucket *bolt.Bucket, onlyMeta *pmapi.Messag
return nil
}
func (store *Store) txPutBodyStructure(bsBucket *bolt.Bucket, msgID string, bs *backendMessage.BodyStructure) error {
func (store *Store) txPutBodyStructure(bsBucket *bolt.Bucket, msgID string, bs *pkgMsg.BodyStructure) error {
raw, err := bs.Serialize()
if err != nil {
return err
@ -183,12 +183,12 @@ func (store *Store) txPutBodyStructure(bsBucket *bolt.Bucket, msgID string, bs *
return nil
}
func (store *Store) txGetBodyStructure(bsBucket *bolt.Bucket, msgID string) (*backendMessage.BodyStructure, error) {
func (store *Store) txGetBodyStructure(bsBucket *bolt.Bucket, msgID string) (*pkgMsg.BodyStructure, error) {
raw := bsBucket.Get([]byte(msgID))
if len(raw) == 0 {
return nil, nil
}
return backendMessage.DeserializeBodyStructure(raw)
return pkgMsg.DeserializeBodyStructure(raw)
}
// createOrUpdateMessageEvent is helper to create only one message with