2023-01-02 10:02:26 +00:00
// Copyright (c) 2023 Proton AG
2022-08-26 15:00:21 +00:00
//
// This file is part of Proton Mail Bridge.Bridge.
//
// Proton Mail 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.
//
// Proton Mail 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 Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>.
package tests
import (
"context"
2022-10-31 12:52:11 +00:00
"os"
2022-08-26 15:00:21 +00:00
"strings"
"testing"
"github.com/cucumber/godog"
)
type scenario struct {
t * testCtx
}
2022-12-13 00:33:41 +00:00
// reset resets the test context for a new scenario.
2022-08-26 15:00:21 +00:00
func ( s * scenario ) reset ( tb testing . TB ) {
s . t = newTestCtx ( tb )
}
2022-12-13 00:33:41 +00:00
// replace replaces the placeholders in the scenario with the values from the test context.
func ( s * scenario ) replace ( sc * godog . Scenario ) {
for _ , step := range sc . Steps {
step . Text = s . t . replace ( step . Text )
if arg := step . Argument ; arg != nil {
if table := arg . DataTable ; table != nil {
for _ , row := range table . Rows {
for _ , cell := range row . Cells {
cell . Value = s . t . replace ( cell . Value )
}
}
}
if doc := arg . DocString ; doc != nil {
doc . Content = s . t . replace ( doc . Content )
}
}
}
}
// close closes the test context.
2022-10-27 09:14:36 +00:00
func ( s * scenario ) close ( _ testing . TB ) {
s . t . close ( context . Background ( ) )
2022-08-26 15:00:21 +00:00
}
func TestFeatures ( testingT * testing . T ) {
2022-12-12 12:49:34 +00:00
var s scenario
2022-10-31 12:52:11 +00:00
2022-08-26 15:00:21 +00:00
suite := godog . TestSuite {
2022-12-12 12:49:34 +00:00
TestSuiteInitializer : func ( ctx * godog . TestSuiteContext ) {
ctx . BeforeSuite ( func ( ) {
// Global setup.
} )
ctx . AfterSuite ( func ( ) {
// Global teardown.
} )
} ,
2022-08-26 15:00:21 +00:00
2022-12-12 12:49:34 +00:00
ScenarioInitializer : func ( ctx * godog . ScenarioContext ) {
2022-12-13 00:33:41 +00:00
ctx . Before ( func ( ctx context . Context , sc * godog . Scenario ) ( context . Context , error ) {
2022-08-26 15:00:21 +00:00
s . reset ( testingT )
2022-12-13 00:33:41 +00:00
s . replace ( sc )
2022-08-26 15:00:21 +00:00
return ctx , nil
} )
2022-12-12 12:49:34 +00:00
ctx . After ( func ( ctx context . Context , _ * godog . Scenario , _ error ) ( context . Context , error ) {
2022-08-26 15:00:21 +00:00
s . close ( testingT )
return ctx , nil
} )
ctx . StepContext ( ) . Before ( func ( ctx context . Context , st * godog . Step ) ( context . Context , error ) {
2022-12-12 23:12:29 +00:00
s . t . beforeStep ( st )
2022-11-04 13:50:43 +00:00
return ctx , nil
} )
2022-12-12 12:49:34 +00:00
ctx . StepContext ( ) . After ( func ( ctx context . Context , st * godog . Step , status godog . StepResultStatus , _ error ) ( context . Context , error ) {
2022-12-13 12:29:58 +00:00
s . t . afterStep ( st , status )
2022-08-26 15:00:21 +00:00
return ctx , nil
} )
// ==== ENVIRONMENT ====
ctx . Step ( ` ^it succeeds$ ` , s . itSucceeds )
ctx . Step ( ` ^it fails$ ` , s . itFails )
ctx . Step ( ` ^it fails with error "([^"]*)"$ ` , s . itFailsWithError )
ctx . Step ( ` ^the internet is turned off$ ` , s . internetIsTurnedOff )
ctx . Step ( ` ^the internet is turned on$ ` , s . internetIsTurnedOn )
ctx . Step ( ` ^the user agent is "([^"]*)"$ ` , s . theUserAgentIs )
2022-10-02 11:28:41 +00:00
ctx . Step ( ` ^the header in the "([^"]*)" request to "([^"]*)" has "([^"]*)" set to "([^"]*)"$ ` , s . theHeaderInTheRequestToHasSetTo )
ctx . Step ( ` ^the body in the "([^"]*)" request to "([^"]*)" is:$ ` , s . theBodyInTheRequestToIs )
2022-10-24 22:16:24 +00:00
ctx . Step ( ` ^the API requires bridge version at least "([^"]*)"$ ` , s . theAPIRequiresBridgeVersion )
2022-08-26 15:00:21 +00:00
2022-09-28 09:29:33 +00:00
// ==== SETUP ====
ctx . Step ( ` ^there exists an account with username "([^"]*)" and password "([^"]*)"$ ` , s . thereExistsAnAccountWithUsernameAndPassword )
ctx . Step ( ` ^the account "([^"]*)" has additional address "([^"]*)"$ ` , s . theAccountHasAdditionalAddress )
2022-12-13 00:46:02 +00:00
ctx . Step ( ` ^the account "([^"]*)" has additional address "([^"]*)" without keys$ ` , s . theAccountHasAdditionalAddressWithoutKeys )
2022-09-28 09:29:33 +00:00
ctx . Step ( ` ^the account "([^"]*)" no longer has additional address "([^"]*)"$ ` , s . theAccountNoLongerHasAdditionalAddress )
ctx . Step ( ` ^the account "([^"]*)" has (\d+) custom folders$ ` , s . theAccountHasCustomFolders )
ctx . Step ( ` ^the account "([^"]*)" has (\d+) custom labels$ ` , s . theAccountHasCustomLabels )
ctx . Step ( ` ^the account "([^"]*)" has the following custom mailboxes:$ ` , s . theAccountHasTheFollowingCustomMailboxes )
ctx . Step ( ` ^the address "([^"]*)" of account "([^"]*)" has the following messages in "([^"]*)":$ ` , s . theAddressOfAccountHasTheFollowingMessagesInMailbox )
ctx . Step ( ` ^the address "([^"]*)" of account "([^"]*)" has (\d+) messages in "([^"]*)"$ ` , s . theAddressOfAccountHasMessagesInMailbox )
2022-12-02 11:47:12 +00:00
ctx . Step ( ` ^the following fields were changed in draft (\d+) for address "([^"]*)" of account "([^"]*)":$ ` , s . theFollowingFieldsWereChangedInDraftForAddressOfAccount )
2022-09-28 09:29:33 +00:00
2023-01-03 09:17:08 +00:00
// === REPORTER ===
ctx . Step ( ` ^test skips reporter checks$ ` , s . skipReporterChecks )
2022-08-26 15:00:21 +00:00
// ==== BRIDGE ====
ctx . Step ( ` ^bridge starts$ ` , s . bridgeStarts )
ctx . Step ( ` ^bridge restarts$ ` , s . bridgeRestarts )
ctx . Step ( ` ^bridge stops$ ` , s . bridgeStops )
ctx . Step ( ` ^bridge is version "([^"]*)" and the latest available version is "([^"]*)" reachable from "([^"]*)"$ ` , s . bridgeVersionIsAndTheLatestAvailableVersionIsReachableFrom )
ctx . Step ( ` ^the user has disabled automatic updates$ ` , s . theUserHasDisabledAutomaticUpdates )
ctx . Step ( ` ^the user changes the IMAP port to (\d+)$ ` , s . theUserChangesTheIMAPPortTo )
ctx . Step ( ` ^the user changes the SMTP port to (\d+)$ ` , s . theUserChangesTheSMTPPortTo )
2022-12-12 23:12:29 +00:00
ctx . Step ( ` ^the user sets the address mode of user "([^"]*)" to "([^"]*)"$ ` , s . theUserSetsTheAddressModeOfUserTo )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^the user changes the gluon path$ ` , s . theUserChangesTheGluonPath )
2022-09-27 11:22:07 +00:00
ctx . Step ( ` ^the user deletes the gluon files$ ` , s . theUserDeletesTheGluonFiles )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^the user reports a bug$ ` , s . theUserReportsABug )
2022-10-24 22:16:24 +00:00
ctx . Step ( ` ^the user hides All Mail$ ` , s . theUserHidesAllMail )
ctx . Step ( ` ^the user shows All Mail$ ` , s . theUserShowsAllMail )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^bridge sends a connection up event$ ` , s . bridgeSendsAConnectionUpEvent )
ctx . Step ( ` ^bridge sends a connection down event$ ` , s . bridgeSendsAConnectionDownEvent )
ctx . Step ( ` ^bridge sends a deauth event for user "([^"]*)"$ ` , s . bridgeSendsADeauthEventForUser )
2022-09-28 09:29:33 +00:00
ctx . Step ( ` ^bridge sends an address created event for user "([^"]*)"$ ` , s . bridgeSendsAnAddressCreatedEventForUser )
ctx . Step ( ` ^bridge sends an address deleted event for user "([^"]*)"$ ` , s . bridgeSendsAnAddressDeletedEventForUser )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^bridge sends sync started and finished events for user "([^"]*)"$ ` , s . bridgeSendsSyncStartedAndFinishedEventsForUser )
ctx . Step ( ` ^bridge sends an update available event for version "([^"]*)"$ ` , s . bridgeSendsAnUpdateAvailableEventForVersion )
ctx . Step ( ` ^bridge sends a manual update event for version "([^"]*)"$ ` , s . bridgeSendsAManualUpdateEventForVersion )
ctx . Step ( ` ^bridge sends an update installed event for version "([^"]*)"$ ` , s . bridgeSendsAnUpdateInstalledEventForVersion )
ctx . Step ( ` ^bridge sends an update not available event$ ` , s . bridgeSendsAnUpdateNotAvailableEvent )
ctx . Step ( ` ^bridge sends a forced update event$ ` , s . bridgeSendsAForcedUpdateEvent )
2022-10-21 16:41:31 +00:00
ctx . Step ( ` ^bridge reports a message with "([^"]*)"$ ` , s . bridgeReportsMessage )
2022-08-26 15:00:21 +00:00
2022-11-03 09:43:25 +00:00
// ==== FRONTEND ====
ctx . Step ( ` ^frontend sees that bridge is version "([^"]*)"$ ` , s . frontendSeesThatBridgeIsVersion )
2022-08-26 15:00:21 +00:00
// ==== USER ====
ctx . Step ( ` ^the user logs in with username "([^"]*)" and password "([^"]*)"$ ` , s . userLogsInWithUsernameAndPassword )
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 )
2022-09-27 10:02:28 +00:00
ctx . Step ( ` ^user "([^"]*)" is eventually listed and connected$ ` , s . userIsEventuallyListedAndConnected )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^user "([^"]*)" is listed but not connected$ ` , s . userIsListedButNotConnected )
ctx . Step ( ` ^user "([^"]*)" is not listed$ ` , s . userIsNotListed )
ctx . Step ( ` ^user "([^"]*)" finishes syncing$ ` , s . userFinishesSyncing )
// ==== IMAP ====
ctx . Step ( ` ^user "([^"]*)" connects IMAP client "([^"]*)"$ ` , s . userConnectsIMAPClient )
ctx . Step ( ` ^user "([^"]*)" connects IMAP client "([^"]*)" on port (\d+)$ ` , s . userConnectsIMAPClientOnPort )
ctx . Step ( ` ^user "([^"]*)" connects and authenticates IMAP client "([^"]*)"$ ` , s . userConnectsAndAuthenticatesIMAPClient )
2022-09-28 09:29:33 +00:00
ctx . Step ( ` ^user "([^"]*)" connects and authenticates IMAP client "([^"]*)" with address "([^"]*)"$ ` , s . userConnectsAndAuthenticatesIMAPClientWithAddress )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" can authenticate$ ` , s . imapClientCanAuthenticate )
2022-10-13 09:02:43 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" can authenticate with address "([^"]*)"$ ` , s . imapClientCanAuthenticateWithAddress )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" cannot authenticate$ ` , s . imapClientCannotAuthenticate )
2022-09-28 09:29:33 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" cannot authenticate with address "([^"]*)"$ ` , s . imapClientCannotAuthenticateWithAddress )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" cannot authenticate with incorrect username$ ` , s . imapClientCannotAuthenticateWithIncorrectUsername )
ctx . Step ( ` ^IMAP client "([^"]*)" cannot authenticate with incorrect password$ ` , s . imapClientCannotAuthenticateWithIncorrectPassword )
ctx . Step ( ` ^IMAP client "([^"]*)" announces its ID with name "([^"]*)" and version "([^"]*)"$ ` , s . imapClientAnnouncesItsIDWithNameAndVersion )
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 )
2022-09-27 11:22:07 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" eventually sees the following mailbox info:$ ` , s . imapClientEventuallySeesTheFollowingMailboxInfo )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" sees the following mailbox info for "([^"]*)":$ ` , s . imapClientSeesTheFollowingMailboxInfoForMailbox )
ctx . Step ( ` ^IMAP client "([^"]*)" sees "([^"]*)"$ ` , s . imapClientSeesMailbox )
ctx . Step ( ` ^IMAP client "([^"]*)" does not see "([^"]*)"$ ` , s . imapClientDoesNotSeeMailbox )
ctx . Step ( ` ^IMAP client "([^"]*)" counts (\d+) mailboxes under "([^"]*)"$ ` , s . imapClientCountsMailboxesUnder )
ctx . Step ( ` ^IMAP client "([^"]*)" selects "([^"]*)"$ ` , s . imapClientSelectsMailbox )
ctx . Step ( ` ^IMAP client "([^"]*)" copies the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$ ` , s . imapClientCopiesTheMessageWithSubjectFromTo )
ctx . Step ( ` ^IMAP client "([^"]*)" copies all messages from "([^"]*)" to "([^"]*)"$ ` , s . imapClientCopiesAllMessagesFromTo )
2023-01-06 09:55:31 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" moves the message with subject "([^"]*)" from "([^"]*)" to "([^"]*)"$ ` , s . imapClientMovesTheMessageWithSubjectFromTo )
ctx . Step ( ` ^IMAP client "([^"]*)" moves all messages from "([^"]*)" to "([^"]*)"$ ` , s . imapClientMovesAllMessagesFromTo )
2022-08-26 15:00:21 +00:00
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 )
2022-10-27 12:56:26 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as deleted$ ` , s . imapClientMarksTheMessageWithSubjectAsDeleted )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" marks message (\d+) as not deleted$ ` , s . imapClientMarksMessageAsNotDeleted )
ctx . Step ( ` ^IMAP client "([^"]*)" marks all messages as deleted$ ` , s . imapClientMarksAllMessagesAsDeleted )
ctx . Step ( ` ^IMAP client "([^"]*)" sees that message (\d+) has the flag "([^"]*)"$ ` , s . imapClientSeesThatMessageHasTheFlag )
ctx . Step ( ` ^IMAP client "([^"]*)" expunges$ ` , s . imapClientExpunges )
2022-10-19 06:00:45 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" appends the following message to "([^"]*)":$ ` , s . imapClientAppendsTheFollowingMessageToMailbox )
2022-10-24 21:15:13 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" appends the following messages to "([^"]*)":$ ` , s . imapClientAppendsTheFollowingMessagesToMailbox )
2022-10-19 06:00:45 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$ ` , s . imapClientAppendsToMailbox )
2023-01-06 09:55:31 +00:00
ctx . Step ( ` ^IMAP clients "([^"]*)" and "([^"]*)" move message with subject "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*) ` , s . imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations )
2023-01-03 14:29:29 +00:00
ctx . Step ( ` ^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$ ` , s . imapClientSeesHeaderInMessageWithSubject )
2022-08-26 15:00:21 +00:00
// ==== SMTP ====
ctx . Step ( ` ^user "([^"]*)" connects SMTP client "([^"]*)"$ ` , s . userConnectsSMTPClient )
ctx . Step ( ` ^user "([^"]*)" connects SMTP client "([^"]*)" on port (\d+)$ ` , s . userConnectsSMTPClientOnPort )
ctx . Step ( ` ^user "([^"]*)" connects and authenticates SMTP client "([^"]*)"$ ` , s . userConnectsAndAuthenticatesSMTPClient )
2022-09-28 09:29:33 +00:00
ctx . Step ( ` ^user "([^"]*)" connects and authenticates SMTP client "([^"]*)" with address "([^"]*)"$ ` , s . userConnectsAndAuthenticatesSMTPClientWithAddress )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^SMTP client "([^"]*)" can authenticate$ ` , s . smtpClientCanAuthenticate )
ctx . Step ( ` ^SMTP client "([^"]*)" cannot authenticate$ ` , s . smtpClientCannotAuthenticate )
ctx . Step ( ` ^SMTP client "([^"]*)" cannot authenticate with incorrect username$ ` , s . smtpClientCannotAuthenticateWithIncorrectUsername )
ctx . Step ( ` ^SMTP client "([^"]*)" cannot authenticate with incorrect password$ ` , s . smtpClientCannotAuthenticateWithIncorrectPassword )
ctx . Step ( ` ^SMTP client "([^"]*)" sends MAIL FROM "([^"]*)"$ ` , s . smtpClientSendsMailFrom )
ctx . Step ( ` ^SMTP client "([^"]*)" sends RCPT TO "([^"]*)"$ ` , s . smtpClientSendsRcptTo )
2022-10-02 11:28:41 +00:00
ctx . Step ( ` ^SMTP client "([^"]*)" sends DATA:$ ` , s . smtpClientSendsData )
2022-08-26 15:00:21 +00:00
ctx . Step ( ` ^SMTP client "([^"]*)" sends RSET$ ` , s . smtpClientSendsReset )
2022-10-02 11:28:41 +00:00
ctx . Step ( ` ^SMTP client "([^"]*)" sends the following message from "([^"]*)" to "([^"]*)":$ ` , s . smtpClientSendsTheFollowingMessageFromTo )
2022-08-26 15:00:21 +00:00
} ,
Options : & godog . Options {
Format : "pretty" ,
2022-12-12 12:49:34 +00:00
Paths : getFeaturePaths ( ) ,
2022-08-26 15:00:21 +00:00
TestingT : testingT ,
} ,
}
if suite . Run ( ) != 0 {
testingT . Fatal ( "non-zero status returned, failed to run feature tests" )
}
}
2022-12-12 12:49:34 +00:00
func getFeaturePaths ( ) [ ] string {
var paths [ ] string
if features := os . Getenv ( "FEATURES" ) ; features != "" {
paths = strings . Split ( features , " " )
} else {
paths = [ ] string { "features" }
}
return paths
}