Tofu/tests/webdav/describeWebdavFailure.test.js

100 lines
3.9 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import { describeWebdavFailure } from '#tofu/tools/webdav/describeWebdavFailure.js'
test('a rejected fetch on an https URL is named as a CORS block', () => {
const failure = describeWebdavFailure({
error: new TypeError('Failed to fetch'),
method: 'PROPFIND',
url: 'https://cloud.exemple.fr/remote.php/dav/files/tofu/',
})
assert.equal(failure.kind, 'cors')
assert.match(failure.message, /CORS/)
assert.match(failure.hint, /docs\/webdav-nextcloud\.md/)
})
test('a rejected fetch without a known URL is still named as a CORS block', () => {
const failure = describeWebdavFailure({ error: new TypeError('Failed to fetch'), method: 'GET' })
assert.equal(failure.kind, 'cors')
})
test('401 is a credentials problem', () => {
const failure = describeWebdavFailure({ response: { status: 401, statusText: 'Unauthorized' }, method: 'GET' })
assert.equal(failure.kind, 'auth')
assert.match(failure.message, /Identifiants refusés/)
})
test('403 is a rights problem', () => {
const failure = describeWebdavFailure({ response: { status: 403, statusText: 'Forbidden' }, method: 'PUT' })
assert.equal(failure.kind, 'forbidden')
})
test('404 is a missing resource', () => {
const failure = describeWebdavFailure({ response: { status: 404, statusText: 'Not Found' }, method: 'GET' })
assert.equal(failure.kind, 'notFound')
})
test('409 is a missing parent folder', () => {
const failure = describeWebdavFailure({ response: { status: 409, statusText: 'Conflict' }, method: 'PUT' })
assert.equal(failure.kind, 'conflict')
assert.match(failure.message, /dossier parent/)
})
test('any other error status keeps the status and its text', () => {
const failure = describeWebdavFailure({
response: { status: 507, statusText: 'Insufficient Storage' },
method: 'PUT',
})
assert.equal(failure.kind, 'http')
assert.match(failure.message, /PUT/)
assert.match(failure.message, /507 Insufficient Storage/)
})
test('a status without a status text still reads correctly', () => {
const failure = describeWebdavFailure({ response: { status: 500, statusText: '' } })
assert.equal(failure.message, 'La requête a échoué : le serveur a répondu 500.')
})
test('unreadable JSON is a parse failure', () => {
const failure = describeWebdavFailure({ error: new SyntaxError('Unexpected token }'), method: 'GET' })
assert.equal(failure.kind, 'parse')
assert.match(failure.message, /JSON/)
})
test('an address that is not https is a network failure, not a CORS block', () => {
const failure = describeWebdavFailure({
error: new TypeError('Failed to fetch'),
method: 'PROPFIND',
url: 'cloud.exemple.fr',
})
assert.equal(failure.kind, 'network')
assert.match(failure.message, /https/)
})
test('a failure with neither error nor response stays a network failure', () => {
const failure = describeWebdavFailure({})
assert.equal(failure.kind, 'network')
})
test('a successful response is never described as a failure', () => {
const failure = describeWebdavFailure({ response: { status: 207, statusText: 'Multi-Status' } })
assert.equal(failure.kind, 'network')
})
test('every diagnosis carries a message and a hint in French', () => {
const failures = [
describeWebdavFailure({ error: new TypeError('Failed to fetch') }),
describeWebdavFailure({ error: new SyntaxError('boom') }),
describeWebdavFailure({ response: { status: 401 } }),
describeWebdavFailure({ response: { status: 403 } }),
describeWebdavFailure({ response: { status: 404 } }),
describeWebdavFailure({ response: { status: 409 } }),
describeWebdavFailure({ response: { status: 500 } }),
describeWebdavFailure({}),
]
for (const { kind, message, hint } of failures) {
assert.ok(kind.length > 0, 'a kind is always given')
assert.ok(message.length > 0, `a message is always given for ${kind}`)
assert.ok(hint.length > 0, `a hint is always given for ${kind}`)
}
})