mirror of
https://github.com/ProtonMail/proton-bridge.git
synced 2025-12-17 23:56:56 +00:00
Import/Export backend
This commit is contained in:
@ -32,9 +32,10 @@ func (ctx *TestContext) GetBridge() *bridge.Bridge {
|
||||
}
|
||||
|
||||
// withBridgeInstance creates a bridge instance for use in the test.
|
||||
// Every TestContext has this by default and thus this doesn't need to be exported.
|
||||
// TestContext has this by default once called with env variable TEST_APP=bridge.
|
||||
func (ctx *TestContext) withBridgeInstance() {
|
||||
ctx.bridge = newBridgeInstance(ctx.t, ctx.cfg, ctx.credStore, ctx.listener, ctx.clientManager)
|
||||
ctx.users = ctx.bridge.Users
|
||||
ctx.addCleanupChecked(ctx.bridge.ClearData, "Cleaning bridge data")
|
||||
}
|
||||
|
||||
@ -69,13 +70,3 @@ func newBridgeInstance(
|
||||
pref := preferences.New(cfg)
|
||||
return bridge.New(cfg, pref, panicHandler, eventListener, clientManager, credStore)
|
||||
}
|
||||
|
||||
// SetLastBridgeError sets the last error that occurred while executing a bridge action.
|
||||
func (ctx *TestContext) SetLastBridgeError(err error) {
|
||||
ctx.bridgeLastError = err
|
||||
}
|
||||
|
||||
// GetLastBridgeError returns the last error that occurred while executing a bridge action.
|
||||
func (ctx *TestContext) GetLastBridgeError() error {
|
||||
return ctx.bridgeLastError
|
||||
}
|
||||
|
||||
@ -77,6 +77,9 @@ func (c *fakeConfig) GetLogPrefix() string {
|
||||
func (c *fakeConfig) GetPreferencesPath() string {
|
||||
return filepath.Join(c.dir, "prefs.json")
|
||||
}
|
||||
func (c *fakeConfig) GetTransferDir() string {
|
||||
return c.dir
|
||||
}
|
||||
func (c *fakeConfig) GetTLSCertPath() string {
|
||||
return filepath.Join(c.dir, "cert.pem")
|
||||
}
|
||||
|
||||
@ -20,6 +20,8 @@ package context
|
||||
|
||||
import (
|
||||
"github.com/ProtonMail/proton-bridge/internal/bridge"
|
||||
"github.com/ProtonMail/proton-bridge/internal/importexport"
|
||||
"github.com/ProtonMail/proton-bridge/internal/transfer"
|
||||
"github.com/ProtonMail/proton-bridge/internal/users"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/pmapi"
|
||||
@ -46,10 +48,12 @@ type TestContext struct {
|
||||
pmapiController PMAPIController
|
||||
clientManager *pmapi.ClientManager
|
||||
|
||||
// Bridge core related variables.
|
||||
bridge *bridge.Bridge
|
||||
bridgeLastError error
|
||||
credStore users.CredentialsStorer
|
||||
// Core related variables.
|
||||
bridge *bridge.Bridge
|
||||
importExport *importexport.ImportExport
|
||||
users *users.Users
|
||||
credStore users.CredentialsStorer
|
||||
lastError error
|
||||
|
||||
// IMAP related variables.
|
||||
imapAddr string
|
||||
@ -63,6 +67,12 @@ type TestContext struct {
|
||||
smtpClients map[string]*mocks.SMTPClient
|
||||
smtpLastResponses map[string]*mocks.SMTPResponse
|
||||
|
||||
// Transfer related variables.
|
||||
transferLocalRootForImport string
|
||||
transferLocalRootForExport string
|
||||
transferRemoteIMAPServer *mocks.IMAPServer
|
||||
transferProgress *transfer.Progress
|
||||
|
||||
// These are the cleanup steps executed when Cleanup() is called.
|
||||
cleanupSteps []*Cleaner
|
||||
|
||||
@ -71,7 +81,7 @@ type TestContext struct {
|
||||
}
|
||||
|
||||
// New returns a new test TestContext.
|
||||
func New() *TestContext {
|
||||
func New(app string) *TestContext {
|
||||
setLogrusVerbosityFromEnv()
|
||||
|
||||
cfg := newFakeConfig()
|
||||
@ -96,8 +106,15 @@ func New() *TestContext {
|
||||
// Ensure that the config is cleaned up after the test is over.
|
||||
ctx.addCleanupChecked(cfg.ClearData, "Cleaning bridge config data")
|
||||
|
||||
// Create bridge instance under test.
|
||||
ctx.withBridgeInstance()
|
||||
// Create bridge or import/export instance under test.
|
||||
switch app {
|
||||
case "bridge":
|
||||
ctx.withBridgeInstance()
|
||||
case "ie":
|
||||
ctx.withImportExportInstance()
|
||||
default:
|
||||
panic("unknown app: " + app)
|
||||
}
|
||||
|
||||
return ctx
|
||||
}
|
||||
@ -125,3 +142,13 @@ func (ctx *TestContext) GetTestingT() *bddT { //nolint[golint]
|
||||
func (ctx *TestContext) GetTestingError() error {
|
||||
return ctx.t.getErrors()
|
||||
}
|
||||
|
||||
// SetLastError sets the last error that occurred while executing an action.
|
||||
func (ctx *TestContext) SetLastError(err error) {
|
||||
ctx.lastError = err
|
||||
}
|
||||
|
||||
// GetLastError returns the last error that occurred while executing an action.
|
||||
func (ctx *TestContext) GetLastError() error {
|
||||
return ctx.lastError
|
||||
}
|
||||
|
||||
48
test/context/importexport.go
Normal file
48
test/context/importexport.go
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2020 Proton Technologies AG
|
||||
//
|
||||
// This file is part of ProtonMail Bridge.Bridge.
|
||||
//
|
||||
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/ProtonMail/proton-bridge/internal/importexport"
|
||||
"github.com/ProtonMail/proton-bridge/internal/users"
|
||||
"github.com/ProtonMail/proton-bridge/pkg/listener"
|
||||
)
|
||||
|
||||
// GetImportExport returns import/export instance.
|
||||
func (ctx *TestContext) GetImportExport() *importexport.ImportExport {
|
||||
return ctx.importExport
|
||||
}
|
||||
|
||||
// withImportExportInstance creates a import/export instance for use in the test.
|
||||
// TestContext has this by default once called with env variable TEST_APP=ie.
|
||||
func (ctx *TestContext) withImportExportInstance() {
|
||||
ctx.importExport = newImportExportInstance(ctx.t, ctx.cfg, ctx.credStore, ctx.listener, ctx.clientManager)
|
||||
ctx.users = ctx.importExport.Users
|
||||
}
|
||||
|
||||
// newImportExportInstance creates a new import/export instance configured to use the given config/credstore.
|
||||
func newImportExportInstance(
|
||||
t *bddT,
|
||||
cfg importexport.Configer,
|
||||
credStore users.CredentialsStorer,
|
||||
eventListener listener.Listener,
|
||||
clientManager users.ClientManager,
|
||||
) *importexport.ImportExport {
|
||||
panicHandler := &panicHandler{t: t}
|
||||
return importexport.New(cfg, panicHandler, eventListener, clientManager, credStore)
|
||||
}
|
||||
@ -33,6 +33,7 @@ type PMAPIController interface {
|
||||
GetLabelIDs(username string, labelNames []string) ([]string, error)
|
||||
AddUserMessage(username string, message *pmapi.Message) error
|
||||
GetMessageID(username, messageIndex string) string
|
||||
GetMessages(username, labelID string) ([]*pmapi.Message, error)
|
||||
ReorderAddresses(user *pmapi.User, addressIDs []string) error
|
||||
PrintCalls()
|
||||
WasCalled(method, path string, expectedRequest []byte) bool
|
||||
|
||||
91
test/context/transfer.go
Normal file
91
test/context/transfer.go
Normal file
@ -0,0 +1,91 @@
|
||||
// Copyright (c) 2020 Proton Technologies AG
|
||||
//
|
||||
// This file is part of ProtonMail Bridge.Bridge.
|
||||
//
|
||||
// ProtonMail Bridge is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// ProtonMail Bridge is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with ProtonMail Bridge. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/ProtonMail/proton-bridge/internal/transfer"
|
||||
"github.com/ProtonMail/proton-bridge/test/mocks"
|
||||
)
|
||||
|
||||
// SetTransferProgress sets transfer progress.
|
||||
func (ctx *TestContext) SetTransferProgress(progress *transfer.Progress) {
|
||||
ctx.transferProgress = progress
|
||||
}
|
||||
|
||||
// GetTransferProgress returns transfer progress.
|
||||
func (ctx *TestContext) GetTransferProgress() *transfer.Progress {
|
||||
return ctx.transferProgress
|
||||
}
|
||||
|
||||
// GetTransferLocalRootForImport creates temporary root for importing
|
||||
// if it not exists yet, and returns its path.
|
||||
func (ctx *TestContext) GetTransferLocalRootForImport() string {
|
||||
if ctx.transferLocalRootForImport != "" {
|
||||
return ctx.transferLocalRootForImport
|
||||
}
|
||||
root := ctx.createLocalRoot()
|
||||
ctx.transferLocalRootForImport = root
|
||||
return root
|
||||
}
|
||||
|
||||
// GetTransferLocalRootForExport creates temporary root for exporting
|
||||
// if it not exists yet, and returns its path.
|
||||
func (ctx *TestContext) GetTransferLocalRootForExport() string {
|
||||
if ctx.transferLocalRootForExport != "" {
|
||||
return ctx.transferLocalRootForExport
|
||||
}
|
||||
root := ctx.createLocalRoot()
|
||||
ctx.transferLocalRootForExport = root
|
||||
return root
|
||||
}
|
||||
|
||||
func (ctx *TestContext) createLocalRoot() string {
|
||||
root, err := ioutil.TempDir("", "transfer")
|
||||
if err != nil {
|
||||
panic("failed to create temp transfer root: " + err.Error())
|
||||
}
|
||||
|
||||
ctx.addCleanupChecked(func() error {
|
||||
return os.RemoveAll(root)
|
||||
}, "Cleaning transfer data")
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
// GetTransferRemoteIMAPServer creates mocked IMAP server if it not created yet, and returns it.
|
||||
func (ctx *TestContext) GetTransferRemoteIMAPServer() *mocks.IMAPServer {
|
||||
if ctx.transferRemoteIMAPServer != nil {
|
||||
return ctx.transferRemoteIMAPServer
|
||||
}
|
||||
|
||||
port := 21300 + rand.Intn(100)
|
||||
ctx.transferRemoteIMAPServer = mocks.NewIMAPServer("user", "pass", "127.0.0.1", strconv.Itoa(port))
|
||||
|
||||
ctx.transferRemoteIMAPServer.Start()
|
||||
ctx.addCleanupChecked(func() error {
|
||||
ctx.transferRemoteIMAPServer.Stop()
|
||||
return nil
|
||||
}, "Cleaning transfer IMAP server")
|
||||
|
||||
return ctx.transferRemoteIMAPServer
|
||||
}
|
||||
@ -30,11 +30,16 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// GetUsers returns users instance.
|
||||
func (ctx *TestContext) GetUsers() *users.Users {
|
||||
return ctx.users
|
||||
}
|
||||
|
||||
// LoginUser logs in the user with the given username, password, and mailbox password.
|
||||
func (ctx *TestContext) LoginUser(username, password, mailboxPassword string) (err error) {
|
||||
srp.RandReader = rand.New(rand.NewSource(42))
|
||||
|
||||
client, auth, err := ctx.bridge.Login(username, password)
|
||||
client, auth, err := ctx.users.Login(username, password)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to login")
|
||||
}
|
||||
@ -45,7 +50,7 @@ func (ctx *TestContext) LoginUser(username, password, mailboxPassword string) (e
|
||||
}
|
||||
}
|
||||
|
||||
user, err := ctx.bridge.FinishLogin(client, auth, mailboxPassword)
|
||||
user, err := ctx.users.FinishLogin(client, auth, mailboxPassword)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to finish login")
|
||||
}
|
||||
@ -57,7 +62,7 @@ func (ctx *TestContext) LoginUser(username, password, mailboxPassword string) (e
|
||||
|
||||
// GetUser retrieves the bridge user matching the given query string.
|
||||
func (ctx *TestContext) GetUser(username string) (*users.User, error) {
|
||||
return ctx.bridge.GetUser(username)
|
||||
return ctx.users.GetUser(username)
|
||||
}
|
||||
|
||||
// GetStore retrieves the store for given username.
|
||||
@ -100,6 +105,9 @@ func (ctx *TestContext) WaitForSync(username string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if store == nil {
|
||||
return nil
|
||||
}
|
||||
// First wait for ongoing sync to be done before starting and waiting for new one.
|
||||
ctx.eventuallySyncIsFinished(store)
|
||||
store.TestSync()
|
||||
@ -121,7 +129,7 @@ func (ctx *TestContext) EventuallySyncIsFinishedForUsername(username string) {
|
||||
|
||||
// LogoutUser logs out the given user.
|
||||
func (ctx *TestContext) LogoutUser(query string) (err error) {
|
||||
user, err := ctx.bridge.GetUser(query)
|
||||
user, err := ctx.users.GetUser(query)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
@ -135,12 +143,12 @@ func (ctx *TestContext) LogoutUser(query string) (err error) {
|
||||
|
||||
// DeleteUser deletes the given user.
|
||||
func (ctx *TestContext) DeleteUser(query string, deleteStore bool) (err error) {
|
||||
user, err := ctx.bridge.GetUser(query)
|
||||
user, err := ctx.users.GetUser(query)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to get user")
|
||||
}
|
||||
|
||||
if err = ctx.bridge.DeleteUser(user.ID(), deleteStore); err != nil {
|
||||
if err = ctx.users.DeleteUser(user.ID(), deleteStore); err != nil {
|
||||
err = errors.Wrap(err, "failed to delete user")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user