/* eslint-disable unicorn/numeric-separators-style */ /* eslint-disable unicorn/no-null */ import type { ExecutionContext } from "ava" import test from "ava" import type { Message } from "discord.js" import { Client, TextChannel } from "discord.js" import { createRoot, Embed, Text } from "reacord" import { pick } from "reacord-helpers/pick.js" import { raise } from "reacord-helpers/raise.js" import React from "react" import { testBotToken, testChannelId } from "./test-environment.js" const client = new Client({ intents: ["GUILDS"], }) let channel: TextChannel test.before(async () => { await client.login(testBotToken) const result = client.channels.cache.get(testChannelId) ?? (await client.channels.fetch(testChannelId)) ?? raise("Channel not found") if (!(result instanceof TextChannel)) { throw new TypeError("Channel must be a text channel") } channel = result }) test.after(() => { client.destroy() }) test.beforeEach(async () => { const messages = await channel.messages.fetch() await Promise.all(messages.map((message) => message.delete())) }) test.serial("kitchen sink + destroy", async (t) => { const root = createRoot(channel) await root.render( <> message content no space description more description another hi , ) await assertMessages(t, [ { content: "message contentno space", embeds: [ { color: 0xfeeeef, description: "description more description", }, { color: null, description: "another hi" }, ], }, ]) await root.destroy() await assertMessages(t, []) }) test.serial("updates", async (t) => { const root = createRoot(channel) // rapid updates void root.render("hi world") await root.render("hi moon") await assertMessages(t, [{ content: "hi moon" }]) // regular update after initial render await root.render(hi sun) await assertMessages(t, [{ content: "hi sun" }]) // update that requires cloning a node await root.render(the) await assertMessages(t, [{ content: "the" }]) }) test.serial("nested text", async (t) => { const root = createRoot(channel) await root.render( hi world{" "} hi moon hi sun , ) await assertMessages(t, [{ content: "hi world hi moon hi sun" }]) }) test.serial("empty embed fallback", async (t) => { const root = createRoot(channel) await root.render() await assertMessages(t, [{ embeds: [{ color: null, description: "_ _" }] }]) }) test.serial("invalid children error", (t) => { const root = createRoot(channel) t.throws(() => root.render( , ), ) }) type MessageData = ReturnType function extractMessageData(message: Message) { return { content: message.content, embeds: message.embeds.map((embed) => pick(embed, "color", "description")), } } async function assertMessages( t: ExecutionContext, expected: Array>, ) { const messages = await channel.messages.fetch() const messageDataFallback: MessageData = { content: "", embeds: [], } t.deepEqual( messages.map((message) => extractMessageData(message)), expected.map((data) => ({ ...messageDataFallback, ...data })), ) }