aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAnthony Wang2022-12-30 00:20:02 +0000
committerAnthony Wang2022-12-30 00:20:02 +0000
commit121be02f37a359a8fbc0d9009cf162094d3b79e8 (patch)
treee95ec7207c8e2fffcea1cdce114273cb42139937 /tests
parentbe381fe16b2189ff309f601efdab89c10fcde61d (diff)
parentea5a752ee66f5f8dccbc058c4e1220e24e01b3e8 (diff)
Merge remote-tracking branch 'origin/main' into forgejo-federation
Diffstat (limited to 'tests')
-rw-r--r--tests/integration/api_nodeinfo_test.go2
-rw-r--r--tests/integration/api_team_test.go2
-rw-r--r--tests/integration/integration_test.go65
-rw-r--r--tests/integration/schemas/nodeinfo_2.1.json188
-rw-r--r--tests/integration/signout_test.go3
5 files changed, 244 insertions, 16 deletions
diff --git a/tests/integration/api_nodeinfo_test.go b/tests/integration/api_nodeinfo_test.go
index a7313f3b2..6e80ebc19 100644
--- a/tests/integration/api_nodeinfo_test.go
+++ b/tests/integration/api_nodeinfo_test.go
@@ -27,6 +27,8 @@ func TestNodeinfo(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
req := NewRequestf(t, "GET", "/api/v1/nodeinfo")
resp := MakeRequest(t, req, http.StatusOK)
+ VerifyJSONSchema(t, resp, "nodeinfo_2.1.json")
+
var nodeinfo api.NodeInfo
DecodeJSON(t, resp, &nodeinfo)
assert.True(t, nodeinfo.OpenRegistrations)
diff --git a/tests/integration/api_team_test.go b/tests/integration/api_team_test.go
index 46207203b..f54c286fc 100644
--- a/tests/integration/api_team_test.go
+++ b/tests/integration/api_team_test.go
@@ -24,7 +24,7 @@ import (
func TestAPITeam(t *testing.T) {
defer tests.PrepareTestEnv(t)()
- teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{})
+ teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{ID: 1})
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamUser.TeamID})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser.UID})
diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go
index 9bf4c38ee..911d9ddf4 100644
--- a/tests/integration/integration_test.go
+++ b/tests/integration/integration_test.go
@@ -33,6 +33,7 @@ import (
"github.com/PuerkitoBio/goquery"
"github.com/stretchr/testify/assert"
+ "github.com/xeipuuv/gojsonschema"
)
var c *web.Route
@@ -208,8 +209,6 @@ func (s *TestSession) MakeRequestNilResponseHashSumRecorder(t testing.TB, req *h
const userPassword = "password"
-var loginSessionCache = make(map[string]*TestSession, 10)
-
func emptyTestSession(t testing.TB) *TestSession {
t.Helper()
jar, err := cookiejar.New(nil)
@@ -224,12 +223,8 @@ func getUserToken(t testing.TB, userName string) string {
func loginUser(t testing.TB, userName string) *TestSession {
t.Helper()
- if session, ok := loginSessionCache[userName]; ok {
- return session
- }
- session := loginUserWithPassword(t, userName, userPassword)
- loginSessionCache[userName] = session
- return session
+
+ return loginUserWithPassword(t, userName, userPassword)
}
func loginUserWithPassword(t testing.TB, userName, password string) *TestSession {
@@ -263,18 +258,45 @@ var tokenCounter int64
func getTokenForLoggedInUser(t testing.TB, session *TestSession) string {
t.Helper()
+ var token string
req := NewRequest(t, "GET", "/user/settings/applications")
resp := session.MakeRequest(t, req, http.StatusOK)
- doc := NewHTMLParser(t, resp.Body)
+ var csrf string
+ for _, cookie := range resp.Result().Cookies() {
+ if cookie.Name != "_csrf" {
+ continue
+ }
+ csrf = cookie.Value
+ break
+ }
+ if csrf == "" {
+ doc := NewHTMLParser(t, resp.Body)
+ csrf = doc.GetCSRF()
+ }
+ assert.NotEmpty(t, csrf)
req = NewRequestWithValues(t, "POST", "/user/settings/applications", map[string]string{
- "_csrf": doc.GetCSRF(),
+ "_csrf": csrf,
"name": fmt.Sprintf("api-testing-token-%d", atomic.AddInt64(&tokenCounter, 1)),
})
- session.MakeRequest(t, req, http.StatusSeeOther)
+ resp = session.MakeRequest(t, req, http.StatusSeeOther)
+
+ // Log the flash values on failure
+ if !assert.Equal(t, resp.Result().Header["Location"], []string{"/user/settings/applications"}) {
+ for _, cookie := range resp.Result().Cookies() {
+ if cookie.Name != "macaron_flash" {
+ continue
+ }
+ flash, _ := url.ParseQuery(cookie.Value)
+ for key, value := range flash {
+ t.Logf("Flash %q: %q", key, value)
+ }
+ }
+ }
+
req = NewRequest(t, "GET", "/user/settings/applications")
resp = session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body)
- token := htmlDoc.doc.Find(".ui.info p").Text()
+ token = htmlDoc.doc.Find(".ui.info p").Text()
assert.NotEmpty(t, token)
return token
}
@@ -398,6 +420,25 @@ func DecodeJSON(t testing.TB, resp *httptest.ResponseRecorder, v interface{}) {
assert.NoError(t, decoder.Decode(v))
}
+func VerifyJSONSchema(t testing.TB, resp *httptest.ResponseRecorder, schemaFile string) {
+ t.Helper()
+
+ schemaFilePath := filepath.Join(filepath.Dir(setting.AppPath), "tests", "integration", "schemas", schemaFile)
+ _, schemaFileErr := os.Stat(schemaFilePath)
+ assert.Nil(t, schemaFileErr)
+
+ schema, schemaFileReadErr := os.ReadFile(schemaFilePath)
+ assert.Nil(t, schemaFileReadErr)
+ assert.True(t, len(schema) > 0)
+
+ nodeinfoSchema := gojsonschema.NewStringLoader(string(schema))
+ nodeinfoString := gojsonschema.NewStringLoader(resp.Body.String())
+ result, schemaValidationErr := gojsonschema.Validate(nodeinfoSchema, nodeinfoString)
+ assert.Nil(t, schemaValidationErr)
+ assert.Empty(t, result.Errors())
+ assert.True(t, result.Valid())
+}
+
func GetCSRF(t testing.TB, session *TestSession, urlStr string) string {
t.Helper()
req := NewRequest(t, "GET", urlStr)
diff --git a/tests/integration/schemas/nodeinfo_2.1.json b/tests/integration/schemas/nodeinfo_2.1.json
new file mode 100644
index 000000000..561e64479
--- /dev/null
+++ b/tests/integration/schemas/nodeinfo_2.1.json
@@ -0,0 +1,188 @@
+{
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "id": "http://nodeinfo.diaspora.software/ns/schema/2.1#",
+ "description": "NodeInfo schema version 2.1.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "version",
+ "software",
+ "protocols",
+ "services",
+ "openRegistrations",
+ "usage",
+ "metadata"
+ ],
+ "properties": {
+ "version": {
+ "description": "The schema version, must be 2.1.",
+ "enum": [
+ "2.1"
+ ]
+ },
+ "software": {
+ "description": "Metadata about server software in use.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "name",
+ "version"
+ ],
+ "properties": {
+ "name": {
+ "description": "The canonical name of this server software.",
+ "type": "string",
+ "pattern": "^[a-z0-9-]+$"
+ },
+ "version": {
+ "description": "The version of this server software.",
+ "type": "string"
+ },
+ "repository": {
+ "description": "The url of the source code repository of this server software.",
+ "type": "string"
+ },
+ "homepage": {
+ "description": "The url of the homepage of this server software.",
+ "type": "string"
+ }
+ }
+ },
+ "protocols": {
+ "description": "The protocols supported on this server.",
+ "type": "array",
+ "minItems": 1,
+ "items": {
+ "enum": [
+ "activitypub",
+ "buddycloud",
+ "dfrn",
+ "diaspora",
+ "libertree",
+ "ostatus",
+ "pumpio",
+ "tent",
+ "xmpp",
+ "zot"
+ ]
+ }
+ },
+ "services": {
+ "description": "The third party sites this server can connect to via their application API.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "inbound",
+ "outbound"
+ ],
+ "properties": {
+ "inbound": {
+ "description": "The third party sites this server can retrieve messages from for combined display with regular traffic.",
+ "type": "array",
+ "minItems": 0,
+ "items": {
+ "enum": [
+ "atom1.0",
+ "gnusocial",
+ "imap",
+ "pnut",
+ "pop3",
+ "pumpio",
+ "rss2.0",
+ "twitter"
+ ]
+ }
+ },
+ "outbound": {
+ "description": "The third party sites this server can publish messages to on the behalf of a user.",
+ "type": "array",
+ "minItems": 0,
+ "items": {
+ "enum": [
+ "atom1.0",
+ "blogger",
+ "buddycloud",
+ "diaspora",
+ "dreamwidth",
+ "drupal",
+ "facebook",
+ "friendica",
+ "gnusocial",
+ "google",
+ "insanejournal",
+ "libertree",
+ "linkedin",
+ "livejournal",
+ "mediagoblin",
+ "myspace",
+ "pinterest",
+ "pnut",
+ "posterous",
+ "pumpio",
+ "redmatrix",
+ "rss2.0",
+ "smtp",
+ "tent",
+ "tumblr",
+ "twitter",
+ "wordpress",
+ "xmpp"
+ ]
+ }
+ }
+ }
+ },
+ "openRegistrations": {
+ "description": "Whether this server allows open self-registration.",
+ "type": "boolean"
+ },
+ "usage": {
+ "description": "Usage statistics for this server.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "users"
+ ],
+ "properties": {
+ "users": {
+ "description": "statistics about the users of this server.",
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "total": {
+ "description": "The total amount of on this server registered users.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "activeHalfyear": {
+ "description": "The amount of users that signed in at least once in the last 180 days.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "activeMonth": {
+ "description": "The amount of users that signed in at least once in the last 30 days.",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+ },
+ "localPosts": {
+ "description": "The amount of posts that were made by users that are registered on this server.",
+ "type": "integer",
+ "minimum": 0
+ },
+ "localComments": {
+ "description": "The amount of comments that were made by users that are registered on this server.",
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+ },
+ "metadata": {
+ "description": "Free form key value pairs for software specific values. Clients should not rely on any specific key present.",
+ "type": "object",
+ "minProperties": 0,
+ "additionalProperties": true
+ }
+ }
+}
diff --git a/tests/integration/signout_test.go b/tests/integration/signout_test.go
index 0416930c6..0e822ac04 100644
--- a/tests/integration/signout_test.go
+++ b/tests/integration/signout_test.go
@@ -21,7 +21,4 @@ func TestSignOut(t *testing.T) {
// try to view a private repo, should fail
req = NewRequest(t, "GET", "/user2/repo2")
session.MakeRequest(t, req, http.StatusNotFound)
-
- // invalidate cached cookies for user2, for subsequent tests
- delete(loginSessionCache, "user2")
}