mirror of
https://git.shipoclu.com/moon/plspace.git
synced 2026-08-13 02:42:30 +00:00
quote posts
This commit is contained in:
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { ApiClient } from './client'
|
||||
import {
|
||||
fetchNotifications,
|
||||
fetchQuotes,
|
||||
postStatus,
|
||||
setEmojiReaction,
|
||||
updateProfileFields,
|
||||
@@ -181,6 +182,58 @@ describe('emoji reaction endpoints', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('quote endpoints', () => {
|
||||
it('sends both current and legacy quote parameters when composing', async () => {
|
||||
const fetchMock = vi.fn(async (_url: string, init?: RequestInit) => {
|
||||
expect(JSON.parse(String(init?.body))).toMatchObject({
|
||||
status: 'Commentary',
|
||||
quoted_status_id: 'quoted/one',
|
||||
quote_id: 'quoted/one',
|
||||
})
|
||||
return new Response(JSON.stringify({ id: 'quote-1' }), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
})
|
||||
})
|
||||
vi.stubGlobal('fetch', fetchMock)
|
||||
|
||||
await postStatus(new ApiClient('example.test', 'token'), {
|
||||
status: 'Commentary',
|
||||
quoted_status_id: 'quoted/one',
|
||||
})
|
||||
})
|
||||
|
||||
it('falls back to the legacy Pleroma quote-list endpoint', async () => {
|
||||
const fetchMock = vi
|
||||
.fn()
|
||||
.mockResolvedValueOnce(
|
||||
new Response(JSON.stringify({ error: 'Not found' }), {
|
||||
status: 404,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}),
|
||||
)
|
||||
.mockResolvedValueOnce(
|
||||
new Response(JSON.stringify([{ id: 'quote-1' }]), {
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
}),
|
||||
)
|
||||
vi.stubGlobal('fetch', fetchMock)
|
||||
|
||||
const page = await fetchQuotes(new ApiClient('old-pleroma.example', 'token'), 'status/one', {
|
||||
limit: 20,
|
||||
})
|
||||
|
||||
expect(page.items).toEqual([{ id: 'quote-1' }])
|
||||
expect(fetchMock.mock.calls[0][0]).toBe(
|
||||
'https://old-pleroma.example/api/v1/statuses/status%2Fone/quotes?limit=20',
|
||||
)
|
||||
expect(fetchMock.mock.calls[1][0]).toBe(
|
||||
'https://old-pleroma.example/api/v1/pleroma/statuses/status%2Fone/quotes?limit=20',
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('fetchNotifications', () => {
|
||||
it('defensively applies requested types when a server ignores the filter', async () => {
|
||||
vi.stubGlobal(
|
||||
|
||||
@@ -283,6 +283,7 @@ export interface ComposeOptions {
|
||||
expires_in: number
|
||||
multiple: boolean
|
||||
}
|
||||
quoted_status_id?: string
|
||||
}
|
||||
|
||||
export function postStatus(api: ApiClient, options: ComposeOptions): Promise<Status> {
|
||||
@@ -297,9 +298,29 @@ export function postStatus(api: ApiClient, options: ComposeOptions): Promise<Sta
|
||||
if (options.media_ids?.length) body.media_ids = options.media_ids
|
||||
if (options.language) body.language = options.language
|
||||
if (options.poll) body.poll = options.poll
|
||||
if (options.quoted_status_id) {
|
||||
body.quoted_status_id = options.quoted_status_id
|
||||
// Older Pleroma/Akkoma releases predate the standardized Mastodon name.
|
||||
// Mastodon ignores unknown JSON keys, while those servers require this.
|
||||
body.quote_id = options.quoted_status_id
|
||||
}
|
||||
return api.post<Status>('/api/v1/statuses', body)
|
||||
}
|
||||
|
||||
export async function fetchQuotes(
|
||||
api: ApiClient,
|
||||
id: string,
|
||||
cursor: Cursor = {},
|
||||
): Promise<Page<Status>> {
|
||||
const encoded = encodeURIComponent(id)
|
||||
try {
|
||||
return await api.page<Status>(`/api/v1/statuses/${encoded}/quotes`, { ...cursor })
|
||||
} catch (cause) {
|
||||
if (!(cause instanceof ApiError) || (cause.status !== 404 && cause.status !== 405)) throw cause
|
||||
return api.page<Status>(`/api/v1/pleroma/statuses/${encoded}/quotes`, { ...cursor })
|
||||
}
|
||||
}
|
||||
|
||||
export function deleteStatus(api: ApiClient, id: string): Promise<Status> {
|
||||
return api.delete<Status>(`/api/v1/statuses/${encodeURIComponent(id)}`)
|
||||
}
|
||||
|
||||
@@ -178,6 +178,32 @@ export interface EmojiReaction {
|
||||
accounts?: Account[]
|
||||
}
|
||||
|
||||
export type QuoteState =
|
||||
| 'pending'
|
||||
| 'accepted'
|
||||
| 'rejected'
|
||||
| 'revoked'
|
||||
| 'deleted'
|
||||
| 'unauthorized'
|
||||
| 'blocked_account'
|
||||
| 'blocked_domain'
|
||||
| 'muted_account'
|
||||
| string
|
||||
|
||||
/** Mastodon 4.4+ quote envelope. Pleroma places the Status under `pleroma.quote`. */
|
||||
export interface StatusQuote {
|
||||
state: QuoteState
|
||||
quoted_status?: Status | null
|
||||
/** Mastodon ShallowQuote form. */
|
||||
quoted_status_id?: string | null
|
||||
}
|
||||
|
||||
export interface QuoteApproval {
|
||||
automatic: string[]
|
||||
manual: string[]
|
||||
current_user: 'automatic' | 'manual' | 'denied' | 'unknown' | string
|
||||
}
|
||||
|
||||
export interface Status {
|
||||
id: string
|
||||
uri: string
|
||||
@@ -198,6 +224,7 @@ export interface Status {
|
||||
replies_count: number
|
||||
reblogs_count: number
|
||||
favourites_count: number
|
||||
quotes_count?: number
|
||||
|
||||
media_attachments: MediaAttachment[]
|
||||
mentions: StatusMention[]
|
||||
@@ -205,6 +232,12 @@ export interface Status {
|
||||
emojis: CustomEmoji[]
|
||||
card?: PreviewCard | null
|
||||
poll?: Poll | null
|
||||
/** Mastodon quote envelope, or a raw quoted Status on a few compatible forks. */
|
||||
quote?: StatusQuote | Status | null
|
||||
quote_approval?: QuoteApproval | null
|
||||
/** Compatibility fields returned at top-level by some Pleroma-family forks. */
|
||||
quote_id?: string | null
|
||||
quote_url?: string | null
|
||||
application?: { name: string; website?: string | null } | null
|
||||
|
||||
reblog: Status | null
|
||||
@@ -222,6 +255,11 @@ export interface Status {
|
||||
spoiler_text?: Record<string, string>
|
||||
/** Pleroma/Akkoma emoji reactions, including custom emoji URLs. */
|
||||
emoji_reactions?: EmojiReaction[]
|
||||
quote?: Status | null
|
||||
quote_id?: string | null
|
||||
quote_url?: string | null
|
||||
quote_visible?: boolean
|
||||
quotes_count?: number
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,6 +288,8 @@ export type NotificationType =
|
||||
| 'favourite'
|
||||
| 'poll'
|
||||
| 'update'
|
||||
| 'quote'
|
||||
| 'quoted_update'
|
||||
| 'admin.sign_up'
|
||||
| 'admin.report'
|
||||
| 'pleroma:emoji_reaction'
|
||||
|
||||
Reference in New Issue
Block a user