- Create test_cloud_provider_contract.py with parametrized suite for Nextcloud, WebDAV, Google Drive, OneDrive - Assert canonical (connection_id, user_id, parent_ref=None, page_token=None) signature, CloudListing return type, trusted caller identity propagation, metadata normalization, pagination completeness, and forbidden-operation spies - Add synthetic credential-free fixtures: nextcloud_root.xml, webdav_root.xml, google_drive_pages.json, onedrive_pages.json - 9 tests fail for nextcloud (expected RED state — incompatible list_folder override) - All webdav, google_drive, onedrive contract tests pass
106 lines
3.2 KiB
XML
106 lines
3.2 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
Synthetic generic WebDAV Depth-1 PROPFIND fixture — no real credentials, hostnames, tokens.
|
|
Root path: /dav/
|
|
Represents: 2 folders + 3 files directly in root.
|
|
Covers: absolute/relative hrefs, missing optional props, foreign href rejection.
|
|
-->
|
|
<d:multistatus xmlns:d="DAV:">
|
|
|
|
<!-- Root self-entry — MUST be filtered out -->
|
|
<d:response>
|
|
<d:href>/dav/</d:href>
|
|
<d:propstat>
|
|
<d:prop>
|
|
<d:resourcetype><d:collection/></d:resourcetype>
|
|
<d:displayname>root</d:displayname>
|
|
</d:prop>
|
|
<d:status>HTTP/1.1 200 OK</d:status>
|
|
</d:propstat>
|
|
</d:response>
|
|
|
|
<!-- Folder: Archive -->
|
|
<d:response>
|
|
<d:href>/dav/Archive/</d:href>
|
|
<d:propstat>
|
|
<d:prop>
|
|
<d:resourcetype><d:collection/></d:resourcetype>
|
|
<d:displayname>Archive</d:displayname>
|
|
<d:getlastmodified>Mon, 10 Jun 2024 08:00:00 GMT</d:getlastmodified>
|
|
</d:prop>
|
|
<d:status>HTTP/1.1 200 OK</d:status>
|
|
</d:propstat>
|
|
</d:response>
|
|
|
|
<!-- Folder: Shared (relative href) -->
|
|
<d:response>
|
|
<d:href>dav/Shared/</d:href>
|
|
<d:propstat>
|
|
<d:prop>
|
|
<d:resourcetype><d:collection/></d:resourcetype>
|
|
<d:displayname>Shared</d:displayname>
|
|
<d:getlastmodified>Tue, 11 Jun 2024 09:00:00 GMT</d:getlastmodified>
|
|
</d:prop>
|
|
<d:status>HTTP/1.1 200 OK</d:status>
|
|
</d:propstat>
|
|
</d:response>
|
|
|
|
<!-- File: readme.txt — all optional props -->
|
|
<d:response>
|
|
<d:href>/dav/readme.txt</d:href>
|
|
<d:propstat>
|
|
<d:prop>
|
|
<d:resourcetype/>
|
|
<d:displayname>readme.txt</d:displayname>
|
|
<d:getcontentlength>512</d:getcontentlength>
|
|
<d:getcontenttype>text/plain</d:getcontenttype>
|
|
<d:getlastmodified>Wed, 12 Jun 2024 10:00:00 GMT</d:getlastmodified>
|
|
<d:getetag>"readmeetag"</d:getetag>
|
|
</d:prop>
|
|
<d:status>HTTP/1.1 200 OK</d:status>
|
|
</d:propstat>
|
|
</d:response>
|
|
|
|
<!-- File: backup.tar.gz — missing optional props -->
|
|
<d:response>
|
|
<d:href>/dav/backup.tar.gz</d:href>
|
|
<d:propstat>
|
|
<d:prop>
|
|
<d:resourcetype/>
|
|
<d:displayname>backup.tar.gz</d:displayname>
|
|
<d:getcontentlength>10240</d:getcontentlength>
|
|
</d:prop>
|
|
<d:status>HTTP/1.1 200 OK</d:status>
|
|
</d:propstat>
|
|
</d:response>
|
|
|
|
<!-- File: project.pdf — encoded spaces in href -->
|
|
<d:response>
|
|
<d:href>/dav/project%20notes.pdf</d:href>
|
|
<d:propstat>
|
|
<d:prop>
|
|
<d:resourcetype/>
|
|
<d:displayname>project notes.pdf</d:displayname>
|
|
<d:getcontentlength>204800</d:getcontentlength>
|
|
<d:getcontenttype>application/pdf</d:getcontenttype>
|
|
<d:getlastmodified>Thu, 13 Jun 2024 11:00:00 GMT</d:getlastmodified>
|
|
</d:prop>
|
|
<d:status>HTTP/1.1 200 OK</d:status>
|
|
</d:propstat>
|
|
</d:response>
|
|
|
|
<!-- Foreign href — escapes configured root; MUST cause listing to be incomplete -->
|
|
<d:response>
|
|
<d:href>/other-root/escape.txt</d:href>
|
|
<d:propstat>
|
|
<d:prop>
|
|
<d:resourcetype/>
|
|
<d:displayname>escape.txt</d:displayname>
|
|
<d:getcontentlength>100</d:getcontentlength>
|
|
</d:prop>
|
|
<d:status>HTTP/1.1 200 OK</d:status>
|
|
</d:propstat>
|
|
</d:response>
|
|
|
|
</d:multistatus>
|