mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-11 05:06:51 +00:00
chore: merge branch release/perth_narrows to devel
This commit is contained in:
@ -162,7 +162,6 @@ func TestFeatures(testingT *testing.T) {
|
||||
ctx.Step(`^user "([^"]*)" logs out$`, s.userLogsOut)
|
||||
ctx.Step(`^user "([^"]*)" is deleted$`, s.userIsDeleted)
|
||||
ctx.Step(`^the auth of user "([^"]*)" is revoked$`, s.theAuthOfUserIsRevoked)
|
||||
ctx.Step(`^user "([^"]*)" is listed and connected$`, s.userIsListedAndConnected)
|
||||
ctx.Step(`^user "([^"]*)" is eventually listed and connected$`, s.userIsEventuallyListedAndConnected)
|
||||
ctx.Step(`^user "([^"]*)" is listed but not connected$`, s.userIsListedButNotConnected)
|
||||
ctx.Step(`^user "([^"]*)" is not listed$`, s.userIsNotListed)
|
||||
@ -184,7 +183,6 @@ func TestFeatures(testingT *testing.T) {
|
||||
ctx.Step(`^IMAP client "([^"]*)" creates "([^"]*)"$`, s.imapClientCreatesMailbox)
|
||||
ctx.Step(`^IMAP client "([^"]*)" deletes "([^"]*)"$`, s.imapClientDeletesMailbox)
|
||||
ctx.Step(`^IMAP client "([^"]*)" renames "([^"]*)" to "([^"]*)"$`, s.imapClientRenamesMailboxTo)
|
||||
ctx.Step(`^IMAP client "([^"]*)" sees the following mailbox info:$`, s.imapClientSeesTheFollowingMailboxInfo)
|
||||
ctx.Step(`^IMAP client "([^"]*)" eventually sees the following mailbox info:$`, s.imapClientEventuallySeesTheFollowingMailboxInfo)
|
||||
ctx.Step(`^IMAP client "([^"]*)" sees the following mailbox info for "([^"]*)":$`, s.imapClientSeesTheFollowingMailboxInfoForMailbox)
|
||||
ctx.Step(`^IMAP client "([^"]*)" sees "([^"]*)"$`, s.imapClientSeesMailbox)
|
||||
@ -195,9 +193,7 @@ func TestFeatures(testingT *testing.T) {
|
||||
ctx.Step(`^IMAP client "([^"]*)" copies all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientCopiesAllMessagesFromTo)
|
||||
ctx.Step(`^IMAP client "([^"]*)" moves the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesTheMessageWithSubjectFromTo)
|
||||
ctx.Step(`^IMAP client "([^"]*)" moves all messages from "([^"]*)" to "([^"]*)"$`, s.imapClientMovesAllMessagesFromTo)
|
||||
ctx.Step(`^IMAP client "([^"]*)" sees the following messages in "([^"]*)":$`, s.imapClientSeesTheFollowingMessagesInMailbox)
|
||||
ctx.Step(`^IMAP client "([^"]*)" eventually sees the following messages in "([^"]*)":$`, s.imapClientEventuallySeesTheFollowingMessagesInMailbox)
|
||||
ctx.Step(`^IMAP client "([^"]*)" sees (\d+) messages in "([^"]*)"$`, s.imapClientSeesMessagesInMailbox)
|
||||
ctx.Step(`^IMAP client "([^"]*)" eventually sees (\d+) messages in "([^"]*)"$`, s.imapClientEventuallySeesMessagesInMailbox)
|
||||
ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as deleted$`, s.imapClientMarksMessageAsDeleted)
|
||||
ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as deleted$`, s.imapClientMarksTheMessageWithSubjectAsDeleted)
|
||||
|
||||
@ -68,10 +68,10 @@ func (s *scenario) theUserChangesTheSMTPPortTo(port int) error {
|
||||
func (s *scenario) theUserSetsTheAddressModeOfUserTo(user, mode string) error {
|
||||
switch mode {
|
||||
case "split":
|
||||
return s.t.bridge.SetAddressMode(context.Background(), s.t.getUserID(user), vault.SplitMode)
|
||||
return s.t.bridge.SetAddressMode(context.Background(), s.t.getUserByName(user).getUserID(), vault.SplitMode)
|
||||
|
||||
case "combined":
|
||||
return s.t.bridge.SetAddressMode(context.Background(), s.t.getUserID(user), vault.CombinedMode)
|
||||
return s.t.bridge.SetAddressMode(context.Background(), s.t.getUserByName(user).getUserID(), vault.CombinedMode)
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown address mode %q", mode)
|
||||
@ -156,7 +156,7 @@ func (s *scenario) bridgeSendsADeauthEventForUser(username string) error {
|
||||
return errors.New("expected deauth event, got none")
|
||||
}
|
||||
|
||||
if wantUserID := s.t.getUserID(username); event.UserID != wantUserID {
|
||||
if wantUserID := s.t.getUserByName(username).getUserID(); event.UserID != wantUserID {
|
||||
return fmt.Errorf("expected deauth event for user %s, got %s", wantUserID, event.UserID)
|
||||
}
|
||||
|
||||
@ -169,7 +169,7 @@ func (s *scenario) bridgeSendsAnAddressCreatedEventForUser(username string) erro
|
||||
return errors.New("expected address created event, got none")
|
||||
}
|
||||
|
||||
if wantUserID := s.t.getUserID(username); event.UserID != wantUserID {
|
||||
if wantUserID := s.t.getUserByName(username).getUserID(); event.UserID != wantUserID {
|
||||
return fmt.Errorf("expected address created event for user %s, got %s", wantUserID, event.UserID)
|
||||
}
|
||||
|
||||
@ -182,7 +182,7 @@ func (s *scenario) bridgeSendsAnAddressDeletedEventForUser(username string) erro
|
||||
return errors.New("expected address deleted event, got none")
|
||||
}
|
||||
|
||||
if wantUserID := s.t.getUserID(username); event.UserID != wantUserID {
|
||||
if wantUserID := s.t.getUserByName(username).getUserID(); event.UserID != wantUserID {
|
||||
return fmt.Errorf("expected address deleted event for user %s, got %s", wantUserID, event.UserID)
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ func (s *scenario) bridgeSendsSyncStartedAndFinishedEventsForUser(username strin
|
||||
return errors.New("expected sync started event, got none")
|
||||
}
|
||||
|
||||
if wantUserID := s.t.getUserID(username); startEvent.UserID != wantUserID {
|
||||
if wantUserID := s.t.getUserByName(username).getUserID(); startEvent.UserID != wantUserID {
|
||||
return fmt.Errorf("expected sync started event for user %s, got %s", wantUserID, startEvent.UserID)
|
||||
}
|
||||
|
||||
@ -204,7 +204,7 @@ func (s *scenario) bridgeSendsSyncStartedAndFinishedEventsForUser(username strin
|
||||
return errors.New("expected sync finished event, got none")
|
||||
}
|
||||
|
||||
if wantUserID := s.t.getUserID(username); finishEvent.UserID != wantUserID {
|
||||
if wantUserID := s.t.getUserByName(username).getUserID(); finishEvent.UserID != wantUserID {
|
||||
return fmt.Errorf("expected sync finished event for user %s, got %s", wantUserID, finishEvent.UserID)
|
||||
}
|
||||
|
||||
|
||||
@ -29,12 +29,14 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
|
||||
"github.com/ProtonMail/gluon/imap"
|
||||
"github.com/ProtonMail/gluon/queue"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/bridge"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/constants"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/cookies"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/events"
|
||||
frontend "github.com/ProtonMail/proton-bridge/v3/internal/frontend/grpc"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/service"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/useragent"
|
||||
"github.com/ProtonMail/proton-bridge/v3/internal/vault"
|
||||
"github.com/sirupsen/logrus"
|
||||
@ -160,6 +162,7 @@ func (t *testCtx) initBridge() (<-chan events.Event, error) {
|
||||
t.mocks.ProxyCtl,
|
||||
t.mocks.CrashHandler,
|
||||
t.reporter,
|
||||
imap.DefaultEpochUIDValidityGenerator(),
|
||||
|
||||
// Logging stuff
|
||||
logIMAP,
|
||||
@ -260,7 +263,7 @@ func (t *testCtx) initFrontendClient() error {
|
||||
return fmt.Errorf("could not read grpcServerConfig.json: %w", err)
|
||||
}
|
||||
|
||||
var cfg frontend.Config
|
||||
var cfg service.Config
|
||||
|
||||
if err := json.Unmarshal(b, &cfg); err != nil {
|
||||
return fmt.Errorf("could not unmarshal grpcServerConfig.json: %w", err)
|
||||
|
||||
@ -20,6 +20,7 @@ package tests
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
|
||||
"github.com/ProtonMail/go-proton-api"
|
||||
@ -33,6 +34,7 @@ func (t *testCtx) withProton(fn func(*proton.Manager) error) error {
|
||||
proton.WithHostURL(t.api.GetHostURL()),
|
||||
proton.WithTransport(proton.InsecureTransport()),
|
||||
proton.WithAppVersion(t.api.GetAppVersion()),
|
||||
proton.WithDebug(os.Getenv("FEATURE_API_DEBUG") != ""),
|
||||
)
|
||||
defer m.Close()
|
||||
|
||||
@ -41,7 +43,7 @@ func (t *testCtx) withProton(fn func(*proton.Manager) error) error {
|
||||
|
||||
// withClient executes the given function with a client that is logged in as the given (known) user.
|
||||
func (t *testCtx) withClient(ctx context.Context, username string, fn func(context.Context, *proton.Client) error) error {
|
||||
return t.withClientPass(ctx, username, t.getUserPass(t.getUserID(username)), fn)
|
||||
return t.withClientPass(ctx, username, t.getUserByName(username).getUserPass(), fn)
|
||||
}
|
||||
|
||||
// withClient executes the given function with a client that is logged in with the given username and password.
|
||||
@ -106,7 +108,7 @@ func (t *testCtx) withAddrKR(
|
||||
return err
|
||||
}
|
||||
|
||||
keyPass, err := salt.SaltForKey([]byte(t.getUserPass(t.getUserID(username))), user.Keys.Primary().ID)
|
||||
keyPass, err := salt.SaltForKey([]byte(t.getUserByName(username).getUserPass()), user.Keys.Primary().ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -122,14 +124,19 @@ func (t *testCtx) withAddrKR(
|
||||
func (t *testCtx) createMessages(ctx context.Context, username, addrID string, req []proton.ImportReq) error {
|
||||
return t.withClient(ctx, username, func(ctx context.Context, c *proton.Client) error {
|
||||
return t.withAddrKR(ctx, c, username, addrID, func(ctx context.Context, addrKR *crypto.KeyRing) error {
|
||||
if _, err := stream.Collect(ctx, c.ImportMessages(
|
||||
str, err := c.ImportMessages(
|
||||
ctx,
|
||||
addrKR,
|
||||
runtime.NumCPU(),
|
||||
runtime.NumCPU(),
|
||||
req...,
|
||||
)); err != nil {
|
||||
return err
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare messages for import: %w", err)
|
||||
}
|
||||
|
||||
if _, err := stream.Collect(ctx, str); err != nil {
|
||||
return fmt.Errorf("failed to import messages: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -40,12 +40,85 @@ import (
|
||||
"github.com/emersion/go-imap/client"
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/exp/maps"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var defaultVersion = semver.MustParse("3.0.6")
|
||||
|
||||
type testUser struct {
|
||||
name string // the test user name
|
||||
userID string // the user's account ID
|
||||
addresses []*testAddr // the user's addresses
|
||||
userPass string // the user's account password
|
||||
bridgePass string // the user's bridge password
|
||||
}
|
||||
|
||||
func newTestUser(userID, name, userPass string) *testUser {
|
||||
return &testUser{
|
||||
userID: userID,
|
||||
name: name,
|
||||
userPass: userPass,
|
||||
}
|
||||
}
|
||||
|
||||
func (user *testUser) getName() string {
|
||||
return user.name
|
||||
}
|
||||
|
||||
func (user *testUser) getUserID() string {
|
||||
return user.userID
|
||||
}
|
||||
|
||||
func (user *testUser) getEmails() []string {
|
||||
return xslices.Map(user.addresses, func(addr *testAddr) string {
|
||||
return addr.email
|
||||
})
|
||||
}
|
||||
|
||||
func (user *testUser) getAddrID(email string) string {
|
||||
for _, addr := range user.addresses {
|
||||
if addr.email == email {
|
||||
return addr.addrID
|
||||
}
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unknown email %q", email))
|
||||
}
|
||||
|
||||
func (user *testUser) addAddress(addrID, email string) {
|
||||
user.addresses = append(user.addresses, newTestAddr(addrID, email))
|
||||
}
|
||||
|
||||
func (user *testUser) remAddress(addrID string) {
|
||||
user.addresses = xslices.Filter(user.addresses, func(addr *testAddr) bool {
|
||||
return addr.addrID != addrID
|
||||
})
|
||||
}
|
||||
|
||||
func (user *testUser) getUserPass() string {
|
||||
return user.userPass
|
||||
}
|
||||
|
||||
func (user *testUser) getBridgePass() string {
|
||||
return user.bridgePass
|
||||
}
|
||||
|
||||
func (user *testUser) setBridgePass(pass string) {
|
||||
user.bridgePass = pass
|
||||
}
|
||||
|
||||
type testAddr struct {
|
||||
addrID string // the remote address ID
|
||||
email string // the test address email
|
||||
}
|
||||
|
||||
func newTestAddr(addrID, email string) *testAddr {
|
||||
return &testAddr{
|
||||
addrID: addrID,
|
||||
email: email,
|
||||
}
|
||||
}
|
||||
|
||||
type testCtx struct {
|
||||
// These are the objects supporting the test.
|
||||
dir string
|
||||
@ -70,13 +143,11 @@ type testCtx struct {
|
||||
clientConn *grpc.ClientConn
|
||||
clientEventCh *queue.QueuedChannel[*frontend.StreamEvent]
|
||||
|
||||
// These maps hold expected userIDByName, their primary addresses and bridge passwords.
|
||||
userUUIDByName map[string]string
|
||||
addrUUIDByName map[string]string
|
||||
userIDByName map[string]string
|
||||
userAddrByEmail map[string]map[string]string
|
||||
userPassByID map[string]string
|
||||
userBridgePassByID map[string][]byte
|
||||
// These maps hold test objects created during the test.
|
||||
userByID map[string]*testUser
|
||||
userUUIDByName map[string]string
|
||||
addrByID map[string]*testAddr
|
||||
addrUUIDByName map[string]string
|
||||
|
||||
// These are the IMAP and SMTP clients used to connect to bridge.
|
||||
imapClients map[string]*imapClient
|
||||
@ -115,12 +186,10 @@ func newTestCtx(tb testing.TB) *testCtx {
|
||||
events: newEventCollector(),
|
||||
reporter: newReportRecorder(tb),
|
||||
|
||||
userUUIDByName: make(map[string]string),
|
||||
addrUUIDByName: make(map[string]string),
|
||||
userIDByName: make(map[string]string),
|
||||
userAddrByEmail: make(map[string]map[string]string),
|
||||
userPassByID: make(map[string]string),
|
||||
userBridgePassByID: make(map[string][]byte),
|
||||
userByID: make(map[string]*testUser),
|
||||
userUUIDByName: make(map[string]string),
|
||||
addrByID: make(map[string]*testAddr),
|
||||
addrUUIDByName: make(map[string]string),
|
||||
|
||||
imapClients: make(map[string]*imapClient),
|
||||
smtpClients: make(map[string]*smtpClient),
|
||||
@ -192,62 +261,22 @@ func (t *testCtx) afterStep(st *godog.Step, status godog.StepResultStatus) {
|
||||
logrus.Debugf("Finished step (%v): %s", status, st.Text)
|
||||
}
|
||||
|
||||
func (t *testCtx) getName(wantUserID string) string {
|
||||
for name, userID := range t.userIDByName {
|
||||
if userID == wantUserID {
|
||||
return name
|
||||
func (t *testCtx) addUser(userID, name, userPass string) {
|
||||
t.userByID[userID] = newTestUser(userID, name, userPass)
|
||||
}
|
||||
|
||||
func (t *testCtx) getUserByName(name string) *testUser {
|
||||
for _, user := range t.userByID {
|
||||
if user.name == name {
|
||||
return user
|
||||
}
|
||||
}
|
||||
|
||||
panic(fmt.Sprintf("unknown user ID %q", wantUserID))
|
||||
panic(fmt.Sprintf("user %q not found", name))
|
||||
}
|
||||
|
||||
func (t *testCtx) getUserID(username string) string {
|
||||
return t.userIDByName[username]
|
||||
}
|
||||
|
||||
func (t *testCtx) setUserID(username, userID string) {
|
||||
t.userIDByName[username] = userID
|
||||
}
|
||||
|
||||
func (t *testCtx) getUserAddrID(userID, email string) string {
|
||||
return t.userAddrByEmail[userID][email]
|
||||
}
|
||||
|
||||
func (t *testCtx) getUserAddrs(userID string) []string {
|
||||
return maps.Keys(t.userAddrByEmail[userID])
|
||||
}
|
||||
|
||||
func (t *testCtx) setUserAddr(userID, addrID, email string) {
|
||||
if _, ok := t.userAddrByEmail[userID]; !ok {
|
||||
t.userAddrByEmail[userID] = make(map[string]string)
|
||||
}
|
||||
|
||||
t.userAddrByEmail[userID][email] = addrID
|
||||
}
|
||||
|
||||
func (t *testCtx) unsetUserAddr(userID, wantAddrID string) {
|
||||
for email, addrID := range t.userAddrByEmail[userID] {
|
||||
if addrID == wantAddrID {
|
||||
delete(t.userAddrByEmail[userID], email)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (t *testCtx) getUserPass(userID string) string {
|
||||
return t.userPassByID[userID]
|
||||
}
|
||||
|
||||
func (t *testCtx) setUserPass(userID, pass string) {
|
||||
t.userPassByID[userID] = pass
|
||||
}
|
||||
|
||||
func (t *testCtx) getUserBridgePass(userID string) string {
|
||||
return string(t.userBridgePassByID[userID])
|
||||
}
|
||||
|
||||
func (t *testCtx) setUserBridgePass(userID string, pass []byte) {
|
||||
t.userBridgePassByID[userID] = pass
|
||||
func (t *testCtx) getUserByID(userID string) *testUser {
|
||||
return t.userByID[userID]
|
||||
}
|
||||
|
||||
func (t *testCtx) getMBoxID(userID string, name string) string {
|
||||
@ -256,7 +285,7 @@ func (t *testCtx) getMBoxID(userID string, name string) string {
|
||||
|
||||
var labelID string
|
||||
|
||||
if err := t.withClient(ctx, t.getName(userID), func(ctx context.Context, client *proton.Client) error {
|
||||
if err := t.withClient(ctx, t.getUserByID(userID).getName(), func(ctx context.Context, client *proton.Client) error {
|
||||
labels, err := client.GetLabels(ctx, proton.LabelTypeLabel, proton.LabelTypeFolder, proton.LabelTypeSystem)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@ -37,7 +37,7 @@ Feature: IMAP create mailbox
|
||||
Then it succeeds
|
||||
When IMAP client "1" creates "Labels/l3"
|
||||
Then it succeeds
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -65,7 +65,7 @@ Feature: IMAP create mailbox
|
||||
Then it succeeds
|
||||
When IMAP client "1" creates "Folders/f2/f22"
|
||||
Then it succeeds
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -89,7 +89,7 @@ Feature: IMAP create mailbox
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
And user "[user:user]" finishes syncing
|
||||
And user "[user:user]" connects and authenticates IMAP client "2"
|
||||
Then IMAP client "2" sees the following mailbox info:
|
||||
Then IMAP client "2" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -119,7 +119,7 @@ Feature: IMAP create mailbox
|
||||
Then it succeeds
|
||||
When IMAP client "1" creates "Folders/f2/f22"
|
||||
Then it succeeds
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -143,7 +143,7 @@ Feature: IMAP create mailbox
|
||||
Then it succeeds
|
||||
When IMAP client "1" renames "Folders/f1/f12" to "Folders/f2/f12"
|
||||
Then it succeeds
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -167,7 +167,7 @@ Feature: IMAP create mailbox
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
And user "[user:user]" finishes syncing
|
||||
And user "[user:user]" connects and authenticates IMAP client "2"
|
||||
Then IMAP client "2" sees the following mailbox info:
|
||||
Then IMAP client "2" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
|
||||
@ -7,7 +7,7 @@ Feature: IMAP Hide All Mail
|
||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||
|
||||
Scenario: Hide All Mail Mailbox
|
||||
Given IMAP client "1" sees the following mailbox info:
|
||||
Given IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -20,7 +20,7 @@ Feature: IMAP Hide All Mail
|
||||
| Folders |
|
||||
| Labels |
|
||||
When the user hides All Mail
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -32,7 +32,7 @@ Feature: IMAP Hide All Mail
|
||||
| Folders |
|
||||
| Labels |
|
||||
When the user shows All Mail
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
|
||||
@ -9,7 +9,7 @@ Feature: IMAP list mailboxes
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
And user "[user:user]" finishes syncing
|
||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name |
|
||||
| INBOX |
|
||||
| Drafts |
|
||||
@ -36,4 +36,27 @@ Feature: IMAP list mailboxes
|
||||
Then IMAP client "1" counts 20 mailboxes under "Folders"
|
||||
And IMAP client "1" counts 60 mailboxes under "Labels"
|
||||
Then IMAP client "2" counts 20 mailboxes under "Folders"
|
||||
And IMAP client "2" counts 60 mailboxes under "Labels"
|
||||
And IMAP client "2" counts 60 mailboxes under "Labels"
|
||||
|
||||
Scenario: List with scheduled mail
|
||||
Given there exists an account with username "[user:user]" and password "password"
|
||||
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Scheduled":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | sch | false |
|
||||
When bridge starts
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
And user "[user:user]" finishes syncing
|
||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name | total |
|
||||
| INBOX | 0 |
|
||||
| Drafts | 0 |
|
||||
| Sent | 0 |
|
||||
| Starred | 0 |
|
||||
| Archive | 0 |
|
||||
| Spam | 0 |
|
||||
| Trash | 0 |
|
||||
| All Mail | 1 |
|
||||
| Folders | 0 |
|
||||
| Labels | 0 |
|
||||
| Scheduled | 1 |
|
||||
|
||||
@ -17,22 +17,22 @@ Feature: IMAP copy messages
|
||||
Scenario: Copy message to label
|
||||
When IMAP client "1" copies the message with subject "foo" from "INBOX" to "Labels/label"
|
||||
And it succeeds
|
||||
Then IMAP client "1" sees the following messages in "INBOX":
|
||||
Then IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
And IMAP client "1" sees the following messages in "Labels/label":
|
||||
And IMAP client "1" eventually sees the following messages in "Labels/label":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
|
||||
Scenario: Copy all messages to label
|
||||
When IMAP client "1" copies all messages from "INBOX" to "Labels/label"
|
||||
And it succeeds
|
||||
Then IMAP client "1" sees the following messages in "INBOX":
|
||||
Then IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
And IMAP client "1" sees the following messages in "Labels/label":
|
||||
And IMAP client "1" eventually sees the following messages in "Labels/label":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
@ -43,14 +43,14 @@ Feature: IMAP copy messages
|
||||
Then IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
And IMAP client "1" sees the following messages in "Folders/mbox":
|
||||
And IMAP client "1" eventually sees the following messages in "Folders/mbox":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
|
||||
Scenario: Copy all messages to folder does move
|
||||
When IMAP client "1" copies all messages from "INBOX" to "Folders/mbox"
|
||||
And it succeeds
|
||||
Then IMAP client "1" sees the following messages in "Folders/mbox":
|
||||
Then IMAP client "1" eventually sees the following messages in "Folders/mbox":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
@ -66,7 +66,7 @@ Feature: IMAP copy messages
|
||||
And IMAP client "1" eventually sees 0 messages in "Sent"
|
||||
|
||||
Scenario: Copy message from All mail moves from the original location
|
||||
Given IMAP client "1" sees the following messages in "INBOX":
|
||||
Given IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
|
||||
@ -12,10 +12,10 @@ Feature: IMAP create messages
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | [user:user]@[domain] | foo | bar |
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees the following messages in "INBOX":
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | [user:user]@[domain] | foo | bar |
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | [user:user]@[domain] | foo | bar |
|
||||
|
||||
@ -37,10 +37,10 @@ Feature: IMAP create messages
|
||||
| from | to | subject | body |
|
||||
| [user:user]@[domain] | john.doe@email.com | foo | bar |
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees the following messages in "Sent":
|
||||
And IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | body |
|
||||
| [user:user]@[domain] | john.doe@email.com | foo | bar |
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | body |
|
||||
| [user:user]@[domain] | john.doe@email.com | foo | bar |
|
||||
|
||||
@ -49,10 +49,10 @@ Feature: IMAP create messages
|
||||
| from | to | subject | body |
|
||||
| [alias:alias]@[domain] | john.doe@email.com | foo | bar |
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees the following messages in "Sent":
|
||||
And IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | body |
|
||||
| [alias:alias]@[domain] | john.doe@email.com | foo | bar |
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | body |
|
||||
| [alias:alias]@[domain] | john.doe@email.com | foo | bar |
|
||||
|
||||
@ -61,10 +61,10 @@ Feature: IMAP create messages
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees the following messages in "INBOX":
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
|
||||
@ -73,10 +73,10 @@ Feature: IMAP create messages
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees the following messages in "Sent":
|
||||
And IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
|
||||
@ -85,7 +85,7 @@ Feature: IMAP create messages
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
And it succeeds
|
||||
And IMAP client "1" sees the following messages in "Sent":
|
||||
And IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
And it succeeds
|
||||
@ -93,7 +93,7 @@ Feature: IMAP create messages
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
And it succeeds
|
||||
And IMAP client "1" sees the following messages in "Sent":
|
||||
And IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | body |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
| john.doe@email.com | john.doe2@[domain] | foo | bar |
|
||||
|
||||
@ -6,6 +6,7 @@ Feature: IMAP remove messages from mailbox
|
||||
| mbox | folder |
|
||||
| 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 1 messages in "Scheduled"
|
||||
And bridge starts
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
And user "[user:user]" finishes syncing
|
||||
@ -18,14 +19,14 @@ Feature: IMAP remove messages from mailbox
|
||||
Then IMAP client "1" sees that message 2 has the flag "\Deleted"
|
||||
When IMAP client "1" expunges
|
||||
And it succeeds
|
||||
Then IMAP client "1" sees 9 messages in "Folders/mbox"
|
||||
Then IMAP client "1" eventually sees 9 messages in "Folders/mbox"
|
||||
|
||||
Scenario: Mark all messages as deleted and EXPUNGE
|
||||
When IMAP client "1" selects "Folders/mbox"
|
||||
And IMAP client "1" marks all messages as deleted
|
||||
And IMAP client "1" expunges
|
||||
And it succeeds
|
||||
Then IMAP client "1" sees 0 messages in "Folders/mbox"
|
||||
Then IMAP client "1" eventually sees 0 messages in "Folders/mbox"
|
||||
|
||||
Scenario: Mark messages as undeleted and EXPUNGE
|
||||
When IMAP client "1" selects "Folders/mbox"
|
||||
@ -37,11 +38,18 @@ Feature: IMAP remove messages from mailbox
|
||||
And it succeeds
|
||||
When IMAP client "1" expunges
|
||||
And it succeeds
|
||||
Then IMAP client "1" sees 2 messages in "Folders/mbox"
|
||||
Then IMAP client "1" eventually sees 2 messages in "Folders/mbox"
|
||||
|
||||
Scenario: Not possible to delete from All Mail and expunge does nothing
|
||||
When IMAP client "1" selects "All Mail"
|
||||
And IMAP client "1" marks message 2 as deleted
|
||||
And it succeeds
|
||||
And IMAP client "1" expunges
|
||||
Then it fails
|
||||
Then it fails
|
||||
|
||||
Scenario: Not possible to delete from Scheduled and expunge does nothing
|
||||
When IMAP client "1" selects "Scheduled"
|
||||
And IMAP client "1" marks message 1 as deleted
|
||||
Then it succeeds
|
||||
And IMAP client "1" expunges
|
||||
Then it fails
|
||||
|
||||
@ -20,14 +20,14 @@ Feature: IMAP remove messages from Trash
|
||||
Then it succeeds
|
||||
When IMAP client "1" marks the message with subject "foo" as deleted
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees 2 messages in "Trash"
|
||||
And IMAP client "1" sees 2 messages in "All Mail"
|
||||
And IMAP client "1" sees 1 messages in "Labels/label"
|
||||
And IMAP client "1" eventually sees 2 messages in "Trash"
|
||||
And IMAP client "1" eventually sees 2 messages in "All Mail"
|
||||
And IMAP client "1" eventually sees 1 messages in "Labels/label"
|
||||
When IMAP client "1" expunges
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees 1 messages in "Trash"
|
||||
And IMAP client "1" sees 2 messages in "All Mail"
|
||||
And IMAP client "1" sees 1 messages in "Labels/label"
|
||||
And IMAP client "1" eventually sees 1 messages in "Trash"
|
||||
And IMAP client "1" eventually sees 2 messages in "All Mail"
|
||||
And IMAP client "1" eventually sees 1 messages in "Labels/label"
|
||||
|
||||
Scenario Outline: Message in Trash only is permanently deleted
|
||||
Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash":
|
||||
@ -41,9 +41,9 @@ Feature: IMAP remove messages from Trash
|
||||
And IMAP client "1" selects "Trash"
|
||||
When IMAP client "1" marks the message with subject "foo" as deleted
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees 2 messages in "Trash"
|
||||
And IMAP client "1" sees 2 messages in "All Mail"
|
||||
And IMAP client "1" eventually sees 2 messages in "Trash"
|
||||
And IMAP client "1" eventually sees 2 messages in "All Mail"
|
||||
When IMAP client "1" expunges
|
||||
Then it succeeds
|
||||
And IMAP client "1" sees 1 messages in "Trash"
|
||||
And IMAP client "1" eventually sees 1 messages in "Trash"
|
||||
And IMAP client "1" eventually sees 1 messages in "All Mail"
|
||||
@ -15,7 +15,7 @@ Feature: IMAP Draft messages
|
||||
Then IMAP client "1" eventually sees the following messages in "Drafts":
|
||||
| body |
|
||||
| This is a dra |
|
||||
And IMAP client "1" sees 1 messages in "Drafts"
|
||||
And IMAP client "1" eventually sees 1 messages in "Drafts"
|
||||
|
||||
Scenario: Draft edited locally
|
||||
When IMAP client "1" marks message 1 as deleted
|
||||
@ -33,7 +33,7 @@ Feature: IMAP Draft messages
|
||||
And IMAP client "1" eventually sees the following messages in "Drafts":
|
||||
| to | subject | body |
|
||||
| someone@example.com | Basic Draft | This is a draft, but longer |
|
||||
And IMAP client "1" sees 1 messages in "Drafts"
|
||||
And IMAP client "1" eventually sees 1 messages in "Drafts"
|
||||
|
||||
Scenario: Draft edited remotely
|
||||
When the following fields were changed in draft 1 for address "[user:user]@[domain]" of account "[user:user]":
|
||||
@ -42,12 +42,12 @@ Feature: IMAP Draft messages
|
||||
Then IMAP client "1" eventually sees the following messages in "Drafts":
|
||||
| to | subject | body |
|
||||
| someone@example.com | Basic Draft | This is a draft body, but longer |
|
||||
And IMAP client "1" sees 1 messages in "Drafts"
|
||||
And IMAP client "1" eventually sees 1 messages in "Drafts"
|
||||
|
||||
Scenario: Draft moved to trash remotely
|
||||
When draft 1 for address "[user:user]@[domain]" of account "[user:user] was moved to trash
|
||||
Then IMAP client "1" eventually sees the following messages in "Trash":
|
||||
| body |
|
||||
| This is a dra |
|
||||
And IMAP client "1" sees 0 messages in "Drafts"
|
||||
And IMAP client "1" eventually sees 0 messages in "Drafts"
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ Feature: IMAP Fetch
|
||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||
|
||||
Scenario: Fetch very old message
|
||||
Given IMAP client "1" sees the following messages in "INBOX":
|
||||
Given IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | date |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | 13 Aug 82 00:00 +0000 |
|
||||
Then IMAP client "1" sees header "X-Original-Date: Sun, 13 Jul 1969 00:00:00 +0000" in message with subject "foo" in "INBOX"
|
||||
@ -21,6 +21,6 @@ Feature: IMAP Fetch
|
||||
|
||||
Scenario: Fetch from deleted cache
|
||||
When the user deletes the gluon cache
|
||||
Then IMAP client "1" sees the following messages in "INBOX":
|
||||
Then IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | date |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | 13 Aug 82 00:00 +0000 |
|
||||
|
||||
@ -104,7 +104,7 @@ Feature: IMAP import messages
|
||||
And IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | body |
|
||||
| foo@example.com | bridgetest@pm.test | Hello | Hello |
|
||||
And IMAP client "1" sees 0 messages in "Inbox"
|
||||
And IMAP client "1" eventually sees 0 messages in "Inbox"
|
||||
|
||||
Scenario: Import non-received message to Inbox
|
||||
When IMAP client "1" appends the following message to "Inbox":
|
||||
@ -119,7 +119,7 @@ Feature: IMAP import messages
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | body |
|
||||
| foo@example.com | bridgetest@pm.test | Hello | Hello |
|
||||
And IMAP client "1" sees 0 messages in "Sent"
|
||||
And IMAP client "1" eventually sees 0 messages in "Sent"
|
||||
|
||||
Scenario: Import non-received message to Sent
|
||||
When IMAP client "1" appends the following message to "Sent":
|
||||
@ -134,7 +134,7 @@ Feature: IMAP import messages
|
||||
And IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | body |
|
||||
| foo@example.com | bridgetest@pm.test | Hello | Hello |
|
||||
And IMAP client "1" sees 0 messages in "Inbox"
|
||||
And IMAP client "1" eventually sees 0 messages in "Inbox"
|
||||
|
||||
Scenario Outline: Import message without sender to <mailbox>
|
||||
When IMAP client "1" appends the following message to "<mailbox>":
|
||||
|
||||
@ -16,6 +16,9 @@ Feature: IMAP move messages
|
||||
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Sent":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | bax | false |
|
||||
And the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Scheduled":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | sch | false |
|
||||
And bridge starts
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
And user "[user:user]" finishes syncing
|
||||
@ -24,11 +27,11 @@ Feature: IMAP move messages
|
||||
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"
|
||||
And it succeeds
|
||||
And IMAP client "1" sees the following messages in "INBOX":
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
And IMAP client "1" sees the following messages in "Labels/label":
|
||||
And IMAP client "1" eventually sees the following messages in "Labels/label":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
|
||||
@ -41,28 +44,51 @@ Feature: IMAP move messages
|
||||
And IMAP client "target" selects "Labels/label"
|
||||
And IMAP clients "source" and "target" move message with subject "foo" of "[user:user]" to "Labels/label" by APPEND DELETE EXPUNGE
|
||||
And it succeeds
|
||||
Then IMAP client "source" sees the following messages in "INBOX":
|
||||
Then IMAP client "source" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
And IMAP client "target" sees the following messages in "Labels/label":
|
||||
And IMAP client "target" eventually sees the following messages in "Labels/label":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
|
||||
Scenario: Move message from label to folder
|
||||
When IMAP client "1" moves the message with subject "baz" from "Labels/label2" to "Folders/mbox"
|
||||
And it succeeds
|
||||
And IMAP client "1" sees the following messages in "Folders/mbox":
|
||||
And IMAP client "1" eventually sees the following messages in "Folders/mbox":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||
And IMAP client "1" sees 0 messages in "Labels/label2"
|
||||
And IMAP client "1" eventually sees 0 messages in "Labels/label2"
|
||||
|
||||
Scenario: Move message from label to label
|
||||
When IMAP client "1" moves the message with subject "baz" from "Labels/label2" to "Labels/label"
|
||||
And it succeeds
|
||||
And IMAP client "1" sees the following messages in "Labels/label":
|
||||
And IMAP client "1" eventually sees the following messages in "Labels/label":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||
And IMAP client "1" sees 0 messages in "Labels/label2"
|
||||
And IMAP client "1" eventually sees 0 messages in "Labels/label2"
|
||||
|
||||
Scenario: Move message from system label to system label
|
||||
When IMAP client "1" moves the message with subject "foo" from "INBOX" to "Trash"
|
||||
And it succeeds
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
And IMAP client "1" eventually sees the following messages in "Trash":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
|
||||
Scenario: Move message from folder to system label
|
||||
When IMAP client "1" moves the message with subject "baz" from "Labels/label2" to "Folders/mbox"
|
||||
And it succeeds
|
||||
And IMAP client "1" eventually sees the following messages in "Folders/mbox":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||
When IMAP client "1" moves the message with subject "baz" from "Folders/mbox" to "Trash"
|
||||
And it succeeds
|
||||
And IMAP client "1" eventually sees 0 messages in "Folders/mbox"
|
||||
And IMAP client "1" eventually sees the following messages in "Trash":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||
|
||||
Scenario: Move message from system label to system label
|
||||
When IMAP client "1" moves the message with subject "foo" from "INBOX" to "Trash"
|
||||
@ -90,14 +116,23 @@ Feature: IMAP move messages
|
||||
Scenario: Move message from All Mail is not possible
|
||||
When IMAP client "1" moves the message with subject "baz" from "All Mail" to "Folders/folder"
|
||||
Then it fails
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
| john.doe@mail.com | [user:user]@[domain] | baz | false |
|
||||
| john.doe@mail.com | [user:user]@[domain] | bax | false |
|
||||
| john.doe@mail.com | [user:user]@[domain] | sch | false |
|
||||
|
||||
Scenario: Move message from Inbox to Sent is not possible
|
||||
Scenario: Move message from Scheduled is not possible
|
||||
Given test skips reporter checks
|
||||
When IMAP client "1" moves the message with subject "sch" from "Scheduled" to "Inbox"
|
||||
Then it fails
|
||||
And IMAP client "1" eventually sees the following messages in "Scheduled":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | sch | false |
|
||||
|
||||
Scenario: Move message from Inbox to Sent is not possible
|
||||
Given test skips reporter checks
|
||||
When IMAP client "1" moves the message with subject "bar" from "Inbox" to "Sent"
|
||||
Then it fails
|
||||
@ -105,4 +140,4 @@ Feature: IMAP move messages
|
||||
Scenario: Move message from Sent to Inbox is not possible
|
||||
Given test skips reporter checks
|
||||
When IMAP client "1" moves the message with subject "bax" from "Sent" to "Inbox"
|
||||
Then it fails
|
||||
Then it fails
|
||||
|
||||
@ -34,8 +34,8 @@ Feature: IMAP move messages by append and delete (without MOVE support, e.g., Ou
|
||||
And IMAP client "source" selects "<srcMailbox>"
|
||||
And IMAP client "target" selects "<dstMailbox>"
|
||||
When IMAP clients "source" and "target" move message with subject "subj2" of "[user:user]" to "<dstMailbox>" by <order>
|
||||
And IMAP client "source" sees 1 messages in "<srcMailbox>"
|
||||
And IMAP client "source" sees the following messages in "<srcMailbox>":
|
||||
And IMAP client "source" eventually sees 1 messages in "<srcMailbox>"
|
||||
And IMAP client "source" eventually sees the following messages in "<srcMailbox>":
|
||||
| from | to | subject |
|
||||
| sndr1@[domain] | rcvr1@[domain] | subj1 |
|
||||
And IMAP client "target" eventually sees 1 messages in "<dstMailbox>"
|
||||
|
||||
@ -17,7 +17,7 @@ Feature: Bridge can fully sync an account
|
||||
Scenario: The user changes the gluon path
|
||||
When the user changes the gluon path
|
||||
And user "[user:user]" connects and authenticates IMAP client "2"
|
||||
Then IMAP client "2" sees the following messages in "INBOX":
|
||||
Then IMAP client "2" eventually sees the following messages in "INBOX":
|
||||
| from | to | subject | unread |
|
||||
| john.doe@mail.com | [user:user]@[domain] | foo | false |
|
||||
| jane.doe@mail.com | name@[domain] | bar | true |
|
||||
|
||||
@ -45,6 +45,7 @@ Feature: SMTP with bcc
|
||||
"""
|
||||
|
||||
|
||||
@long-black
|
||||
Scenario: Send message only to bcc
|
||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:bcc]@[domain]":
|
||||
"""
|
||||
|
||||
@ -7,6 +7,7 @@ Feature: SMTP sending embedded message
|
||||
And the user logs in with username "[user:to]" and password "password"
|
||||
And user "[user:user]" connects and authenticates SMTP client "1"
|
||||
|
||||
@long-black
|
||||
Scenario: Send it
|
||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||
"""
|
||||
|
||||
@ -6,6 +6,8 @@ Feature: SMTP sending two messages
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
And the user logs in with username "[user:recp]" and password "password"
|
||||
|
||||
|
||||
@long-black
|
||||
Scenario: Send from one account to the other
|
||||
When user "[user:user]" connects and authenticates SMTP client "1"
|
||||
And SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:recp]@[domain]":
|
||||
@ -60,6 +62,8 @@ Feature: SMTP sending two messages
|
||||
| from | to | subject | body |
|
||||
| [user:user]@[domain] | [user:recp]@[domain] | One account to the other | hello |
|
||||
|
||||
|
||||
@long-black
|
||||
Scenario: Send from one account to the other with attachments
|
||||
When user "[user:user]" connects and authenticates SMTP client "1"
|
||||
And SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:recp]@[domain]":
|
||||
|
||||
@ -16,6 +16,7 @@ Feature: SMTP sending the same message twice
|
||||
"""
|
||||
And it succeeds
|
||||
|
||||
@long-black
|
||||
Scenario: The exact same message is not sent twice
|
||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||
"""
|
||||
@ -36,6 +37,7 @@ Feature: SMTP sending the same message twice
|
||||
| [user:user]@[domain] | [user:to]@[domain] | Hello | World |
|
||||
|
||||
|
||||
@long-black
|
||||
Scenario: Slight change means different message and is sent twice
|
||||
When SMTP client "1" sends the following message from "[user:user]@[domain]" to "[user:to]@[domain]":
|
||||
"""
|
||||
|
||||
153
tests/features/smtp/send/send_reply.feature
Normal file
153
tests/features/smtp/send/send_reply.feature
Normal file
@ -0,0 +1,153 @@
|
||||
Feature: SMTP send reply
|
||||
|
||||
Background:
|
||||
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 bridge starts
|
||||
And the user logs in with username "[user:user1]" and password "password"
|
||||
And user "[user:user1]" connects and authenticates SMTP client "1"
|
||||
And user "[user:user1]" connects and authenticates IMAP client "1"
|
||||
And user "[user:user1]" finishes syncing
|
||||
|
||||
@long-black
|
||||
Scenario: Reply with In-Reply-To but no References
|
||||
# User1 send the initial message.
|
||||
When SMTP client "1" sends the following message from "[user:user1]@[domain]" to "[user:user2]@[domain]":
|
||||
"""
|
||||
From: Bridge Test <[user:user1]@[domain]>
|
||||
To: Internal Bridge <[user:user2]@[domain]>
|
||||
Subject: Please Reply
|
||||
Message-ID: <something@protonmail.ch>
|
||||
|
||||
hello
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | message-id |
|
||||
| [user:user1]@[domain] | [user:user2]@[domain] | Please Reply | <something@protonmail.ch> |
|
||||
# login user2.
|
||||
And the user logs in with username "[user:user2]" and password "password"
|
||||
And user "[user:user2]" connects and authenticates IMAP client "2"
|
||||
And user "[user:user2]" connects and authenticates SMTP client "2"
|
||||
And user "[user:user2]" finishes syncing
|
||||
# User2 receive the message.
|
||||
Then IMAP client "2" eventually sees the following messages in "INBOX":
|
||||
| from | subject | message-id |
|
||||
| [user:user1]@[domain] | Please Reply | <something@protonmail.ch> |
|
||||
# User2 reply to it.
|
||||
When SMTP client "2" sends the following message from "[user:user2]@[domain]" to "[user:user1]@[domain]":
|
||||
"""
|
||||
From: Internal Bridge <[user:user2]@[domain]>
|
||||
To: Bridge Test <[user:user1]@[domain]>
|
||||
Content-Type: text/plain
|
||||
Subject: FW - Please Reply
|
||||
In-Reply-To: <something@protonmail.ch>
|
||||
|
||||
Heya
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
Then IMAP client "2" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | in-reply-to | references |
|
||||
| [user:user2]@[domain] | [user:user1]@[domain] | FW - Please Reply | <something@protonmail.ch> | <something@protonmail.ch> |
|
||||
# User1 receive the reply.|
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | subject | body | in-reply-to | references |
|
||||
| [user:user2]@[domain] | FW - Please Reply | Heya | <something@protonmail.ch> | <something@protonmail.ch> |
|
||||
|
||||
@long-black
|
||||
Scenario: Reply with References but no In-Reply-To
|
||||
# User1 send the initial message.
|
||||
When SMTP client "1" sends the following message from "[user:user1]@[domain]" to "[user:user2]@[domain]":
|
||||
"""
|
||||
From: Bridge Test <[user:user1]@[domain]>
|
||||
To: Internal Bridge <[user:user2]@[domain]>
|
||||
Subject: Please Reply
|
||||
Message-ID: <something@protonmail.ch>
|
||||
|
||||
hello
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | message-id |
|
||||
| [user:user1]@[domain] | [user:user2]@[domain] | Please Reply | <something@protonmail.ch> |
|
||||
# login user2.
|
||||
And the user logs in with username "[user:user2]" and password "password"
|
||||
And user "[user:user2]" connects and authenticates IMAP client "2"
|
||||
And user "[user:user2]" connects and authenticates SMTP client "2"
|
||||
And user "[user:user2]" finishes syncing
|
||||
# User2 receive the message.
|
||||
Then IMAP client "2" eventually sees the following messages in "INBOX":
|
||||
| from | subject | message-id |
|
||||
| [user:user1]@[domain] | Please Reply | <something@protonmail.ch> |
|
||||
# User2 reply to it.
|
||||
When SMTP client "2" sends the following message from "[user:user2]@[domain]" to "[user:user1]@[domain]":
|
||||
"""
|
||||
From: Internal Bridge <[user:user2]@[domain]>
|
||||
To: Bridge Test <[user:user1]@[domain]>
|
||||
Content-Type: text/plain
|
||||
Subject: FW - Please Reply
|
||||
References: <something@protonmail.ch>
|
||||
|
||||
Heya
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
Then IMAP client "2" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | in-reply-to | references |
|
||||
| [user:user2]@[domain] | [user:user1]@[domain] | FW - Please Reply | <something@protonmail.ch> | <something@protonmail.ch> |
|
||||
# User1 receive the reply.|
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | subject | body | in-reply-to | references |
|
||||
| [user:user2]@[domain] | FW - Please Reply | Heya | <something@protonmail.ch> | <something@protonmail.ch> |
|
||||
|
||||
|
||||
@long-black
|
||||
Scenario: Reply with both References and In-Reply-To
|
||||
# User1 send the initial message.
|
||||
When SMTP client "1" sends the following message from "[user:user1]@[domain]" to "[user:user2]@[domain]":
|
||||
"""
|
||||
From: Bridge Test <[user:user1]@[domain]>
|
||||
To: Internal Bridge <[user:user2]@[domain]>
|
||||
Subject: Please Reply
|
||||
Message-ID: <something@protonmail.ch>
|
||||
|
||||
hello
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
Then IMAP client "1" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | message-id |
|
||||
| [user:user1]@[domain] | [user:user2]@[domain] | Please Reply | <something@protonmail.ch> |
|
||||
# login user2.
|
||||
And the user logs in with username "[user:user2]" and password "password"
|
||||
And user "[user:user2]" connects and authenticates IMAP client "2"
|
||||
And user "[user:user2]" connects and authenticates SMTP client "2"
|
||||
And user "[user:user2]" finishes syncing
|
||||
# User2 receive the message.
|
||||
Then IMAP client "2" eventually sees the following messages in "INBOX":
|
||||
| from | subject | message-id |
|
||||
| [user:user1]@[domain] | Please Reply | <something@protonmail.ch> |
|
||||
# User2 reply to it.
|
||||
When SMTP client "2" sends the following message from "[user:user2]@[domain]" to "[user:user1]@[domain]":
|
||||
"""
|
||||
From: Internal Bridge <[user:user2]@[domain]>
|
||||
To: Bridge Test <[user:user1]@[domain]>
|
||||
Content-Type: text/plain
|
||||
Subject: FW - Please Reply
|
||||
In-Reply-To: <something@protonmail.ch>
|
||||
References: <something@protonmail.ch>
|
||||
|
||||
Heya
|
||||
|
||||
"""
|
||||
Then it succeeds
|
||||
Then IMAP client "2" eventually sees the following messages in "Sent":
|
||||
| from | to | subject | in-reply-to | references |
|
||||
| [user:user2]@[domain] | [user:user1]@[domain] | FW - Please Reply | <something@protonmail.ch> | <something@protonmail.ch> |
|
||||
# User1 receive the reply.|
|
||||
And IMAP client "1" eventually sees the following messages in "INBOX":
|
||||
| from | subject | body | in-reply-to | references |
|
||||
| [user:user2]@[domain] | FW - Please Reply | Heya | <something@protonmail.ch> | <something@protonmail.ch> |
|
||||
@ -20,30 +20,30 @@ Feature: Address mode
|
||||
|
||||
Scenario: The user is in combined mode
|
||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||
Then IMAP client "1" sees the following messages in "Folders/one":
|
||||
Then IMAP client "1" eventually sees the following messages in "Folders/one":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
And IMAP client "1" sees the following messages in "Folders/two":
|
||||
And IMAP client "1" eventually sees the following messages in "Folders/two":
|
||||
| from | to | subject | unread |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
When user "[user:user]" connects and authenticates IMAP client "2" with address "[alias:alias]@[domain]"
|
||||
Then IMAP client "2" sees the following messages in "Folders/one":
|
||||
Then IMAP client "2" eventually sees the following messages in "Folders/one":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
And IMAP client "2" sees the following messages in "Folders/two":
|
||||
And IMAP client "2" eventually sees the following messages in "Folders/two":
|
||||
| from | to | subject | unread |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
And IMAP client "2" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
@ -54,22 +54,22 @@ Feature: Address mode
|
||||
Given the user sets the address mode of user "[user:user]" to "split"
|
||||
And user "[user:user]" finishes syncing
|
||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||
Then IMAP client "1" sees the following messages in "Folders/one":
|
||||
Then IMAP client "1" eventually sees the following messages in "Folders/one":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
And IMAP client "1" sees 0 messages in "Folders/two"
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees 0 messages in "Folders/two"
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
When user "[user:user]" connects and authenticates IMAP client "2" with address "[alias:alias]@[domain]"
|
||||
Then IMAP client "2" sees 0 messages in "Folders/one"
|
||||
And IMAP client "2" sees the following messages in "Folders/two":
|
||||
Then IMAP client "2" eventually sees 0 messages in "Folders/one"
|
||||
And IMAP client "2" eventually sees the following messages in "Folders/two":
|
||||
| from | to | subject | unread |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
And IMAP client "2" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
@ -80,14 +80,14 @@ Feature: Address mode
|
||||
And the user sets the address mode of user "[user:user]" to "combined"
|
||||
And user "[user:user]" finishes syncing
|
||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||
Then IMAP client "1" sees the following messages in "All Mail":
|
||||
Then IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
When user "[user:user]" connects and authenticates IMAP client "2" with address "[alias:alias]@[domain]"
|
||||
Then IMAP client "2" sees the following messages in "All Mail":
|
||||
Then IMAP client "2" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
@ -96,14 +96,14 @@ Feature: Address mode
|
||||
|
||||
Scenario: The user adds an address while in combined mode
|
||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||
Then IMAP client "1" sees the following messages in "All Mail":
|
||||
Then IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
When user "[user:user]" connects and authenticates IMAP client "2" with address "[alias:alias]@[domain]"
|
||||
Then IMAP client "2" sees the following messages in "All Mail":
|
||||
Then IMAP client "2" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
@ -112,7 +112,7 @@ Feature: Address mode
|
||||
Given the account "[user:user]" has additional address "other@[domain]"
|
||||
And bridge sends an address created event for user "[user:user]"
|
||||
When user "[user:user]" connects and authenticates IMAP client "3" with address "other@[domain]"
|
||||
Then IMAP client "3" sees the following messages in "All Mail":
|
||||
Then IMAP client "3" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
@ -123,12 +123,12 @@ Feature: Address mode
|
||||
Given the user sets the address mode of user "[user:user]" to "split"
|
||||
And user "[user:user]" finishes syncing
|
||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
When user "[user:user]" connects and authenticates IMAP client "2" with address "[alias:alias]@[domain]"
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
And IMAP client "2" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
@ -139,14 +139,14 @@ Feature: Address mode
|
||||
|
||||
Scenario: The user deletes an address while in combined mode
|
||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||
Then IMAP client "1" sees the following messages in "All Mail":
|
||||
Then IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
When user "[user:user]" connects and authenticates IMAP client "2" with address "[alias:alias]@[domain]"
|
||||
Then IMAP client "2" sees the following messages in "All Mail":
|
||||
Then IMAP client "2" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
@ -161,12 +161,12 @@ Feature: Address mode
|
||||
Given the user sets the address mode of user "[user:user]" to "split"
|
||||
And user "[user:user]" finishes syncing
|
||||
When user "[user:user]" connects and authenticates IMAP client "1" with address "[user:user]@[domain]"
|
||||
And IMAP client "1" sees the following messages in "All Mail":
|
||||
And IMAP client "1" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| a@[domain] | a@[domain] | one | true |
|
||||
| b@[domain] | b@[domain] | two | false |
|
||||
When user "[user:user]" connects and authenticates IMAP client "2" with address "[alias:alias]@[domain]"
|
||||
And IMAP client "2" sees the following messages in "All Mail":
|
||||
And IMAP client "2" eventually sees the following messages in "All Mail":
|
||||
| from | to | subject | unread |
|
||||
| c@[domain] | c@[domain] | three | true |
|
||||
| d@[domain] | d@[domain] | four | false |
|
||||
|
||||
@ -7,15 +7,15 @@ Feature: A user can login
|
||||
|
||||
Scenario: Login to account
|
||||
When the user logs in with username "[user:user]" and password "password"
|
||||
Then user "[user:user]" is listed and connected
|
||||
Then user "[user:user]" is eventually listed and connected
|
||||
|
||||
Scenario: Login to account with wrong password
|
||||
When the user logs in with username "[user:user]" and password "wrong"
|
||||
Then user "[user:user]" is not listed
|
||||
|
||||
Scenario: Login to nonexistent account
|
||||
When the user logs in with username "[user:other]" and password "unknown"
|
||||
Then user "[user:other]" is not listed
|
||||
When the user logs in with username "nonexistent" and password "unknown"
|
||||
Then user "nonexistent" is not listed
|
||||
|
||||
Scenario: Login to account without internet
|
||||
Given the internet is turned off
|
||||
@ -24,11 +24,11 @@ Feature: A user can login
|
||||
|
||||
Scenario: Login to account with caps
|
||||
When the user logs in with username "[user:MixedCaps]" and password "password"
|
||||
Then user "[user:MixedCaps]" is listed and connected
|
||||
Then user "[user:MixedCaps]" is eventually listed and connected
|
||||
|
||||
Scenario: Login to account with disabled primary
|
||||
When the user logs in with username "[user:disabled]" and password "password"
|
||||
Then user "[user:disabled]" is listed and connected
|
||||
Then user "[user:disabled]" is eventually listed and connected
|
||||
|
||||
Scenario: Login to account without internet but the connection is later restored
|
||||
When the user logs in with username "[user:user]" and password "password"
|
||||
@ -42,5 +42,5 @@ Feature: A user can login
|
||||
Given there exists an account with username "[user:additional]" and password "password"
|
||||
When the user logs in with username "[user:user]" and password "password"
|
||||
And the user logs in with username "[user:additional]" and password "password"
|
||||
Then user "[user:user]" is listed and connected
|
||||
And user "[user:additional]" is listed and connected
|
||||
Then user "[user:user]" is eventually listed and connected
|
||||
And user "[user:additional]" is eventually listed and connected
|
||||
@ -8,7 +8,7 @@ Feature: A logged out user can login again
|
||||
When user "[user:user]" logs out
|
||||
And bridge restarts
|
||||
And the user logs in with username "[user:user]" and password "password"
|
||||
Then user "[user:user]" is listed and connected
|
||||
Then user "[user:user]" is eventually listed and connected
|
||||
|
||||
Scenario: Cannot login to removed account
|
||||
When user "[user:user]" is deleted
|
||||
|
||||
@ -21,7 +21,7 @@ Feature: Bridge can fully sync an account
|
||||
Then bridge sends sync started and finished events for user "[user:user]"
|
||||
When bridge restarts
|
||||
And user "[user:user]" connects and authenticates IMAP client "1"
|
||||
Then IMAP client "1" sees the following mailbox info:
|
||||
Then IMAP client "1" eventually sees the following mailbox info:
|
||||
| name | total | unread |
|
||||
| INBOX | 0 | 0 |
|
||||
| Drafts | 0 | 0 |
|
||||
|
||||
@ -38,35 +38,35 @@ import (
|
||||
)
|
||||
|
||||
func (s *scenario) userConnectsIMAPClient(username, clientID string) error {
|
||||
return s.t.newIMAPClient(s.t.getUserID(username), clientID)
|
||||
return s.t.newIMAPClient(s.t.getUserByName(username).getUserID(), clientID)
|
||||
}
|
||||
|
||||
func (s *scenario) userConnectsIMAPClientOnPort(username, clientID string, port int) error {
|
||||
return s.t.newIMAPClientOnPort(s.t.getUserID(username), clientID, port)
|
||||
return s.t.newIMAPClientOnPort(s.t.getUserByName(username).getUserID(), clientID, port)
|
||||
}
|
||||
|
||||
func (s *scenario) userConnectsAndAuthenticatesIMAPClient(username, clientID string) error {
|
||||
return s.userConnectsAndAuthenticatesIMAPClientWithAddress(username, clientID, s.t.getUserAddrs(s.t.getUserID(username))[0])
|
||||
return s.userConnectsAndAuthenticatesIMAPClientWithAddress(username, clientID, s.t.getUserByName(username).getEmails()[0])
|
||||
}
|
||||
|
||||
func (s *scenario) userConnectsAndAuthenticatesIMAPClientWithAddress(username, clientID, address string) error {
|
||||
if err := s.t.newIMAPClient(s.t.getUserID(username), clientID); err != nil {
|
||||
if err := s.t.newIMAPClient(s.t.getUserByName(username).getUserID(), clientID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
return client.Login(address, s.t.getUserBridgePass(userID))
|
||||
return client.Login(address, s.t.getUserByID(userID).getBridgePass())
|
||||
}
|
||||
|
||||
func (s *scenario) userConnectsAndCanNotAuthenticateIMAPClientWithAddress(username, clientID, address string) error {
|
||||
if err := s.t.newIMAPClient(s.t.getUserID(username), clientID); err != nil {
|
||||
if err := s.t.newIMAPClient(s.t.getUserByName(username).getUserID(), clientID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
if err := client.Login(address, s.t.getUserBridgePass(userID)); err == nil {
|
||||
if err := client.Login(address, s.t.getUserByID(userID).getBridgePass()); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
@ -76,19 +76,19 @@ func (s *scenario) userConnectsAndCanNotAuthenticateIMAPClientWithAddress(userna
|
||||
func (s *scenario) imapClientCanAuthenticate(clientID string) error {
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
return client.Login(s.t.getUserAddrs(userID)[0], s.t.getUserBridgePass(userID))
|
||||
return client.Login(s.t.getUserByID(userID).getEmails()[0], s.t.getUserByID(userID).getBridgePass())
|
||||
}
|
||||
|
||||
func (s *scenario) imapClientCanAuthenticateWithAddress(clientID string, address string) error {
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
return client.Login(address, s.t.getUserBridgePass(userID))
|
||||
return client.Login(address, s.t.getUserByID(userID).getBridgePass())
|
||||
}
|
||||
|
||||
func (s *scenario) imapClientCannotAuthenticate(clientID string) error {
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
if err := client.Login(s.t.getUserAddrs(userID)[0], s.t.getUserBridgePass(userID)); err == nil {
|
||||
if err := client.Login(s.t.getUserByID(userID).getEmails()[0], s.t.getUserByID(userID).getBridgePass()); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
@ -98,7 +98,7 @@ func (s *scenario) imapClientCannotAuthenticate(clientID string) error {
|
||||
func (s *scenario) imapClientCannotAuthenticateWithAddress(clientID, address string) error {
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
if err := client.Login(address, s.t.getUserBridgePass(userID)); err == nil {
|
||||
if err := client.Login(address, s.t.getUserByID(userID).getBridgePass()); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
@ -108,7 +108,7 @@ func (s *scenario) imapClientCannotAuthenticateWithAddress(clientID, address str
|
||||
func (s *scenario) imapClientCannotAuthenticateWithIncorrectUsername(clientID string) error {
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
if err := client.Login(s.t.getUserAddrs(userID)[0]+"bad", s.t.getUserBridgePass(userID)); err == nil {
|
||||
if err := client.Login(s.t.getUserByID(userID).getEmails()[0]+"bad", s.t.getUserByID(userID).getBridgePass()); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@ func (s *scenario) imapClientCannotAuthenticateWithIncorrectUsername(clientID st
|
||||
func (s *scenario) imapClientCannotAuthenticateWithIncorrectPassword(clientID string) error {
|
||||
userID, client := s.t.getIMAPClient(clientID)
|
||||
|
||||
if err := client.Login(s.t.getUserAddrs(userID)[0], s.t.getUserBridgePass(userID)+"bad"); err == nil {
|
||||
if err := client.Login(s.t.getUserByID(userID).getEmails()[0], s.t.getUserByID(userID).getBridgePass()+"bad"); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
|
||||
@ -27,25 +27,25 @@ import (
|
||||
)
|
||||
|
||||
func (s *scenario) userConnectsSMTPClient(username, clientID string) error {
|
||||
return s.t.newSMTPClient(s.t.getUserID(username), clientID)
|
||||
return s.t.newSMTPClient(s.t.getUserByName(username).getUserID(), clientID)
|
||||
}
|
||||
|
||||
func (s *scenario) userConnectsSMTPClientOnPort(username, clientID string, port int) error {
|
||||
return s.t.newSMTPClientOnPort(s.t.getUserID(username), clientID, port)
|
||||
return s.t.newSMTPClientOnPort(s.t.getUserByName(username).getUserID(), clientID, port)
|
||||
}
|
||||
|
||||
func (s *scenario) userConnectsAndAuthenticatesSMTPClient(username, clientID string) error {
|
||||
return s.userConnectsAndAuthenticatesSMTPClientWithAddress(username, clientID, s.t.getUserAddrs(s.t.getUserID(username))[0])
|
||||
return s.userConnectsAndAuthenticatesSMTPClientWithAddress(username, clientID, s.t.getUserByName(username).getEmails()[0])
|
||||
}
|
||||
|
||||
func (s *scenario) userConnectsAndAuthenticatesSMTPClientWithAddress(username, clientID, address string) error {
|
||||
if err := s.t.newSMTPClient(s.t.getUserID(username), clientID); err != nil {
|
||||
if err := s.t.newSMTPClient(s.t.getUserByName(username).getUserID(), clientID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
userID, client := s.t.getSMTPClient(clientID)
|
||||
|
||||
s.t.pushError(client.Auth(smtp.PlainAuth("", address, s.t.getUserBridgePass(userID), constants.Host)))
|
||||
s.t.pushError(client.Auth(smtp.PlainAuth("", address, s.t.getUserByID(userID).getBridgePass(), constants.Host)))
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -53,7 +53,7 @@ func (s *scenario) userConnectsAndAuthenticatesSMTPClientWithAddress(username, c
|
||||
func (s *scenario) smtpClientCanAuthenticate(clientID string) error {
|
||||
userID, client := s.t.getSMTPClient(clientID)
|
||||
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserAddrs(userID)[0], s.t.getUserBridgePass(userID), constants.Host)); err != nil {
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserByID(userID).getEmails()[0], s.t.getUserByID(userID).getBridgePass(), constants.Host)); err != nil {
|
||||
return fmt.Errorf("expected no error, got %v", err)
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ func (s *scenario) smtpClientCanAuthenticate(clientID string) error {
|
||||
func (s *scenario) smtpClientCannotAuthenticate(clientID string) error {
|
||||
userID, client := s.t.getSMTPClient(clientID)
|
||||
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserAddrs(userID)[0], s.t.getUserBridgePass(userID), constants.Host)); err == nil {
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserByID(userID).getEmails()[0], s.t.getUserByID(userID).getBridgePass(), constants.Host)); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
@ -73,7 +73,7 @@ func (s *scenario) smtpClientCannotAuthenticate(clientID string) error {
|
||||
func (s *scenario) smtpClientCannotAuthenticateWithIncorrectUsername(clientID string) error {
|
||||
userID, client := s.t.getSMTPClient(clientID)
|
||||
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserAddrs(userID)[0]+"bad", s.t.getUserBridgePass(userID), constants.Host)); err == nil {
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserByID(userID).getEmails()[0]+"bad", s.t.getUserByID(userID).getBridgePass(), constants.Host)); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ func (s *scenario) smtpClientCannotAuthenticateWithIncorrectUsername(clientID st
|
||||
func (s *scenario) smtpClientCannotAuthenticateWithIncorrectPassword(clientID string) error {
|
||||
userID, client := s.t.getSMTPClient(clientID)
|
||||
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserAddrs(userID)[0], s.t.getUserBridgePass(userID)+"bad", constants.Host)); err == nil {
|
||||
if err := client.Auth(smtp.PlainAuth("", s.t.getUserByID(userID).getEmails()[0], s.t.getUserByID(userID).getBridgePass()+"bad", constants.Host)); err == nil {
|
||||
return fmt.Errorf("expected error, got nil")
|
||||
}
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
@ -49,6 +50,9 @@ type Message struct {
|
||||
|
||||
Unread bool `bdd:"unread"`
|
||||
Deleted bool `bdd:"deleted"`
|
||||
|
||||
InReplyTo string `bdd:"in-reply-to"`
|
||||
References string `bdd:"references"`
|
||||
}
|
||||
|
||||
func (msg Message) Build() []byte {
|
||||
@ -74,6 +78,14 @@ func (msg Message) Build() []byte {
|
||||
b = append(b, "Subject: "+msg.Subject+"\r\n"...)
|
||||
}
|
||||
|
||||
if msg.InReplyTo != "" {
|
||||
b = append(b, "In-Reply-To: "+msg.InReplyTo+"\r\n"...)
|
||||
}
|
||||
|
||||
if msg.References != "" {
|
||||
b = append(b, "References: "+msg.References+"\r\n"...)
|
||||
}
|
||||
|
||||
if msg.Date != "" {
|
||||
date, err := time.Parse(time.RFC822, msg.Date)
|
||||
if err != nil {
|
||||
@ -125,6 +137,9 @@ func newMessageFromIMAP(msg *imap.Message) Message {
|
||||
Unread: !slices.Contains(msg.Flags, imap.SeenFlag),
|
||||
Deleted: slices.Contains(msg.Flags, imap.DeletedFlag),
|
||||
Date: msg.Envelope.Date.Format(time.RFC822Z),
|
||||
InReplyTo: msg.Envelope.InReplyTo,
|
||||
// Go-imap only supports in-reply-to so we have to mimic other client by using it as references.
|
||||
References: msg.Envelope.InReplyTo,
|
||||
}
|
||||
|
||||
if len(msg.Envelope.From) > 0 {
|
||||
@ -195,7 +210,13 @@ func matchMailboxes(have, want []Mailbox) error {
|
||||
func eventually(condition func() error) error {
|
||||
ch := make(chan error, 1)
|
||||
|
||||
timer := time.NewTimer(30 * time.Second)
|
||||
var timerDuration = 30 * time.Second
|
||||
// Extend to 5min for live API.
|
||||
if hostURL := os.Getenv("FEATURE_TEST_HOST_URL"); hostURL != "" {
|
||||
timerDuration = 600 * time.Second
|
||||
}
|
||||
|
||||
timer := time.NewTimer(timerDuration)
|
||||
defer timer.Stop()
|
||||
|
||||
ticker := time.NewTicker(100 * time.Millisecond)
|
||||
|
||||
@ -32,7 +32,6 @@ import (
|
||||
"github.com/bradenaw/juniper/xslices"
|
||||
"github.com/cucumber/godog"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
func (s *scenario) thereExistsAnAccountWithUsernameAndPassword(username, password string) error {
|
||||
@ -52,7 +51,7 @@ func (s *scenario) theAccountHasAdditionalDisabledAddress(username, address stri
|
||||
}
|
||||
|
||||
func (s *scenario) theAccountHasAdditionalAddressWithoutKeys(username, address string) error {
|
||||
userID := s.t.getUserID(username)
|
||||
userID := s.t.getUserByName(username).getUserID()
|
||||
|
||||
// Decrypt the user's encrypted ID for use with quark.
|
||||
userDecID, err := s.t.runQuarkCmd(context.Background(), "encryption:id", "--decrypt", userID)
|
||||
@ -65,7 +64,8 @@ func (s *scenario) theAccountHasAdditionalAddressWithoutKeys(username, address s
|
||||
context.Background(),
|
||||
"user:create:address",
|
||||
string(userDecID),
|
||||
s.t.getUserPass(userID),
|
||||
s.t.getUserByID(userID).getUserPass(),
|
||||
|
||||
address,
|
||||
); err != nil {
|
||||
return err
|
||||
@ -78,15 +78,15 @@ func (s *scenario) theAccountHasAdditionalAddressWithoutKeys(username, address s
|
||||
}
|
||||
|
||||
// Set the new address of the user.
|
||||
s.t.setUserAddr(userID, addr[len(addr)-1].ID, address)
|
||||
s.t.getUserByID(userID).addAddress(addr[len(addr)-1].ID, address)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *scenario) theAccountNoLongerHasAdditionalAddress(username, address string) error {
|
||||
userID := s.t.getUserID(username)
|
||||
addrID := s.t.getUserAddrID(userID, address)
|
||||
userID := s.t.getUserByName(username).getUserID()
|
||||
addrID := s.t.getUserByName(username).getAddrID(address)
|
||||
|
||||
if err := s.t.withClient(context.Background(), username, func(ctx context.Context, c *proton.Client) error {
|
||||
if err := c.DisableAddress(ctx, addrID); err != nil {
|
||||
@ -98,7 +98,7 @@ func (s *scenario) theAccountNoLongerHasAdditionalAddress(username, address stri
|
||||
return err
|
||||
}
|
||||
|
||||
s.t.unsetUserAddr(userID, addrID)
|
||||
s.t.getUserByID(userID).remAddress(addrID)
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -184,8 +184,8 @@ func (s *scenario) theAddressOfAccountHasTheFollowingMessagesInMailbox(address,
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
userID := s.t.getUserID(username)
|
||||
addrID := s.t.getUserAddrID(userID, address)
|
||||
userID := s.t.getUserByName(username).getUserID()
|
||||
addrID := s.t.getUserByName(username).getAddrID(address)
|
||||
mboxID := s.t.getMBoxID(userID, mailbox)
|
||||
|
||||
wantMessages, err := unmarshalTable[Message](table)
|
||||
@ -193,14 +193,6 @@ func (s *scenario) theAddressOfAccountHasTheFollowingMessagesInMailbox(address,
|
||||
return err
|
||||
}
|
||||
|
||||
var messageFlags proton.MessageFlag
|
||||
|
||||
if !strings.EqualFold(mailbox, "Sent") {
|
||||
messageFlags = proton.MessageFlagReceived
|
||||
} else {
|
||||
messageFlags = proton.MessageFlagSent
|
||||
}
|
||||
|
||||
return s.t.createMessages(ctx, username, addrID, xslices.Map(wantMessages, func(message Message) proton.ImportReq {
|
||||
return proton.ImportReq{
|
||||
|
||||
@ -208,7 +200,7 @@ func (s *scenario) theAddressOfAccountHasTheFollowingMessagesInMailbox(address,
|
||||
AddressID: addrID,
|
||||
LabelIDs: []string{mboxID},
|
||||
Unread: proton.Bool(message.Unread),
|
||||
Flags: messageFlags,
|
||||
Flags: flagsForMailbox(mailbox),
|
||||
},
|
||||
Message: message.Build(),
|
||||
}
|
||||
@ -219,8 +211,8 @@ func (s *scenario) theAddressOfAccountHasMessagesInMailbox(address, username str
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
userID := s.t.getUserID(username)
|
||||
addrID := s.t.getUserAddrID(userID, address)
|
||||
userID := s.t.getUserByName(username).getUserID()
|
||||
addrID := s.t.getUserByName(username).getAddrID(address)
|
||||
mboxID := s.t.getMBoxID(userID, mailbox)
|
||||
|
||||
return s.t.createMessages(ctx, username, addrID, iterator.Collect(iterator.Map(iterator.Counter(count), func(idx int) proton.ImportReq {
|
||||
@ -228,7 +220,7 @@ func (s *scenario) theAddressOfAccountHasMessagesInMailbox(address, username str
|
||||
Metadata: proton.ImportMetadata{
|
||||
AddressID: addrID,
|
||||
LabelIDs: []string{mboxID},
|
||||
Flags: proton.MessageFlagReceived,
|
||||
Flags: flagsForMailbox(mailbox),
|
||||
},
|
||||
Message: Message{
|
||||
Subject: fmt.Sprintf("%d", idx),
|
||||
@ -240,6 +232,18 @@ func (s *scenario) theAddressOfAccountHasMessagesInMailbox(address, username str
|
||||
})))
|
||||
}
|
||||
|
||||
func flagsForMailbox(mailboxName string) proton.MessageFlag {
|
||||
if strings.EqualFold(mailboxName, "Sent") {
|
||||
return proton.MessageFlagSent
|
||||
}
|
||||
|
||||
if strings.EqualFold(mailboxName, "Scheduled") {
|
||||
return proton.MessageFlagScheduledSend
|
||||
}
|
||||
|
||||
return proton.MessageFlagReceived
|
||||
}
|
||||
|
||||
// accountDraftChanged changes the draft attributes, where draftIndex is
|
||||
// similar to sequential ID i.e. 1 represents the first message of draft folder
|
||||
// sorted by API creation time.
|
||||
@ -262,7 +266,7 @@ func (s *scenario) theFollowingFieldsWereChangedInDraftForAddressOfAccount(draft
|
||||
defer cancel()
|
||||
|
||||
return s.t.withClient(ctx, username, func(ctx context.Context, c *proton.Client) error {
|
||||
return s.t.withAddrKR(ctx, c, username, s.t.getUserAddrID(s.t.getUserID(username), address), func(_ context.Context, addrKR *crypto.KeyRing) error {
|
||||
return s.t.withAddrKR(ctx, c, username, s.t.getUserByName(username).getAddrID(address), func(_ context.Context, addrKR *crypto.KeyRing) error {
|
||||
var changes proton.DraftTemplate
|
||||
|
||||
if wantMessages[0].From != "" {
|
||||
@ -311,7 +315,7 @@ func (s *scenario) drafAtIndexWasMovedToTrashForAddressOfAccount(draftIndex int,
|
||||
defer cancel()
|
||||
|
||||
return s.t.withClient(ctx, username, func(ctx context.Context, c *proton.Client) error {
|
||||
return s.t.withAddrKR(ctx, c, username, s.t.getUserAddrID(s.t.getUserID(username), address), func(_ context.Context, addrKR *crypto.KeyRing) error {
|
||||
return s.t.withAddrKR(ctx, c, username, s.t.getUserByName(username).getAddrID(address), func(_ context.Context, addrKR *crypto.KeyRing) error {
|
||||
if err := c.UnlabelMessages(ctx, []string{draftID}, proton.DraftsLabel); err != nil {
|
||||
return fmt.Errorf("failed to unlabel draft")
|
||||
}
|
||||
@ -329,7 +333,7 @@ func (s *scenario) userLogsInWithUsernameAndPassword(username, password string)
|
||||
if err != nil {
|
||||
s.t.pushError(err)
|
||||
} else {
|
||||
if userID != s.t.getUserID(username) {
|
||||
if userID != s.t.getUserByName(username).getUserID() {
|
||||
return errors.New("user ID mismatch")
|
||||
}
|
||||
|
||||
@ -338,18 +342,18 @@ func (s *scenario) userLogsInWithUsernameAndPassword(username, password string)
|
||||
return err
|
||||
}
|
||||
|
||||
s.t.setUserBridgePass(userID, info.BridgePass)
|
||||
s.t.getUserByID(userID).setBridgePass(string(info.BridgePass))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *scenario) userLogsOut(username string) error {
|
||||
return s.t.bridge.LogoutUser(context.Background(), s.t.getUserID(username))
|
||||
return s.t.bridge.LogoutUser(context.Background(), s.t.getUserByName(username).getUserID())
|
||||
}
|
||||
|
||||
func (s *scenario) userIsDeleted(username string) error {
|
||||
return s.t.bridge.DeleteUser(context.Background(), s.t.getUserID(username))
|
||||
return s.t.bridge.DeleteUser(context.Background(), s.t.getUserByName(username).getUserID())
|
||||
}
|
||||
|
||||
func (s *scenario) theAuthOfUserIsRevoked(username string) error {
|
||||
@ -359,7 +363,7 @@ func (s *scenario) theAuthOfUserIsRevoked(username string) error {
|
||||
}
|
||||
|
||||
func (s *scenario) userIsListedAndConnected(username string) error {
|
||||
user, err := s.t.bridge.GetUserInfo(s.t.getUserID(username))
|
||||
user, err := s.t.bridge.GetUserInfo(s.t.getUserByName(username).getUserID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -382,7 +386,7 @@ func (s *scenario) userIsEventuallyListedAndConnected(username string) error {
|
||||
}
|
||||
|
||||
func (s *scenario) userIsListedButNotConnected(username string) error {
|
||||
user, err := s.t.bridge.GetUserInfo(s.t.getUserID(username))
|
||||
user, err := s.t.bridge.GetUserInfo(s.t.getUserByName(username).getUserID())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -399,7 +403,7 @@ func (s *scenario) userIsListedButNotConnected(username string) error {
|
||||
}
|
||||
|
||||
func (s *scenario) userIsNotListed(username string) error {
|
||||
if slices.Contains(s.t.bridge.GetUserIDs(), s.t.getUserID(username)) {
|
||||
if _, err := s.t.bridge.QueryUserInfo(username); !errors.Is(err, bridge.ErrNoSuchUser) {
|
||||
return errors.New("user listed")
|
||||
}
|
||||
|
||||
@ -411,7 +415,7 @@ func (s *scenario) userFinishesSyncing(username string) error {
|
||||
}
|
||||
|
||||
func (s *scenario) addAdditionalAddressToAccount(username, address string, disabled bool) error {
|
||||
userID := s.t.getUserID(username)
|
||||
userID := s.t.getUserByName(username).getUserID()
|
||||
|
||||
// Decrypt the user's encrypted ID for use with quark.
|
||||
userDecID, err := s.t.runQuarkCmd(context.Background(), "encryption:id", "--decrypt", userID)
|
||||
@ -429,7 +433,7 @@ func (s *scenario) addAdditionalAddressToAccount(username, address string, disab
|
||||
|
||||
args = append(args,
|
||||
string(userDecID),
|
||||
s.t.getUserPass(userID),
|
||||
s.t.getUserByID(userID).getUserPass(),
|
||||
address,
|
||||
)
|
||||
|
||||
@ -449,7 +453,7 @@ func (s *scenario) addAdditionalAddressToAccount(username, address string, disab
|
||||
}
|
||||
|
||||
// Set the new address of the user.
|
||||
s.t.setUserAddr(userID, addr[len(addr)-1].ID, address)
|
||||
s.t.getUserByID(userID).addAddress(addr[len(addr)-1].ID, address)
|
||||
|
||||
return nil
|
||||
})
|
||||
@ -503,14 +507,11 @@ func (s *scenario) createUserAccount(username, password string, disabled bool) e
|
||||
return err
|
||||
}
|
||||
|
||||
// Set the ID of the user.
|
||||
s.t.setUserID(username, user.ID)
|
||||
|
||||
// Set the password of the user.
|
||||
s.t.setUserPass(user.ID, password)
|
||||
// Add the test user.
|
||||
s.t.addUser(user.ID, username, password)
|
||||
|
||||
// Set the address of the user.
|
||||
s.t.setUserAddr(user.ID, addr[0].ID, addr[0].Email)
|
||||
s.t.getUserByID(user.ID).addAddress(addr[0].ID, addr[0].Email)
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user