Commentaires fédérés via Mastodon (bokante.o-k-i.net) — backend #5
@@ -0,0 +1,73 @@
|
|||||||
|
import {describe, it, expect, vi, afterEach, beforeEach} from 'vitest';
|
||||||
|
import {createStatus, getStatusContext} from '../bokante-mastodon.js';
|
||||||
|
|
||||||
|
describe('bokante-mastodon', () => {
|
||||||
|
const originalFetch = global.fetch;
|
||||||
|
const originalEnv = {...process.env};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
process.env.BOKANTE_INSTANCE_URL = 'https://bokante.o-k-i.net';
|
||||||
|
process.env.BOKANTE_ACCESS_TOKEN = 'test-token';
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
global.fetch = originalFetch;
|
||||||
|
process.env = {...originalEnv};
|
||||||
|
vi.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('createStatus', () => {
|
||||||
|
it('poste le statut avec le bon endpoint, jeton et corps', async () => {
|
||||||
|
global.fetch = vi.fn(async () => ({
|
||||||
|
ok: true,
|
||||||
|
json: async () => ({id: '112233', url: 'https://bokante.o-k-i.net/@paroles/112233'})
|
||||||
|
}));
|
||||||
|
|
||||||
|
const result = await createStatus('Nouvelle parole : "Titre"');
|
||||||
|
|
||||||
|
const [url, options] = global.fetch.mock.calls[0];
|
||||||
|
expect(url).toBe('https://bokante.o-k-i.net/api/v1/statuses');
|
||||||
|
expect(options.method).toBe('POST');
|
||||||
|
expect(options.headers.Authorization).toBe('Bearer test-token');
|
||||||
|
expect(JSON.parse(options.body)).toEqual({
|
||||||
|
status: 'Nouvelle parole : "Titre"',
|
||||||
|
visibility: 'public'
|
||||||
|
});
|
||||||
|
expect(result).toEqual({id: '112233', url: 'https://bokante.o-k-i.net/@paroles/112233'});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lève une erreur claire sur réponse HTTP non-ok', async () => {
|
||||||
|
global.fetch = vi.fn(async () => ({
|
||||||
|
ok: false,
|
||||||
|
status: 422,
|
||||||
|
text: async () => 'Validation Failed'
|
||||||
|
}));
|
||||||
|
|
||||||
|
await expect(createStatus('texte')).rejects.toThrow('Mastodon 422: Validation Failed');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getStatusContext', () => {
|
||||||
|
it('récupère le contexte du statut avec le bon endpoint et jeton', async () => {
|
||||||
|
const context = {ancestors: [], descendants: [{id: '1', content: '<p>coucou</p>'}]};
|
||||||
|
global.fetch = vi.fn(async () => ({ok: true, json: async () => context}));
|
||||||
|
|
||||||
|
const result = await getStatusContext('112233');
|
||||||
|
|
||||||
|
const [url, options] = global.fetch.mock.calls[0];
|
||||||
|
expect(url).toBe('https://bokante.o-k-i.net/api/v1/statuses/112233/context');
|
||||||
|
expect(options.headers.Authorization).toBe('Bearer test-token');
|
||||||
|
expect(result).toEqual(context);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('lève une erreur claire sur réponse HTTP non-ok', async () => {
|
||||||
|
global.fetch = vi.fn(async () => ({
|
||||||
|
ok: false,
|
||||||
|
status: 404,
|
||||||
|
text: async () => 'Record not found'
|
||||||
|
}));
|
||||||
|
|
||||||
|
await expect(getStatusContext('inconnu')).rejects.toThrow('Mastodon 404: Record not found');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
function getConfig() {
|
||||||
|
return {
|
||||||
|
instanceUrl: process.env.BOKANTE_INSTANCE_URL || 'https://bokante.o-k-i.net',
|
||||||
|
accessToken: process.env.BOKANTE_ACCESS_TOKEN
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function mastodonFetch(url, options) {
|
||||||
|
const {accessToken} = getConfig();
|
||||||
|
const response = await fetch(url, {
|
||||||
|
...options,
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${accessToken}`,
|
||||||
|
...options.headers
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
const body = await response.text();
|
||||||
|
throw new Error(`Mastodon ${response.status}: ${body}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createStatus(text, {visibility = 'public'} = {}) {
|
||||||
|
const {instanceUrl} = getConfig();
|
||||||
|
return mastodonFetch(`${instanceUrl}/api/v1/statuses`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {'Content-Type': 'application/json'},
|
||||||
|
body: JSON.stringify({status: text, visibility})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getStatusContext(statusId) {
|
||||||
|
const {instanceUrl} = getConfig();
|
||||||
|
return mastodonFetch(`${instanceUrl}/api/v1/statuses/${statusId}/context`, {
|
||||||
|
method: 'GET'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {createStatus, getStatusContext};
|
||||||
Reference in New Issue
Block a user