Skip to content

Commit 4ae9f68

Browse files
committed
test(nextcloud): Add checks to ensure that all available props are parsed
Signed-off-by: provokateurin <[email protected]>
1 parent 729a5b8 commit 4ae9f68

File tree

3 files changed

+190
-9
lines changed

3 files changed

+190
-9
lines changed

packages/nextcloud/test/api/webdav/webdav_test.dart

Lines changed: 164 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import 'dart:convert';
33
import 'dart:math';
44
import 'dart:typed_data';
55

6-
import 'package:http/http.dart';
6+
import 'package:collection/collection.dart';
7+
import 'package:http/http.dart' as http;
78
import 'package:http/testing.dart';
89
import 'package:mocktail/mocktail.dart';
910
import 'package:nextcloud/core.dart' as core;
@@ -15,6 +16,7 @@ import 'package:nextcloud_test/nextcloud_test.dart';
1516
import 'package:test/test.dart';
1617
import 'package:universal_io/io.dart';
1718
import 'package:version/version.dart';
19+
import 'package:xml/xml.dart';
1820

1921
class MockCallbackFunction extends Mock {
2022
void progressCallback(double progress);
@@ -24,6 +26,35 @@ class _FileMock extends Mock implements File {}
2426

2527
class _FileStatMock extends Mock implements FileStat {}
2628

29+
List<String> _getMultistatusPropNames(XmlElement root) {
30+
return root.firstElementChild!.childElements
31+
.singleWhere(
32+
(node) =>
33+
node.name.local == 'propstat' &&
34+
node.childElements.singleWhere((node) => node.name.local == 'status').innerText.contains('200 OK'),
35+
)
36+
.childElements
37+
.singleWhere((node) => node.name.local == 'prop')
38+
.childElements
39+
.map((el) => '{${el.name.namespaceUri}}${el.name.local}')
40+
.toList()
41+
.sorted();
42+
}
43+
44+
Future<void> _expectAllPropsAreParsed(NextcloudTester tester, WebDavMultistatus result, PathUri uri) async {
45+
final parsedProps = _getMultistatusPropNames(result.toXmlElement(namespaces: namespaces));
46+
expect(parsedProps, isNotEmpty);
47+
48+
final streamedResponse = await tester.client.webdav.httpClient.send(tester.client.webdav.propfind_Request(uri));
49+
expect(streamedResponse.statusCode, 207);
50+
final rawResponse = await http.Response.fromStream(streamedResponse);
51+
52+
final expectedProps = _getMultistatusPropNames(XmlDocument.parse(rawResponse.body).rootElement);
53+
expect(expectedProps, isNotEmpty);
54+
55+
expect(parsedProps, expectedProps);
56+
}
57+
2758
void main() {
2859
test('Chunked responses', () async {
2960
await HttpServer.bind('127.0.0.1', 0).then((server) async {
@@ -82,10 +113,10 @@ void main() {
82113
late FileStat fileStat;
83114

84115
setUpAll(() {
85-
registerFallbackValue(Request('get', Uri()) as BaseRequest);
116+
registerFallbackValue(http.Request('get', Uri()) as http.BaseRequest);
86117

87118
final mockClient = MockClient((request) async {
88-
return Response('', 400);
119+
return http.Response('', 400);
89120
});
90121

91122
client = WebDavClient(
@@ -162,7 +193,7 @@ void main() {
162193
final file = File('test/files/test.png');
163194
await tester.client.webdav.putFile(file, file.statSync(), PathUri.parse('test/test.png'));
164195

165-
final response = await tester.client.webdav.propfind(
196+
var response = await tester.client.webdav.propfind(
166197
PathUri.parse('test/test.png'),
167198
prop: const WebDavPropWithoutValues.fromBools(
168199
davCreationdate: true,
@@ -226,7 +257,7 @@ void main() {
226257
),
227258
);
228259

229-
final props = response.responses.first.propstats.first.prop;
260+
var props = response.responses.first.propstats.first.prop;
230261
expect(props.davCreationdate!.isBefore(DateTime.timestamp()), isTrue);
231262
expect(props.davDisplayname, 'test.png');
232263
expect(props.davGetcontentlanguage, isNull);
@@ -284,14 +315,77 @@ void main() {
284315
expect(props.ocTags!.tags, isNull);
285316
expect(json.decode(props.ocmSharePermissions!), ['share', 'read', 'write']);
286317
expect(props.ocsSharePermissions, 19);
318+
319+
response = await tester.client.webdav.propfind(PathUri.parse('test/test.png'));
320+
321+
props = response.responses.first.propstats.first.prop;
322+
expect(props.davCreationdate, isNull);
323+
expect(props.davDisplayname, isNull);
324+
expect(props.davGetcontentlanguage, isNull);
325+
expect(props.davGetcontentlength, 8650);
326+
expect(props.davGetcontenttype, 'image/png');
327+
expect(props.davGetetag, isNotEmpty);
328+
expect(props.davGetlastmodified!.isBefore(DateTime.timestamp()), isTrue);
329+
expect(props.davQuotaAvailableBytes, isNull);
330+
expect(props.davQuotaUsedBytes, isNull);
331+
expect(props.davResourcetype!.collection, isNull);
332+
expect(props.ncCreationTime, isNull);
333+
expect(props.ncAclCanManage, isNull);
334+
expect(props.ncAclEnabled, isNull);
335+
expect(props.ncAclList, isNull);
336+
expect(props.ncContainedFileCount, isNull);
337+
expect(props.ncContainedFolderCount, isNull);
338+
expect(props.ncDataFingerprint, isNull);
339+
expect(props.ncGroupFolderId, isNull);
340+
expect(props.ncHasPreview, isNull);
341+
expect(props.ncHidden, isNull);
342+
expect(props.ncInheritedAclList, isNull);
343+
expect(props.ncIsEncrypted, isNull);
344+
expect(props.ncIsMountRoot, isNull);
345+
expect(props.ncLock, isNull);
346+
expect(props.ncLockOwner, isNull);
347+
expect(props.ncLockOwnerDisplayname, isNull);
348+
expect(props.ncLockOwnerType, isNull);
349+
expect(props.ncLockTime, isNull);
350+
expect(props.ncLockTimeout, isNull);
351+
expect(props.ncLockToken, isNull);
352+
expect(props.ncMountType, isNull);
353+
expect(props.ncNote, isNull);
354+
expect(props.ncReminderDueDate, isNull);
355+
expect(props.ncRichWorkspace, isNull);
356+
expect(props.ncRichWorkspaceFile, isNull);
357+
expect(props.ncShareAttributes, isNull);
358+
expect(props.ncSharees, isNull);
359+
expect(props.ncUploadTime, isNull);
360+
expect(props.ncVersionAuthor, isNull);
361+
expect(props.ncVersionLabel, isNull);
362+
expect(props.ncMetadataBlurhash, isNull);
363+
expect(props.ocChecksums, isNull);
364+
expect(props.ocCommentsCount, isNull);
365+
expect(props.ocCommentsHref, isNull);
366+
expect(props.ocCommentsUnread, isNull);
367+
expect(props.ocDownloadURL, isNull);
368+
expect(props.ocFavorite, isNull);
369+
expect(props.ocFileid, isNull);
370+
expect(props.ocId, isNull);
371+
expect(props.ocOwnerDisplayName, isNull);
372+
expect(props.ocOwnerId, isNull);
373+
expect(props.ocPermissions, isNull);
374+
expect(props.ocShareTypes, isNull);
375+
expect(props.ocSize, isNull);
376+
expect(props.ocTags, isNull);
377+
expect(props.ocmSharePermissions, isNull);
378+
expect(props.ocsSharePermissions, isNull);
379+
380+
await _expectAllPropsAreParsed(tester, response, PathUri.parse('test/test.png'));
287381
});
288382

289383
test('Get directory props', () async {
290384
await tester.client.webdav.mkcol(PathUri.parse('test/dir-props'));
291385
final file = File('test/files/test.png');
292386
await tester.client.webdav.putFile(file, file.statSync(), PathUri.parse('test/dir-props/test.png'));
293387

294-
final response = await tester.client.webdav.propfind(
388+
var response = await tester.client.webdav.propfind(
295389
PathUri.parse('test/dir-props'),
296390
prop: const WebDavPropWithoutValues.fromBools(
297391
davCreationdate: true,
@@ -356,7 +450,7 @@ void main() {
356450
depth: WebDavDepth.zero,
357451
);
358452

359-
final props = response.responses.first.propstats.first.prop;
453+
var props = response.responses.first.propstats.first.prop;
360454
expect(props.davCreationdate!.isBefore(DateTime.timestamp()), isTrue);
361455
expect(props.davDisplayname, 'dir-props');
362456
expect(props.davGetcontentlanguage, isNull);
@@ -414,6 +508,69 @@ void main() {
414508
expect(props.ocTags!.tags, isNull);
415509
expect(json.decode(props.ocmSharePermissions!), ['share', 'read', 'write']);
416510
expect(props.ocsSharePermissions, 31);
511+
512+
response = await tester.client.webdav.propfind(PathUri.parse('test/dir-props'));
513+
514+
props = response.responses.first.propstats.first.prop;
515+
expect(props.davCreationdate, isNull);
516+
expect(props.davDisplayname, isNull);
517+
expect(props.davGetcontentlanguage, isNull);
518+
expect(props.davGetcontentlength, isNull);
519+
expect(props.davGetcontenttype, isNull);
520+
expect(props.davGetetag, isNotEmpty);
521+
expect(props.davGetlastmodified!.isBefore(DateTime.timestamp()), isTrue);
522+
expect(props.davQuotaAvailableBytes, -3);
523+
expect(props.davQuotaUsedBytes, 8650);
524+
expect(props.davResourcetype!.collection, <dynamic>[]);
525+
expect(props.ncCreationTime, isNull);
526+
expect(props.ncAclCanManage, isNull);
527+
expect(props.ncAclEnabled, isNull);
528+
expect(props.ncAclList, isNull);
529+
expect(props.ncContainedFileCount, isNull);
530+
expect(props.ncContainedFolderCount, isNull);
531+
expect(props.ncDataFingerprint, isNull);
532+
expect(props.ncGroupFolderId, isNull);
533+
expect(props.ncHasPreview, isNull);
534+
expect(props.ncHidden, isNull);
535+
expect(props.ncInheritedAclList, isNull);
536+
expect(props.ncIsEncrypted, isNull);
537+
expect(props.ncIsMountRoot, isNull);
538+
expect(props.ncLock, isNull);
539+
expect(props.ncLockOwner, isNull);
540+
expect(props.ncLockOwnerDisplayname, isNull);
541+
expect(props.ncLockOwnerType, isNull);
542+
expect(props.ncLockTime, isNull);
543+
expect(props.ncLockTimeout, isNull);
544+
expect(props.ncLockToken, isNull);
545+
expect(props.ncMountType, isNull);
546+
expect(props.ncNote, isNull);
547+
expect(props.ncReminderDueDate, isNull);
548+
expect(props.ncRichWorkspace, isNull);
549+
expect(props.ncRichWorkspaceFile, isNull);
550+
expect(props.ncShareAttributes, isNull);
551+
expect(props.ncSharees, isNull);
552+
expect(props.ncUploadTime, isNull);
553+
expect(props.ncVersionAuthor, isNull);
554+
expect(props.ncVersionLabel, isNull);
555+
expect(props.ncMetadataBlurhash, isNull);
556+
expect(props.ocChecksums, isNull);
557+
expect(props.ocCommentsCount, isNull);
558+
expect(props.ocCommentsHref, isNull);
559+
expect(props.ocCommentsUnread, isNull);
560+
expect(props.ocDownloadURL, isNull);
561+
expect(props.ocFavorite, isNull);
562+
expect(props.ocFileid, isNull);
563+
expect(props.ocId, isNull);
564+
expect(props.ocOwnerDisplayName, isNull);
565+
expect(props.ocOwnerId, isNull);
566+
expect(props.ocPermissions, isNull);
567+
expect(props.ocShareTypes, isNull);
568+
expect(props.ocSize, isNull);
569+
expect(props.ocTags, isNull);
570+
expect(props.ocmSharePermissions, isNull);
571+
expect(props.ocsSharePermissions, isNull);
572+
573+
await _expectAllPropsAreParsed(tester, response, PathUri.parse('test/dir-props'));
417574
});
418575

419576
test('Create share', () async {

packages/nextcloud/test/fixtures/webdav/get_directory_props.regexp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,16 @@ content-type: application/xml
1616
depth: 0
1717
ocs-apirequest: true
1818
requesttoken: token
19-
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop><d:creationdate/><d:displayname/><d:getcontentlanguage/><d:getcontentlength/><d:getcontenttype/><d:getetag/><d:getlastmodified/><d:quota-available-bytes/><d:quota-used-bytes/><d:resourcetype/><nc:acl-can-manage/><nc:acl-enabled/><nc:acl-list/><nc:contained-file-count/><nc:contained-folder-count/><nc:creation_time/><nc:data-fingerprint/><nc:group-folder-id/><nc:has-preview/><nc:hidden/><nc:inherited-acl-list/><nc:is-encrypted/><nc:is-mount-root/><nc:lock/><nc:lock-owner/><nc:lock-owner-displayname/><nc:lock-owner-editor/><nc:lock-owner-type/><nc:lock-time/><nc:lock-timeout/><nc:lock-token/><nc:mount-type/><nc:note/><nc:reminder-due-date/><nc:rich-workspace/><nc:rich-workspace-file/><nc:share-attributes/><nc:sharees/><nc:upload_time/><nc:version-author/><nc:version-label/><nc:metadata-blurhash/><oc:checksums/><oc:comments-count/><oc:comments-href/><oc:comments-unread/><oc:downloadURL/><oc:favorite/><oc:fileid/><oc:id/><oc:owner-display-name/><oc:owner-id/><oc:permissions/><oc:share-types/><oc:size/><oc:tags/><ocm:share-permissions/><ocs:share-permissions/></d:prop></d:propfind>
19+
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop><d:creationdate/><d:displayname/><d:getcontentlanguage/><d:getcontentlength/><d:getcontenttype/><d:getetag/><d:getlastmodified/><d:quota-available-bytes/><d:quota-used-bytes/><d:resourcetype/><nc:acl-can-manage/><nc:acl-enabled/><nc:acl-list/><nc:contained-file-count/><nc:contained-folder-count/><nc:creation_time/><nc:data-fingerprint/><nc:group-folder-id/><nc:has-preview/><nc:hidden/><nc:inherited-acl-list/><nc:is-encrypted/><nc:is-mount-root/><nc:lock/><nc:lock-owner/><nc:lock-owner-displayname/><nc:lock-owner-editor/><nc:lock-owner-type/><nc:lock-time/><nc:lock-timeout/><nc:lock-token/><nc:mount-type/><nc:note/><nc:reminder-due-date/><nc:rich-workspace/><nc:rich-workspace-file/><nc:share-attributes/><nc:sharees/><nc:upload_time/><nc:version-author/><nc:version-label/><nc:metadata-blurhash/><oc:checksums/><oc:comments-count/><oc:comments-href/><oc:comments-unread/><oc:downloadURL/><oc:favorite/><oc:fileid/><oc:id/><oc:owner-display-name/><oc:owner-id/><oc:permissions/><oc:share-types/><oc:size/><oc:tags/><ocm:share-permissions/><ocs:share-permissions/></d:prop></d:propfind>
20+
PROPFIND http://localhost/remote\.php/webdav/test/dir-props
21+
authorization: Bearer mock
22+
content-type: application/xml
23+
ocs-apirequest: true
24+
requesttoken: token
25+
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop/></d:propfind>
26+
PROPFIND http://localhost/remote\.php/webdav/test/dir-props
27+
authorization: Bearer mock
28+
content-type: application/xml
29+
ocs-apirequest: true
30+
requesttoken: token
31+
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop/></d:propfind>

packages/nextcloud/test/fixtures/webdav/get_file_props.regexp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,16 @@ authorization: Bearer mock
1010
content-type: application/xml
1111
ocs-apirequest: true
1212
requesttoken: token
13-
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop><d:creationdate/><d:displayname/><d:getcontentlanguage/><d:getcontentlength/><d:getcontenttype/><d:getetag/><d:getlastmodified/><d:quota-available-bytes/><d:quota-used-bytes/><d:resourcetype/><nc:acl-can-manage/><nc:acl-enabled/><nc:acl-list/><nc:contained-file-count/><nc:contained-folder-count/><nc:creation_time/><nc:data-fingerprint/><nc:group-folder-id/><nc:has-preview/><nc:hidden/><nc:inherited-acl-list/><nc:is-encrypted/><nc:is-mount-root/><nc:lock/><nc:lock-owner/><nc:lock-owner-displayname/><nc:lock-owner-editor/><nc:lock-owner-type/><nc:lock-time/><nc:lock-timeout/><nc:lock-token/><nc:mount-type/><nc:note/><nc:reminder-due-date/><nc:rich-workspace/><nc:rich-workspace-file/><nc:share-attributes/><nc:sharees/><nc:upload_time/><nc:version-author/><nc:version-label/><nc:metadata-blurhash/><oc:checksums/><oc:comments-count/><oc:comments-href/><oc:comments-unread/><oc:downloadURL/><oc:favorite/><oc:fileid/><oc:id/><oc:owner-display-name/><oc:owner-id/><oc:permissions/><oc:share-types/><oc:size/><oc:tags/><ocm:share-permissions/><ocs:share-permissions/></d:prop></d:propfind>
13+
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop><d:creationdate/><d:displayname/><d:getcontentlanguage/><d:getcontentlength/><d:getcontenttype/><d:getetag/><d:getlastmodified/><d:quota-available-bytes/><d:quota-used-bytes/><d:resourcetype/><nc:acl-can-manage/><nc:acl-enabled/><nc:acl-list/><nc:contained-file-count/><nc:contained-folder-count/><nc:creation_time/><nc:data-fingerprint/><nc:group-folder-id/><nc:has-preview/><nc:hidden/><nc:inherited-acl-list/><nc:is-encrypted/><nc:is-mount-root/><nc:lock/><nc:lock-owner/><nc:lock-owner-displayname/><nc:lock-owner-editor/><nc:lock-owner-type/><nc:lock-time/><nc:lock-timeout/><nc:lock-token/><nc:mount-type/><nc:note/><nc:reminder-due-date/><nc:rich-workspace/><nc:rich-workspace-file/><nc:share-attributes/><nc:sharees/><nc:upload_time/><nc:version-author/><nc:version-label/><nc:metadata-blurhash/><oc:checksums/><oc:comments-count/><oc:comments-href/><oc:comments-unread/><oc:downloadURL/><oc:favorite/><oc:fileid/><oc:id/><oc:owner-display-name/><oc:owner-id/><oc:permissions/><oc:share-types/><oc:size/><oc:tags/><ocm:share-permissions/><ocs:share-permissions/></d:prop></d:propfind>
14+
PROPFIND http://localhost/remote\.php/webdav/test/test\.png
15+
authorization: Bearer mock
16+
content-type: application/xml
17+
ocs-apirequest: true
18+
requesttoken: token
19+
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop/></d:propfind>
20+
PROPFIND http://localhost/remote\.php/webdav/test/test\.png
21+
authorization: Bearer mock
22+
content-type: application/xml
23+
ocs-apirequest: true
24+
requesttoken: token
25+
<d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud\.org/ns" xmlns:nc="http://nextcloud\.org/ns" xmlns:ocs="http://open-collaboration-services\.org/ns" xmlns:ocm="http://open-cloud-mesh\.org/ns"><d:prop/></d:propfind>

0 commit comments

Comments
 (0)