Skip to content

Commit f58d695

Browse files
committed
async uploads: add initial set of tests
Signed-off-by: Sumner Evans <[email protected]>
1 parent b986a30 commit f58d695

File tree

2 files changed

+86
-0
lines changed

2 files changed

+86
-0
lines changed

internal/client/client.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,20 @@ type CSAPI struct {
9797
txnID int64
9898
}
9999

100+
// CreateMedia creates an MXC URI for asynchronous media uploads.
101+
func (c *CSAPI) CreateMedia(t *testing.T) string {
102+
t.Helper()
103+
res := c.MustDoFunc(t, "POST", []string{"_matrix", "media", "v1", "create"})
104+
body := ParseJSON(t, res)
105+
return GetJSONFieldStr(t, body, "content_uri")
106+
}
107+
108+
// UploadMediaAsync uploads the provided content to the given server and media ID. Fails the test on error.
109+
func (c *CSAPI) UploadMediaAsync(t *testing.T, serverName, mediaID string, fileBody []byte, fileName string, contentType string) {
110+
t.Helper()
111+
c.MustDoFunc(t, "PUT", []string{"_matrix", "media", "v3", "upload", serverName, mediaID})
112+
}
113+
100114
// UploadContent uploads the provided content with an optional file name. Fails the test on error. Returns the MXC URI.
101115
func (c *CSAPI) UploadContent(t *testing.T, fileBody []byte, fileName string, contentType string) string {
102116
t.Helper()
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package csapi_tests
2+
3+
import (
4+
"bytes"
5+
"net/http"
6+
"strings"
7+
"testing"
8+
9+
"github.com/matrix-org/complement/internal/b"
10+
"github.com/matrix-org/complement/internal/client"
11+
"github.com/matrix-org/complement/internal/data"
12+
"github.com/matrix-org/complement/internal/match"
13+
"github.com/matrix-org/complement/internal/must"
14+
"github.com/matrix-org/complement/runtime"
15+
)
16+
17+
func TestAsyncUpload(t *testing.T) {
18+
runtime.SkipIf(t, runtime.Dendrite) // Dendrite doesn't support async uploads
19+
20+
deployment := Deploy(t, b.BlueprintAlice)
21+
defer deployment.Destroy(t)
22+
23+
alice := deployment.Client(t, "hs1", "@alice:hs1")
24+
25+
var mxcURI, mediaID string
26+
t.Run("Create media", func(t *testing.T) {
27+
mxcURI = alice.CreateMedia(t)
28+
parts := strings.Split(mxcURI, "/")
29+
mediaID = parts[len(parts)-1]
30+
})
31+
32+
origin, mediaID := client.SplitMxc(mxcURI)
33+
34+
t.Run("Not yet uploaded", func(t *testing.T) {
35+
// Check that the media is not yet uploaded
36+
res := alice.DoFunc(t, "GET", []string{"_matrix", "media", "v3", "download", origin, mediaID})
37+
must.MatchResponse(t, res, match.HTTPResponse{
38+
StatusCode: http.StatusGatewayTimeout,
39+
JSON: []match.JSON{
40+
match.JSONKeyEqual("errcode", "M_NOT_YET_UPLOADED"),
41+
match.JSONKeyEqual("error", "Media has not been uploaded yet"),
42+
},
43+
})
44+
})
45+
46+
wantContentType := "image/png"
47+
48+
t.Run("Upload media", func(t *testing.T) {
49+
alice.UploadMediaAsync(t, origin, mediaID, data.MatrixPng, "test.png", wantContentType)
50+
})
51+
52+
t.Run("Cannot upload to a media ID that has already been uploaded to", func(t *testing.T) {
53+
res := alice.DoFunc(t, "PUT", []string{"_matrix", "media", "v3", "upload", origin, mediaID})
54+
must.MatchResponse(t, res, match.HTTPResponse{
55+
StatusCode: http.StatusConflict,
56+
JSON: []match.JSON{
57+
match.JSONKeyEqual("errcode", "M_INVALID_USERNAME"),
58+
match.JSONKeyEqual("error", "Media ID already has content"),
59+
},
60+
})
61+
})
62+
63+
t.Run("Download media", func(t *testing.T) {
64+
content, contentType := alice.DownloadContent(t, mxcURI)
65+
if !bytes.Equal(data.MatrixPng, content) {
66+
t.Fatalf("uploaded and downloaded content doesn't match: want %v\ngot\n%v", data.MatrixPng, content)
67+
}
68+
if contentType != wantContentType {
69+
t.Fatalf("expected contentType to be %s, got %s", wantContentType, contentType)
70+
}
71+
})
72+
}

0 commit comments

Comments
 (0)