|
4 | 4 | package integration |
5 | 5 |
|
6 | 6 | import ( |
| 7 | + "fmt" |
| 8 | + "net/http" |
| 9 | + "testing" |
| 10 | + |
7 | 11 | auth_model "code.gitea.io/gitea/models/auth" |
8 | | - "code.gitea.io/gitea/models/db" |
9 | 12 | repo_model "code.gitea.io/gitea/models/repo" |
10 | 13 | "code.gitea.io/gitea/models/unittest" |
11 | 14 | user_model "code.gitea.io/gitea/models/user" |
12 | 15 | "code.gitea.io/gitea/modules/git" |
13 | 16 | "code.gitea.io/gitea/modules/gitrepo" |
14 | 17 | "code.gitea.io/gitea/modules/setting" |
15 | 18 | api "code.gitea.io/gitea/modules/structs" |
| 19 | + "code.gitea.io/gitea/modules/test" |
16 | 20 | "code.gitea.io/gitea/modules/util" |
17 | | - repo_service "code.gitea.io/gitea/services/repository" |
18 | | - "encoding/base64" |
19 | | - "fmt" |
| 21 | + "code.gitea.io/gitea/tests" |
| 22 | + |
20 | 23 | "github.com/stretchr/testify/assert" |
21 | | - "net/http" |
22 | | - "net/url" |
23 | | - "testing" |
24 | | - "time" |
| 24 | + "github.com/stretchr/testify/require" |
25 | 25 | ) |
26 | 26 |
|
27 | 27 | func TestAPIGetRequestedFiles(t *testing.T) { |
28 | | - onGiteaRun(t, testAPIGetRequestedFiles) |
29 | | -} |
| 28 | + defer tests.PrepareTestEnv(t)() |
30 | 29 |
|
31 | | -func testAPIGetRequestedFiles(t *testing.T, u *url.URL) { |
32 | | - /*** SETUP ***/ |
33 | 30 | user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16 |
34 | 31 | org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org |
35 | 32 | user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos |
36 | 33 | repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo |
37 | 34 | repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo |
38 | 35 | repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo |
39 | 36 |
|
| 37 | + // TODO: add "GET" support |
| 38 | + |
40 | 39 | // Get user2's token |
41 | 40 | session := loginUser(t, user2.Name) |
42 | | - token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // TODO: allow for a POST-request to be scope read |
| 41 | + token2 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) |
43 | 42 | // Get user4's token |
44 | 43 | session = loginUser(t, user4.Name) |
45 | | - token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // TODO: allow for a POST-request to be scope read |
| 44 | + token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) |
46 | 45 |
|
47 | 46 | gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo1) |
48 | 47 | assert.NoError(t, err) |
@@ -97,94 +96,52 @@ func testAPIGetRequestedFiles(t *testing.T, u *url.URL) { |
97 | 96 | MakeRequest(t, req, http.StatusOK) |
98 | 97 | }) |
99 | 98 |
|
100 | | - // TODO: use mocked config to test without creating new files (to speed up the test) |
101 | | - // Test pagination |
102 | | - for i := 0; i < 40; i++ { |
103 | | - filesOptions.Files = append(filesOptions.Files, filesOptions.Files[0]) |
104 | | - } |
105 | | - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/files", user2.Name, repo1.Name), &filesOptions) |
106 | | - resp = MakeRequest(t, req, http.StatusOK) |
107 | | - DecodeJSON(t, resp, &contentsListResponse) |
108 | | - assert.NotNil(t, contentsListResponse) |
109 | | - assert.Len(t, contentsListResponse, setting.API.DefaultPagingNum) |
110 | | - |
111 | | - // create new repo for large file tests |
112 | | - baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user2, user2, repo_service.CreateRepoOptions{ |
113 | | - Name: "repo-test-files-api", |
114 | | - Description: "test files api", |
115 | | - AutoInit: true, |
116 | | - Gitignores: "Go", |
117 | | - License: "MIT", |
118 | | - Readme: "Default", |
119 | | - DefaultBranch: "main", |
120 | | - IsPrivate: false, |
121 | | - }) |
122 | | - assert.NoError(t, err) |
123 | | - assert.NotEmpty(t, baseRepo) |
| 99 | + t.Run("ResponseList", func(t *testing.T) { |
| 100 | + defer test.MockVariableValue(&setting.API.DefaultPagingNum)() |
| 101 | + defer test.MockVariableValue(&setting.API.DefaultMaxBlobSize)() |
| 102 | + defer test.MockVariableValue(&setting.API.DefaultMaxResponseSize)() |
124 | 103 |
|
125 | | - // Test file size limit |
126 | | - largeFile := make([]byte, 15728640) // 15 MiB -> over max blob size |
127 | | - for i := range largeFile { |
128 | | - largeFile[i] = byte(i % 256) |
129 | | - } |
130 | | - user2APICtx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository) |
131 | | - doAPICreateFile(user2APICtx, "large-file.txt", &api.CreateFileOptions{ |
132 | | - FileOptions: api.FileOptions{ |
133 | | - Message: "create large-file.txt", |
134 | | - Author: api.Identity{ |
135 | | - Name: user2.Name, |
136 | | - Email: user2.Email, |
137 | | - }, |
138 | | - Committer: api.Identity{ |
139 | | - Name: user2.Name, |
140 | | - Email: user2.Email, |
141 | | - }, |
142 | | - Dates: api.CommitDateOptions{ |
143 | | - Author: time.Now(), |
144 | | - Committer: time.Now(), |
145 | | - }, |
146 | | - }, |
147 | | - ContentBase64: base64.StdEncoding.EncodeToString(largeFile), |
148 | | - })(t) |
149 | | - |
150 | | - filesOptions.Files = []string{"large-file.txt"} |
151 | | - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/files", user2.Name, baseRepo.Name), &filesOptions) |
152 | | - resp = MakeRequest(t, req, http.StatusOK) |
153 | | - DecodeJSON(t, resp, &contentsListResponse) |
154 | | - assert.NotNil(t, contentsListResponse) |
155 | | - assert.Equal(t, int64(15728640), contentsListResponse[0].Size) |
156 | | - assert.Empty(t, *contentsListResponse[0].Content) |
157 | | - |
158 | | - // Test response size limit |
159 | | - smallFile := make([]byte, 5242880) // 5 MiB -> under max blob size |
160 | | - for i := range smallFile { |
161 | | - smallFile[i] = byte(i % 256) |
162 | | - } |
163 | | - doAPICreateFile(user2APICtx, "small-file.txt", &api.CreateFileOptions{ |
164 | | - FileOptions: api.FileOptions{ |
165 | | - Message: "create small-file.txt", |
166 | | - Author: api.Identity{ |
167 | | - Name: user2.Name, |
168 | | - Email: user2.Email, |
169 | | - }, |
170 | | - Committer: api.Identity{ |
171 | | - Name: user2.Name, |
172 | | - Email: user2.Email, |
173 | | - }, |
174 | | - Dates: api.CommitDateOptions{ |
175 | | - Author: time.Now(), |
176 | | - Committer: time.Now(), |
177 | | - }, |
178 | | - }, |
179 | | - ContentBase64: base64.StdEncoding.EncodeToString(smallFile), |
180 | | - })(t) |
181 | | - filesOptions.Files = []string{"small-file.txt"} |
182 | | - for i := 0; i < 40; i++ { |
183 | | - filesOptions.Files = append(filesOptions.Files, filesOptions.Files[0]) |
184 | | - } |
185 | | - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/files", user2.Name, baseRepo.Name), &filesOptions) |
186 | | - resp = MakeRequest(t, req, http.StatusOK) |
187 | | - DecodeJSON(t, resp, &contentsListResponse) |
188 | | - assert.NotNil(t, contentsListResponse) |
189 | | - assert.Len(t, contentsListResponse, 15) // base64-encoded content is around 4/3 the size of the original content |
| 104 | + type expected struct { |
| 105 | + Name string |
| 106 | + HasContent bool |
| 107 | + } |
| 108 | + assertResponse := func(t *testing.T, expected []*expected, ret []*api.ContentsResponse) { |
| 109 | + require.Len(t, ret, len(expected)) |
| 110 | + for i, e := range expected { |
| 111 | + if e == nil { |
| 112 | + assert.Nil(t, ret[i], "item %d", i) |
| 113 | + continue |
| 114 | + } |
| 115 | + assert.Equal(t, e.Name, ret[i].Name, "item %d name", i) |
| 116 | + if e.HasContent { |
| 117 | + require.NotNil(t, ret[i].Content, "item %d content", i) |
| 118 | + assert.NotEmpty(t, *ret[i].Content, "item %d content", i) |
| 119 | + } else { |
| 120 | + assert.Nil(t, ret[i].Content, "item %d content", i) |
| 121 | + } |
| 122 | + } |
| 123 | + } |
| 124 | + |
| 125 | + // repo1 "DefaultBranch" has 2 files: LICENSE (1064 bytes), README.md (30 bytes) |
| 126 | + ret := requestFiles(t, "/api/v1/repos/user2/repo1/files?ref=DefaultBranch", []string{"no-such.txt", "LICENSE", "README.md"}) |
| 127 | + assertResponse(t, []*expected{nil, {"LICENSE", true}, {"README.md", true}}, ret) |
| 128 | + |
| 129 | + // the returned file list is limited by the DefaultPagingNum |
| 130 | + setting.API.DefaultPagingNum = 2 |
| 131 | + ret = requestFiles(t, "/api/v1/repos/user2/repo1/files?ref=DefaultBranch", []string{"no-such.txt", "LICENSE", "README.md"}) |
| 132 | + assertResponse(t, []*expected{nil, {"LICENSE", true}}, ret) |
| 133 | + setting.API.DefaultPagingNum = 100 |
| 134 | + |
| 135 | + // if a file exceeds the DefaultMaxBlobSize, the content is not returned |
| 136 | + setting.API.DefaultMaxBlobSize = 200 |
| 137 | + ret = requestFiles(t, "/api/v1/repos/user2/repo1/files?ref=DefaultBranch", []string{"no-such.txt", "LICENSE", "README.md"}) |
| 138 | + assertResponse(t, []*expected{nil, {"LICENSE", false}, {"README.md", true}}, ret) |
| 139 | + setting.API.DefaultMaxBlobSize = 20000 |
| 140 | + |
| 141 | + // if the total response size would exceed the DefaultMaxResponseSize, then the list stops |
| 142 | + setting.API.DefaultMaxResponseSize = 1064*4/3 + 1 |
| 143 | + ret = requestFiles(t, "/api/v1/repos/user2/repo1/files?ref=DefaultBranch", []string{"no-such.txt", "LICENSE", "README.md"}) |
| 144 | + assertResponse(t, []*expected{nil, {"LICENSE", true}}, ret) |
| 145 | + setting.API.DefaultMaxBlobSize = 20000 |
| 146 | + }) |
190 | 147 | } |
0 commit comments