mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
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]>
157 lines
6.2 KiB
Go
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)
|
|
}
|