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  }