diff --git a/Makefile b/Makefile
index 321f9463..50dcc62e 100644
--- a/Makefile
+++ b/Makefile
@@ -246,7 +246,7 @@ test-race: gofiles
test-integration: gofiles
mkdir -p coverage/integration
go test \
- -v -timeout=60m -p=1 -count=1 \
+ -v -timeout=60m -p=1 -count=1 -tags=test_integration \
${GOCOVERAGE} \
github.com/ProtonMail/proton-bridge/v3/tests \
${GOCOVERDIR}/integration
@@ -261,7 +261,7 @@ test-integration-race: gofiles
test-integration-nightly: gofiles
mkdir -p coverage/integration
go test \
- -v -timeout=90m -p=1 -count=1 \
+ -v -timeout=90m -p=1 -count=1 -tags=test_integration \
${GOCOVERAGE} \
github.com/ProtonMail/proton-bridge/v3/tests \
${GOCOVERDIR}/integration \
diff --git a/internal/bridge/api_default.go b/internal/bridge/api_default.go
index 244543f8..78b882f2 100644
--- a/internal/bridge/api_default.go
+++ b/internal/bridge/api_default.go
@@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see .
-//go:build !build_qa
+//go:build !build_qa && !test_integration
package bridge
diff --git a/internal/bridge/api_qa.go b/internal/bridge/api_qa.go
index 6bdcd6d4..049e0a49 100644
--- a/internal/bridge/api_qa.go
+++ b/internal/bridge/api_qa.go
@@ -15,7 +15,7 @@
// You should have received a copy of the GNU General Public License
// along with Proton Mail Bridge. If not, see .
-//go:build build_qa
+//go:build build_qa || test_integration
package bridge
diff --git a/internal/services/telemetry/service.go b/internal/services/telemetry/service.go
index cc378718..6969c24d 100644
--- a/internal/services/telemetry/service.go
+++ b/internal/services/telemetry/service.go
@@ -51,7 +51,7 @@ func NewService(
settingsGetter SettingsGetter,
eventService userevents.Subscribable,
) *Service {
- s := &Service{
+ return &Service{
cpc: cpc.NewCPC(),
log: logrus.WithFields(logrus.Fields{
"user": userID,
@@ -66,14 +66,10 @@ func NewService(
userID: userID,
settingsGetter: settingsGetter,
}
-
- s.initialise()
-
- return s
}
-func (s *Service) initialise() {
- settings, err := s.settingsGetter.GetUserSettings(context.Background())
+func (s *Service) initialise(ctx context.Context) {
+ settings, err := s.settingsGetter.GetUserSettings(ctx)
if err != nil {
logrus.WithError(err).Error("Cannot get telemetry settings, asuming off")
s.isInitialised = false
@@ -88,6 +84,8 @@ func (s *Service) initialise() {
}
func (s *Service) Start(ctx context.Context, group *orderedtasks.OrderedCancelGroup) {
+ s.initialise(ctx)
+
group.Go(ctx, s.userID, "telemetry-service", s.run)
}
@@ -118,7 +116,7 @@ func (s *Service) run(ctx context.Context) {
case *isTelemetryEnabledReq:
s.log.Debug("Received is telemetry enabled request")
if !s.isInitialised {
- s.initialise()
+ s.initialise(ctx)
}
request.Reply(ctx, s.isTelemetryEnabled, nil)
@@ -137,8 +135,8 @@ func (s *Service) run(ctx context.Context) {
}
}
-func (s *Service) HandleRefreshEvent(_ context.Context, _ proton.RefreshFlag) error {
- s.initialise()
+func (s *Service) HandleRefreshEvent(ctx context.Context, _ proton.RefreshFlag) error {
+ s.initialise(ctx)
return nil
}
diff --git a/internal/services/telemetry/service_test.go b/internal/services/telemetry/service_test.go
index 5bcbcabc..f296096b 100644
--- a/internal/services/telemetry/service_test.go
+++ b/internal/services/telemetry/service_test.go
@@ -78,14 +78,14 @@ func TestService_OnUserSettingsEvent(t *testing.T) {
mockSettingsGetter,
&userevents.NoOpSubscribable{},
)
-
- require.True(t, service.isInitialised)
+ require.False(t, service.isInitialised)
ctx := context.Background()
group := orderedtasks.NewOrderedCancelGroup(async.NoopPanicHandler{})
defer group.CancelAndWait()
service.Start(ctx, group)
+ require.True(t, service.isInitialised)
require.False(t, service.IsTelemetryEnabled(ctx))
require.NoError(t, service.HandleUserSettingsEvent(context.Background(), &proton.UserSettings{Telemetry: proton.SettingEnabled}))
diff --git a/internal/services/userevents/subscription.go b/internal/services/userevents/subscription.go
index b25b7b7d..3a43b1e7 100644
--- a/internal/services/userevents/subscription.go
+++ b/internal/services/userevents/subscription.go
@@ -46,7 +46,7 @@ func (e EventHandler) OnEvent(ctx context.Context, event proton.Event) error {
}
// Start with user settings because of telemetry.
- if event.UserSettings != nil {
+ if event.UserSettings != nil && e.UserSettingsHandler != nil {
if err := e.UserSettingsHandler.HandleUserSettingsEvent(ctx, event.UserSettings); err != nil {
return fmt.Errorf("failed to apply user event: %w", err)
}
diff --git a/internal/user/user_test.go b/internal/user/user_test.go
index 5055b939..6169447b 100644
--- a/internal/user/user_test.go
+++ b/internal/user/user_test.go
@@ -85,23 +85,6 @@ func TestUser_AddressMode(t *testing.T) {
})
}
-func TestUser_Telemetry(t *testing.T) {
- withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) {
- withAccount(t, s, "username", "password", []string{}, func(string, []string) {
- withUser(t, ctx, s, m, "username", "password", func(user *User) {
- // By default, user should have Telemetry enabled.
- telemetry := user.IsTelemetryEnabled(ctx)
- require.Equal(t, true, telemetry)
-
- user.client.Close()
- // If telemetry cannot be retrieved it is disabled.
- telemetry = user.IsTelemetryEnabled(ctx)
- require.Equal(t, false, telemetry)
- })
- })
- })
-}
-
func withAPI(_ testing.TB, ctx context.Context, fn func(context.Context, *server.Server, *proton.Manager)) { //nolint:revive
server := server.New()
defer server.Close()
diff --git a/tests/bdd_test.go b/tests/bdd_test.go
index 658acbaf..9402c9f0 100644
--- a/tests/bdd_test.go
+++ b/tests/bdd_test.go
@@ -97,171 +97,7 @@ func TestFeatures(testingT *testing.T) {
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)
- ctx.Step(`^the header in the "([^"]*)" request to "([^"]*)" has "([^"]*)" set to "([^"]*)"$`, s.theHeaderInTheRequestToHasSetTo)
- ctx.Step(`^the body in the "([^"]*)" request to "([^"]*)" is:$`, s.theBodyInTheRequestToIs)
- ctx.Step(`^the body in the "([^"]*)" response to "([^"]*)" is:$`, s.theBodyInTheResponseToIs)
- ctx.Step(`^the API requires bridge version at least "([^"]*)"$`, s.theAPIRequiresBridgeVersion)
- ctx.Step(`^the network port (\d+) is busy$`, s.networkPortIsBusy)
- ctx.Step(`^the network port range (\d+)-(\d+) is busy$`, s.networkPortRangeIsBusy)
- ctx.Step(`^bridge IMAP port is (\d+)`, s.bridgeIMAPPortIs)
- ctx.Step(`^bridge SMTP port is (\d+)`, s.bridgeSMTPPortIs)
- // ==== SETUP ====
- ctx.Step(`^there exists an account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPassword)
- ctx.Step(`^there exists a disabled account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPasswordWithDisablePrimary)
- ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)"$`, s.theAccountHasAdditionalAddress)
- ctx.Step(`^the account "([^"]*)" has additional disabled address "([^"]*)"$`, s.theAccountHasAdditionalDisabledAddress)
- ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)" without keys$`, s.theAccountHasAdditionalAddressWithoutKeys)
- 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)
- ctx.Step(`^the following fields were changed in draft (\d+) for address "([^"]*)" of account "([^"]*)":$`, s.theFollowingFieldsWereChangedInDraftForAddressOfAccount)
- ctx.Step(`^draft (\d+) for address "([^"]*)" of account "([^"]*)" was moved to trash$`, s.drafAtIndexWasMovedToTrashForAddressOfAccount)
-
- // === REPORTER ===
- ctx.Step(`^test skips reporter checks$`, s.skipReporterChecks)
-
- // ==== 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 has disabled automatic start`, s.theUserHasDisabledAutomaticStart)
- ctx.Step(`^the user has enabled alternative routing`, s.theUserHasEnabledAlternativeRouting)
- ctx.Step(`^the user set IMAP mode to SSL`, s.theUserSetIMAPModeToSSL)
- ctx.Step(`^the user set SMTP mode to SSL`, s.theUserSetSMTPModeToSSL)
- ctx.Step(`^the user changes the IMAP port to (\d+)$`, s.theUserChangesTheIMAPPortTo)
- ctx.Step(`^the user changes the SMTP port to (\d+)$`, s.theUserChangesTheSMTPPortTo)
- ctx.Step(`^the user sets the address mode of user "([^"]*)" to "([^"]*)"$`, s.theUserSetsTheAddressModeOfUserTo)
- ctx.Step(`^the user changes the default keychain application`, s.theUserChangesTheDefaultKeychainApplication)
- ctx.Step(`^the user changes the gluon path$`, s.theUserChangesTheGluonPath)
- ctx.Step(`^the user deletes the gluon files$`, s.theUserDeletesTheGluonFiles)
- ctx.Step(`^the user deletes the gluon cache$`, s.theUserDeletesTheGluonCache)
- ctx.Step(`^the user reports a bug$`, s.theUserReportsABug)
- ctx.Step(`^the user hides All Mail$`, s.theUserHidesAllMail)
- ctx.Step(`^the user shows All Mail$`, s.theUserShowsAllMail)
- ctx.Step(`^the user disables telemetry in bridge settings$`, s.theUserDisablesTelemetryInBridgeSettings)
- ctx.Step(`^the user enables telemetry in bridge settings$`, s.theUserEnablesTelemetryInBridgeSettings)
- 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)
- ctx.Step(`^bridge sends an address created event for user "([^"]*)"$`, s.bridgeSendsAnAddressCreatedEventForUser)
- ctx.Step(`^bridge sends an address deleted event for user "([^"]*)"$`, s.bridgeSendsAnAddressDeletedEventForUser)
- 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)
- ctx.Step(`^bridge reports a message with "([^"]*)"$`, s.bridgeReportsMessage)
- ctx.Step(`^bridge telemetry feature is enabled$`, s.bridgeTelemetryFeatureEnabled)
- ctx.Step(`^bridge telemetry feature is disabled$`, s.bridgeTelemetryFeatureDisabled)
-
- // ==== FRONTEND ====
- ctx.Step(`^frontend sees that bridge is version "([^"]*)"$`, s.frontendSeesThatBridgeIsVersion)
-
- // ==== 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 eventually listed and connected$`, s.userIsEventuallyListedAndConnected)
- 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)
- ctx.Step(`^user "([^"]*)" has telemetry set to (\d+)$`, s.userHasTelemetrySetTo)
- ctx.Step(`^the bridge password of user "([^"]*)" is changed to "([^"]*)"`, s.bridgePasswordOfUserIsChangedTo)
- ctx.Step(`^the bridge password of user "([^"]*)" is equal to "([^"]*)"`, s.bridgePasswordOfUserIsEqualTo)
-
- // ==== 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)
- ctx.Step(`^user "([^"]*)" connects and authenticates IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesIMAPClientWithAddress)
- ctx.Step(`^user "([^"]*)" connects and can not authenticate IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndCanNotAuthenticateIMAPClientWithAddress)
- ctx.Step(`^IMAP client "([^"]*)" can authenticate$`, s.imapClientCanAuthenticate)
- ctx.Step(`^IMAP client "([^"]*)" can authenticate with address "([^"]*)"$`, s.imapClientCanAuthenticateWithAddress)
- ctx.Step(`^IMAP client "([^"]*)" cannot authenticate$`, s.imapClientCannotAuthenticate)
- ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with address "([^"]*)"$`, s.imapClientCannotAuthenticateWithAddress)
- 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 "([^"]*)" closes$`, s.imapClientCloses)
- 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 "([^"]*)" 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)
- 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)
- 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 "([^"]*)" eventually sees the following messages in "([^"]*)":$`, s.imapClientEventuallySeesTheFollowingMessagesInMailbox)
- 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)
- 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 "([^"]*)" expunges$`, s.imapClientExpunges)
- ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as "([^"]*)"$`, s.imapClientMarksMessageAsState)
- ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as "([^"]*)"$`, s.imapClientMarksTheMessageWithSubjectAsState)
- ctx.Step(`^IMAP client "([^"]*)" marks all messages as "([^"]*)"$`, s.imapClientMarksAllMessagesAsState)
- ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) has the flag "([^"]*)"$`, s.imapClientSeesThatMessageHasTheFlag)
- ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) does not have the flag "([^"]*)"$`, s.imapClientSeesThatMessageDoesNotHaveTheFlag)
- ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" has the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectHasTheFlag)
- ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" does not have the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectDoesNotHaveTheFlag)
- ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesHaveTheFlag)
- ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages do not have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesDoNotHaveTheFlag)
- ctx.Step(`^IMAP client "([^"]*)" appends the following message to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessageToMailbox)
- ctx.Step(`^IMAP client "([^"]*)" appends the following messages to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessagesToMailbox)
- ctx.Step(`^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$`, s.imapClientAppendsToMailbox)
- ctx.Step(`^IMAP clients "([^"]*)" and "([^"]*)" move message with subject "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*)`, s.imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations)
- ctx.Step(`^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientSeesHeaderInMessageWithSubject)
- ctx.Step(`^IMAP client "([^"]*)" does not see header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientDoesNotSeeHeaderInMessageWithSubject)
-
- // ==== 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)
- ctx.Step(`^user "([^"]*)" connects and authenticates SMTP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesSMTPClientWithAddress)
- 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)
- ctx.Step(`^SMTP client "([^"]*)" sends DATA:$`, s.smtpClientSendsData)
- ctx.Step(`^SMTP client "([^"]*)" sends RSET$`, s.smtpClientSendsReset)
- ctx.Step(`^SMTP client "([^"]*)" sends the following message from "([^"]*)" to "([^"]*)":$`, s.smtpClientSendsTheFollowingMessageFromTo)
- ctx.Step(`^SMTP client "([^"]*)" sends the following EML "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.smtpClientSendsTheFollowingEmlFromTo)
- ctx.Step(`^SMTP client "([^"]*)" logs out$`, s.smtpClientLogsOut)
-
- // ==== TELEMETRY ====
- ctx.Step(`^bridge eventually sends the following heartbeat:$`, s.bridgeEventuallySendsTheFollowingHeartbeat)
- ctx.Step(`^bridge needs to send heartbeat`, s.bridgeNeedsToSendHeartbeat)
- ctx.Step(`^bridge do not need to send heartbeat`, s.bridgeDoNotNeedToSendHeartbeat)
- ctx.Step(`^heartbeat is not whitelisted`, s.heartbeatIsNotwhitelisted)
- ctx.Step(`^config status file exist for user "([^"]*)"$`, s.configStatusFileExistForUser)
- ctx.Step(`^config status is pending for user "([^"]*)"$`, s.configStatusIsPendingForUser)
- ctx.Step(`^config status is pending with failure for user "([^"]*)"$`, s.configStatusIsPendingWithFailureForUser)
- ctx.Step(`^config status succeed for user "([^"]*)"$`, s.configStatusSucceedForUser)
- ctx.Step(`^config status event "([^"]*)" is eventually send (\d+) time`, s.configStatusEventIsEventuallySendXTime)
- ctx.Step(`^config status event "([^"]*)" is not send more than (\d+) time`, s.configStatusEventIsNotSendMoreThanXTime)
- ctx.Step(`^force config status progress to be sent for user"([^"]*)"$`, s.forceConfigStatusProgressToBeSentForUser)
+ s.steps(ctx)
},
Options: &godog.Options{
Format: "pretty",
diff --git a/tests/bridge_test.go b/tests/bridge_test.go
index 2be4aece..df346e08 100644
--- a/tests/bridge_test.go
+++ b/tests/bridge_test.go
@@ -320,11 +320,13 @@ func (s *scenario) bridgeTelemetryFeatureDisabled() error {
}
func (s *scenario) checkTelemetry(expect bool) error {
- res := s.t.bridge.IsTelemetryAvailable(context.Background())
- if res != expect {
- return fmt.Errorf("expected telemetry feature %v but got %v ", expect, res)
- }
- return nil
+ return eventually(func() error {
+ res := s.t.bridge.IsTelemetryAvailable(context.Background())
+ if res != expect {
+ return fmt.Errorf("expected telemetry feature %v but got %v ", expect, res)
+ }
+ return nil
+ })
}
func (s *scenario) theUserHidesAllMail() error {
diff --git a/tests/main_test.go b/tests/main_test.go
index e568f9fa..4bf3e1e6 100644
--- a/tests/main_test.go
+++ b/tests/main_test.go
@@ -26,7 +26,13 @@ import (
)
func TestMain(m *testing.M) {
- if level := os.Getenv("FEATURE_TEST_LOG_LEVEL"); level != "" {
+ level := os.Getenv("FEATURE_TEST_LOG_LEVEL")
+
+ if os.Getenv("BRIDGE_API_DEBUG") != "" {
+ level = "trace"
+ }
+
+ if level != "" {
if parsed, err := logrus.ParseLevel(level); err == nil {
logrus.SetLevel(parsed)
}
diff --git a/tests/steps_test.go b/tests/steps_test.go
new file mode 100644
index 00000000..98269da3
--- /dev/null
+++ b/tests/steps_test.go
@@ -0,0 +1,188 @@
+// Copyright (c) 2023 Proton AG
+//
+// 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 .
+
+package tests
+
+import "github.com/cucumber/godog"
+
+func (s *scenario) steps(ctx *godog.ScenarioContext) {
+ // ==== 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)
+ ctx.Step(`^the header in the "([^"]*)" request to "([^"]*)" has "([^"]*)" set to "([^"]*)"$`, s.theHeaderInTheRequestToHasSetTo)
+ ctx.Step(`^the body in the "([^"]*)" request to "([^"]*)" is:$`, s.theBodyInTheRequestToIs)
+ ctx.Step(`^the body in the "([^"]*)" response to "([^"]*)" is:$`, s.theBodyInTheResponseToIs)
+ ctx.Step(`^the API requires bridge version at least "([^"]*)"$`, s.theAPIRequiresBridgeVersion)
+ ctx.Step(`^the network port (\d+) is busy$`, s.networkPortIsBusy)
+ ctx.Step(`^the network port range (\d+)-(\d+) is busy$`, s.networkPortRangeIsBusy)
+ ctx.Step(`^bridge IMAP port is (\d+)`, s.bridgeIMAPPortIs)
+ ctx.Step(`^bridge SMTP port is (\d+)`, s.bridgeSMTPPortIs)
+ // ==== SETUP ====
+ ctx.Step(`^there exists an account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPassword)
+ ctx.Step(`^there exists a disabled account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPasswordWithDisablePrimary)
+ ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)"$`, s.theAccountHasAdditionalAddress)
+ ctx.Step(`^the account "([^"]*)" has additional disabled address "([^"]*)"$`, s.theAccountHasAdditionalDisabledAddress)
+ ctx.Step(`^the account "([^"]*)" has additional address "([^"]*)" without keys$`, s.theAccountHasAdditionalAddressWithoutKeys)
+ 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)
+ ctx.Step(`^the following fields were changed in draft (\d+) for address "([^"]*)" of account "([^"]*)":$`, s.theFollowingFieldsWereChangedInDraftForAddressOfAccount)
+ ctx.Step(`^draft (\d+) for address "([^"]*)" of account "([^"]*)" was moved to trash$`, s.drafAtIndexWasMovedToTrashForAddressOfAccount)
+
+ // === REPORTER ===
+ ctx.Step(`^test skips reporter checks$`, s.skipReporterChecks)
+
+ // ==== 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 has disabled automatic start`, s.theUserHasDisabledAutomaticStart)
+ ctx.Step(`^the user has enabled alternative routing`, s.theUserHasEnabledAlternativeRouting)
+ ctx.Step(`^the user set IMAP mode to SSL`, s.theUserSetIMAPModeToSSL)
+ ctx.Step(`^the user set SMTP mode to SSL`, s.theUserSetSMTPModeToSSL)
+ ctx.Step(`^the user changes the IMAP port to (\d+)$`, s.theUserChangesTheIMAPPortTo)
+ ctx.Step(`^the user changes the SMTP port to (\d+)$`, s.theUserChangesTheSMTPPortTo)
+ ctx.Step(`^the user sets the address mode of user "([^"]*)" to "([^"]*)"$`, s.theUserSetsTheAddressModeOfUserTo)
+ ctx.Step(`^the user changes the default keychain application`, s.theUserChangesTheDefaultKeychainApplication)
+ ctx.Step(`^the user changes the gluon path$`, s.theUserChangesTheGluonPath)
+ ctx.Step(`^the user deletes the gluon files$`, s.theUserDeletesTheGluonFiles)
+ ctx.Step(`^the user deletes the gluon cache$`, s.theUserDeletesTheGluonCache)
+ ctx.Step(`^the user reports a bug$`, s.theUserReportsABug)
+ ctx.Step(`^the user hides All Mail$`, s.theUserHidesAllMail)
+ ctx.Step(`^the user shows All Mail$`, s.theUserShowsAllMail)
+ ctx.Step(`^the user disables telemetry in bridge settings$`, s.theUserDisablesTelemetryInBridgeSettings)
+ ctx.Step(`^the user enables telemetry in bridge settings$`, s.theUserEnablesTelemetryInBridgeSettings)
+ 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)
+ ctx.Step(`^bridge sends an address created event for user "([^"]*)"$`, s.bridgeSendsAnAddressCreatedEventForUser)
+ ctx.Step(`^bridge sends an address deleted event for user "([^"]*)"$`, s.bridgeSendsAnAddressDeletedEventForUser)
+ 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)
+ ctx.Step(`^bridge reports a message with "([^"]*)"$`, s.bridgeReportsMessage)
+ ctx.Step(`^bridge telemetry feature is enabled$`, s.bridgeTelemetryFeatureEnabled)
+ ctx.Step(`^bridge telemetry feature is disabled$`, s.bridgeTelemetryFeatureDisabled)
+
+ // ==== FRONTEND ====
+ ctx.Step(`^frontend sees that bridge is version "([^"]*)"$`, s.frontendSeesThatBridgeIsVersion)
+
+ // ==== 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 eventually listed and connected$`, s.userIsEventuallyListedAndConnected)
+ 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)
+ ctx.Step(`^user "([^"]*)" has telemetry set to (\d+)$`, s.userHasTelemetrySetTo)
+ ctx.Step(`^the bridge password of user "([^"]*)" is changed to "([^"]*)"`, s.bridgePasswordOfUserIsChangedTo)
+ ctx.Step(`^the bridge password of user "([^"]*)" is equal to "([^"]*)"`, s.bridgePasswordOfUserIsEqualTo)
+
+ // ==== 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)
+ ctx.Step(`^user "([^"]*)" connects and authenticates IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesIMAPClientWithAddress)
+ ctx.Step(`^user "([^"]*)" connects and can not authenticate IMAP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndCanNotAuthenticateIMAPClientWithAddress)
+ ctx.Step(`^IMAP client "([^"]*)" can authenticate$`, s.imapClientCanAuthenticate)
+ ctx.Step(`^IMAP client "([^"]*)" can authenticate with address "([^"]*)"$`, s.imapClientCanAuthenticateWithAddress)
+ ctx.Step(`^IMAP client "([^"]*)" cannot authenticate$`, s.imapClientCannotAuthenticate)
+ ctx.Step(`^IMAP client "([^"]*)" cannot authenticate with address "([^"]*)"$`, s.imapClientCannotAuthenticateWithAddress)
+ 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 "([^"]*)" closes$`, s.imapClientCloses)
+ 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 "([^"]*)" 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)
+ 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)
+ 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 "([^"]*)" eventually sees the following messages in "([^"]*)":$`, s.imapClientEventuallySeesTheFollowingMessagesInMailbox)
+ 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)
+ 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 "([^"]*)" expunges$`, s.imapClientExpunges)
+ ctx.Step(`^IMAP client "([^"]*)" marks message (\d+) as "([^"]*)"$`, s.imapClientMarksMessageAsState)
+ ctx.Step(`^IMAP client "([^"]*)" marks the message with subject "([^"]*)" as "([^"]*)"$`, s.imapClientMarksTheMessageWithSubjectAsState)
+ ctx.Step(`^IMAP client "([^"]*)" marks all messages as "([^"]*)"$`, s.imapClientMarksAllMessagesAsState)
+ ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) has the flag "([^"]*)"$`, s.imapClientSeesThatMessageHasTheFlag)
+ ctx.Step(`^IMAP client "([^"]*)" eventually sees that message at row (\d+) does not have the flag "([^"]*)"$`, s.imapClientSeesThatMessageDoesNotHaveTheFlag)
+ ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" has the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectHasTheFlag)
+ ctx.Step(`^IMAP client "([^"]*)" eventually sees that the message with subject "([^"]*)" does not have the flag "([^"]*)"`, s.imapClientSeesThatTheMessageWithSubjectDoesNotHaveTheFlag)
+ ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesHaveTheFlag)
+ ctx.Step(`^IMAP client "([^"]*)" eventually sees that all the messages do not have the flag "([^"]*)"`, s.imapClientSeesThatAllTheMessagesDoNotHaveTheFlag)
+ ctx.Step(`^IMAP client "([^"]*)" appends the following message to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessageToMailbox)
+ ctx.Step(`^IMAP client "([^"]*)" appends the following messages to "([^"]*)":$`, s.imapClientAppendsTheFollowingMessagesToMailbox)
+ ctx.Step(`^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$`, s.imapClientAppendsToMailbox)
+ ctx.Step(`^IMAP clients "([^"]*)" and "([^"]*)" move message with subject "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*)`, s.imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations)
+ ctx.Step(`^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientSeesHeaderInMessageWithSubject)
+ ctx.Step(`^IMAP client "([^"]*)" does not see header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientDoesNotSeeHeaderInMessageWithSubject)
+
+ // ==== 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)
+ ctx.Step(`^user "([^"]*)" connects and authenticates SMTP client "([^"]*)" with address "([^"]*)"$`, s.userConnectsAndAuthenticatesSMTPClientWithAddress)
+ 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)
+ ctx.Step(`^SMTP client "([^"]*)" sends DATA:$`, s.smtpClientSendsData)
+ ctx.Step(`^SMTP client "([^"]*)" sends RSET$`, s.smtpClientSendsReset)
+ ctx.Step(`^SMTP client "([^"]*)" sends the following message from "([^"]*)" to "([^"]*)":$`, s.smtpClientSendsTheFollowingMessageFromTo)
+ ctx.Step(`^SMTP client "([^"]*)" sends the following EML "([^"]*)" from "([^"]*)" to "([^"]*)"$`, s.smtpClientSendsTheFollowingEmlFromTo)
+ ctx.Step(`^SMTP client "([^"]*)" logs out$`, s.smtpClientLogsOut)
+
+ // ==== TELEMETRY ====
+ ctx.Step(`^bridge eventually sends the following heartbeat:$`, s.bridgeEventuallySendsTheFollowingHeartbeat)
+ ctx.Step(`^bridge needs to send heartbeat`, s.bridgeNeedsToSendHeartbeat)
+ ctx.Step(`^bridge do not need to send heartbeat`, s.bridgeDoNotNeedToSendHeartbeat)
+ ctx.Step(`^heartbeat is not whitelisted`, s.heartbeatIsNotwhitelisted)
+ ctx.Step(`^config status file exist for user "([^"]*)"$`, s.configStatusFileExistForUser)
+ ctx.Step(`^config status is pending for user "([^"]*)"$`, s.configStatusIsPendingForUser)
+ ctx.Step(`^config status is pending with failure for user "([^"]*)"$`, s.configStatusIsPendingWithFailureForUser)
+ ctx.Step(`^config status succeed for user "([^"]*)"$`, s.configStatusSucceedForUser)
+ ctx.Step(`^config status event "([^"]*)" is eventually send (\d+) time`, s.configStatusEventIsEventuallySendXTime)
+ ctx.Step(`^config status event "([^"]*)" is not send more than (\d+) time`, s.configStatusEventIsNotSendMoreThanXTime)
+ ctx.Step(`^force config status progress to be sent for user"([^"]*)"$`, s.forceConfigStatusProgressToBeSentForUser)
+}
diff --git a/tests/types_test.go b/tests/types_test.go
index 183637d6..e654635d 100644
--- a/tests/types_test.go
+++ b/tests/types_test.go
@@ -214,6 +214,7 @@ func matchMailboxes(have, want []Mailbox) error {
func eventually(condition func() error) error {
ch := make(chan error, 1)
+ var lastErr error
var timerDuration = 30 * time.Second
// Extend to 5min for live API.
@@ -230,7 +231,7 @@ func eventually(condition func() error) error {
for tick := ticker.C; ; {
select {
case <-timer.C:
- return fmt.Errorf("timed out")
+ return fmt.Errorf("timed out: %w", lastErr)
case <-tick:
tick = nil
@@ -242,6 +243,7 @@ func eventually(condition func() error) error {
return nil
}
+ lastErr = err
tick = ticker.C
}
}