From 0dac4c5b62655486f935c248e264b86b9ded7850 Mon Sep 17 00:00:00 2001 From: davrot Date: Sat, 1 Feb 2025 22:43:35 +0000 Subject: [PATCH] tests/integration/README.md aktualisiert --- tests/integration/README.md | 231 ++++++++++++++++++++++++++++++++++++ 1 file changed, 231 insertions(+) diff --git a/tests/integration/README.md b/tests/integration/README.md index d83685388e..621fd10faf 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -120,3 +120,234 @@ GITEA_SLOW_TEST_TIME="10s" GITEA_SLOW_FLUSH_TIME="5s" make test-sqlite If you know noteworthy tests that can act as an inspiration for new tests, please add some details here. + + +# Example: Test app.ini parameter with effect on visible elements + +## The test file and where to find it + +The file is defined in: +``` +forgejo/tests/integration/disable_forgotten_password_test.go +``` +and the test function is called: +``` +TestDisableForgottenPasswordTrue +``` + +## How to run the isolated test + +Now we know the name of the test function (well, we defined it). We can run a selected test function via: + + +``` +make clean build +make test-sqlite#TestDisableForgottenPasswordTrue +``` + +## The parameter we want to manipulate + +The first line of interest is +``` +defer test.MockVariableValue(&setting.Service.SignInForgottenPasswordEnabled, true)() +``` + +Here we set the app.ini parameter +``` +[Service] +SIGNIN_FORGOTTEN_PASSWORD_ENABLED +``` +to true. + +As you can see, the test doesn't include the processing of the actual processing of the value entered into the app.ini. We start your test after modules/setting/service.go did this: + +``` +Service.SignInForgottenPasswordEnabled = sec.Key("SIGNIN_FORGOTTEN_PASSWORD_ENABLED").MustBool(true) +``` + +In the case SignInForgottenPasswordEnabled doesn't exist in modules/setting/service.go (e.g. by misspelling it or if it just doesn't exists), you will get an error when running the test. i.e. the test will not run. + + +## Get the page + +Our parameter changes elements on the /user/login page. Thus we want to see what happens there and we need to grep it: + +``` +req := NewRequest(t, "GET", "/user/login/") +resp := MakeRequest(t, req, http.StatusOK) +``` + +Note: You can add "fmt" to the import section and then use e.g. + +``` +fmt.Printf("XXXXX %+v\n",resp) +``` +to "visually" inspect what is going on (here the variable resp). I add the tag XXXXX because this help to visually find the output as well as allow to search for it easily. Or %T to see the type of a variable: +``` +parser := NewHTMLParser(t, resp.Body) +fmt.Printf("XXXXX %T\n",parser) +``` +This tells us that the parser is related to integration.HTMLDoc. (we can google this "go integration.HTMLDoc" for more information) + +## Parse the page and find selectors + +We find more information about integration.HTMLDoc here: https://pkg.go.dev/code.gitea.io/gitea/tests/integration + +More specifically we are interested in .Find() https://pkg.go.dev/code.gitea.io/gitea/tests/integration#HTMLDoc.Find + +After we looked into resp, we know that the target of our interest lies in the lines: + +``` +
+ Forgot password? +
+``` + +Hence we ask the parser to find all instances of a link: +``` +doc := NewHTMLParser(t, resp.Body).Find("a") +``` + +Obviously, there will be more than one link on the page. Thus we will inspect them individually via a for loop: +``` +for i := range doc.Nodes { + one_element := doc.Eq(i) +} +``` + +one_element is of "type Selection" ( more information how the methods type has see here: https://pkg.go.dev/github.com/PuerkitoBio/goquery#Selection ) + +For example we can list the value which is in between "" and "" with + +``` +doc := NewHTMLParser(t, resp.Body).Find("a") +for i := range doc.Nodes { + oneElement := doc.Eq(i) + htmlText, _ := oneElement.Html() + fmt.Printf("XXXXX %+v\n",htmlText) +} +``` +For our problem we could now check for "Forgot password?" which is in between "" "". But this is theoretically depended on the language setting and also not the functionality we want to check against. Hence, we will focus on the link itself. We get the link information via the .Attr() method: + +``` +doc := NewHTMLParser(t, resp.Body).Find("a") +for i := range doc.Nodes { + oneElement := doc.Eq(i) + attValue, attExists := oneElement.Attr("href") + if attExists { + fmt.Printf("XXXXX %+v\n",attValue) + } +} +``` + +This results in: + +``` +XXXXX / +XXXXX /explore/repos +XXXXX https://forgejo.org/docs/latest/ +XXXXX /user/sign_up +XXXXX /user/login +XXXXX /user/sign_up +XXXXX /user/forgot_password +XXXXX https://forgejo.org +XXXXX /assets/licenses.txt +XXXXX /api/swagger +``` + +Now we count the number of instances of "/user/forgot_password" and evaluate that. + +``` +package integration + +import ( + "net/http" + "testing" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" + "code.gitea.io/gitea/tests" + + "github.com/stretchr/testify/assert" +) + +func TestDisableForgottenPasswordTrue(t *testing.T) { + defer tests.PrepareTestEnv(t)() + defer test.MockVariableValue(&setting.Service.SignInForgottenPasswordEnabled, true)() + + req := NewRequest(t, "GET", "/user/login/") + resp := MakeRequest(t, req, http.StatusOK) + doc := NewHTMLParser(t, resp.Body).Find("a") + var counterInstances int = 0 + for i := range doc.Nodes { + oneElement := doc.Eq(i) + attValue, attExists := oneElement.Attr("href") + if attExists { + if attValue == "/user/forgot_password" { + counterInstances += 1 + } + } + } + assert.EqualValues(t, 1, counterInstances) +} +``` + + +One is the loneliest number because it is the only correct solution here. + +``` +assert.EqualValues(t, 1, counterInstances) +``` + +## Adding the two other cases + +We make two copies of + +``` +func TestDisableForgottenPasswordTrue(t *testing.T) +``` + +and call them + +``` +func TestDisableForgottenPasswordDefault(t *testing.T) +``` +and +``` +func TestDisableForgottenPasswordFalse(t *testing.T) +``` + + +In +``` +func TestDisableForgottenPasswordDefault(t *testing.T) +``` +we remove the line +``` +defer test.MockVariableValue(&setting.Service.SignInForgottenPasswordEnabled, true)() +``` +to test the default setting. + + +In +``` +func TestDisableForgottenPasswordFalse(t *testing.T) +``` +we change the two lines: +``` +defer test.MockVariableValue(&setting.Service.SignInForgottenPasswordEnabled, false)() +``` +(parameter is false) +and +``` +assert.EqualValues(t, 0, counterInstances) +``` +(the link never occurs i.e. counterInstances is zero). + + +## Final test +Check if everything works during the real test: +``` +make test-sqlite +``` +