code.gitea.io/gitea@v1.22.3/tests/integration/repo_commits_test.go (about) 1 // Copyright 2017 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "fmt" 8 "net/http" 9 "net/http/httptest" 10 "path" 11 "sync" 12 "testing" 13 14 auth_model "code.gitea.io/gitea/models/auth" 15 "code.gitea.io/gitea/modules/json" 16 "code.gitea.io/gitea/modules/setting" 17 api "code.gitea.io/gitea/modules/structs" 18 "code.gitea.io/gitea/tests" 19 20 "github.com/stretchr/testify/assert" 21 ) 22 23 func TestRepoCommits(t *testing.T) { 24 defer tests.PrepareTestEnv(t)() 25 26 session := loginUser(t, "user2") 27 28 // Request repository commits page 29 req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master") 30 resp := session.MakeRequest(t, req, http.StatusOK) 31 32 doc := NewHTMLParser(t, resp.Body) 33 commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Attr("href") 34 assert.True(t, exists) 35 assert.NotEmpty(t, commitURL) 36 } 37 38 func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) { 39 defer tests.PrepareTestEnv(t)() 40 41 session := loginUser(t, "user2") 42 43 // Request repository commits page 44 req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master") 45 resp := session.MakeRequest(t, req, http.StatusOK) 46 47 doc := NewHTMLParser(t, resp.Body) 48 // Get first commit URL 49 commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Attr("href") 50 assert.True(t, exists) 51 assert.NotEmpty(t, commitURL) 52 53 // Call API to add status for commit 54 ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository) 55 t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ 56 State: api.CommitStatusState(state), 57 TargetURL: "http://test.ci/", 58 Description: "", 59 Context: "testci", 60 })) 61 62 req = NewRequest(t, "GET", "/user2/repo1/commits/branch/master") 63 resp = session.MakeRequest(t, req, http.StatusOK) 64 65 doc = NewHTMLParser(t, resp.Body) 66 // Check if commit status is displayed in message column (.tippy-target to ignore the tippy trigger) 67 sel := doc.doc.Find("#commits-table tbody tr td.message .tippy-target .commit-status") 68 assert.Equal(t, 1, sel.Length()) 69 for _, class := range classes { 70 assert.True(t, sel.HasClass(class)) 71 } 72 73 // By SHA 74 req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/"+path.Base(commitURL)+"/statuses") 75 reqOne := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/"+path.Base(commitURL)+"/status") 76 testRepoCommitsWithStatus(t, session.MakeRequest(t, req, http.StatusOK), session.MakeRequest(t, reqOne, http.StatusOK), state) 77 78 // By short SHA 79 req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/"+path.Base(commitURL)[:10]+"/statuses") 80 reqOne = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/"+path.Base(commitURL)[:10]+"/status") 81 testRepoCommitsWithStatus(t, session.MakeRequest(t, req, http.StatusOK), session.MakeRequest(t, reqOne, http.StatusOK), state) 82 83 // By Ref 84 req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/master/statuses") 85 reqOne = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/master/status") 86 testRepoCommitsWithStatus(t, session.MakeRequest(t, req, http.StatusOK), session.MakeRequest(t, reqOne, http.StatusOK), state) 87 req = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/v1.1/statuses") 88 reqOne = NewRequest(t, "GET", "/api/v1/repos/user2/repo1/commits/v1.1/status") 89 testRepoCommitsWithStatus(t, session.MakeRequest(t, req, http.StatusOK), session.MakeRequest(t, reqOne, http.StatusOK), state) 90 } 91 92 func testRepoCommitsWithStatus(t *testing.T, resp, respOne *httptest.ResponseRecorder, state string) { 93 var statuses []*api.CommitStatus 94 assert.NoError(t, json.Unmarshal(resp.Body.Bytes(), &statuses)) 95 var status api.CombinedStatus 96 assert.NoError(t, json.Unmarshal(respOne.Body.Bytes(), &status)) 97 assert.NotNil(t, status) 98 99 if assert.Len(t, statuses, 1) { 100 assert.Equal(t, api.CommitStatusState(state), statuses[0].State) 101 assert.Equal(t, setting.AppURL+"api/v1/repos/user2/repo1/statuses/65f1bf27bc3bf70f64657658635e66094edbcb4d", statuses[0].URL) 102 assert.Equal(t, "http://test.ci/", statuses[0].TargetURL) 103 assert.Equal(t, "", statuses[0].Description) 104 assert.Equal(t, "testci", statuses[0].Context) 105 106 assert.Len(t, status.Statuses, 1) 107 assert.Equal(t, statuses[0], status.Statuses[0]) 108 assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", status.SHA) 109 } 110 } 111 112 func TestRepoCommitsWithStatusPending(t *testing.T) { 113 doTestRepoCommitWithStatus(t, "pending", "octicon-dot-fill", "yellow") 114 } 115 116 func TestRepoCommitsWithStatusSuccess(t *testing.T) { 117 doTestRepoCommitWithStatus(t, "success", "octicon-check", "green") 118 } 119 120 func TestRepoCommitsWithStatusError(t *testing.T) { 121 doTestRepoCommitWithStatus(t, "error", "gitea-exclamation", "red") 122 } 123 124 func TestRepoCommitsWithStatusFailure(t *testing.T) { 125 doTestRepoCommitWithStatus(t, "failure", "octicon-x", "red") 126 } 127 128 func TestRepoCommitsWithStatusWarning(t *testing.T) { 129 doTestRepoCommitWithStatus(t, "warning", "gitea-exclamation", "yellow") 130 } 131 132 func TestRepoCommitsStatusParallel(t *testing.T) { 133 defer tests.PrepareTestEnv(t)() 134 135 session := loginUser(t, "user2") 136 137 // Request repository commits page 138 req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master") 139 resp := session.MakeRequest(t, req, http.StatusOK) 140 141 doc := NewHTMLParser(t, resp.Body) 142 // Get first commit URL 143 commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Attr("href") 144 assert.True(t, exists) 145 assert.NotEmpty(t, commitURL) 146 147 var wg sync.WaitGroup 148 for i := 0; i < 10; i++ { 149 wg.Add(1) 150 go func(parentT *testing.T, i int) { 151 parentT.Run(fmt.Sprintf("ParallelCreateStatus_%d", i), func(t *testing.T) { 152 ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository) 153 runBody := doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ 154 State: api.CommitStatusPending, 155 TargetURL: "http://test.ci/", 156 Description: "", 157 Context: "testci", 158 }) 159 runBody(t) 160 wg.Done() 161 }) 162 }(t, i) 163 } 164 wg.Wait() 165 } 166 167 func TestRepoCommitsStatusMultiple(t *testing.T) { 168 defer tests.PrepareTestEnv(t)() 169 170 session := loginUser(t, "user2") 171 172 // Request repository commits page 173 req := NewRequest(t, "GET", "/user2/repo1/commits/branch/master") 174 resp := session.MakeRequest(t, req, http.StatusOK) 175 176 doc := NewHTMLParser(t, resp.Body) 177 // Get first commit URL 178 commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Attr("href") 179 assert.True(t, exists) 180 assert.NotEmpty(t, commitURL) 181 182 // Call API to add status for commit 183 ctx := NewAPITestContext(t, "user2", "repo1", auth_model.AccessTokenScopeWriteRepository) 184 t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ 185 State: api.CommitStatusSuccess, 186 TargetURL: "http://test.ci/", 187 Description: "", 188 Context: "testci", 189 })) 190 191 t.Run("CreateStatus", doAPICreateCommitStatus(ctx, path.Base(commitURL), api.CreateStatusOption{ 192 State: api.CommitStatusSuccess, 193 TargetURL: "http://test.ci/", 194 Description: "", 195 Context: "other_context", 196 })) 197 198 req = NewRequest(t, "GET", "/user2/repo1/commits/branch/master") 199 resp = session.MakeRequest(t, req, http.StatusOK) 200 201 doc = NewHTMLParser(t, resp.Body) 202 // Check that the data-tippy="commit-statuses" (for trigger) and commit-status (svg) are present 203 sel := doc.doc.Find("#commits-table tbody tr td.message [data-tippy=\"commit-statuses\"] .commit-status") 204 assert.Equal(t, 1, sel.Length()) 205 }