Skip to content

Commit

Permalink
Merge pull request #2558 from nextcloud/test/nextcloud/all-props-parsed
Browse files Browse the repository at this point in the history
  • Loading branch information
provokateurin authored Oct 24, 2024
2 parents afbf242 + 866e261 commit db2f21f
Show file tree
Hide file tree
Showing 8 changed files with 406 additions and 108 deletions.
1 change: 1 addition & 0 deletions .cspell/nextcloud.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ requesttoken
reshares
resharing
rgdnvw
rgdnvck
roomid
rowocs
setsip
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export 'src/fixtures.dart' hide appendFixture;
export 'src/matchers/webdav_props.dart';
export 'src/models/nextcloud_tester.dart';
export 'src/presets.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import 'package:built_collection/built_collection.dart';
import 'package:collection/collection.dart';
import 'package:http/http.dart' as http;
// ignore: implementation_imports
import 'package:matcher/src/expect/async_matcher.dart';
import 'package:nextcloud/webdav.dart';
import 'package:nextcloud_test/src/models/models.dart';
import 'package:test/test.dart';
import 'package:xml/xml.dart';

class _ContainsAllAvailableProps extends AsyncMatcher {
_ContainsAllAvailableProps(
this.tester,
this.uri,
);

final NextcloudTester tester;
final PathUri uri;

@override
Description describe(Description description) {
return description;
}

@override
Future<String?> matchAsync(dynamic item) async {
if (item is! XmlElement) {
return 'Expected XmlElement, got ${item.runtimeType}.';
}

final parsedProps = _getMultistatusPropNames(item);
if (parsedProps.isEmpty) {
return 'Parsed props were empty';
}

final streamedResponse = await tester.client.webdav.httpClient.send(tester.client.webdav.propfind_Request(uri));
if (streamedResponse.statusCode != 207) {
return 'PROPFIND response status code was not 207';
}
final rawResponse = await http.Response.fromStream(streamedResponse);

final expectedProps = _getMultistatusPropNames(XmlDocument.parse(rawResponse.body).rootElement);
if (expectedProps.isEmpty) {
return 'Expected props were empty';
}

if (parsedProps != expectedProps) {
return 'Missing props: ${expectedProps.where((p) => !parsedProps.contains(p)).join(', ')}';
}

return null;
}

BuiltList<String> _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()
.toBuiltList();
}
}

/// Checks that all props have been parsed, by comparing them to a raw PROPFIND response of a request to [uri].
Matcher containsAllAvailableProps(NextcloudTester tester, PathUri uri) => _ContainsAllAvailableProps(tester, uri);
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:meta/meta.dart';
import 'package:nextcloud_test/nextcloud_test.dart';
import 'package:nextcloud_test/src/models/models.dart';
import 'package:nextcloud_test/src/test_target/test_target.dart';
import 'package:test/test.dart';

Expand Down
3 changes: 3 additions & 0 deletions packages/nextcloud/packages/nextcloud_test/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ environment:

dependencies:
built_collection: ^5.1.1
collection: ^1.0.0
cookie_store:
git:
url: https://github.com/nextcloud/neon
Expand All @@ -17,6 +18,7 @@ dependencies:
git:
url: https://github.com/nextcloud/neon
path: packages/interceptor_http_client
matcher: ^0.12.0
meta: ^1.0.0
nextcloud: ^8.1.0
path: ^1.9.0
Expand All @@ -25,6 +27,7 @@ dependencies:
test_api: ^0.7.0
universal_io: ^2.0.0
version: ^3.0.0
xml: ^6.0.0

dev_dependencies:
neon_lints:
Expand Down
Loading

0 comments on commit db2f21f

Please sign in to comment.