e2e/assetweb_test.go

v1.42.0
gitbay/e2e/assetweb_test.go history · blame · raw

85 lines · 3339 bytes

 1package e2e
 2
 3import (
 4	"bytes"
 5	"mime/multipart"
 6	"os"
 7	"path/filepath"
 8	"strings"
 9	"testing"
10)
11
12// TestReleaseAssetUploadFromTheWeb uploads a release asset through the
13// releases page's multipart form. The bytes match what the CLI reads back
14// and what the download route serves, and an upload over max_asset_bytes
15// stores nothing (#296).
16func TestReleaseAssetUploadFromTheWeb(t *testing.T) {
17	t.Parallel()
18	inst := startInstanceWith(t, "[web]\nmode = \"accounts\"\n[limits]\nmax_asset_bytes = 4096\n")
19	aliceKey := inst.newKey(t, "alice")
20	inst.admin(t, "admin", "user", "create", "alice",
21		"--key", aliceKey+".pub", "--email", "alice@example.test", "--verified")
22	if _, errOut, code := inst.ssh(t, aliceKey, "", "repo", "create", "alice/app"); code != 0 {
23		t.Fatalf("repo create: %s", errOut)
24	}
25	env := inst.gitEnv(aliceKey)
26	work := t.TempDir()
27	mustGit(t, work, env, "clone", inst.sshURL("alice/app"), "w")
28	dir := filepath.Join(work, "w")
29	os.WriteFile(filepath.Join(dir, "a.txt"), []byte("a\n"), 0o644)
30	mustGit(t, dir, env, "checkout", "-q", "-b", "main")
31	mustGit(t, dir, env, "add", ".")
32	mustGit(t, dir, env, "commit", "-q", "-m", "base")
33	mustGit(t, dir, env, "tag", "-a", "v1.0", "-m", "first")
34	mustGit(t, dir, env, "push", "-q", "origin", "main", "v1.0")
35	if _, errOut, code := inst.ssh(t, aliceKey, "", "release", "create", "alice/app", "v1.0"); code != 0 {
36		t.Fatalf("release create: %s", errOut)
37	}
38	alice := inst.login(t, aliceKey)
39	base := inst.base() + "/alice/app"
40
41	send := func(name string, data []byte) (int, string) {
42		var buf bytes.Buffer
43		mw := multipart.NewWriter(&buf)
44		mw.WriteField("tag", "v1.0")
45		fw, _ := mw.CreateFormFile("file", name)
46		fw.Write(data)
47		mw.Close()
48		resp, err := alice.Post(base+"/releases/assets", mw.FormDataContentType(), &buf)
49		if err != nil {
50			t.Fatal(err)
51		}
52		defer resp.Body.Close()
53		var out bytes.Buffer
54		out.ReadFrom(resp.Body)
55		return resp.StatusCode, out.String()
56	}
57
58	payload := []byte("BINARY\x00\x01\x02 asset from the browser\n")
59	if status, page := send("tool-linux-amd64", payload); status != 200 || !strings.Contains(page, "tool-linux-amd64") {
60		t.Fatalf("upload: %d\n%s", status, page)
61	}
62	got, _, code := inst.ssh(t, aliceKey, "", "release", "asset", "get", "alice/app", "v1.0", "tool-linux-amd64")
63	if code != 0 || got != string(payload) {
64		t.Fatalf("CLI read back %q (exit %d)", got, code)
65	}
66	if status, body := browserGet(t, alice, base+"/releases/download/v1.0/tool-linux-amd64"); status != 200 || body != string(payload) {
67		t.Fatalf("download: %d %q", status, body)
68	}
69
70	if _, page := send("big.bin", bytes.Repeat([]byte("x"), 8192)); !strings.Contains(page, "max_asset_bytes") {
71		t.Fatalf("oversized upload not refused:\n%s", page)
72	}
73	out, _, _ := inst.ssh(t, aliceKey, "", "release", "show", "alice/app", "v1.0", "--json")
74	if strings.Contains(out, "big.bin") {
75		t.Fatalf("oversized asset stored: %s", out)
76	}
77
78	if status, _ := browserPost(t, alice, base+"/releases/assets", map[string][]string{
79		"action": {"remove"}, "tag": {"v1.0"}, "name": {"tool-linux-amd64"}, "confirm": {"tool-linux-amd64"}}); status != 200 {
80		t.Fatal("remove failed")
81	}
82	if out, _, _ = inst.ssh(t, aliceKey, "", "release", "show", "alice/app", "v1.0", "--json"); strings.Contains(out, "tool-linux-amd64") {
83		t.Fatalf("asset still listed: %s", out)
84	}
85}