feat: apply service.VALID_SITE_URL_SCHEMES to apply to repository and organization profiles (#12962)
Turns out this was a one-line fix for each affected field (change the binding from `ValidUrl` to `ValidSiteUrl`), but the tests are rather verbose. The tests are, however, each a simple flow of Create Thing > Try HTTP Website > Try Different Website (notice failure) > Try Different Website With New Config (notice success). I wrote this PR by adding failing tests first, then making the change, for each affected field. Not sure if this should be "feat:" or "fix:" tbh. I figured "fix:" for this PR since IMO the expected behavior is for `VALID_SITE_URL_SCHEMES` to apply in each of these cases, not only for user profiles via the UI form. (Later changed to "feat:" at @limiting-factor's suggestion, based on the observation that this change extends documented behavior.) This PR deals with the server-side validation only. #12991 covers client-side validation (deriving a `pattern` attribute from `VALID_SITE_URL_SCHEMES`, etc.) Closes #5519 Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/12962 Reviewed-by: limiting-factor <limiting-factor@noreply.codeberg.org>
This commit is contained in:
@@ -915,7 +915,7 @@ LEVEL = Info
|
||||
;;
|
||||
;; Minimum amount of time a user must exist before comments are kept when the user is deleted.
|
||||
;USER_DELETE_WITH_COMMENTS_MAX_TIME = 0
|
||||
;; Valid site url schemes for user profiles
|
||||
;; Valid site url schemes for user, organization, or repository profiles
|
||||
;VALID_SITE_URL_SCHEMES=http,https
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
@@ -37,7 +37,7 @@ type EditUserOption struct {
|
||||
FullName *string `json:"full_name" binding:"MaxSize(100)"`
|
||||
Password string `json:"password" binding:"MaxSize(255)"`
|
||||
MustChangePassword *bool `json:"must_change_password"`
|
||||
Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"`
|
||||
Website *string `json:"website" binding:"OmitEmpty;ValidSiteUrl;MaxSize(255)"`
|
||||
Location *string `json:"location" binding:"MaxSize(50)"`
|
||||
Pronouns *string `json:"pronouns" binding:"MaxSize(50)"`
|
||||
Description *string `json:"description" binding:"MaxSize(255)"`
|
||||
|
||||
@@ -38,7 +38,7 @@ type CreateOrgOption struct {
|
||||
FullName string `json:"full_name" binding:"MaxSize(100)"`
|
||||
Email string `json:"email" binding:"MaxSize(255)"`
|
||||
Description string `json:"description" binding:"MaxSize(255)"`
|
||||
Website string `json:"website" binding:"ValidUrl;MaxSize(255)"`
|
||||
Website string `json:"website" binding:"ValidSiteUrl;MaxSize(255)"`
|
||||
Location string `json:"location" binding:"MaxSize(50)"`
|
||||
// possible values are `public` (default), `limited` or `private`
|
||||
// enum: ["public", "limited", "private"]
|
||||
@@ -53,7 +53,7 @@ type EditOrgOption struct {
|
||||
FullName string `json:"full_name" binding:"MaxSize(100)"`
|
||||
Email *string `json:"email" binding:"MaxSize(255)"`
|
||||
Description string `json:"description" binding:"MaxSize(255)"`
|
||||
Website string `json:"website" binding:"ValidUrl;MaxSize(255)"`
|
||||
Website string `json:"website" binding:"ValidSiteUrl;MaxSize(255)"`
|
||||
Location string `json:"location" binding:"MaxSize(50)"`
|
||||
// possible values are `public`, `limited` or `private`
|
||||
// enum: ["public", "limited", "private"]
|
||||
|
||||
@@ -92,7 +92,7 @@ type UserSettings struct {
|
||||
// swagger:model
|
||||
type UserSettingsOptions struct {
|
||||
FullName *string `json:"full_name" binding:"MaxSize(100)"`
|
||||
Website *string `json:"website" binding:"OmitEmpty;ValidUrl;MaxSize(255)"`
|
||||
Website *string `json:"website" binding:"OmitEmpty;ValidSiteUrl;MaxSize(255)"`
|
||||
Description *string `json:"description" binding:"MaxSize(255)"`
|
||||
Location *string `json:"location" binding:"MaxSize(50)"`
|
||||
Pronouns *string `json:"pronouns" binding:"MaxSize(50)"`
|
||||
|
||||
@@ -39,7 +39,7 @@ type AdminEditUserForm struct {
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Email string `binding:"Required;EmailForAdmin;MaxSize(254)"`
|
||||
Password string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"ValidUrl;MaxSize(255)"`
|
||||
Website string `binding:"ValidSiteUrl;MaxSize(255)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
Language string `binding:"MaxSize(5)"`
|
||||
Pronouns string `binding:"MaxSize(50)"`
|
||||
|
||||
@@ -40,7 +40,7 @@ type UpdateOrgSettingForm struct {
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Email string `binding:"MaxSize(255)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"ValidUrl;MaxSize(255)"`
|
||||
Website string `binding:"ValidSiteUrl;MaxSize(255)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
Visibility structs.VisibleType
|
||||
MaxRepoCreation int
|
||||
|
||||
@@ -130,7 +130,7 @@ func ParseRemoteAddr(remoteAddr, authUsername, authPassword string) (string, err
|
||||
type RepoSettingForm struct {
|
||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||
Description string `binding:"MaxSize(2048)"`
|
||||
Website string `binding:"ValidUrl;MaxSize(1024)"`
|
||||
Website string `binding:"ValidSiteUrl;MaxSize(1024)"`
|
||||
FollowingRepos string
|
||||
Interval string
|
||||
MirrorAddress string
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -15,9 +16,12 @@ import (
|
||||
issues_model "forgejo.org/models/issues"
|
||||
"forgejo.org/models/unittest"
|
||||
user_model "forgejo.org/models/user"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
"forgejo.org/modules/timeutil"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@@ -128,6 +132,63 @@ func TestAdminEditUserHideEmail(t *testing.T) {
|
||||
htmlDoc.AssertElement(t, `input[name="hide_email"][checked]`, true)
|
||||
}
|
||||
|
||||
func TestAdminEditUserWebsite(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
session := loginUser(t, "user1")
|
||||
user := forgery.CreateUser(t, nil)
|
||||
urlStr := fmt.Sprintf("/admin/users/%d/edit", user.ID)
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"user_name": user.Name,
|
||||
"login_name": user.LoginName,
|
||||
"login_type": "0-0",
|
||||
"email": user.Email,
|
||||
"website": "https://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should not work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"user_name": user.Name,
|
||||
"login_name": user.LoginName,
|
||||
"login_type": "0-0",
|
||||
"email": user.Email,
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
flash := doc.Find("#flash-message").Text()
|
||||
assert.Equal(t, `Website"Url" is not a valid URL.`, strings.TrimSpace(flash))
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"user_name": user.Name,
|
||||
"login_name": user.LoginName,
|
||||
"login_type": "0-0",
|
||||
"email": user.Email,
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
}
|
||||
|
||||
func testSuccessfulEdit(t *testing.T, formData user_model.User) {
|
||||
makeRequest(t, formData, http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,9 @@ import (
|
||||
"forgejo.org/modules/json"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
"forgejo.org/tests"
|
||||
"forgejo.org/tests/forgery"
|
||||
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -512,6 +514,65 @@ func TestAPIEditUser_NotAllowedEmailDomain(t *testing.T) {
|
||||
MakeRequest(t, req, http.StatusOK)
|
||||
}
|
||||
|
||||
func TestAPIUser_Website(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
session := loginUser(t, "user1")
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteAdmin)
|
||||
user := forgery.CreateUser(t, nil)
|
||||
urlStr := fmt.Sprintf("/api/v1/admin/users/%s", user.Name)
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should work
|
||||
website := "https://codeberg.org"
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditUserOption{
|
||||
Website: &website,
|
||||
}).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var apiUser api.User
|
||||
DecodeJSON(t, resp, &apiUser)
|
||||
|
||||
assert.Equal(t, website, apiUser.Website)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should not work
|
||||
website := "h3://codeberg.org"
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditUserOption{
|
||||
Website: &website,
|
||||
}).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||
|
||||
var apiErr api.APIError
|
||||
DecodeJSON(t, resp, &apiErr)
|
||||
|
||||
assert.Equal(t, "[Website]: Url", apiErr.Message)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// changing website should work
|
||||
website := "h3://codeberg.org"
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.EditUserOption{
|
||||
Website: &website,
|
||||
}).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var apiUser api.User
|
||||
DecodeJSON(t, resp, &apiUser)
|
||||
|
||||
assert.Equal(t, website, apiUser.Website)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPIAdminListUserEmails(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
|
||||
@@ -100,6 +100,67 @@ func TestAPIOrgCreate(t *testing.T) {
|
||||
assert.Equal(t, "user1", users[0].UserName)
|
||||
}
|
||||
|
||||
func TestAPIOrgCreateWithWebsite(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization)
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// setting website should work
|
||||
org := api.CreateOrgOption{
|
||||
UserName: "user1_org",
|
||||
FullName: "User1's organization",
|
||||
Website: "https://codeberg.org",
|
||||
}
|
||||
req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
var apiOrg api.Organization
|
||||
DecodeJSON(t, resp, &apiOrg)
|
||||
|
||||
assert.Equal(t, org.Website, apiOrg.Website)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// setting website should not work
|
||||
org := api.CreateOrgOption{
|
||||
UserName: "user1_org_2",
|
||||
FullName: "User1's second organization",
|
||||
Website: "h3://codeberg.org",
|
||||
}
|
||||
req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||
|
||||
var apiErr api.APIError
|
||||
DecodeJSON(t, resp, &apiErr)
|
||||
|
||||
assert.Equal(t, "[Website]: Url", apiErr.Message)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// setting website should work
|
||||
org := api.CreateOrgOption{
|
||||
UserName: "user1_org_2",
|
||||
FullName: "User1's second organization",
|
||||
Website: "h3://codeberg.org",
|
||||
}
|
||||
req := NewRequestWithJSON(t, "POST", "/api/v1/orgs", &org).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusCreated)
|
||||
|
||||
var apiOrg api.Organization
|
||||
DecodeJSON(t, resp, &apiOrg)
|
||||
|
||||
assert.Equal(t, org.Website, apiOrg.Website)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPIOrgRename(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
token := getUserToken(t, "user1", auth_model.AccessTokenScopeWriteOrganization)
|
||||
@@ -150,6 +211,64 @@ func TestAPIOrgEdit(t *testing.T) {
|
||||
assert.Equal(t, org.Visibility, apiOrg.Visibility)
|
||||
}
|
||||
|
||||
func TestAPIOrgEditWebsite(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
const orgName = "org3"
|
||||
urlStr := fmt.Sprintf("/api/v1/orgs/%s", orgName)
|
||||
session := loginUser(t, "user1")
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteOrganization)
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should work
|
||||
org := api.EditOrgOption{
|
||||
Website: "https://codeberg.org",
|
||||
}
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &org).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var apiOrg api.Organization
|
||||
DecodeJSON(t, resp, &apiOrg)
|
||||
|
||||
assert.Equal(t, org.Website, apiOrg.Website)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should not work
|
||||
org := api.EditOrgOption{
|
||||
Website: "h3://codeberg.org",
|
||||
}
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &org).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||
|
||||
var apiErr api.APIError
|
||||
DecodeJSON(t, resp, &apiErr)
|
||||
|
||||
assert.Equal(t, "[Website]: Url", apiErr.Message)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// changing website should work
|
||||
org := api.EditOrgOption{
|
||||
Website: "h3://codeberg.org",
|
||||
}
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &org).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var apiOrg api.Organization
|
||||
DecodeJSON(t, resp, &apiOrg)
|
||||
|
||||
assert.Equal(t, org.Website, apiOrg.Website)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAPIOrgEditBadVisibility(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
session := loginUser(t, "user1")
|
||||
|
||||
@@ -6,10 +6,13 @@ package integration
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
auth_model "forgejo.org/models/auth"
|
||||
"forgejo.org/modules/setting"
|
||||
api "forgejo.org/modules/structs"
|
||||
"forgejo.org/modules/test"
|
||||
"forgejo.org/tests"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -94,3 +97,51 @@ func TestOrgSettingsChangeEmail(t *testing.T) {
|
||||
assert.Empty(t, org.Email)
|
||||
})
|
||||
}
|
||||
|
||||
func TestOrgSettingsUpdateWebsite(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
const orgName = "org3"
|
||||
urlStr := fmt.Sprintf("/org/%s/settings", orgName)
|
||||
session := loginUser(t, "user1")
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"name": orgName,
|
||||
"website": "https://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should not work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"name": orgName,
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
flash := doc.Find("#flash-message").Text()
|
||||
assert.Equal(t, `Website"Url" is not a valid URL.`, strings.TrimSpace(flash))
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"name": orgName,
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ package integration
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"forgejo.org/models/db"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"forgejo.org/models/unittest"
|
||||
"forgejo.org/modules/optional"
|
||||
"forgejo.org/modules/setting"
|
||||
"forgejo.org/modules/test"
|
||||
app_context "forgejo.org/services/context"
|
||||
repo_service "forgejo.org/services/repository"
|
||||
user_service "forgejo.org/services/user"
|
||||
@@ -36,6 +38,56 @@ func TestRepoSettingsUnits(t *testing.T) {
|
||||
session.MakeRequest(t, req, http.StatusOK)
|
||||
}
|
||||
|
||||
func TestRepoSettingsUpdateWebsite(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
repo := forgery.CreateRepository(t, nil, nil)
|
||||
session := loginUser(t, repo.Owner.Name)
|
||||
urlStr := fmt.Sprintf("%s/settings", repo.Link())
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"action": "update",
|
||||
"repo_name": repo.Name,
|
||||
"website": "https://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should not work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"action": "update",
|
||||
"repo_name": repo.Name,
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
flash := doc.Find("#flash-message").Text()
|
||||
assert.Equal(t, `Website"Url" is not a valid URL.`, strings.TrimSpace(flash))
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", urlStr, map[string]string{
|
||||
"action": "update",
|
||||
"repo_name": repo.Name,
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepoSettingsAdminOptions(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ package integration
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"forgejo.org/models/auth"
|
||||
@@ -133,6 +134,48 @@ func TestUserSettingsDelete(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserSettingsUpdateWebsite(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
session := loginUser(t, "user2")
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
|
||||
"website": "https://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should not work
|
||||
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusOK)
|
||||
doc := NewHTMLParser(t, resp.Body)
|
||||
flash := doc.Find("#flash-message").Text()
|
||||
assert.Equal(t, `Website"Url" is not a valid URL.`, strings.TrimSpace(flash))
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// changing website should work
|
||||
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
|
||||
"website": "h3://codeberg.org",
|
||||
})
|
||||
resp := session.MakeRequest(t, req, http.StatusSeeOther)
|
||||
assertHasFlashMessages(t, resp, "success")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserRename(t *testing.T) {
|
||||
defer unittest.OverrideFixtures("tests/integration/fixtures/TestUserRename")()
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
@@ -742,6 +742,65 @@ func TestUserPronouns(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserEditWebsite(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
user := forgery.CreateUser(t, nil)
|
||||
urlStr := "/api/v1/user/settings"
|
||||
session := loginUser(t, user.Name)
|
||||
token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)
|
||||
|
||||
t.Run("an HTTPS website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should work
|
||||
website := "https://codeberg.org"
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.UserSettingsOptions{
|
||||
Website: &website,
|
||||
}).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var apiUser api.UserSettings
|
||||
DecodeJSON(t, resp, &apiUser)
|
||||
|
||||
assert.Equal(t, website, apiUser.Website)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under default schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
|
||||
// changing website should not work
|
||||
website := "h3://codeberg.org"
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.UserSettingsOptions{
|
||||
Website: &website,
|
||||
}).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusUnprocessableEntity)
|
||||
|
||||
var apiErr api.APIError
|
||||
DecodeJSON(t, resp, &apiErr)
|
||||
|
||||
assert.Equal(t, "[Website]: Url", apiErr.Message)
|
||||
})
|
||||
|
||||
t.Run("an H3 website under custom schemes", func(t *testing.T) {
|
||||
defer tests.PrintCurrentTest(t)()
|
||||
defer test.MockProtect(&setting.Service.ValidSiteURLSchemes)()
|
||||
setting.Service.ValidSiteURLSchemes = append(setting.Service.ValidSiteURLSchemes, "h3")
|
||||
|
||||
// changing website should work
|
||||
website := "h3://codeberg.org"
|
||||
req := NewRequestWithJSON(t, "PATCH", urlStr, &api.UserSettingsOptions{
|
||||
Website: &website,
|
||||
}).AddTokenAuth(token)
|
||||
resp := MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
var apiUser api.UserSettings
|
||||
DecodeJSON(t, resp, &apiUser)
|
||||
|
||||
assert.Equal(t, website, apiUser.Website)
|
||||
})
|
||||
}
|
||||
|
||||
func TestUserTOTPMail(t *testing.T) {
|
||||
defer tests.PrepareTestEnv(t)()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user