From 4ae9f68fc8aeaf426dfd4aa970d8de8b3d43d53f Mon Sep 17 00:00:00 2001 From: provokateurin Date: Wed, 9 Oct 2024 16:05:37 +0200 Subject: [PATCH] test(nextcloud): Add checks to ensure that all available props are parsed Signed-off-by: provokateurin --- .../test/api/webdav/webdav_test.dart | 171 +++++++++++++++++- .../webdav/get_directory_props.regexp | 14 +- .../fixtures/webdav/get_file_props.regexp | 14 +- 3 files changed, 190 insertions(+), 9 deletions(-) diff --git a/packages/nextcloud/test/api/webdav/webdav_test.dart b/packages/nextcloud/test/api/webdav/webdav_test.dart index 83f75e609e1..7a7a5380edc 100644 --- a/packages/nextcloud/test/api/webdav/webdav_test.dart +++ b/packages/nextcloud/test/api/webdav/webdav_test.dart @@ -3,7 +3,8 @@ import 'dart:convert'; import 'dart:math'; import 'dart:typed_data'; -import 'package:http/http.dart'; +import 'package:collection/collection.dart'; +import 'package:http/http.dart' as http; import 'package:http/testing.dart'; import 'package:mocktail/mocktail.dart'; import 'package:nextcloud/core.dart' as core; @@ -15,6 +16,7 @@ import 'package:nextcloud_test/nextcloud_test.dart'; import 'package:test/test.dart'; import 'package:universal_io/io.dart'; import 'package:version/version.dart'; +import 'package:xml/xml.dart'; class MockCallbackFunction extends Mock { void progressCallback(double progress); @@ -24,6 +26,35 @@ class _FileMock extends Mock implements File {} class _FileStatMock extends Mock implements FileStat {} +List _getMultistatusPropNames(XmlElement root) { + return root.firstElementChild!.childElements + .singleWhere( + (node) => + node.name.local == 'propstat' && + node.childElements.singleWhere((node) => node.name.local == 'status').innerText.contains('200 OK'), + ) + .childElements + .singleWhere((node) => node.name.local == 'prop') + .childElements + .map((el) => '{${el.name.namespaceUri}}${el.name.local}') + .toList() + .sorted(); +} + +Future _expectAllPropsAreParsed(NextcloudTester tester, WebDavMultistatus result, PathUri uri) async { + final parsedProps = _getMultistatusPropNames(result.toXmlElement(namespaces: namespaces)); + expect(parsedProps, isNotEmpty); + + final streamedResponse = await tester.client.webdav.httpClient.send(tester.client.webdav.propfind_Request(uri)); + expect(streamedResponse.statusCode, 207); + final rawResponse = await http.Response.fromStream(streamedResponse); + + final expectedProps = _getMultistatusPropNames(XmlDocument.parse(rawResponse.body).rootElement); + expect(expectedProps, isNotEmpty); + + expect(parsedProps, expectedProps); +} + void main() { test('Chunked responses', () async { await HttpServer.bind('127.0.0.1', 0).then((server) async { @@ -82,10 +113,10 @@ void main() { late FileStat fileStat; setUpAll(() { - registerFallbackValue(Request('get', Uri()) as BaseRequest); + registerFallbackValue(http.Request('get', Uri()) as http.BaseRequest); final mockClient = MockClient((request) async { - return Response('', 400); + return http.Response('', 400); }); client = WebDavClient( @@ -162,7 +193,7 @@ void main() { final file = File('test/files/test.png'); await tester.client.webdav.putFile(file, file.statSync(), PathUri.parse('test/test.png')); - final response = await tester.client.webdav.propfind( + var response = await tester.client.webdav.propfind( PathUri.parse('test/test.png'), prop: const WebDavPropWithoutValues.fromBools( davCreationdate: true, @@ -226,7 +257,7 @@ void main() { ), ); - final props = response.responses.first.propstats.first.prop; + var props = response.responses.first.propstats.first.prop; expect(props.davCreationdate!.isBefore(DateTime.timestamp()), isTrue); expect(props.davDisplayname, 'test.png'); expect(props.davGetcontentlanguage, isNull); @@ -284,6 +315,69 @@ void main() { expect(props.ocTags!.tags, isNull); expect(json.decode(props.ocmSharePermissions!), ['share', 'read', 'write']); expect(props.ocsSharePermissions, 19); + + response = await tester.client.webdav.propfind(PathUri.parse('test/test.png')); + + props = response.responses.first.propstats.first.prop; + expect(props.davCreationdate, isNull); + expect(props.davDisplayname, isNull); + expect(props.davGetcontentlanguage, isNull); + expect(props.davGetcontentlength, 8650); + expect(props.davGetcontenttype, 'image/png'); + expect(props.davGetetag, isNotEmpty); + expect(props.davGetlastmodified!.isBefore(DateTime.timestamp()), isTrue); + expect(props.davQuotaAvailableBytes, isNull); + expect(props.davQuotaUsedBytes, isNull); + expect(props.davResourcetype!.collection, isNull); + expect(props.ncCreationTime, isNull); + expect(props.ncAclCanManage, isNull); + expect(props.ncAclEnabled, isNull); + expect(props.ncAclList, isNull); + expect(props.ncContainedFileCount, isNull); + expect(props.ncContainedFolderCount, isNull); + expect(props.ncDataFingerprint, isNull); + expect(props.ncGroupFolderId, isNull); + expect(props.ncHasPreview, isNull); + expect(props.ncHidden, isNull); + expect(props.ncInheritedAclList, isNull); + expect(props.ncIsEncrypted, isNull); + expect(props.ncIsMountRoot, isNull); + expect(props.ncLock, isNull); + expect(props.ncLockOwner, isNull); + expect(props.ncLockOwnerDisplayname, isNull); + expect(props.ncLockOwnerType, isNull); + expect(props.ncLockTime, isNull); + expect(props.ncLockTimeout, isNull); + expect(props.ncLockToken, isNull); + expect(props.ncMountType, isNull); + expect(props.ncNote, isNull); + expect(props.ncReminderDueDate, isNull); + expect(props.ncRichWorkspace, isNull); + expect(props.ncRichWorkspaceFile, isNull); + expect(props.ncShareAttributes, isNull); + expect(props.ncSharees, isNull); + expect(props.ncUploadTime, isNull); + expect(props.ncVersionAuthor, isNull); + expect(props.ncVersionLabel, isNull); + expect(props.ncMetadataBlurhash, isNull); + expect(props.ocChecksums, isNull); + expect(props.ocCommentsCount, isNull); + expect(props.ocCommentsHref, isNull); + expect(props.ocCommentsUnread, isNull); + expect(props.ocDownloadURL, isNull); + expect(props.ocFavorite, isNull); + expect(props.ocFileid, isNull); + expect(props.ocId, isNull); + expect(props.ocOwnerDisplayName, isNull); + expect(props.ocOwnerId, isNull); + expect(props.ocPermissions, isNull); + expect(props.ocShareTypes, isNull); + expect(props.ocSize, isNull); + expect(props.ocTags, isNull); + expect(props.ocmSharePermissions, isNull); + expect(props.ocsSharePermissions, isNull); + + await _expectAllPropsAreParsed(tester, response, PathUri.parse('test/test.png')); }); test('Get directory props', () async { @@ -291,7 +385,7 @@ void main() { final file = File('test/files/test.png'); await tester.client.webdav.putFile(file, file.statSync(), PathUri.parse('test/dir-props/test.png')); - final response = await tester.client.webdav.propfind( + var response = await tester.client.webdav.propfind( PathUri.parse('test/dir-props'), prop: const WebDavPropWithoutValues.fromBools( davCreationdate: true, @@ -356,7 +450,7 @@ void main() { depth: WebDavDepth.zero, ); - final props = response.responses.first.propstats.first.prop; + var props = response.responses.first.propstats.first.prop; expect(props.davCreationdate!.isBefore(DateTime.timestamp()), isTrue); expect(props.davDisplayname, 'dir-props'); expect(props.davGetcontentlanguage, isNull); @@ -414,6 +508,69 @@ void main() { expect(props.ocTags!.tags, isNull); expect(json.decode(props.ocmSharePermissions!), ['share', 'read', 'write']); expect(props.ocsSharePermissions, 31); + + response = await tester.client.webdav.propfind(PathUri.parse('test/dir-props')); + + props = response.responses.first.propstats.first.prop; + expect(props.davCreationdate, isNull); + expect(props.davDisplayname, isNull); + expect(props.davGetcontentlanguage, isNull); + expect(props.davGetcontentlength, isNull); + expect(props.davGetcontenttype, isNull); + expect(props.davGetetag, isNotEmpty); + expect(props.davGetlastmodified!.isBefore(DateTime.timestamp()), isTrue); + expect(props.davQuotaAvailableBytes, -3); + expect(props.davQuotaUsedBytes, 8650); + expect(props.davResourcetype!.collection, []); + expect(props.ncCreationTime, isNull); + expect(props.ncAclCanManage, isNull); + expect(props.ncAclEnabled, isNull); + expect(props.ncAclList, isNull); + expect(props.ncContainedFileCount, isNull); + expect(props.ncContainedFolderCount, isNull); + expect(props.ncDataFingerprint, isNull); + expect(props.ncGroupFolderId, isNull); + expect(props.ncHasPreview, isNull); + expect(props.ncHidden, isNull); + expect(props.ncInheritedAclList, isNull); + expect(props.ncIsEncrypted, isNull); + expect(props.ncIsMountRoot, isNull); + expect(props.ncLock, isNull); + expect(props.ncLockOwner, isNull); + expect(props.ncLockOwnerDisplayname, isNull); + expect(props.ncLockOwnerType, isNull); + expect(props.ncLockTime, isNull); + expect(props.ncLockTimeout, isNull); + expect(props.ncLockToken, isNull); + expect(props.ncMountType, isNull); + expect(props.ncNote, isNull); + expect(props.ncReminderDueDate, isNull); + expect(props.ncRichWorkspace, isNull); + expect(props.ncRichWorkspaceFile, isNull); + expect(props.ncShareAttributes, isNull); + expect(props.ncSharees, isNull); + expect(props.ncUploadTime, isNull); + expect(props.ncVersionAuthor, isNull); + expect(props.ncVersionLabel, isNull); + expect(props.ncMetadataBlurhash, isNull); + expect(props.ocChecksums, isNull); + expect(props.ocCommentsCount, isNull); + expect(props.ocCommentsHref, isNull); + expect(props.ocCommentsUnread, isNull); + expect(props.ocDownloadURL, isNull); + expect(props.ocFavorite, isNull); + expect(props.ocFileid, isNull); + expect(props.ocId, isNull); + expect(props.ocOwnerDisplayName, isNull); + expect(props.ocOwnerId, isNull); + expect(props.ocPermissions, isNull); + expect(props.ocShareTypes, isNull); + expect(props.ocSize, isNull); + expect(props.ocTags, isNull); + expect(props.ocmSharePermissions, isNull); + expect(props.ocsSharePermissions, isNull); + + await _expectAllPropsAreParsed(tester, response, PathUri.parse('test/dir-props')); }); test('Create share', () async { diff --git a/packages/nextcloud/test/fixtures/webdav/get_directory_props.regexp b/packages/nextcloud/test/fixtures/webdav/get_directory_props.regexp index fd8e7907181..d025ed4a037 100644 --- a/packages/nextcloud/test/fixtures/webdav/get_directory_props.regexp +++ b/packages/nextcloud/test/fixtures/webdav/get_directory_props.regexp @@ -16,4 +16,16 @@ content-type: application/xml depth: 0 ocs-apirequest: true requesttoken: token - \ No newline at end of file + +PROPFIND http://localhost/remote\.php/webdav/test/dir-props +authorization: Bearer mock +content-type: application/xml +ocs-apirequest: true +requesttoken: token + +PROPFIND http://localhost/remote\.php/webdav/test/dir-props +authorization: Bearer mock +content-type: application/xml +ocs-apirequest: true +requesttoken: token + \ No newline at end of file diff --git a/packages/nextcloud/test/fixtures/webdav/get_file_props.regexp b/packages/nextcloud/test/fixtures/webdav/get_file_props.regexp index 05624aa6512..ae5246ea44f 100644 --- a/packages/nextcloud/test/fixtures/webdav/get_file_props.regexp +++ b/packages/nextcloud/test/fixtures/webdav/get_file_props.regexp @@ -10,4 +10,16 @@ authorization: Bearer mock content-type: application/xml ocs-apirequest: true requesttoken: token - \ No newline at end of file + +PROPFIND http://localhost/remote\.php/webdav/test/test\.png +authorization: Bearer mock +content-type: application/xml +ocs-apirequest: true +requesttoken: token + +PROPFIND http://localhost/remote\.php/webdav/test/test\.png +authorization: Bearer mock +content-type: application/xml +ocs-apirequest: true +requesttoken: token + \ No newline at end of file