Skip to content

Commit 4e1854d

Browse files
authored
Initial set of tests for MSC2246 async uploads. (#641)
1 parent 7efd8fc commit 4e1854d

File tree

2 files changed

+94
-0
lines changed

2 files changed

+94
-0
lines changed

client/client.go

+21
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,27 @@ type CSAPI struct {
7979
txnID int64
8080
}
8181

82+
// CreateMedia creates an MXC URI for asynchronous media uploads.
83+
func (c *CSAPI) CreateMedia(t TestLike) string {
84+
t.Helper()
85+
res := c.MustDo(t, "POST", []string{"_matrix", "media", "v1", "create"})
86+
body := ParseJSON(t, res)
87+
return GetJSONFieldStr(t, body, "content_uri")
88+
}
89+
90+
// UploadMediaAsync uploads the provided content to the given server and media ID. Fails the test on error.
91+
func (c *CSAPI) UploadMediaAsync(t TestLike, serverName, mediaID string, fileBody []byte, fileName string, contentType string) {
92+
t.Helper()
93+
query := url.Values{}
94+
if fileName != "" {
95+
query.Set("filename", fileName)
96+
}
97+
c.MustDo(
98+
t, "PUT", []string{"_matrix", "media", "v3", "upload", serverName, mediaID},
99+
WithRawBody(fileBody), WithContentType(contentType), WithQueries(query),
100+
)
101+
}
102+
82103
// UploadContent uploads the provided content with an optional file name. Fails the test on error. Returns the MXC URI.
83104
func (c *CSAPI) UploadContent(t TestLike, fileBody []byte, fileName string, contentType string) string {
84105
t.Helper()
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package csapi_tests
2+
3+
import (
4+
"bytes"
5+
"net/http"
6+
"strings"
7+
"testing"
8+
9+
"github.com/matrix-org/complement"
10+
"github.com/matrix-org/complement/client"
11+
"github.com/matrix-org/complement/helpers"
12+
"github.com/matrix-org/complement/internal/data"
13+
"github.com/matrix-org/complement/match"
14+
"github.com/matrix-org/complement/must"
15+
"github.com/matrix-org/complement/runtime"
16+
)
17+
18+
func TestAsyncUpload(t *testing.T) {
19+
runtime.SkipIf(t, runtime.Dendrite) // Dendrite doesn't support async uploads
20+
21+
deployment := complement.Deploy(t, 1)
22+
defer deployment.Destroy(t)
23+
24+
alice := deployment.Register(t, "hs1", helpers.RegistrationOpts{})
25+
26+
var mxcURI, mediaID string
27+
t.Run("Create media", func(t *testing.T) {
28+
mxcURI = alice.CreateMedia(t)
29+
parts := strings.Split(mxcURI, "/")
30+
mediaID = parts[len(parts)-1]
31+
})
32+
33+
origin, mediaID := client.SplitMxc(mxcURI)
34+
35+
t.Run("Not yet uploaded", func(t *testing.T) {
36+
// Check that the media is not yet uploaded
37+
res := alice.Do(t, "GET", []string{"_matrix", "media", "v3", "download", origin, mediaID})
38+
must.MatchResponse(t, res, match.HTTPResponse{
39+
StatusCode: http.StatusGatewayTimeout,
40+
JSON: []match.JSON{
41+
match.JSONKeyEqual("errcode", "M_NOT_YET_UPLOADED"),
42+
match.JSONKeyEqual("error", "Media has not been uploaded yet"),
43+
},
44+
})
45+
})
46+
47+
wantContentType := "image/png"
48+
49+
t.Run("Upload media", func(t *testing.T) {
50+
alice.UploadMediaAsync(t, origin, mediaID, data.MatrixPng, "test.png", wantContentType)
51+
})
52+
53+
t.Run("Cannot upload to a media ID that has already been uploaded to", func(t *testing.T) {
54+
res := alice.Do(t, "PUT", []string{"_matrix", "media", "v3", "upload", origin, mediaID})
55+
must.MatchResponse(t, res, match.HTTPResponse{
56+
StatusCode: http.StatusConflict,
57+
JSON: []match.JSON{
58+
match.JSONKeyEqual("errcode", "M_CANNOT_OVERWRITE_MEDIA"),
59+
match.JSONKeyEqual("error", "Media ID already has content"),
60+
},
61+
})
62+
})
63+
64+
t.Run("Download media", func(t *testing.T) {
65+
content, contentType := alice.DownloadContent(t, mxcURI)
66+
if !bytes.Equal(data.MatrixPng, content) {
67+
t.Fatalf("uploaded and downloaded content doesn't match: want %v\ngot\n%v", data.MatrixPng, content)
68+
}
69+
if contentType != wantContentType {
70+
t.Fatalf("expected contentType to be %s, got %s", wantContentType, contentType)
71+
}
72+
})
73+
}

0 commit comments

Comments
 (0)