diff --git a/lib/api/route/messages.dart b/lib/api/route/messages.dart index 618ae36c89..0345b2703b 100644 --- a/lib/api/route/messages.dart +++ b/lib/api/route/messages.dart @@ -262,9 +262,10 @@ Future uploadFile( required Stream> content, required int length, required String filename, + required String? mimeType, }) { return connection.postFileFromStream('uploadFile', UploadFileResult.fromJson, 'user_uploads', - content, length, filename: filename); + content, length, filename: filename, contentType: mimeType); } @JsonSerializable(fieldRename: FieldRename.snake) diff --git a/lib/widgets/compose_box.dart b/lib/widgets/compose_box.dart index 1e3ae73bdd..abd634dda4 100644 --- a/lib/widgets/compose_box.dart +++ b/lib/widgets/compose_box.dart @@ -478,7 +478,11 @@ Future _uploadFiles({ Uri? url; try { final result = await uploadFile(store.connection, - content: content, length: length, filename: filename); + content: content, + length: length, + filename: filename, + mimeType: null, // TODO(#829) + ); url = Uri.parse(result.uri); } catch (e) { if (!context.mounted) return; diff --git a/test/api/route/messages_test.dart b/test/api/route/messages_test.dart index c860c4de43..b91fb3e732 100644 --- a/test/api/route/messages_test.dart +++ b/test/api/route/messages_test.dart @@ -414,6 +414,55 @@ void main() { }); }); + group('uploadFile', () { + Future checkUploadFile(FakeApiConnection connection, { + required List> content, + required int length, + required String filename, + required String? mimeType, + }) async { + connection.prepare(json: + UploadFileResult(uri: '/user_uploads/1/4e/m2A3MSqFnWRLUf9SaPzQ0Up_/$filename').toJson()); + await uploadFile(connection, + content: Stream.fromIterable(content), + length: length, + filename: filename, + mimeType: mimeType); + check(connection.lastRequest).isA() + ..method.equals('POST') + ..url.path.equals('/api/v1/user_uploads') + ..files.single.which((it) => it + ..field.equals('file') + ..length.equals(length) + ..filename.equals(filename) + ..contentType.asString.equals(mimeType ?? 'application/octet-stream') + ..has>>((f) => f.finalize().toBytes(), 'contents') + .completes((it) => it.deepEquals(content.expand((l) => l)))); + } + + test('with mime type', () { + return FakeApiConnection.with_((connection) async { + await checkUploadFile(connection, + content: ['asdf'.codeUnits], + length: 4, + filename: 'image.jpg', + mimeType: 'image/jpeg', + ); + }); + }); + + test('without mime type', () { + return FakeApiConnection.with_((connection) async { + await checkUploadFile(connection, + content: ['asdf'.codeUnits], + length: 4, + filename: 'some_file', + mimeType: null, + ); + }); + }); + }); + group('addReaction', () { Future checkAddReaction(FakeApiConnection connection, { required int messageId,