mirror of
https://github.com/go-gitea/gitea.git
synced 2025-12-08 15:45:27 +01:00
196 lines
6.3 KiB
Go
196 lines
6.3 KiB
Go
// Copyright 2025 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package integration
|
|
|
|
import (
|
|
"archive/zip"
|
|
"bytes"
|
|
"fmt"
|
|
"mime/multipart"
|
|
"net/http"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
"testing"
|
|
|
|
render_model "code.gitea.io/gitea/models/render"
|
|
"code.gitea.io/gitea/models/unittest"
|
|
"code.gitea.io/gitea/modules/json"
|
|
"code.gitea.io/gitea/modules/renderplugin"
|
|
"code.gitea.io/gitea/modules/storage"
|
|
"code.gitea.io/gitea/modules/web/middleware"
|
|
"code.gitea.io/gitea/tests"
|
|
|
|
"github.com/PuerkitoBio/goquery"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestRenderPluginLifecycle(t *testing.T) {
|
|
defer tests.PrepareTestEnv(t)()
|
|
require.NoError(t, storage.Clean(renderplugin.Storage()))
|
|
t.Cleanup(func() {
|
|
_ = storage.Clean(renderplugin.Storage())
|
|
})
|
|
|
|
const pluginID = "itest-plugin"
|
|
|
|
session := loginUser(t, "user1")
|
|
|
|
uploadArchive(t, session, "/-/admin/render-plugins/upload", buildRenderPluginArchive(t, pluginID, "Integration Plugin", "1.0.0"))
|
|
flash := expectFlashSuccess(t, session)
|
|
assert.Contains(t, flash.SuccessMsg, "installed")
|
|
row := requireRenderPluginRow(t, session, pluginID)
|
|
assert.Equal(t, "1.0.0", row.Version)
|
|
assert.False(t, row.Enabled)
|
|
|
|
postPluginAction(t, session, fmt.Sprintf("/-/admin/render-plugins/%d/enable", row.ID))
|
|
flash = expectFlashSuccess(t, session)
|
|
assert.Contains(t, flash.SuccessMsg, "enabled")
|
|
row = requireRenderPluginRow(t, session, pluginID)
|
|
assert.True(t, row.Enabled)
|
|
|
|
metas := fetchRenderPluginMetadata(t)
|
|
require.Len(t, metas, 1)
|
|
assert.Equal(t, pluginID, metas[0].ID)
|
|
assert.Contains(t, metas[0].EntryURL, "render.js")
|
|
MakeRequest(t, NewRequest(t, "GET", metas[0].EntryURL), http.StatusOK)
|
|
|
|
uploadArchive(t, session, fmt.Sprintf("/-/admin/render-plugins/%d/upgrade", row.ID), buildRenderPluginArchive(t, pluginID, "Integration Plugin", "2.0.0"))
|
|
flash = expectFlashSuccess(t, session)
|
|
assert.Contains(t, flash.SuccessMsg, "upgraded")
|
|
row = requireRenderPluginRow(t, session, pluginID)
|
|
assert.Equal(t, "2.0.0", row.Version)
|
|
|
|
postPluginAction(t, session, fmt.Sprintf("/-/admin/render-plugins/%d/disable", row.ID))
|
|
flash = expectFlashSuccess(t, session)
|
|
assert.Contains(t, flash.SuccessMsg, "disabled")
|
|
row = requireRenderPluginRow(t, session, pluginID)
|
|
assert.False(t, row.Enabled)
|
|
require.Empty(t, fetchRenderPluginMetadata(t))
|
|
|
|
postPluginAction(t, session, fmt.Sprintf("/-/admin/render-plugins/%d/delete", row.ID))
|
|
flash = expectFlashSuccess(t, session)
|
|
assert.Contains(t, flash.SuccessMsg, "deleted")
|
|
unittest.AssertNotExistsBean(t, &render_model.Plugin{Identifier: pluginID})
|
|
_, err := renderplugin.Storage().Stat(renderplugin.ObjectPath(pluginID, "render.js"))
|
|
assert.Error(t, err)
|
|
require.Nil(t, findRenderPluginRow(t, session, pluginID))
|
|
}
|
|
|
|
func postPluginAction(t *testing.T, session *TestSession, path string) {
|
|
req := NewRequestWithValues(t, "POST", path, map[string]string{
|
|
"_csrf": GetUserCSRFToken(t, session),
|
|
})
|
|
session.MakeRequest(t, req, http.StatusSeeOther)
|
|
}
|
|
|
|
func uploadArchive(t *testing.T, session *TestSession, path string, archive []byte) {
|
|
var body bytes.Buffer
|
|
writer := multipart.NewWriter(&body)
|
|
require.NoError(t, writer.WriteField("_csrf", GetUserCSRFToken(t, session)))
|
|
part, err := writer.CreateFormFile("plugin", "plugin.zip")
|
|
require.NoError(t, err)
|
|
_, err = part.Write(archive)
|
|
require.NoError(t, err)
|
|
require.NoError(t, writer.Close())
|
|
|
|
req := NewRequestWithBody(t, "POST", path, bytes.NewReader(body.Bytes()))
|
|
req.Header.Set("Content-Type", writer.FormDataContentType())
|
|
resp := session.MakeRequest(t, req, http.StatusOK)
|
|
doc := NewHTMLParser(t, resp.Body)
|
|
token := doc.GetInputValueByName("token")
|
|
require.NotEmpty(t, token, "pending upload token not found")
|
|
confirmReq := NewRequestWithValues(t, "POST", path+"/confirm", map[string]string{
|
|
"_csrf": GetUserCSRFToken(t, session),
|
|
"token": token,
|
|
})
|
|
session.MakeRequest(t, confirmReq, http.StatusSeeOther)
|
|
}
|
|
|
|
func buildRenderPluginArchive(t *testing.T, id, name, version string) []byte {
|
|
manifest := fmt.Sprintf(`{
|
|
"schemaVersion": 1,
|
|
"id": %q,
|
|
"name": %q,
|
|
"version": %q,
|
|
"description": "integration test plugin",
|
|
"entry": "render.js",
|
|
"filePatterns": ["*.itest"]
|
|
}`, id, name, version)
|
|
|
|
var buf bytes.Buffer
|
|
zipWriter := zip.NewWriter(&buf)
|
|
file, err := zipWriter.Create("manifest.json")
|
|
require.NoError(t, err)
|
|
_, err = file.Write([]byte(manifest))
|
|
require.NoError(t, err)
|
|
|
|
file, err = zipWriter.Create("render.js")
|
|
require.NoError(t, err)
|
|
_, err = file.Write([]byte("export default {render(){}};"))
|
|
require.NoError(t, err)
|
|
require.NoError(t, zipWriter.Close())
|
|
return buf.Bytes()
|
|
}
|
|
|
|
func fetchRenderPluginMetadata(t *testing.T) []renderplugin.Metadata {
|
|
resp := MakeRequest(t, NewRequest(t, "GET", "/assets/render-plugins/index.json"), http.StatusOK)
|
|
var metas []renderplugin.Metadata
|
|
require.NoError(t, json.Unmarshal(resp.Body.Bytes(), &metas))
|
|
return metas
|
|
}
|
|
|
|
func expectFlashSuccess(t *testing.T, session *TestSession) *middleware.Flash {
|
|
flash := session.GetCookieFlashMessage()
|
|
require.NotNil(t, flash, "expected flash message")
|
|
require.Empty(t, flash.ErrorMsg)
|
|
return flash
|
|
}
|
|
|
|
type renderPluginRow struct {
|
|
ID int64
|
|
Identifier string
|
|
Version string
|
|
Enabled bool
|
|
}
|
|
|
|
func requireRenderPluginRow(t *testing.T, session *TestSession, identifier string) *renderPluginRow {
|
|
row := findRenderPluginRow(t, session, identifier)
|
|
require.NotNil(t, row, "plugin %s not found", identifier)
|
|
return row
|
|
}
|
|
|
|
func findRenderPluginRow(t *testing.T, session *TestSession, identifier string) *renderPluginRow {
|
|
resp := session.MakeRequest(t, NewRequest(t, "GET", "/-/admin/render-plugins"), http.StatusOK)
|
|
doc := NewHTMLParser(t, resp.Body)
|
|
var result *renderPluginRow
|
|
doc.Find("table tbody tr").EachWithBreak(func(_ int, s *goquery.Selection) bool {
|
|
cols := s.Find("td")
|
|
if cols.Length() < 6 {
|
|
return true
|
|
}
|
|
idText := strings.TrimSpace(cols.Eq(1).Text())
|
|
if idText != identifier {
|
|
return true
|
|
}
|
|
link := cols.Eq(5).Find("a[href]").First()
|
|
href, _ := link.Attr("href")
|
|
id, err := strconv.ParseInt(path.Base(href), 10, 64)
|
|
if err != nil {
|
|
return true
|
|
}
|
|
version := strings.TrimSpace(cols.Eq(2).Text())
|
|
enabled := cols.Eq(4).Find(".ui.green").Length() > 0
|
|
result = &renderPluginRow{
|
|
ID: id,
|
|
Identifier: idText,
|
|
Version: version,
|
|
Enabled: enabled,
|
|
}
|
|
return false
|
|
})
|
|
return result
|
|
}
|