diff --git a/internal/client/client.go b/internal/client/client.go index 9dde9516..1fcd2d4a 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -97,6 +97,20 @@ type CSAPI struct { txnID int64 } +// CreateMedia creates an MXC URI for asynchronous media uploads. +func (c *CSAPI) CreateMedia(t *testing.T) string { + t.Helper() + res := c.MustDoFunc(t, "POST", []string{"_matrix", "media", "v1", "create"}) + body := ParseJSON(t, res) + return GetJSONFieldStr(t, body, "content_uri") +} + +// UploadMediaAsync uploads the provided content to the given server and media ID. Fails the test on error. +func (c *CSAPI) UploadMediaAsync(t *testing.T, serverName, mediaID string, fileBody []byte, fileName string, contentType string) { + t.Helper() + c.MustDoFunc(t, "PUT", []string{"_matrix", "media", "v3", "upload", serverName, mediaID}) +} + // UploadContent uploads the provided content with an optional file name. Fails the test on error. Returns the MXC URI. func (c *CSAPI) UploadContent(t *testing.T, fileBody []byte, fileName string, contentType string) string { t.Helper() diff --git a/tests/csapi/media_async_uploads_test.go b/tests/csapi/media_async_uploads_test.go new file mode 100644 index 00000000..3c235b5e --- /dev/null +++ b/tests/csapi/media_async_uploads_test.go @@ -0,0 +1,46 @@ +package csapi_tests + +import ( + "net/http" + "strings" + "testing" + + "github.com/matrix-org/complement/internal/b" + "github.com/matrix-org/complement/internal/client" + "github.com/matrix-org/complement/internal/data" + "github.com/matrix-org/complement/runtime" +) + +func TestAsyncUpload(t *testing.T) { + runtime.SkipIf(t, runtime.Dendrite) // Dendrite doesn't support async uploads + + deployment := Deploy(t, b.BlueprintAlice) + defer deployment.Destroy(t) + + alice := deployment.Client(t, "hs1", "@alice:hs1") + + var mxcURI, mediaID string + t.Run("Create media", func(t *testing.T) { + mxcURI = alice.CreateMedia(t) + parts := strings.Split(mxcURI, "/") + mediaID = parts[len(parts)-1] + }) + + origin, mediaID := client.SplitMxc(mxcURI) + + t.Run("Not yet uploaded", func(t *testing.T) { + // Check that the media is not yet uploaded + res := alice.DoFunc(t, "GET", []string{"_matrix", "media", "v3", "download", origin, mediaID}) + if res.StatusCode != http.StatusGatewayTimeout { + t.Fatalf("Expected 504 response code, got %d", res.StatusCode) + } + }) + + t.Run("Upload media", func(t *testing.T) { + alice.UploadMediaAsync(t, origin, mediaID, data.MatrixPng, "test.png", "image/png") + }) + + t.Run("Cannot upload to a media ID that has already been uploaded to", func(t *testing.T) { + alice.UploadMediaAsync(t, origin, mediaID, data.MatrixPng, "test.png", "image/png") + }) +}