mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-10 12:46:46 +00:00
test: fix flaky tests.
This commit is contained in:
@ -99,7 +99,7 @@ test-linux:
|
|||||||
- .rules-branch-manual-MR-and-devel-always
|
- .rules-branch-manual-MR-and-devel-always
|
||||||
- .after-script-code-coverage
|
- .after-script-code-coverage
|
||||||
tags:
|
tags:
|
||||||
- medium
|
- large
|
||||||
|
|
||||||
test-linux-race:
|
test-linux-race:
|
||||||
extends:
|
extends:
|
||||||
|
|||||||
6
Makefile
6
Makefile
@ -228,13 +228,13 @@ change-copyright-year:
|
|||||||
./utils/missing_license.sh change-year
|
./utils/missing_license.sh change-year
|
||||||
|
|
||||||
test: gofiles
|
test: gofiles
|
||||||
go test -v -timeout=10m -p=1 -count=1 -coverprofile=/tmp/coverage.out -run=${TESTRUN} ./internal/... ./pkg/...
|
go test -v -timeout=20m -p=1 -count=1 -coverprofile=/tmp/coverage.out -run=${TESTRUN} ./internal/... ./pkg/...
|
||||||
|
|
||||||
test-race: gofiles
|
test-race: gofiles
|
||||||
go test -v -timeout=30m -p=1 -count=1 -race -failfast -run=${TESTRUN} ./internal/... ./pkg/...
|
go test -v -timeout=40m -p=1 -count=1 -race -failfast -run=${TESTRUN} ./internal/... ./pkg/...
|
||||||
|
|
||||||
test-integration: gofiles
|
test-integration: gofiles
|
||||||
go test -v -timeout=30m -p=1 -count=1 github.com/ProtonMail/proton-bridge/v3/tests
|
go test -v -timeout=60m -p=1 -count=1 github.com/ProtonMail/proton-bridge/v3/tests
|
||||||
|
|
||||||
test-integration-debug: gofiles
|
test-integration-debug: gofiles
|
||||||
dlv test github.com/ProtonMail/proton-bridge/v3/tests -- -test.v -test.timeout=10m -test.parallel=1 -test.count=1
|
dlv test github.com/ProtonMail/proton-bridge/v3/tests -- -test.v -test.timeout=10m -test.parallel=1 -test.count=1
|
||||||
|
|||||||
@ -50,7 +50,6 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/v3/tests"
|
"github.com/ProtonMail/proton-bridge/v3/tests"
|
||||||
"github.com/bradenaw/juniper/xslices"
|
"github.com/bradenaw/juniper/xslices"
|
||||||
imapid "github.com/emersion/go-imap-id"
|
imapid "github.com/emersion/go-imap-id"
|
||||||
"github.com/emersion/go-imap/client"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -182,14 +181,18 @@ func TestBridge_UserAgent_Persistence(t *testing.T) {
|
|||||||
imapWaiter := waitForIMAPServerReady(b)
|
imapWaiter := waitForIMAPServerReady(b)
|
||||||
defer imapWaiter.Done()
|
defer imapWaiter.Done()
|
||||||
|
|
||||||
|
smtpWaiter := waitForSMTPServerReady(b)
|
||||||
|
defer smtpWaiter.Done()
|
||||||
|
|
||||||
require.NoError(t, getErr(b.LoginFull(ctx, otherUser, otherPassword, nil, nil)))
|
require.NoError(t, getErr(b.LoginFull(ctx, otherUser, otherPassword, nil, nil)))
|
||||||
|
|
||||||
imapWaiter.Wait()
|
imapWaiter.Wait()
|
||||||
|
smtpWaiter.Wait()
|
||||||
|
|
||||||
currentUserAgent := b.GetCurrentUserAgent()
|
currentUserAgent := b.GetCurrentUserAgent()
|
||||||
require.Contains(t, currentUserAgent, vault.DefaultUserAgent)
|
require.Contains(t, currentUserAgent, vault.DefaultUserAgent)
|
||||||
|
|
||||||
imapClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
imapClient, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer func() { _ = imapClient.Logout() }()
|
defer func() { _ = imapClient.Logout() }()
|
||||||
|
|
||||||
@ -241,11 +244,15 @@ func TestBridge_UserAgentFromIMAPID(t *testing.T) {
|
|||||||
imapWaiter := waitForIMAPServerReady(b)
|
imapWaiter := waitForIMAPServerReady(b)
|
||||||
defer imapWaiter.Done()
|
defer imapWaiter.Done()
|
||||||
|
|
||||||
|
smtpWaiter := waitForSMTPServerReady(b)
|
||||||
|
defer smtpWaiter.Done()
|
||||||
|
|
||||||
require.NoError(t, getErr(b.LoginFull(ctx, otherUser, otherPassword, nil, nil)))
|
require.NoError(t, getErr(b.LoginFull(ctx, otherUser, otherPassword, nil, nil)))
|
||||||
|
|
||||||
imapWaiter.Wait()
|
imapWaiter.Wait()
|
||||||
|
smtpWaiter.Wait()
|
||||||
|
|
||||||
imapClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
imapClient, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
defer func() { _ = imapClient.Logout() }()
|
defer func() { _ = imapClient.Logout() }()
|
||||||
|
|
||||||
@ -619,6 +626,9 @@ func TestBridge_LoginFailed(t *testing.T) {
|
|||||||
imapWaiter := waitForIMAPServerReady(bridge)
|
imapWaiter := waitForIMAPServerReady(bridge)
|
||||||
defer imapWaiter.Done()
|
defer imapWaiter.Done()
|
||||||
|
|
||||||
|
smtpWaiter := waitForSMTPServerReady(bridge)
|
||||||
|
defer smtpWaiter.Done()
|
||||||
|
|
||||||
failCh, done := chToType[events.Event, events.IMAPLoginFailed](bridge.GetEvents(events.IMAPLoginFailed{}))
|
failCh, done := chToType[events.Event, events.IMAPLoginFailed](bridge.GetEvents(events.IMAPLoginFailed{}))
|
||||||
defer done()
|
defer done()
|
||||||
|
|
||||||
@ -626,8 +636,9 @@ func TestBridge_LoginFailed(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
imapWaiter.Wait()
|
imapWaiter.Wait()
|
||||||
|
smtpWaiter.Wait()
|
||||||
|
|
||||||
imapClient, err := client.Dial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
imapClient, err := eventuallyDial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
require.Error(t, imapClient.Login("badUser", "badPass"))
|
require.Error(t, imapClient.Login("badUser", "badPass"))
|
||||||
@ -657,6 +668,9 @@ func TestBridge_ChangeCacheDirectory(t *testing.T) {
|
|||||||
imapWaiter := waitForIMAPServerReady(b)
|
imapWaiter := waitForIMAPServerReady(b)
|
||||||
defer imapWaiter.Done()
|
defer imapWaiter.Done()
|
||||||
|
|
||||||
|
smtpWaiter := waitForSMTPServerReady(b)
|
||||||
|
defer smtpWaiter.Done()
|
||||||
|
|
||||||
// Login the user.
|
// Login the user.
|
||||||
syncCh, done := chToType[events.Event, events.SyncFinished](b.GetEvents(events.SyncFinished{}))
|
syncCh, done := chToType[events.Event, events.SyncFinished](b.GetEvents(events.SyncFinished{}))
|
||||||
defer done()
|
defer done()
|
||||||
@ -691,8 +705,9 @@ func TestBridge_ChangeCacheDirectory(t *testing.T) {
|
|||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
imapWaiter.Wait()
|
imapWaiter.Wait()
|
||||||
|
smtpWaiter.Wait()
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
@ -732,7 +747,7 @@ func TestBridge_ChangeAddressOrder(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
@ -753,7 +768,7 @@ func TestBridge_ChangeAddressOrder(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
@ -990,6 +1005,14 @@ func waitForSMTPServerReady(b *bridge.Bridge) *eventWaiter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func waitForSMTPServerStopped(b *bridge.Bridge) *eventWaiter {
|
||||||
|
evtCh, cancel := b.GetEvents(events.SMTPServerStopped{})
|
||||||
|
return &eventWaiter{
|
||||||
|
evtCh: evtCh,
|
||||||
|
cancel: cancel,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func waitForIMAPServerReady(b *bridge.Bridge) *eventWaiter {
|
func waitForIMAPServerReady(b *bridge.Bridge) *eventWaiter {
|
||||||
evtCh, cancel := b.GetEvents(events.IMAPServerReady{})
|
evtCh, cancel := b.GetEvents(events.IMAPServerReady{})
|
||||||
return &eventWaiter{
|
return &eventWaiter{
|
||||||
|
|||||||
@ -28,7 +28,6 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
||||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||||
"github.com/bradenaw/juniper/iterator"
|
"github.com/bradenaw/juniper/iterator"
|
||||||
"github.com/emersion/go-imap/client"
|
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
@ -66,7 +65,7 @@ func TestBridge_Refresh(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
@ -99,7 +98,7 @@ func TestBridge_Refresh(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
|
|||||||
@ -34,7 +34,6 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
||||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||||
"github.com/emersion/go-imap"
|
"github.com/emersion/go-imap"
|
||||||
"github.com/emersion/go-imap/client"
|
|
||||||
"github.com/emersion/go-sasl"
|
"github.com/emersion/go-sasl"
|
||||||
"github.com/emersion/go-smtp"
|
"github.com/emersion/go-smtp"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -96,13 +95,13 @@ func TestBridge_Send(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect the sender IMAP client.
|
// Connect the sender IMAP client.
|
||||||
senderIMAPClient, err := client.Dial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
senderIMAPClient, err := eventuallyDial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, senderIMAPClient.Login(senderInfo.Addresses[0], string(senderInfo.BridgePass)))
|
require.NoError(t, senderIMAPClient.Login(senderInfo.Addresses[0], string(senderInfo.BridgePass)))
|
||||||
defer senderIMAPClient.Logout() //nolint:errcheck
|
defer senderIMAPClient.Logout() //nolint:errcheck
|
||||||
|
|
||||||
// Connect the recipient IMAP client.
|
// Connect the recipient IMAP client.
|
||||||
recipientIMAPClient, err := client.Dial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
recipientIMAPClient, err := eventuallyDial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, recipientIMAPClient.Login(recipientInfo.Addresses[0], string(recipientInfo.BridgePass)))
|
require.NoError(t, recipientIMAPClient.Login(recipientInfo.Addresses[0], string(recipientInfo.BridgePass)))
|
||||||
defer recipientIMAPClient.Logout() //nolint:errcheck
|
defer recipientIMAPClient.Logout() //nolint:errcheck
|
||||||
@ -146,7 +145,7 @@ func TestBridge_SendDraftFlags(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Connect the sender IMAP client.
|
// Connect the sender IMAP client.
|
||||||
imapClient, err := client.Dial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
imapClient, err := eventuallyDial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, imapClient.Login(userInfo.Addresses[0], string(userInfo.BridgePass)))
|
require.NoError(t, imapClient.Login(userInfo.Addresses[0], string(userInfo.BridgePass)))
|
||||||
defer imapClient.Logout() //nolint:errcheck
|
defer imapClient.Logout() //nolint:errcheck
|
||||||
@ -256,7 +255,7 @@ func TestBridge_SendInvite(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Connect the sender IMAP client.
|
// Connect the sender IMAP client.
|
||||||
imapClient, err := client.Dial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
imapClient, err := eventuallyDial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, imapClient.Login(userInfo.Addresses[0], string(userInfo.BridgePass)))
|
require.NoError(t, imapClient.Login(userInfo.Addresses[0], string(userInfo.BridgePass)))
|
||||||
defer imapClient.Logout() //nolint:errcheck
|
defer imapClient.Logout() //nolint:errcheck
|
||||||
@ -454,13 +453,13 @@ SGVsbG8gd29ybGQK
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Connect the sender IMAP client.
|
// Connect the sender IMAP client.
|
||||||
senderIMAPClient, err := client.Dial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
senderIMAPClient, err := eventuallyDial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, senderIMAPClient.Login(senderInfo.Addresses[0], string(senderInfo.BridgePass)))
|
require.NoError(t, senderIMAPClient.Login(senderInfo.Addresses[0], string(senderInfo.BridgePass)))
|
||||||
defer senderIMAPClient.Logout() //nolint:errcheck
|
defer senderIMAPClient.Logout() //nolint:errcheck
|
||||||
|
|
||||||
// Connect the recipient IMAP client.
|
// Connect the recipient IMAP client.
|
||||||
recipientIMAPClient, err := client.Dial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
recipientIMAPClient, err := eventuallyDial(net.JoinHostPort(constants.Host, fmt.Sprint(bridge.GetIMAPPort())))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, recipientIMAPClient.Login(recipientInfo.Addresses[0], string(recipientInfo.BridgePass)))
|
require.NoError(t, recipientIMAPClient.Login(recipientInfo.Addresses[0], string(recipientInfo.BridgePass)))
|
||||||
defer recipientIMAPClient.Logout() //nolint:errcheck
|
defer recipientIMAPClient.Logout() //nolint:errcheck
|
||||||
|
|||||||
@ -27,14 +27,13 @@ import (
|
|||||||
"github.com/ProtonMail/proton-bridge/v3/internal/bridge"
|
"github.com/ProtonMail/proton-bridge/v3/internal/bridge"
|
||||||
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
||||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||||
"github.com/emersion/go-imap/client"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestServerManager_NoLoadedUsersNoServers(t *testing.T) {
|
func TestServerManager_NoLoadedUsersNoServers(t *testing.T) {
|
||||||
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
|
withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) {
|
||||||
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
|
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
|
||||||
_, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
_, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -113,7 +112,7 @@ func TestServerManager_ServersDoNotStopWhenThereIsStillOneActiveUser(t *testing.
|
|||||||
|
|
||||||
waitForEvent(t, evtCh, events.UserDeauth{})
|
waitForEvent(t, evtCh, events.UserDeauth{})
|
||||||
|
|
||||||
imapClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
imapClient, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, imapClient.Logout())
|
require.NoError(t, imapClient.Logout())
|
||||||
})
|
})
|
||||||
@ -138,7 +137,7 @@ func TestServerManager_ServersStartIfAtLeastOneUserIsLoggedIn(t *testing.T) {
|
|||||||
require.NoError(t, s.RevokeUser(userIDOther))
|
require.NoError(t, s.RevokeUser(userIDOther))
|
||||||
|
|
||||||
withBridgeWaitForServers(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
|
withBridgeWaitForServers(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) {
|
||||||
imapClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
imapClient, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, imapClient.Logout())
|
require.NoError(t, imapClient.Logout())
|
||||||
})
|
})
|
||||||
@ -151,21 +150,30 @@ func TestServerManager_NetworkLossStopsServers(t *testing.T) {
|
|||||||
imapWaiter := waitForIMAPServerReady(bridge)
|
imapWaiter := waitForIMAPServerReady(bridge)
|
||||||
defer imapWaiter.Done()
|
defer imapWaiter.Done()
|
||||||
|
|
||||||
|
smtpWaiter := waitForSMTPServerReady(bridge)
|
||||||
|
defer smtpWaiter.Done()
|
||||||
|
|
||||||
imapWaiterStop := waitForIMAPServerStopped(bridge)
|
imapWaiterStop := waitForIMAPServerStopped(bridge)
|
||||||
defer imapWaiterStop.Done()
|
defer imapWaiterStop.Done()
|
||||||
|
|
||||||
|
smtpWaiterStop := waitForSMTPServerStopped(bridge)
|
||||||
|
defer smtpWaiterStop.Done()
|
||||||
|
|
||||||
_, err := bridge.LoginFull(ctx, username, password, nil, nil)
|
_, err := bridge.LoginFull(ctx, username, password, nil, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
imapWaiter.Wait()
|
imapWaiter.Wait()
|
||||||
|
smtpWaiter.Wait()
|
||||||
|
|
||||||
netCtl.Disable()
|
netCtl.Disable()
|
||||||
|
|
||||||
imapWaiterStop.Wait()
|
imapWaiterStop.Wait()
|
||||||
|
smtpWaiterStop.Wait()
|
||||||
|
|
||||||
netCtl.Enable()
|
netCtl.Enable()
|
||||||
|
|
||||||
imapWaiter.Wait()
|
imapWaiter.Wait()
|
||||||
|
smtpWaiter.Wait()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -80,7 +80,7 @@ func TestBridge_Sync(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
@ -127,7 +127,7 @@ func TestBridge_Sync(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
@ -178,7 +178,7 @@ func _TestBridge_Sync_BadMessage(t *testing.T) { //nolint:unused,deadcode
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
@ -293,7 +293,7 @@ func TestBridge_SyncWithOngoingEvents(t *testing.T) {
|
|||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, info.State == bridge.Connected)
|
require.True(t, info.State == bridge.Connected)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
client, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = client.Logout() }()
|
||||||
|
|||||||
@ -444,14 +444,14 @@ func TestBridge_User_DropConn_NoBadEvent(t *testing.T) {
|
|||||||
info, err := bridge.QueryUserInfo("user")
|
info, err := bridge.QueryUserInfo("user")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
cli, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, cli.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = cli.Logout() }()
|
||||||
|
|
||||||
// The IMAP client will eventually see 20 messages.
|
// The IMAP client will eventually see 20 messages.
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
status, err := client.Status("INBOX", []imap.StatusItem{imap.StatusMessages})
|
status, err := cli.Status("INBOX", []imap.StatusItem{imap.StatusMessages})
|
||||||
return err == nil && status.Messages == 20
|
return err == nil && status.Messages == 20
|
||||||
}, 10*time.Second, 100*time.Millisecond)
|
}, 10*time.Second, 100*time.Millisecond)
|
||||||
})
|
})
|
||||||
@ -645,12 +645,12 @@ func TestBridge_User_SendDraftRemoveDraftFlag(t *testing.T) {
|
|||||||
info, err := bridge.QueryUserInfo("user")
|
info, err := bridge.QueryUserInfo("user")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
cli, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, cli.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = cli.Logout() }()
|
||||||
|
|
||||||
messages, err := clientFetch(client, "Drafts")
|
messages, err := clientFetch(cli, "Drafts")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, messages, 1)
|
require.Len(t, messages, 1)
|
||||||
require.Contains(t, messages[0].Flags, imap.DraftFlag)
|
require.Contains(t, messages[0].Flags, imap.DraftFlag)
|
||||||
@ -684,12 +684,12 @@ func TestBridge_User_SendDraftRemoveDraftFlag(t *testing.T) {
|
|||||||
info, err := bridge.QueryUserInfo("user")
|
info, err := bridge.QueryUserInfo("user")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
cli, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, cli.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = cli.Logout() }()
|
||||||
|
|
||||||
messages, err := clientFetch(client, "Sent")
|
messages, err := clientFetch(cli, "Sent")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Len(t, messages, 1)
|
require.Len(t, messages, 1)
|
||||||
require.NotContains(t, messages[0].Flags, imap.DraftFlag)
|
require.NotContains(t, messages[0].Flags, imap.DraftFlag)
|
||||||
@ -781,17 +781,21 @@ func TestBridge_User_HandleParentLabelRename(t *testing.T) {
|
|||||||
imapWaiter := waitForIMAPServerReady(bridge)
|
imapWaiter := waitForIMAPServerReady(bridge)
|
||||||
defer imapWaiter.Done()
|
defer imapWaiter.Done()
|
||||||
|
|
||||||
|
smtpWaiter := waitForSMTPServerReady(bridge)
|
||||||
|
defer smtpWaiter.Done()
|
||||||
|
|
||||||
require.NoError(t, getErr(bridge.LoginFull(ctx, username, password, nil, nil)))
|
require.NoError(t, getErr(bridge.LoginFull(ctx, username, password, nil, nil)))
|
||||||
|
|
||||||
info, err := bridge.QueryUserInfo(username)
|
info, err := bridge.QueryUserInfo(username)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
imapWaiter.Wait()
|
imapWaiter.Wait()
|
||||||
|
smtpWaiter.Wait()
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
cli, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, cli.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = cli.Logout() }()
|
||||||
|
|
||||||
withClient(ctx, t, s, username, password, func(ctx context.Context, c *proton.Client) {
|
withClient(ctx, t, s, username, password, func(ctx context.Context, c *proton.Client) {
|
||||||
parentName := uuid.NewString()
|
parentName := uuid.NewString()
|
||||||
@ -807,7 +811,7 @@ func TestBridge_User_HandleParentLabelRename(t *testing.T) {
|
|||||||
|
|
||||||
// Wait for the parent folder to be created.
|
// Wait for the parent folder to be created.
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
return xslices.IndexFunc(clientList(client), func(mailbox *imap.MailboxInfo) bool {
|
return xslices.IndexFunc(clientList(cli), func(mailbox *imap.MailboxInfo) bool {
|
||||||
return mailbox.Name == fmt.Sprintf("Folders/%v", parentName)
|
return mailbox.Name == fmt.Sprintf("Folders/%v", parentName)
|
||||||
}) >= 0
|
}) >= 0
|
||||||
}, 100*user.EventPeriod, user.EventPeriod)
|
}, 100*user.EventPeriod, user.EventPeriod)
|
||||||
@ -824,7 +828,7 @@ func TestBridge_User_HandleParentLabelRename(t *testing.T) {
|
|||||||
|
|
||||||
// Wait for the parent folder to be created.
|
// Wait for the parent folder to be created.
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
return xslices.IndexFunc(clientList(client), func(mailbox *imap.MailboxInfo) bool {
|
return xslices.IndexFunc(clientList(cli), func(mailbox *imap.MailboxInfo) bool {
|
||||||
return mailbox.Name == fmt.Sprintf("Folders/%v/%v", parentName, childName)
|
return mailbox.Name == fmt.Sprintf("Folders/%v/%v", parentName, childName)
|
||||||
}) >= 0
|
}) >= 0
|
||||||
}, 100*user.EventPeriod, user.EventPeriod)
|
}, 100*user.EventPeriod, user.EventPeriod)
|
||||||
@ -839,14 +843,14 @@ func TestBridge_User_HandleParentLabelRename(t *testing.T) {
|
|||||||
|
|
||||||
// Wait for the parent folder to be renamed.
|
// Wait for the parent folder to be renamed.
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
return xslices.IndexFunc(clientList(client), func(mailbox *imap.MailboxInfo) bool {
|
return xslices.IndexFunc(clientList(cli), func(mailbox *imap.MailboxInfo) bool {
|
||||||
return mailbox.Name == fmt.Sprintf("Folders/%v", newParentName)
|
return mailbox.Name == fmt.Sprintf("Folders/%v", newParentName)
|
||||||
}) >= 0
|
}) >= 0
|
||||||
}, 100*user.EventPeriod, user.EventPeriod)
|
}, 100*user.EventPeriod, user.EventPeriod)
|
||||||
|
|
||||||
// Wait for the child folder to be renamed.
|
// Wait for the child folder to be renamed.
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
return xslices.IndexFunc(clientList(client), func(mailbox *imap.MailboxInfo) bool {
|
return xslices.IndexFunc(clientList(cli), func(mailbox *imap.MailboxInfo) bool {
|
||||||
return mailbox.Name == fmt.Sprintf("Folders/%v/%v", newParentName, childName)
|
return mailbox.Name == fmt.Sprintf("Folders/%v/%v", newParentName, childName)
|
||||||
}) >= 0
|
}) >= 0
|
||||||
}, 100*user.EventPeriod, user.EventPeriod)
|
}, 100*user.EventPeriod, user.EventPeriod)
|
||||||
@ -898,10 +902,10 @@ func userContinueEventProcess(
|
|||||||
info, err := bridge.QueryUserInfo("user")
|
info, err := bridge.QueryUserInfo("user")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
cli, err := eventuallyDial(fmt.Sprintf("%v:%v", constants.Host, bridge.GetIMAPPort()))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NoError(t, client.Login(info.Addresses[0], string(info.BridgePass)))
|
require.NoError(t, cli.Login(info.Addresses[0], string(info.BridgePass)))
|
||||||
defer func() { _ = client.Logout() }()
|
defer func() { _ = cli.Logout() }()
|
||||||
|
|
||||||
randomLabel := uuid.NewString()
|
randomLabel := uuid.NewString()
|
||||||
|
|
||||||
@ -916,8 +920,21 @@ func userContinueEventProcess(
|
|||||||
|
|
||||||
// Wait for the label to be created.
|
// Wait for the label to be created.
|
||||||
require.Eventually(t, func() bool {
|
require.Eventually(t, func() bool {
|
||||||
return xslices.IndexFunc(clientList(client), func(mailbox *imap.MailboxInfo) bool {
|
return xslices.IndexFunc(clientList(cli), func(mailbox *imap.MailboxInfo) bool {
|
||||||
return mailbox.Name == "Labels/"+randomLabel
|
return mailbox.Name == "Labels/"+randomLabel
|
||||||
}) >= 0
|
}) >= 0
|
||||||
}, 100*user.EventPeriod, user.EventPeriod)
|
}, 100*user.EventPeriod, user.EventPeriod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func eventuallyDial(addr string) (cli *client.Client, err error) {
|
||||||
|
var sleep = 1 * time.Second
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
cli, err := client.Dial(addr)
|
||||||
|
if err == nil {
|
||||||
|
return cli, nil
|
||||||
|
}
|
||||||
|
time.Sleep(sleep)
|
||||||
|
sleep *= 2
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("after 5 attempts, last error: %s", err)
|
||||||
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ package tests
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
||||||
"github.com/emersion/go-imap/client"
|
"github.com/emersion/go-imap/client"
|
||||||
@ -29,14 +30,14 @@ func (t *testCtx) newIMAPClient(userID, clientID string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *testCtx) newIMAPClientOnPort(userID, clientID string, imapPort int) error {
|
func (t *testCtx) newIMAPClientOnPort(userID, clientID string, imapPort int) error {
|
||||||
client, err := client.Dial(fmt.Sprintf("%v:%d", constants.Host, imapPort))
|
cli, err := eventuallyDial(fmt.Sprintf("%v:%d", constants.Host, imapPort))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
t.imapClients[clientID] = &imapClient{
|
t.imapClients[clientID] = &imapClient{
|
||||||
userID: userID,
|
userID: userID,
|
||||||
client: client,
|
client: cli,
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -45,3 +46,16 @@ func (t *testCtx) newIMAPClientOnPort(userID, clientID string, imapPort int) err
|
|||||||
func (t *testCtx) getIMAPClient(clientID string) (string, *client.Client) {
|
func (t *testCtx) getIMAPClient(clientID string) (string, *client.Client) {
|
||||||
return t.imapClients[clientID].userID, t.imapClients[clientID].client
|
return t.imapClients[clientID].userID, t.imapClients[clientID].client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func eventuallyDial(addr string) (cli *client.Client, err error) {
|
||||||
|
var sleep = 1 * time.Second
|
||||||
|
for i := 0; i < 5; i++ {
|
||||||
|
cli, err := client.Dial(addr)
|
||||||
|
if err == nil {
|
||||||
|
return cli, nil
|
||||||
|
}
|
||||||
|
time.Sleep(sleep)
|
||||||
|
sleep *= 2
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("after 5 attempts, last error: %s", err)
|
||||||
|
}
|
||||||
|
|||||||
@ -169,6 +169,7 @@ type testCtx struct {
|
|||||||
dummyListeners []net.Listener
|
dummyListeners []net.Listener
|
||||||
|
|
||||||
imapServerStarted bool
|
imapServerStarted bool
|
||||||
|
smtpServerStarted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type imapClient struct {
|
type imapClient struct {
|
||||||
|
|||||||
@ -1,7 +1,9 @@
|
|||||||
Feature: Send Telemetry Heartbeat
|
Feature: Send Telemetry Heartbeat
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user1]" and password "password"
|
Given there exists an account with username "[user:user1]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
|
|
||||||
Scenario: Send at first start - one user default settings
|
Scenario: Send at first start - one user default settings
|
||||||
|
|||||||
@ -4,9 +4,11 @@ Feature: A user can authenticate an IMAP client
|
|||||||
And there exists an account with username "[user:user2]" and password "password2"
|
And there exists an account with username "[user:user2]" and password "password2"
|
||||||
And the account "[user:user]" has additional address "[alias:alias]@[domain]"
|
And the account "[user:user]" has additional address "[alias:alias]@[domain]"
|
||||||
And the account "[user:user2]" has additional disabled address "[alias:alias2]@[domain]"
|
And the account "[user:user2]" has additional disabled address "[alias:alias2]@[domain]"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user logs in with username "[user:user2]" and password "password2"
|
And the user logs in with username "[user:user2]" and password "password2"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: IMAP client can authenticate successfully
|
Scenario: IMAP client can authenticate successfully
|
||||||
When user "[user:user]" connects IMAP client "1"
|
When user "[user:user]" connects IMAP client "1"
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
Feature: The IMAP ID is propagated to bridge
|
Feature: The IMAP ID is propagated to bridge
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Initial user agent before an IMAP client announces its ID
|
Scenario: Initial user agent before an IMAP client announces its ID
|
||||||
When user "[user:user]" connects IMAP client "1"
|
When user "[user:user]" connects IMAP client "1"
|
||||||
|
|||||||
@ -7,10 +7,12 @@ Feature: IMAP create mailbox
|
|||||||
| f2 | folder |
|
| f2 | folder |
|
||||||
| l1 | label |
|
| l1 | label |
|
||||||
| l2 | label |
|
| l2 | label |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Create folder
|
Scenario: Create folder
|
||||||
When IMAP client "1" creates "Folders/mbox"
|
When IMAP client "1" creates "Folders/mbox"
|
||||||
|
|||||||
@ -6,10 +6,12 @@ Feature: IMAP delete mailbox
|
|||||||
| one | folder |
|
| one | folder |
|
||||||
| two | folder |
|
| two | folder |
|
||||||
| three | label |
|
| three | label |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Delete folder
|
Scenario: Delete folder
|
||||||
When IMAP client "1" deletes "Folders/one"
|
When IMAP client "1" deletes "Folders/one"
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
Feature: IMAP Hide All Mail
|
Feature: IMAP Hide All Mail
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Hide All Mail Mailbox
|
Scenario: Hide All Mail Mailbox
|
||||||
Given IMAP client "1" eventually sees the following mailbox info:
|
Given IMAP client "1" eventually sees the following mailbox info:
|
||||||
|
|||||||
@ -8,9 +8,11 @@ Feature: IMAP get mailbox info
|
|||||||
| from | to | subject | unread |
|
| from | to | subject | unread |
|
||||||
| a@example.com | a@example.com | one | true |
|
| a@example.com | a@example.com | one | true |
|
||||||
| b@example.com | b@example.com | two | false |
|
| b@example.com | b@example.com | two | false |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Mailbox status reports correct name, total and unread
|
Scenario: Mailbox status reports correct name, total and unread
|
||||||
When user "[user:user]" connects and authenticates IMAP client "1"
|
When user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
|||||||
@ -5,11 +5,13 @@ Feature: IMAP list mailboxes
|
|||||||
| name | type |
|
| name | type |
|
||||||
| mbox1 | folder |
|
| mbox1 | folder |
|
||||||
| mbox2 | label |
|
| mbox2 | label |
|
||||||
|
Then it succeeds
|
||||||
When bridge starts
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
Then IMAP client "1" eventually sees the following mailbox info:
|
Then it succeeds
|
||||||
|
And IMAP client "1" eventually sees the following mailbox info:
|
||||||
| name |
|
| name |
|
||||||
| INBOX |
|
| INBOX |
|
||||||
| Drafts |
|
| Drafts |
|
||||||
|
|||||||
@ -5,10 +5,12 @@ Feature: IMAP get mailbox info
|
|||||||
| name | type |
|
| name | type |
|
||||||
| f1 | folder |
|
| f1 | folder |
|
||||||
| l1 | label |
|
| l1 | label |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Rename folder
|
Scenario: Rename folder
|
||||||
When IMAP client "1" renames "Folders/f1" to "Folders/f2"
|
When IMAP client "1" renames "Folders/f1" to "Folders/f2"
|
||||||
|
|||||||
@ -5,10 +5,12 @@ Feature: IMAP get mailbox info
|
|||||||
| name | type |
|
| name | type |
|
||||||
| f1 | folder |
|
| f1 | folder |
|
||||||
| f1/f2| folder |
|
| f1/f2| folder |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Rename folder with subfolders
|
Scenario: Rename folder with subfolders
|
||||||
When IMAP client "1" renames "Folders/f1" to "Folders/f3"
|
When IMAP client "1" renames "Folders/f1" to "Folders/f3"
|
||||||
|
|||||||
@ -5,10 +5,12 @@ Feature: IMAP select mailbox
|
|||||||
| name | type |
|
| name | type |
|
||||||
| mbox | folder |
|
| mbox | folder |
|
||||||
| label | label |
|
| label | label |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Select inbox
|
Scenario: Select inbox
|
||||||
When IMAP client "1" selects "INBOX"
|
When IMAP client "1" selects "INBOX"
|
||||||
|
|||||||
@ -9,10 +9,12 @@ Feature: IMAP copy messages
|
|||||||
| from | to | subject | unread |
|
| from | to | subject | unread |
|
||||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Copy message to label
|
Scenario: Copy message to label
|
||||||
When IMAP client "1" copies the message with subject "foo" from "INBOX" to "Labels/label"
|
When IMAP client "1" copies the message with subject "foo" from "INBOX" to "Labels/label"
|
||||||
|
|||||||
@ -2,10 +2,12 @@ Feature: IMAP create messages
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And the account "[user:user]" has additional address "[alias:alias]@[domain]"
|
And the account "[user:user]" has additional address "[alias:alias]@[domain]"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Creates message to user's primary address
|
Scenario: Creates message to user's primary address
|
||||||
When IMAP client "1" appends the following messages to "INBOX":
|
When IMAP client "1" appends the following messages to "INBOX":
|
||||||
|
|||||||
@ -7,10 +7,12 @@ Feature: IMAP remove messages from mailbox
|
|||||||
| label | label |
|
| label | label |
|
||||||
And the address "[user:user]@[domain]" of account "[user:user]" has 10 messages in "Folders/mbox"
|
And the address "[user:user]@[domain]" of account "[user:user]" has 10 messages in "Folders/mbox"
|
||||||
And the address "[user:user]@[domain]" of account "[user:user]" has 1 messages in "Scheduled"
|
And the address "[user:user]@[domain]" of account "[user:user]" has 1 messages in "Scheduled"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Mark message as deleted and EXPUNGE
|
Scenario: Mark message as deleted and EXPUNGE
|
||||||
When IMAP client "1" selects "Folders/mbox"
|
When IMAP client "1" selects "Folders/mbox"
|
||||||
|
|||||||
@ -5,6 +5,7 @@ Feature: IMAP remove messages from Trash
|
|||||||
| name | type |
|
| name | type |
|
||||||
| mbox | folder |
|
| mbox | folder |
|
||||||
| label | label |
|
| label | label |
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario Outline: Message in Trash and some other label is not permanently deleted
|
Scenario Outline: Message in Trash and some other label is not permanently deleted
|
||||||
Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash":
|
Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash":
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
Feature: IMAP Draft messages
|
Feature: IMAP Draft messages
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
@ -11,12 +12,13 @@ Feature: IMAP Draft messages
|
|||||||
|
|
||||||
This is a dra
|
This is a dra
|
||||||
"""
|
"""
|
||||||
And it succeeds
|
Then it succeeds
|
||||||
Then IMAP client "1" eventually sees the following messages in "Drafts":
|
And IMAP client "1" eventually sees the following messages in "Drafts":
|
||||||
| body |
|
| body |
|
||||||
| This is a dra |
|
| This is a dra |
|
||||||
And IMAP client "1" eventually sees 1 messages in "Drafts"
|
And IMAP client "1" eventually sees 1 messages in "Drafts"
|
||||||
|
|
||||||
|
|
||||||
Scenario: Draft edited locally
|
Scenario: Draft edited locally
|
||||||
When IMAP client "1" marks message 1 as deleted
|
When IMAP client "1" marks message 1 as deleted
|
||||||
And IMAP client "1" expunges
|
And IMAP client "1" expunges
|
||||||
|
|||||||
@ -7,10 +7,12 @@ Feature: IMAP Fetch
|
|||||||
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Inbox":
|
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Inbox":
|
||||||
| from | to | subject | date |
|
| from | to | subject | date |
|
||||||
| john.doe@mail.com | [user:user]@[domain] | foo | 13 Jul 69 00:00 +0000 |
|
| john.doe@mail.com | [user:user]@[domain] | foo | 13 Jul 69 00:00 +0000 |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Fetch very old message
|
Scenario: Fetch very old message
|
||||||
Given IMAP client "1" eventually sees the following messages in "INBOX":
|
Given IMAP client "1" eventually sees the following messages in "INBOX":
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
Feature: IMAP import messages
|
Feature: IMAP import messages
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Basic message import
|
Scenario: Basic message import
|
||||||
When IMAP client "1" appends the following message to "INBOX":
|
When IMAP client "1" appends the following message to "INBOX":
|
||||||
|
|||||||
@ -19,10 +19,12 @@ Feature: IMAP move messages
|
|||||||
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Scheduled":
|
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Scheduled":
|
||||||
| from | to | subject | unread |
|
| from | to | subject | unread |
|
||||||
| john.doe@mail.com | [user:user]@[domain] | sch | false |
|
| john.doe@mail.com | [user:user]@[domain] | sch | false |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Move message from folder to label (keeps in folder)
|
Scenario: Move message from folder to label (keeps in folder)
|
||||||
When IMAP client "1" moves the message with subject "foo" from "INBOX" to "Labels/label"
|
When IMAP client "1" moves the message with subject "foo" from "INBOX" to "Labels/label"
|
||||||
|
|||||||
@ -4,11 +4,13 @@ Feature: IMAP move messages by append and delete (without MOVE support, e.g., Ou
|
|||||||
And the account "[user:user]" has the following custom mailboxes:
|
And the account "[user:user]" has the following custom mailboxes:
|
||||||
| name | type |
|
| name | type |
|
||||||
| mbox | folder |
|
| mbox | folder |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
And user "[user:user]" connects and authenticates IMAP client "source"
|
And user "[user:user]" connects and authenticates IMAP client "source"
|
||||||
And user "[user:user]" connects and authenticates IMAP client "target"
|
And user "[user:user]" connects and authenticates IMAP client "target"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario Outline: Move message from <srcMailbox> to <dstMailbox> by <order>
|
Scenario Outline: Move message from <srcMailbox> to <dstMailbox> by <order>
|
||||||
When IMAP client "source" appends the following message to "<srcMailbox>":
|
When IMAP client "source" appends the following message to "<srcMailbox>":
|
||||||
|
|||||||
@ -7,10 +7,11 @@ Feature: Bridge can fully sync an account
|
|||||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||||
And the account "[user:user]" has 20 custom folders
|
And the account "[user:user]" has 20 custom folders
|
||||||
And the account "[user:user]" has 60 custom labels
|
And the account "[user:user]" has 60 custom labels
|
||||||
|
Then it succeeds
|
||||||
When bridge starts
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
When user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
Then IMAP client "1" counts 20 mailboxes under "Folders"
|
Then IMAP client "1" counts 20 mailboxes under "Folders"
|
||||||
And IMAP client "1" counts 60 mailboxes under "Labels"
|
And IMAP client "1" counts 60 mailboxes under "Labels"
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
Feature: A user can connect an IMAP client to custom ports
|
Feature: A user can connect an IMAP client to custom ports
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user changes the IMAP port to 1144
|
And the user changes the IMAP port to 1144
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Authenticates successfully on custom port
|
Scenario: Authenticates successfully on custom port
|
||||||
When user "[user:user]" connects IMAP client "1" on port 1144
|
When user "[user:user]" connects IMAP client "1" on port 1144
|
||||||
|
|||||||
@ -6,10 +6,12 @@ Feature: A user can authenticate an SMTP client
|
|||||||
And the account "[user:user]" has additional address "[alias:alias]@[domain]"
|
And the account "[user:user]" has additional address "[alias:alias]@[domain]"
|
||||||
And the account "[user:user2]" has additional disabled address "[alias:alias2]@[domain]"
|
And the account "[user:user2]" has additional disabled address "[alias:alias2]@[domain]"
|
||||||
And the account "[user:user3]" has additional address "[alias:alias3]@[domain]"
|
And the account "[user:user3]" has additional address "[alias:alias3]@[domain]"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user logs in with username "[user:user2]" and password "password2"
|
And the user logs in with username "[user:user2]" and password "password2"
|
||||||
And the user logs in with username "[user:user3]" and password "password3"
|
And the user logs in with username "[user:user3]" and password "password3"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: SMTP client can authenticate successfully
|
Scenario: SMTP client can authenticate successfully
|
||||||
When user "[user:user]" connects SMTP client "1"
|
When user "[user:user]" connects SMTP client "1"
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
Feature: SMTP initiation
|
Feature: SMTP initiation
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
When user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Send without first announcing FROM and TO
|
Scenario: Send without first announcing FROM and TO
|
||||||
When SMTP client "1" sends DATA:
|
When SMTP client "1" sends DATA:
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
Feature: A user can connect an SMTP client to custom ports
|
Feature: A user can connect an SMTP client to custom ports
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user changes the SMTP port to 1144
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Authenticates successfully on custom port
|
Scenario: Authenticates successfully on custom port
|
||||||
|
When the user changes the SMTP port to 1144
|
||||||
When user "[user:user]" connects SMTP client "1" on port 1144
|
When user "[user:user]" connects SMTP client "1" on port 1144
|
||||||
Then SMTP client "1" can authenticate
|
Then SMTP client "1" can authenticate
|
||||||
@ -1,12 +1,14 @@
|
|||||||
Feature: SMTP with bcc
|
Feature: SMTP with bcc
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
Given there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
Given there exists an account with username "[user:bcc]" and password "password"
|
And there exists an account with username "[user:bcc]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user logs in with username "[user:bcc]" and password "password"
|
And the user logs in with username "[user:bcc]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Send message to address in to and bcc
|
Scenario: Send message to address in to and bcc
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain], [user:bcc]@[domain]":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain], [user:bcc]@[domain]":
|
||||||
|
|||||||
@ -2,10 +2,12 @@ Feature: SMTP sending embedded message
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user logs in with username "[user:to]" and password "password"
|
And the user logs in with username "[user:to]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
@long-black
|
@long-black
|
||||||
Scenario: Send it
|
Scenario: Send it
|
||||||
|
|||||||
@ -2,9 +2,11 @@ Feature: SMTP wrong messages
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Message with attachment and wrong boundaries
|
Scenario: Message with attachment and wrong boundaries
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||||
|
|||||||
@ -2,9 +2,11 @@ Feature: SMTP sending of plain messages
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: HTML message to external account
|
Scenario: HTML message to external account
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "pm.bridge.qa@gmail.com":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "pm.bridge.qa@gmail.com":
|
||||||
|
|||||||
@ -2,9 +2,11 @@ Feature: SMTP sending of plain messages
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: HTML message with attachment to internal account
|
Scenario: HTML message with attachment to internal account
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||||
|
|||||||
@ -2,9 +2,11 @@ Feature: SMTP messages containing inlines
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: A message with inline attachment to internal account
|
Scenario: A message with inline attachment to internal account
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||||
|
|||||||
@ -2,9 +2,11 @@ Feature: SMTP sending with mixed case address
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Mixed sender case in sender address
|
Scenario: Mixed sender case in sender address
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||||
|
|||||||
@ -2,9 +2,11 @@ Feature: SMTP sending two messages
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:recp]" and password "password"
|
And there exists an account with username "[user:recp]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user logs in with username "[user:recp]" and password "password"
|
And the user logs in with username "[user:recp]" and password "password"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
|
|
||||||
@long-black
|
@long-black
|
||||||
|
|||||||
@ -3,9 +3,11 @@ Feature: SMTP sending of plain messages
|
|||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And there exists an account with username "[user:cc]" and password "password"
|
And there exists an account with username "[user:cc]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Only from and to headers to internal account
|
Scenario: Only from and to headers to internal account
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||||
|
|||||||
@ -2,9 +2,11 @@ Feature: SMTP sending of plain messages
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Basic message with attachment to internal account
|
Scenario: Basic message with attachment to internal account
|
||||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||||
|
|||||||
@ -2,7 +2,8 @@ Feature: SMTP sending the same message twice
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user logs in with username "[user:to]" and password "password"
|
And the user logs in with username "[user:to]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
|||||||
@ -2,10 +2,12 @@ Feature: SMTP sending with APPENDing to Sent
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Send message and append to Sent
|
Scenario: Send message and append to Sent
|
||||||
# First do sending.
|
# First do sending.
|
||||||
|
|||||||
@ -3,11 +3,13 @@ Feature: SMTP send reply
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user1]" and password "password"
|
Given there exists an account with username "[user:user1]" and password "password"
|
||||||
And there exists an account with username "[user:user2]" and password "password"
|
And there exists an account with username "[user:user2]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user1]" and password "password"
|
And the user logs in with username "[user:user1]" and password "password"
|
||||||
And user "[user:user1]" finishes syncing
|
And user "[user:user1]" finishes syncing
|
||||||
And user "[user:user1]" connects and authenticates SMTP client "1"
|
And user "[user:user1]" connects and authenticates SMTP client "1"
|
||||||
And user "[user:user1]" connects and authenticates IMAP client "1"
|
And user "[user:user1]" connects and authenticates IMAP client "1"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
@long-black
|
@long-black
|
||||||
Scenario: Reply with In-Reply-To but no References
|
Scenario: Reply with In-Reply-To but no References
|
||||||
|
|||||||
@ -4,10 +4,12 @@ Feature: SMTP sending two messages
|
|||||||
And there exists an account with username "[user:multi]" and password "password"
|
And there exists an account with username "[user:multi]" and password "password"
|
||||||
And the account "[user:multi]" has additional address "[user:multi-alias]@[domain]"
|
And the account "[user:multi]" has additional address "[user:multi-alias]@[domain]"
|
||||||
And there exists an account with username "[user:to]" and password "password"
|
And there exists an account with username "[user:to]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And the user logs in with username "[user:multi]" and password "password"
|
And the user logs in with username "[user:multi]" and password "password"
|
||||||
And the user sets the address mode of user "[user:multi]" to "split"
|
And the user sets the address mode of user "[user:multi]" to "split"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Send two messages in one connection
|
Scenario: Send two messages in one connection
|
||||||
When user "[user:user]" connects and authenticates SMTP client "1"
|
When user "[user:user]" connects and authenticates SMTP client "1"
|
||||||
|
|||||||
@ -14,9 +14,11 @@ Feature: Address mode
|
|||||||
| from | to | subject | unread |
|
| from | to | subject | unread |
|
||||||
| c@[domain] | c@[domain] | three | true |
|
| c@[domain] | c@[domain] | three | true |
|
||||||
| d@[domain] | d@[domain] | four | false |
|
| d@[domain] | d@[domain] | four | false |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
And user "[user:user]" finishes syncing
|
And user "[user:user]" finishes syncing
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: The user is in combined mode
|
Scenario: The user is in combined mode
|
||||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
Feature: A user can be deleted
|
Feature: A user can be deleted
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Delete a connected user
|
Scenario: Delete a connected user
|
||||||
When user "[user:user]" is deleted
|
When user "[user:user]" is deleted
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
Feature: A user can login
|
Feature: A user can login
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
Given there exists an account with username "[user:MixedCaps]" and password "password"
|
And there exists an account with username "[user:MixedCaps]" and password "password"
|
||||||
Given there exists a disabled account with username "[user:disabled]" and password "password"
|
And there exists a disabled account with username "[user:disabled]" and password "password"
|
||||||
|
Then it succeeds
|
||||||
And bridge starts
|
And bridge starts
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Login to account
|
Scenario: Login to account
|
||||||
When the user logs in with username "[user:user]" and password "password"
|
When the user logs in with username "[user:user]" and password "password"
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
Feature: A logged out user can login again
|
Feature: A logged out user can login again
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: Login to disconnected account
|
Scenario: Login to disconnected account
|
||||||
When user "[user:user]" logs out
|
When user "[user:user]" logs out
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
Feature: A logged in user is logged out when its auth is revoked.
|
Feature: A logged in user is logged out when its auth is revoked.
|
||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user]" and password "password"
|
Given there exists an account with username "[user:user]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
And the user logs in with username "[user:user]" and password "password"
|
And the user logs in with username "[user:user]" and password "password"
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: The auth is revoked while bridge is running
|
Scenario: The auth is revoked while bridge is running
|
||||||
When the auth of user "[user:user]" is revoked
|
When the auth of user "[user:user]" is revoked
|
||||||
|
|||||||
@ -14,7 +14,9 @@ Feature: Bridge can fully sync an account
|
|||||||
| from | to | subject | unread |
|
| from | to | subject | unread |
|
||||||
| a@[domain] | a@[domain] | one | true |
|
| a@[domain] | a@[domain] | one | true |
|
||||||
| b@[domain] | b@[domain] | two | false |
|
| b@[domain] | b@[domain] | two | false |
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
Scenario: The account is synced when the user logs in and persists across bridge restarts
|
Scenario: The account is synced when the user logs in and persists across bridge restarts
|
||||||
When the user logs in with username "[user:user]" and password "password"
|
When the user logs in with username "[user:user]" and password "password"
|
||||||
|
|||||||
@ -2,7 +2,9 @@ Feature: Bridge send usage metrics
|
|||||||
Background:
|
Background:
|
||||||
Given there exists an account with username "[user:user1]" and password "password"
|
Given there exists an account with username "[user:user1]" and password "password"
|
||||||
And there exists an account with username "[user:user2]" and password "password"
|
And there exists an account with username "[user:user2]" and password "password"
|
||||||
And bridge starts
|
Then it succeeds
|
||||||
|
When bridge starts
|
||||||
|
Then it succeeds
|
||||||
|
|
||||||
|
|
||||||
Scenario: Telemetry availability - No user
|
Scenario: Telemetry availability - No user
|
||||||
|
|||||||
@ -332,8 +332,10 @@ func (s *scenario) drafAtIndexWasMovedToTrashForAddressOfAccount(draftIndex int,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *scenario) userLogsInWithUsernameAndPassword(username, password string) error {
|
func (s *scenario) userLogsInWithUsernameAndPassword(username, password string) error {
|
||||||
evtCh, cancel := s.t.bridge.GetEvents(events.SMTPServerReady{})
|
smtpEvtCh, cancelSMTP := s.t.bridge.GetEvents(events.SMTPServerReady{})
|
||||||
defer cancel()
|
defer cancelSMTP()
|
||||||
|
imapEvtCh, cancelIMAP := s.t.bridge.GetEvents(events.IMAPServerReady{})
|
||||||
|
defer cancelIMAP()
|
||||||
|
|
||||||
userID, err := s.t.bridge.LoginFull(context.Background(), username, []byte(password), nil, nil)
|
userID, err := s.t.bridge.LoginFull(context.Background(), username, []byte(password), nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -342,9 +344,13 @@ func (s *scenario) userLogsInWithUsernameAndPassword(username, password string)
|
|||||||
// We need to wait for server to be up or we won't be able to connect. It should only happen once to avoid
|
// We need to wait for server to be up or we won't be able to connect. It should only happen once to avoid
|
||||||
// blocking on multiple Logins.
|
// blocking on multiple Logins.
|
||||||
if !s.t.imapServerStarted {
|
if !s.t.imapServerStarted {
|
||||||
<-evtCh
|
<-imapEvtCh
|
||||||
s.t.imapServerStarted = true
|
s.t.imapServerStarted = true
|
||||||
}
|
}
|
||||||
|
if !s.t.smtpServerStarted {
|
||||||
|
<-smtpEvtCh
|
||||||
|
s.t.smtpServerStarted = true
|
||||||
|
}
|
||||||
|
|
||||||
if userID != s.t.getUserByName(username).getUserID() {
|
if userID != s.t.getUserByName(username).getUserID() {
|
||||||
return errors.New("user ID mismatch")
|
return errors.New("user ID mismatch")
|
||||||
|
|||||||
Reference in New Issue
Block a user