test: add test with changing address order
This commit is contained in:
parent
c61e8bdc71
commit
2d200f6f8c
2
go.mod
2
go.mod
|
@ -8,6 +8,7 @@ require (
|
|||
github.com/docker/docker-credential-helpers v0.0.0-00010101000000-000000000000
|
||||
github.com/emersion/go-smtp v0.0.0-20180712174835-db5eec195e67
|
||||
github.com/jameskeane/bcrypt v0.0.0-20170924085257-7509ea014998
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -61,7 +62,6 @@ require (
|
|||
github.com/twinj/uuid v1.0.0 // indirect
|
||||
github.com/urfave/cli v1.22.3
|
||||
go.etcd.io/bbolt v1.3.3
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
|
||||
golang.org/x/text v0.3.2
|
||||
gopkg.in/stretchr/testify.v1 v1.2.2 // indirect
|
||||
|
|
13
go.sum
13
go.sum
|
@ -7,16 +7,12 @@ github.com/ProtonMail/crypto v0.0.0-20190604143603-d3d8a14a4d4f h1:cFhATQTJGK2iZ
|
|||
github.com/ProtonMail/crypto v0.0.0-20190604143603-d3d8a14a4d4f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
github.com/ProtonMail/docker-credential-helpers v1.0.0 h1:0DQXbZNvUszWgXUuP7TzvQdwnkK1D5Zf/glBgCFJFCk=
|
||||
github.com/ProtonMail/docker-credential-helpers v1.0.0/go.mod h1:R1gQindzdYFcWJuuGXteYHDJzUCVtyU+EpEqp9aWcFs=
|
||||
github.com/ProtonMail/go-appdir v1.0.0 h1:PZXQ0HkveuEugga3LeDycxWtybrXQfKR0ThxURd6ojw=
|
||||
github.com/ProtonMail/go-appdir v1.0.0/go.mod h1:3d8Y9F5mbEUjrYbcJ3rcDxcWbqbttF+011nVZmdRdzc=
|
||||
github.com/ProtonMail/go-appdir v1.1.0 h1:9hdNDlU9kTqRKVNzmoqah8qqrj5QZyLByQdwQNlFWig=
|
||||
github.com/ProtonMail/go-appdir v1.1.0/go.mod h1:3d8Y9F5mbEUjrYbcJ3rcDxcWbqbttF+011nVZmdRdzc=
|
||||
github.com/ProtonMail/go-apple-mobileconfig v0.0.0-20160701194735-7ea9927a11f6 h1:YsSJ/mvZFYydQm/hRrt8R8UtgETixN2y3LK98f5LT60=
|
||||
github.com/ProtonMail/go-apple-mobileconfig v0.0.0-20160701194735-7ea9927a11f6/go.mod h1:EtDfBMIDWmVe4viZCuBTEfe3OIIo0ghbpOaAZVO+hVg=
|
||||
github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a h1:fXK2KsfnkBV9Nh+9SKzHchYjuE9s0vI20JG1mbtEAcc=
|
||||
github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4=
|
||||
github.com/ProtonMail/go-imap v0.0.0-20190327080220-0e686f0e855f h1:QkLm4yfhBQuBxrC46Vhy2sonOWVrwIJo5bgKpA82+TY=
|
||||
github.com/ProtonMail/go-imap v0.0.0-20190327080220-0e686f0e855f/go.mod h1:+m2uLXghuYktgE/vc5AkmCxx1qhu33ZKHFWg1cGZPD0=
|
||||
github.com/ProtonMail/go-imap-id v0.0.0-20190926060100-f94a56b9ecde h1:5koQozTDELymYOyFbQ/VSubexAEXzDR8qGM5mO8GRdw=
|
||||
github.com/ProtonMail/go-imap-id v0.0.0-20190926060100-f94a56b9ecde/go.mod h1:795VPXcRUIQ9JyMNHP4el582VokQfippgjkQP3Gk0r0=
|
||||
github.com/ProtonMail/go-mime v0.0.0-20190521135552-09454e3dbe72 h1:hGCc4Oc2fD3I5mNnZ1VlREncVc9EXJF8dxW3sw16gWM=
|
||||
|
@ -52,17 +48,14 @@ github.com/danieljoos/wincred v1.0.2/go.mod h1:SnuYRW9lp1oJrZX/dXJqr0cPK5gYXqx3E
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emersion/go-imap v0.0.0-20171113213225-939ec3994dbe h1:iAEcORtl7uQrqv7iRXGUqLqfXDcTGtXnvow31KkCmm8=
|
||||
github.com/emersion/go-imap v0.0.0-20171113213225-939ec3994dbe/go.mod h1:oydmHwiyv92ZOiNfQY9BDax5heePWN8P2+W1B2T6qjc=
|
||||
github.com/emersion/go-imap v0.0.0-20200415151653-89df427d2794 h1:tlFeCqKFZOhJaxW6ttvR6HWkYmQj4i+UR8cCzsx/Gis=
|
||||
github.com/emersion/go-imap v0.0.0-20200415151653-89df427d2794/go.mod h1:yKASt+C3ZiDAiCSssxg9caIckWF/JG7ZQTO7GAmvicU=
|
||||
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a h1:bMdSPm6sssuOFpIaveu3XGAijMS3Tq2S3EqFZmZxidc=
|
||||
github.com/emersion/go-imap-appendlimit v0.0.0-20190308131241-25671c986a6a/go.mod h1:ikgISoP7pRAolqsVP64yMteJa2FIpS6ju88eBT6K1yQ=
|
||||
github.com/emersion/go-imap-idle v0.0.0-20190519112320-2704abd7050e h1:L7bswVJZcf2YHofgom49oFRwVqmBj/qZqDy9/SJpZMY=
|
||||
github.com/emersion/go-imap-idle v0.0.0-20190519112320-2704abd7050e/go.mod h1:o14zPKCmEH5WC1vU5SdPoZGgNvQx7zzKSnxPQlobo78=
|
||||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342 h1:5p1t3e1PomYgLWwEwhwEU5kVBwcyAcVrOpexv8AeZx0=
|
||||
github.com/emersion/go-imap-move v0.0.0-20190710073258-6e5a51a5b342/go.mod h1:QuMaZcKFDVI0yCrnAbPLfbwllz1wtOrZH8/vZ5yzp4w=
|
||||
github.com/emersion/go-imap-quota v0.0.0-20171113212021-e883a2bc54d6 h1:CQ9z5Gk5HBUI8+kM5XNZXUoAv8RF1GnXmYrN4OkDvZU=
|
||||
github.com/emersion/go-imap-quota v0.0.0-20171113212021-e883a2bc54d6/go.mod h1:iApyhIQBiU4XFyr+3kdJyyGqle82TbQyuP2o+OZHrV0=
|
||||
github.com/emersion/go-imap-quota v0.0.0-20200423100218-dcfd1b7d2b41 h1:z5lDGnSURauBEDdNLj3o0+HogVYKQCGeY3Anl/xyRfU=
|
||||
github.com/emersion/go-imap-quota v0.0.0-20200423100218-dcfd1b7d2b41/go.mod h1:iApyhIQBiU4XFyr+3kdJyyGqle82TbQyuP2o+OZHrV0=
|
||||
github.com/emersion/go-imap-specialuse v0.0.0-20161227184202-ba031ced6a62 h1:4ZAfwfc8aDlj26kkEap1UDSwwDnJp9Ie8Uj1MSXAkPk=
|
||||
|
@ -159,10 +152,6 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H
|
|||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41 h1:yBVcrpbaQYJBdKT2pxTdlL4hBE/eM4UPcyj9YpyvSok=
|
||||
github.com/therecipe/qt v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:SUUR2j3aE1z6/g76SdD6NwACEpvCxb3fvG82eKbD6us=
|
||||
github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41 h1:My9HYsfDI/fJPZGyilw6066buBiZ7pgKRRgAyvKK5lA=
|
||||
github.com/therecipe/qt/internal/binding/files/docs/5.12.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:7m8PDYDEtEVqfjoUQc2UrFqhG0CDmoVJjRlQxexndFc=
|
||||
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41 h1:jTzKrQ6EIPvKw1B9/wwoKJLrXF+ManMsXoUzufxAdsg=
|
||||
github.com/therecipe/qt/internal/binding/files/docs/5.13.0 v0.0.0-20200126204426-5074eb6d8c41/go.mod h1:mH55Ek7AZcdns5KPp99O0bg+78el64YCYWHiQKrOdt4=
|
||||
github.com/twinj/uuid v1.0.0 h1:fzz7COZnDrXGTAOHGuUGYd6sG+JMq+AoE7+Jlu0przk=
|
||||
github.com/twinj/uuid v1.0.0/go.mod h1:mMgcE1RHFUFqe5AfiwlINXisXfDGro23fWdPUfOMjRY=
|
||||
github.com/urfave/cli v1.22.3 h1:FpNT6zq26xNpHZy08emi755QwzLPs6Pukqjlc7RfOMU=
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Code generated by ./credits.sh at Fri Apr 24 08:21:38 CEST 2020. DO NOT EDIT.
|
||||
// Code generated by ./credits.sh at Wed May 6 07:17:01 CEST 2020. DO NOT EDIT.
|
||||
|
||||
package bridge
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ const pollIntervalSpread = 5 * time.Second
|
|||
type eventLoop struct {
|
||||
cache *Cache
|
||||
currentEventID string
|
||||
currentEvent *pmapi.Event
|
||||
pollCh chan chan struct{}
|
||||
stopCh chan struct{}
|
||||
notifyStopCh chan struct{}
|
||||
|
@ -136,13 +137,18 @@ func (loop *eventLoop) start() { // nolint[funlen]
|
|||
loop.log.WithField("lastEventID", loop.currentEventID).Warn("Subscription stopped")
|
||||
}()
|
||||
|
||||
t := time.NewTicker(pollInterval - pollIntervalSpread)
|
||||
defer t.Stop()
|
||||
|
||||
loop.hasInternet = true
|
||||
|
||||
go loop.pollNow()
|
||||
|
||||
loop.loop()
|
||||
}
|
||||
|
||||
// loop is the main body of the event loop.
|
||||
func (loop *eventLoop) loop() {
|
||||
t := time.NewTicker(pollInterval - pollIntervalSpread)
|
||||
defer t.Stop()
|
||||
|
||||
for {
|
||||
var eventProcessedCh chan struct{}
|
||||
select {
|
||||
|
@ -251,6 +257,8 @@ func (loop *eventLoop) processNextEvent() (more bool, err error) { // nolint[fun
|
|||
return false, errors.Wrap(err, "failed to get event")
|
||||
}
|
||||
|
||||
loop.currentEvent = event
|
||||
|
||||
if event == nil {
|
||||
return false, errors.New("received empty event")
|
||||
}
|
||||
|
|
|
@ -46,6 +46,11 @@ func (store *Store) TestGetEventLoop() *eventLoop { //nolint[golint]
|
|||
return store.eventLoop
|
||||
}
|
||||
|
||||
// TestGetLastEvent returns last event processed by the store's event loop.
|
||||
func (store *Store) TestGetLastEvent() *pmapi.Event { //nolint[golint]
|
||||
return store.eventLoop.currentEvent
|
||||
}
|
||||
|
||||
// TestGetStoreFilePath returns the filepath of the store's database file.
|
||||
func (store *Store) TestGetStoreFilePath() string {
|
||||
return store.filePath
|
||||
|
|
|
@ -174,6 +174,29 @@ func (c *client) GetAddresses() (addresses AddressList, err error) {
|
|||
return res.Addresses, res.Err()
|
||||
}
|
||||
|
||||
func (c *client) ReorderAddresses(addressIDs []string) (err error) {
|
||||
defer c.UpdateUser()
|
||||
|
||||
var reqBody struct {
|
||||
AddressIDs []string
|
||||
}
|
||||
|
||||
reqBody.AddressIDs = addressIDs
|
||||
|
||||
req, err := c.NewJSONRequest("PUT", "/addresses/order", reqBody)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var addContactsRes AddContactsResponse
|
||||
if err = c.DoJSON(req, &addContactsRes); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Addresses returns the addresses stored in the client object itself rather than fetching from the API.
|
||||
func (c *client) Addresses() AddressList {
|
||||
return c.addresses
|
||||
}
|
||||
|
|
|
@ -121,6 +121,7 @@ type Client interface {
|
|||
|
||||
GetAddresses() (addresses AddressList, err error)
|
||||
Addresses() AddressList
|
||||
ReorderAddresses(addressIDs []string) error
|
||||
|
||||
GetEvent(eventID string) (*Event, error)
|
||||
|
||||
|
|
|
@ -146,6 +146,10 @@ func (a *TestAccount) AddressID() string {
|
|||
return a.addressToBeUsed.ID
|
||||
}
|
||||
|
||||
func (a *TestAccount) GetAddressID(addressTestID string) string {
|
||||
return a.addressesByBDDAddressID[addressTestID].ID
|
||||
}
|
||||
|
||||
// EnsureAddressID accepts address (simply the address) or bddAddressID used
|
||||
// in tests (in format [bddAddressID]) and returns always the real address ID.
|
||||
// If the address is not found, the ID of main address is returned.
|
||||
|
@ -163,6 +167,10 @@ func (a *TestAccount) EnsureAddressID(addressOrAddressTestID string) string {
|
|||
return a.AddressID()
|
||||
}
|
||||
|
||||
func (a *TestAccount) GetAddress(addressTestID string) string {
|
||||
return a.addressesByBDDAddressID[addressTestID].Email
|
||||
}
|
||||
|
||||
// EnsureAddress accepts address (simply the address) or bddAddressID used
|
||||
// in tests (in format [bddAddressID]) and returns always the address.
|
||||
// If the address ID cannot be found, the original value is returned.
|
||||
|
|
|
@ -55,7 +55,8 @@ func (a *TestAccounts) GetTestAccount(username string) *TestAccount {
|
|||
return a.GetTestAccountWithAddress(username, "")
|
||||
}
|
||||
|
||||
func (a *TestAccounts) GetTestAccountWithAddress(username, addressID string) *TestAccount {
|
||||
// GetTestAccount returns the test account with the given username configured to use the given bddAddressID.
|
||||
func (a *TestAccounts) GetTestAccountWithAddress(username, bddAddressID string) *TestAccount {
|
||||
// Do lookup by full address and convert to name in tests.
|
||||
// Used by getting real data to ensure correct address or address ID.
|
||||
for key, user := range a.Users {
|
||||
|
@ -71,7 +72,7 @@ func (a *TestAccounts) GetTestAccountWithAddress(username, addressID string) *Te
|
|||
return newTestAccount(
|
||||
user,
|
||||
a.Addresses[user.Name],
|
||||
addressID,
|
||||
bddAddressID,
|
||||
a.Passwords[user.Name],
|
||||
a.MailboxPasswords[user.Name],
|
||||
a.TwoFAs[user.Name],
|
||||
|
|
|
@ -35,6 +35,7 @@ func BridgeActionsFeatureContext(s *godog.Suite) {
|
|||
s.Step(`^the internet connection is lost$`, theInternetConnectionIsLost)
|
||||
s.Step(`^the internet connection is restored$`, theInternetConnectionIsRestored)
|
||||
s.Step(`^(\d+) seconds pass$`, secondsPass)
|
||||
s.Step(`^"([^"]*)" swaps address "([^"]*)" with address "([^"]*)"$`, swapsAddressWithAddress)
|
||||
}
|
||||
|
||||
func bridgeStarts() error {
|
||||
|
@ -132,3 +133,32 @@ func secondsPass(seconds int) error {
|
|||
time.Sleep(time.Duration(seconds) * time.Second)
|
||||
return nil
|
||||
}
|
||||
|
||||
func swapsAddressWithAddress(bddUserID, bddAddressID1, bddAddressID2 string) error {
|
||||
account := ctx.GetTestAccount(bddUserID)
|
||||
if account == nil {
|
||||
return godog.ErrPending
|
||||
}
|
||||
|
||||
address1ID := account.GetAddressID(bddAddressID1)
|
||||
address2ID := account.GetAddressID(bddAddressID2)
|
||||
|
||||
var address1Index, address2Index int
|
||||
var addressIDs []string
|
||||
for i, v := range *account.Addresses() {
|
||||
if v.ID == address1ID {
|
||||
address1Index = i
|
||||
}
|
||||
if v.ID == address2ID {
|
||||
address2Index = i
|
||||
}
|
||||
addressIDs = append(addressIDs, v.ID)
|
||||
}
|
||||
|
||||
addressIDs[address1Index], addressIDs[address2Index] = addressIDs[address2Index], addressIDs[address1Index]
|
||||
|
||||
ctx.ReorderAddresses(account.Username(), bddAddressID1, bddAddressID2)
|
||||
ctx.GetPMAPIController().ReorderAddresses(account.User(), addressIDs)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ func (ctx *TestContext) GetTestAccount(bddUserID string) *accounts.TestAccount {
|
|||
return ctx.testAccounts.GetTestAccount(bddUserID)
|
||||
}
|
||||
|
||||
func (ctx *TestContext) GetTestAccountWithAddress(bddUserID, addressID string) *accounts.TestAccount {
|
||||
return ctx.testAccounts.GetTestAccountWithAddress(bddUserID, addressID)
|
||||
func (ctx *TestContext) GetTestAccountWithAddress(bddUserID, bddAddressID string) *accounts.TestAccount {
|
||||
return ctx.testAccounts.GetTestAccountWithAddress(bddUserID, bddAddressID)
|
||||
}
|
||||
|
||||
func (ctx *TestContext) EnsureAddressID(bddUserID, addressOrAddressTestID string) string {
|
||||
|
@ -55,3 +55,9 @@ func (ctx *TestContext) EnsureAddress(bddUserID, addressOrAddressTestID string)
|
|||
}
|
||||
return account.EnsureAddress(addressOrAddressTestID)
|
||||
}
|
||||
|
||||
func (ctx *TestContext) ReorderAddresses(userID, addressA, addressB string) {
|
||||
addresses := ctx.testAccounts.Addresses[userID]
|
||||
|
||||
addresses[addressA], addresses[addressB] = addresses[addressB], addresses[addressA]
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ type PMAPIController interface {
|
|||
GetLabelIDs(username string, labelNames []string) ([]string, error)
|
||||
AddUserMessage(username string, message *pmapi.Message) error
|
||||
GetMessageID(username, messageIndex string) string
|
||||
ReorderAddresses(user *pmapi.User, addressIDs []string) error
|
||||
PrintCalls()
|
||||
WasCalled(method, path string, expectedRequest []byte) bool
|
||||
GetCalls(method, path string) [][]byte
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package fakeapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -44,6 +45,15 @@ func (ctl *Controller) TurnInternetConnectionOn() {
|
|||
ctl.noInternetConnection = false
|
||||
}
|
||||
|
||||
func (ctl *Controller) ReorderAddresses(user *pmapi.User, addressIDs []string) error {
|
||||
api := ctl.getFakeAPIForUser(user.ID)
|
||||
if api == nil {
|
||||
return errors.New("no such user")
|
||||
}
|
||||
|
||||
return api.ReorderAddresses(addressIDs)
|
||||
}
|
||||
|
||||
func (ctl *Controller) AddUser(user *pmapi.User, addresses *pmapi.AddressList, password string, twoFAEnabled bool) error {
|
||||
ctl.usersByUsername[user.Name] = &fakeUser{
|
||||
user: user,
|
||||
|
@ -131,6 +141,15 @@ func (ctl *Controller) AddUserMessage(username string, message *pmapi.Message) e
|
|||
return nil
|
||||
}
|
||||
|
||||
func (ctl *Controller) getFakeAPIForUser(userID string) *FakePMAPI {
|
||||
for _, fakeAPI := range ctl.fakeAPIs {
|
||||
if fakeAPI.userID == userID {
|
||||
return fakeAPI
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctl *Controller) resetUsers() {
|
||||
for _, fakeAPI := range ctl.fakeAPIs {
|
||||
_ = fakeAPI.setUser(fakeAPI.username)
|
||||
|
|
|
@ -40,20 +40,24 @@ func (api *FakePMAPI) GetEvent(eventID string) (*pmapi.Event, error) {
|
|||
foundEvent = event
|
||||
continue
|
||||
}
|
||||
|
||||
if foundEvent != nil {
|
||||
mergedEvent.EventID = event.EventID
|
||||
mergedEvent.Refresh |= event.Refresh
|
||||
mergedEvent.Messages = append(mergedEvent.Messages, event.Messages...)
|
||||
mergedEvent.MessageCounts = append(mergedEvent.MessageCounts, event.MessageCounts...)
|
||||
mergedEvent.Labels = append(mergedEvent.Labels, event.Labels...)
|
||||
mergedEvent.Addresses = append(mergedEvent.Addresses, event.Addresses...)
|
||||
mergedEvent.Notices = append(mergedEvent.Notices, event.Notices...)
|
||||
mergedEvent.User = event.User
|
||||
}
|
||||
}
|
||||
|
||||
// If there isn't next event, return the same one.
|
||||
if mergedEvent.EventID == "" {
|
||||
return foundEvent, nil
|
||||
}
|
||||
|
||||
return mergedEvent, nil
|
||||
}
|
||||
|
||||
|
@ -103,6 +107,19 @@ func (api *FakePMAPI) addEventMessage(action pmapi.EventAction, message *pmapi.M
|
|||
})
|
||||
}
|
||||
|
||||
func (api *FakePMAPI) addEventAddress(action pmapi.EventAction, address *pmapi.Address) {
|
||||
api.addEvent(&pmapi.Event{
|
||||
EventID: api.eventIDGenerator.next("event"),
|
||||
Addresses: []*pmapi.EventAddress{{
|
||||
EventItem: pmapi.EventItem{
|
||||
ID: address.ID,
|
||||
Action: pmapi.EventUpdate,
|
||||
},
|
||||
Address: address,
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
func (api *FakePMAPI) addEvent(event *pmapi.Event) {
|
||||
api.events = append(api.events, event)
|
||||
}
|
||||
|
|
|
@ -57,6 +57,29 @@ func (api *FakePMAPI) GetAddresses() (pmapi.AddressList, error) {
|
|||
return *api.addresses, nil
|
||||
}
|
||||
|
||||
func (api *FakePMAPI) ReorderAddresses(addressIDs []string) error {
|
||||
if err := api.checkAndRecordCall(PUT, "/addresses/order", nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for wantedIndex, addressID := range addressIDs {
|
||||
var currentIndex int
|
||||
|
||||
for i, v := range *api.addresses {
|
||||
if v.ID == addressID {
|
||||
currentIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
(*api.addresses)[wantedIndex], (*api.addresses)[currentIndex] = (*api.addresses)[currentIndex], (*api.addresses)[wantedIndex]
|
||||
(*api.addresses)[wantedIndex].Order = wantedIndex + 1 // Starts counting from 1.
|
||||
api.addEventAddress(pmapi.EventUpdate, (*api.addresses)[wantedIndex])
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (api *FakePMAPI) Addresses() pmapi.AddressList {
|
||||
return *api.addresses
|
||||
}
|
||||
|
|
|
@ -44,3 +44,12 @@ Feature: Address mode
|
|||
| from | to | subject |
|
||||
| john.doe@mail.com | [primary] | foo |
|
||||
| jane.doe@mail.com | [secondary] | bar |
|
||||
|
||||
Scenario: Make secondary address primary in combined mode
|
||||
Given there is "userMoreAddresses" in "combined" address mode
|
||||
When "userMoreAddresses" swaps address "primary" with address "secondary"
|
||||
And "userMoreAddresses" receives an address event
|
||||
Then mailbox "Folders/mbox" for address "primary" of "userMoreAddresses" has messages
|
||||
| from | to | subject |
|
||||
| john.doe@mail.com | [primary] | foo |
|
||||
| jane.doe@mail.com | [secondary] | bar |
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
func cleanup(client pmapi.Client) error {
|
||||
func cleanup(client pmapi.Client, addresses *pmapi.AddressList) error {
|
||||
if err := cleanSystemFolders(client); err != nil {
|
||||
return errors.Wrap(err, "failed to clean system folders")
|
||||
}
|
||||
|
@ -34,6 +34,9 @@ func cleanup(client pmapi.Client) error {
|
|||
if err := cleanTrash(client); err != nil {
|
||||
return errors.Wrap(err, "failed to clean trash")
|
||||
}
|
||||
if err := reorderAddresses(client, addresses); err != nil {
|
||||
return errors.Wrap(err, "failed to clean trash")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -130,3 +133,13 @@ func emptyFolder(client pmapi.Client, labelID string) error {
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func reorderAddresses(client pmapi.Client, addresses *pmapi.AddressList) error {
|
||||
addressIDs := []string{}
|
||||
|
||||
for _, address := range *addresses {
|
||||
addressIDs = append(addressIDs, address.ID)
|
||||
}
|
||||
|
||||
return client.ReorderAddresses(addressIDs)
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func (ctl *Controller) AddUser(user *pmapi.User, addresses *pmapi.AddressList, p
|
|||
return errors.Wrap(err, "failed to unlock addresses")
|
||||
}
|
||||
|
||||
if err := cleanup(client); err != nil {
|
||||
if err := cleanup(client, addresses); err != nil {
|
||||
return errors.Wrap(err, "failed to clean user")
|
||||
}
|
||||
|
||||
|
@ -58,3 +58,9 @@ func (ctl *Controller) AddUser(user *pmapi.User, addresses *pmapi.AddressList, p
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctl *Controller) ReorderAddresses(user *pmapi.User, addressIDs []string) error {
|
||||
client := ctl.clientManager.GetClient(user.ID)
|
||||
|
||||
return client.ReorderAddresses(addressIDs)
|
||||
}
|
||||
|
|
|
@ -18,11 +18,15 @@
|
|||
package tests
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func StoreActionsFeatureContext(s *godog.Suite) {
|
||||
s.Step(`^the event loop of "([^"]*)" loops once$`, theEventLoopLoops)
|
||||
s.Step(`^"([^"]*)" receives an address event$`, receivesAnAddressEvent)
|
||||
}
|
||||
|
||||
func theEventLoopLoops(username string) error {
|
||||
|
@ -37,3 +41,19 @@ func theEventLoopLoops(username string) error {
|
|||
store.TestPollNow()
|
||||
return nil
|
||||
}
|
||||
|
||||
func receivesAnAddressEvent(username string) error {
|
||||
acc := ctx.GetTestAccount(username)
|
||||
if acc == nil {
|
||||
return godog.ErrPending
|
||||
}
|
||||
store, err := ctx.GetStore(acc.Username())
|
||||
if err != nil {
|
||||
return internalError(err, "getting store of user %s", username)
|
||||
}
|
||||
assert.Eventually(ctx.GetTestingT(), func() bool {
|
||||
store.TestPollNow()
|
||||
return len(store.TestGetLastEvent().Addresses) > 0
|
||||
}, 5*time.Second, time.Second)
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue