code.gitea.io/gitea@v1.22.3/tests/integration/attachment_test.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package integration 5 6 import ( 7 "bytes" 8 "image" 9 "image/png" 10 "io" 11 "mime/multipart" 12 "net/http" 13 "strings" 14 "testing" 15 16 repo_model "code.gitea.io/gitea/models/repo" 17 "code.gitea.io/gitea/modules/storage" 18 "code.gitea.io/gitea/modules/test" 19 "code.gitea.io/gitea/tests" 20 21 "github.com/stretchr/testify/assert" 22 ) 23 24 func generateImg() bytes.Buffer { 25 // Generate image 26 myImage := image.NewRGBA(image.Rect(0, 0, 32, 32)) 27 var buff bytes.Buffer 28 png.Encode(&buff, myImage) 29 return buff 30 } 31 32 func createAttachment(t *testing.T, session *TestSession, csrf, repoURL, filename string, buff bytes.Buffer, expectedStatus int) string { 33 body := &bytes.Buffer{} 34 35 // Setup multi-part 36 writer := multipart.NewWriter(body) 37 part, err := writer.CreateFormFile("file", filename) 38 assert.NoError(t, err) 39 _, err = io.Copy(part, &buff) 40 assert.NoError(t, err) 41 err = writer.Close() 42 assert.NoError(t, err) 43 44 req := NewRequestWithBody(t, "POST", repoURL+"/issues/attachments", body) 45 req.Header.Add("X-Csrf-Token", csrf) 46 req.Header.Add("Content-Type", writer.FormDataContentType()) 47 resp := session.MakeRequest(t, req, expectedStatus) 48 49 if expectedStatus != http.StatusOK { 50 return "" 51 } 52 var obj map[string]string 53 DecodeJSON(t, resp, &obj) 54 return obj["uuid"] 55 } 56 57 func TestCreateAnonymousAttachment(t *testing.T) { 58 defer tests.PrepareTestEnv(t)() 59 session := emptyTestSession(t) 60 createAttachment(t, session, GetCSRF(t, session, "/user/login"), "user2/repo1", "image.png", generateImg(), http.StatusSeeOther) 61 } 62 63 func TestCreateIssueAttachment(t *testing.T) { 64 defer tests.PrepareTestEnv(t)() 65 const repoURL = "user2/repo1" 66 session := loginUser(t, "user2") 67 uuid := createAttachment(t, session, GetCSRF(t, session, repoURL), repoURL, "image.png", generateImg(), http.StatusOK) 68 69 req := NewRequest(t, "GET", repoURL+"/issues/new") 70 resp := session.MakeRequest(t, req, http.StatusOK) 71 htmlDoc := NewHTMLParser(t, resp.Body) 72 73 link, exists := htmlDoc.doc.Find("form#new-issue").Attr("action") 74 assert.True(t, exists, "The template has changed") 75 76 postData := map[string]string{ 77 "_csrf": htmlDoc.GetCSRF(), 78 "title": "New Issue With Attachment", 79 "content": "some content", 80 "files": uuid, 81 } 82 83 req = NewRequestWithValues(t, "POST", link, postData) 84 resp = session.MakeRequest(t, req, http.StatusOK) 85 test.RedirectURL(resp) // check that redirect URL exists 86 87 // Validate that attachment is available 88 req = NewRequest(t, "GET", "/attachments/"+uuid) 89 session.MakeRequest(t, req, http.StatusOK) 90 91 // anonymous visit should be allowed because user2/repo1 is a public repository 92 MakeRequest(t, req, http.StatusOK) 93 } 94 95 func TestGetAttachment(t *testing.T) { 96 defer tests.PrepareTestEnv(t)() 97 adminSession := loginUser(t, "user1") 98 user2Session := loginUser(t, "user2") 99 user8Session := loginUser(t, "user8") 100 emptySession := emptyTestSession(t) 101 testCases := []struct { 102 name string 103 uuid string 104 createFile bool 105 session *TestSession 106 want int 107 }{ 108 {"LinkedIssueUUID", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", true, user2Session, http.StatusOK}, 109 {"LinkedCommentUUID", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17", true, user2Session, http.StatusOK}, 110 {"linked_release_uuid", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a19", true, user2Session, http.StatusOK}, 111 {"NotExistingUUID", "b0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18", false, user2Session, http.StatusNotFound}, 112 {"FileMissing", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18", false, user2Session, http.StatusInternalServerError}, 113 {"NotLinked", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20", true, user2Session, http.StatusNotFound}, 114 {"NotLinkedAccessibleByUploader", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a20", true, user8Session, http.StatusOK}, 115 {"PublicByNonLogged", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", true, emptySession, http.StatusOK}, 116 {"PrivateByNonLogged", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12", true, emptySession, http.StatusNotFound}, 117 {"PrivateAccessibleByAdmin", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12", true, adminSession, http.StatusOK}, 118 {"PrivateAccessibleByUser", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12", true, user2Session, http.StatusOK}, 119 {"RepoNotAccessibleByUser", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a12", true, user8Session, http.StatusNotFound}, 120 {"OrgNotAccessibleByUser", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a21", true, user8Session, http.StatusNotFound}, 121 } 122 for _, tc := range testCases { 123 t.Run(tc.name, func(t *testing.T) { 124 // Write empty file to be available for response 125 if tc.createFile { 126 _, err := storage.Attachments.Save(repo_model.AttachmentRelativePath(tc.uuid), strings.NewReader("hello world"), -1) 127 assert.NoError(t, err) 128 } 129 // Actual test 130 req := NewRequest(t, "GET", "/attachments/"+tc.uuid) 131 tc.session.MakeRequest(t, req, tc.want) 132 }) 133 } 134 }