Files
forge/tests/integration/signup_test.go
zeekayandHanzo Dev aa87442fdd Record upstream authorship centrally in NOTICE instead of in every file header
Source files keep their SPDX-License-Identifier and Hanzo copyright line; the
Gitea, Gogs and LFS Test Server copyrights they used to repeat now live once in
NOTICE, alongside LICENSE. The header lint accepts any copyright line above the
SPDX line, so it no longer demands an upstream one.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-10 17:50:35 -07:00

157 lines
6.2 KiB
Go

// Copyright 2026 Hanzo AI, Inc. All rights reserved.
// SPDX-License-Identifier: MIT
package integration
import (
"fmt"
"net/http"
"strings"
"testing"
"github.com/hanzoai/git/models/db"
"github.com/hanzoai/git/models/unittest"
user_model "github.com/hanzoai/git/models/user"
"github.com/hanzoai/git/modules/setting"
"github.com/hanzoai/git/modules/test"
"github.com/hanzoai/git/modules/translation"
"github.com/hanzoai/git/tests"
"github.com/stretchr/testify/assert"
)
func TestSignup(t *testing.T) {
defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Service.EnableCaptcha, false)()
req := NewRequestWithValues(t, "POST", "/user/sign_up", map[string]string{
"user_name": "exampleUser",
"email": "[email protected]",
"password": "examplePassword!1",
"retype": "examplePassword!1",
})
MakeRequest(t, req, http.StatusSeeOther)
// should be able to view new user's page
req = NewRequest(t, "GET", "/exampleUser")
MakeRequest(t, req, http.StatusOK)
}
func TestSignupAsRestricted(t *testing.T) {
defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Service.EnableCaptcha, false)()
defer test.MockVariableValue(&setting.Service.DefaultUserIsRestricted, true)()
req := NewRequestWithValues(t, "POST", "/user/sign_up", map[string]string{
"user_name": "restrictedUser",
"email": "[email protected]",
"password": "examplePassword!1",
"retype": "examplePassword!1",
})
MakeRequest(t, req, http.StatusSeeOther)
// should be able to view new user's page
req = NewRequest(t, "GET", "/restrictedUser")
MakeRequest(t, req, http.StatusOK)
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "restrictedUser"})
assert.True(t, user2.IsRestricted)
}
func TestSignupEmailValidation(t *testing.T) {
defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Service.EnableCaptcha, false)()
tests := []struct {
email string
wantStatus int
wantMsg string
}{
{"[email protected]\r\n", http.StatusOK, translation.NewLocale("en-US").TrString("form.email_invalid")},
{"[email protected]\r", http.StatusOK, translation.NewLocale("en-US").TrString("form.email_invalid")},
{"[email protected]\n", http.StatusOK, translation.NewLocale("en-US").TrString("form.email_invalid")},
{"[email protected]", http.StatusSeeOther, ""},
}
for i, test := range tests {
req := NewRequestWithValues(t, "POST", "/user/sign_up", map[string]string{
"user_name": fmt.Sprintf("exampleUser%d", i),
"email": test.email,
"password": "examplePassword!1",
"retype": "examplePassword!1",
})
resp := MakeRequest(t, req, test.wantStatus)
if test.wantMsg != "" {
htmlDoc := NewHTMLParser(t, resp.Body)
assert.Equal(t,
test.wantMsg,
strings.TrimSpace(htmlDoc.doc.Find(".ui.message").Text()),
)
}
}
}
func TestSignupEmailActive(t *testing.T) {
defer tests.PrepareTestEnv(t)()
defer test.MockVariableValue(&setting.Service.RegisterEmailConfirm, true)()
// try to sign up and send the activation email
req := NewRequestWithValues(t, "POST", "/user/sign_up", map[string]string{
"user_name": "Test-User-1",
"email": "[email protected]",
"password": "password1",
"retype": "password1",
})
resp := MakeRequest(t, req, http.StatusOK)
assert.Contains(t, resp.Body.String(), `A new confirmation email has been sent to <b>[email protected]</b>.`)
// access "user/activate" means trying to re-send the activation email
session := loginUserWithPassword(t, "test-user-1", "password1")
resp = session.MakeRequest(t, NewRequest(t, "GET", "/user/activate"), http.StatusOK)
assert.Contains(t, resp.Body.String(), "You have already requested an activation email recently")
// access anywhere else will see an "Activate Your Account" prompt, and there is a chance to change email
resp = session.MakeRequest(t, NewRequest(t, "GET", "/user/issues"), http.StatusOK)
assert.Contains(t, resp.Body.String(), `<input id="change-email" name="change_email" `)
// post to "user/activate" with a new email
session.MakeRequest(t, NewRequestWithValues(t, "POST", "/user/activate", map[string]string{"change_email": "[email protected]"}), http.StatusSeeOther)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "Test-User-1"})
assert.Equal(t, "[email protected]", user.Email)
email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "[email protected]"})
assert.False(t, email.IsActivated)
assert.True(t, email.IsPrimary)
// generate an activation code from lower-cased email
activationCode := user_model.GenerateUserTimeLimitCode(&user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeActivateAccount}, user)
// and update the user email to case-sensitive, it shouldn't affect the verification later
_, _ = db.Exec(t.Context(), "UPDATE `user` SET email=? WHERE id=?", "[email protected]", user.ID)
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "Test-User-1"})
assert.Equal(t, "[email protected]", user.Email)
// access "user/activate" with a valid activation code, then get the "verify password" page
resp = session.MakeRequest(t, NewRequest(t, "GET", "/user/activate?code="+activationCode), http.StatusOK)
assert.Contains(t, resp.Body.String(), `<input id="verify-password"`)
// try to use a wrong password, it should fail
req = NewRequestWithValues(t, "POST", "/user/activate", map[string]string{
"code": activationCode,
"password": "password-wrong",
})
resp = session.MakeRequest(t, req, http.StatusOK)
assert.Contains(t, resp.Body.String(), `Your password does not match`)
assert.Contains(t, resp.Body.String(), `<input id="verify-password"`)
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "Test-User-1"})
assert.False(t, user.IsActive)
// then use a correct password, the user should be activated
req = NewRequestWithValues(t, "POST", "/user/activate", map[string]string{
"code": activationCode,
"password": "password1",
})
resp = session.MakeRequest(t, req, http.StatusSeeOther)
assert.Equal(t, "/", test.RedirectURL(resp))
user = unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "Test-User-1"})
assert.True(t, user.IsActive)
}