hesprs_obsidian-webdav-sync/test/webdav-patch.test.ts
tarmbruster c7b5182435
fix(webdav-patch): use content-type header instead of accept for requestUrl (#176)
* fix(webdav-patch): use content-type header instead of accept for requestUrl

PROPFIND requests send a comma-separated Accept header
(text/plain,application/xml), which was previously used as the
Content-Type when forwarding to Obsidian's requestUrl. Some WebDAV
servers (e.g. GMX) reject that with 400 Bad Request since it's not a
valid Content-Type value. Prefer the actual content-type header and
only fall back to accept when it's absent.

* fix(webdav-patch): never fall back to accept for requestUrl contentType

client.exists()/stat() PROPFIND requests only set an Accept header
(a comma list) and send no body, so the previous fallback still
leaked the comma list into Content-Type and GMX kept rejecting it
with 400. Only use an explicit content-type header; leave contentType
unset otherwise.

* cleanup(api): cleanup dead code in API patch

`retractedHeaders` seems to be unused. Old technical debt, remove anyway.

---------

Co-authored-by: Hēsperus <hesprs@outlook.com>
2026-07-20 18:20:15 +08:00

58 lines
1.4 KiB
TypeScript

import { beforeEach, expect, mock, test } from 'bun:test';
import { getPatcher } from 'webdav';
import patchWebDav from '~/webdav-patch';
type RequestUrlCall = {
contentType?: string;
headers: Record<string, string>;
method: string;
url: string;
};
let lastCall: RequestUrlCall | undefined;
const requestUrlMock = mock(async (p: RequestUrlCall) => {
lastCall = p;
return {
arrayBuffer: new ArrayBuffer(0),
headers: {},
status: 207,
text: '',
};
});
void mock.module('~/utils/request-url', () => ({
default: requestUrlMock,
}));
beforeEach(() => {
lastCall = undefined;
patchWebDav();
});
test('uses the content-type header when present, ignoring accept', async () => {
await getPatcher().execute('request', {
headers: {
accept: 'text/plain,application/xml',
'content-type': 'application/xml; charset=utf-8',
},
method: 'PUT',
url: 'https://webdav.mc.gmx.net/Notes/file.md',
});
expect(lastCall?.contentType).toBe('application/xml; charset=utf-8');
});
test('leaves contentType unset for body-less PROPFIND requests that only send accept', async () => {
// Mirrors the webdav library's stat()/exists() calls, which only set an
// Accept header (a comma list, invalid as Content-Type) and no body
await getPatcher().execute('request', {
headers: {
Accept: 'text/plain,application/xml',
Depth: '0',
},
method: 'PROPFIND',
url: 'https://webdav.mc.gmx.net/',
});
expect(lastCall?.contentType).toBeUndefined();
});