tests/cloud_account_confirmation_test.go
Rama master · réplica de lectura del repositorio original.
package main
import (
"context"
"net/http"
"testing"
"github.com/go-resty/resty/v2"
"github.com/shellhub-io/shellhub/pkg/models"
"github.com/shellhub-io/shellhub/tests/environment"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
// TestCloudAccountConfirmation runs a cloud instance, the only edition with open sign-up, for the
// code a new account confirms its email with.
func TestCloudAccountConfirmation(t *testing.T) {
t.Parallel()
ctx := context.Background()
compose := environment.New(t, run).WithEdition(environment.EditionCloud).Up(ctx)
t.Cleanup(compose.Down)
t.Run("the emailed code confirms the account and signs it in", func(t *testing.T) {
email := signUp(t, compose, "confirm-code")
code := confirmationCode(t, compose.AwaitEmail(t, email, "/confirm-account"))
auth := requireConfirmed(t, compose, "confirm-code", code)
resp, err := asBearer(t, compose, auth.Token).Get("/api/auth/user")
require.NoError(t, err)
assert.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())
})
t.Run("the email confirms an account signed in with its email", func(t *testing.T) {
email := signUp(t, compose, "confirm-by-email")
code := confirmationCode(t, compose.AwaitEmail(t, email, "/confirm-account"))
requireConfirmed(t, compose, email, code)
})
t.Run("wrong codes lock a pending and an unknown identifier out alike, on the third", func(t *testing.T) {
email := signUp(t, compose, "confirm-wrong")
code := confirmationCode(t, compose.AwaitEmail(t, email, "/confirm-account"))
wrong := "000000"
if code == wrong {
wrong = "111111"
}
for _, identifier := range []string{"confirm-wrong", "confirm-unknown"} {
for _, status := range []int{http.StatusUnauthorized, http.StatusUnauthorized, http.StatusTooManyRequests} {
resp := confirmAccount(t, compose, identifier, wrong, nil)
require.Equal(t, status, resp.StatusCode(), "%s: %s", identifier, resp.String())
}
}
})
t.Run("a resend delivers the same code, once a minute", func(t *testing.T) {
email := signUp(t, compose, "confirm-resend")
first := confirmationCode(t, compose.AwaitEmail(t, email, "/confirm-account"))
resp := resend(t, compose, "confirm-resend")
require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())
emails := compose.AwaitEmails(t, email, "/confirm-account", 2)
assert.Equal(t, first, confirmationCode(t, emails[0]))
resp = resend(t, compose, "confirm-resend")
assert.Equal(t, http.StatusTooManyRequests, resp.StatusCode(), resp.String())
})
t.Run("a resend answers alike for an unknown and a confirmed account, and sends nothing", func(t *testing.T) {
done := "confirm-done" + stripeTestEmailDomain
compose.NewUser(t, "confirm-done", done, ShellHubPassword)
for _, identifier := range []string{"confirm-nobody", "confirm-done"} {
resp := resend(t, compose, identifier)
assert.Equal(t, http.StatusOK, resp.StatusCode(), "%s: %s", identifier, resp.String())
}
pending := signUp(t, compose, "confirm-flushed")
compose.AwaitEmail(t, pending, "/confirm-account")
assert.Empty(t, compose.Emails(t, done, "/confirm-account"))
})
t.Run("a code never confirms a confirmed account", func(t *testing.T) {
compose.NewUser(t, "confirm-already", "confirm-already"+stripeTestEmailDomain, ShellHubPassword)
resp := confirmAccount(t, compose, "confirm-already", "123456", nil)
assert.Equal(t, http.StatusUnauthorized, resp.StatusCode(), resp.String())
})
t.Run("signing in to a pending account checks the password first", func(t *testing.T) {
signUp(t, compose, "confirm-login")
for password, status := range map[string]int{"wrong-password": http.StatusUnauthorized, ShellHubPassword: http.StatusForbidden} {
resp, err := compose.Anonymous(t.Context()).
SetBody(map[string]string{"username": "confirm-login", "password": password}).
Post("/api/login")
require.NoError(t, err)
assert.Equal(t, status, resp.StatusCode(), "%s: %s", password, resp.String())
}
})
}
func signUp(t *testing.T, compose *environment.DockerCompose, username string) string {
t.Helper()
email := username + stripeTestEmailDomain
resp := signUpWithEmail(t, compose, username, email)
require.Equal(t, http.StatusNoContent, resp.StatusCode(), resp.String())
return email
}
func confirmationCode(t *testing.T, email environment.Email) string {
t.Helper()
code, ok := email.Labelled("Confirmation code")
require.True(t, ok, "the email carries no confirmation code: %s", email.Text())
require.Len(t, code, 6)
return code
}
func confirmAccount(t *testing.T, compose *environment.DockerCompose, identifier, code string, result any) *resty.Response {
t.Helper()
req := compose.Anonymous(t.Context()).
SetBody(map[string]string{"identifier": identifier, "code": code})
if result != nil {
req.SetResult(result)
}
resp, err := req.Post("/api/user/confirm_account")
require.NoError(t, err)
return resp
}
func requireConfirmed(t *testing.T, compose *environment.DockerCompose, identifier, code string) *models.UserAuthResponse {
t.Helper()
auth := new(models.UserAuthResponse)
resp := confirmAccount(t, compose, identifier, code, auth)
require.Equal(t, http.StatusOK, resp.StatusCode(), resp.String())
require.NotEmpty(t, auth.Token)
return auth
}
func resend(t *testing.T, compose *environment.DockerCompose, identifier string) *resty.Response {
t.Helper()
resp, err := compose.Anonymous(t.Context()).
SetBody(map[string]string{"identifier": identifier}).
Post("/api/user/resend_email")
require.NoError(t, err)
return resp
}