Files
FEDEO/mobile/tests/chat-picker.test.mjs

57 lines
3.1 KiB
JavaScript

import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { createRequire } from 'node:module';
import { test } from 'node:test';
import React from 'react';
import { act, create } from 'react-test-renderer';
import ts from 'typescript';
import * as chatModel from '../src/lib/chat.ts';
globalThis.IS_REACT_ACT_ENVIRONMENT = true;
const require = createRequire(import.meta.url);
function harness() {
let resolvePicker;
const picker = new Promise(resolve => { resolvePicker = resolve; });
const drafts = [];
const chat = { detail: { name: 'Test', canSend: true }, messages: [], members: [], reactions: {}, loading: false };
const output = ts.transpileModule(readFileSync(new URL('../components/chat-conversation.tsx', import.meta.url), 'utf8'), {
compilerOptions: { module: ts.ModuleKind.CommonJS, jsx: ts.JsxEmit.ReactJSX, target: ts.ScriptTarget.ES2022 },
}).outputText;
const exports = {};
new Function('require', 'exports', output)(name => {
if (name === 'react-native') return { ...Object.fromEntries(['ActivityIndicator', 'FlatList', 'Modal', 'Pressable', 'ScrollView', 'Text', 'TextInput', 'View'].map(key => [key, key])), StyleSheet: { create: value => value } };
if (name === '@expo/vector-icons') return { Ionicons: 'Icon' };
if (name === 'expo-image') return { Image: 'Image' };
if (name === 'expo-image-picker') return { launchImageLibraryAsync: () => picker };
if (name === '@/hooks/use-chat-conversation') return { useChatConversation: () => chat };
if (name === '@/src/lib/chat-api') return { chatApi: {} };
if (name === '@/src/lib/chat-image') return { prepareMobileChatImage: async () => ({ name: 'Bild.jpg', dataUrl: 'data:image/jpeg;base64,YQ==' }) };
if (name === '@/src/lib/chat') return chatModel;
return require(name);
}, exports);
const props = { token: 't', room: { key: 'test', name: 'Test' }, enabled: true,
draft: { text: 'Bild dazu', image: null, clientId: 'draft' }, onDraft: draft => drafts.push(draft) };
let root;
return {
drafts,
async render(enabled) { await act(async () => { const element = React.createElement(exports.ChatConversation, { ...props, enabled }); if (root) root.update(element); else root = create(element); }); },
async pick() { await act(async () => root.root.findByProps({ accessibilityLabel: 'Bild anhängen' }).props.onPress()); },
async finish() { await act(async () => resolvePicker({ canceled: false, assets: [{ uri: 'file:///test.jpg' }] })); },
async dispose() { await act(async () => root.unmount()); },
};
}
test('System-Fotoauswahl darf die App vorübergehend in den Hintergrund versetzen', async () => {
const h = harness();
try {
await h.render(true); await h.pick(); await h.render(false); await h.finish();
assert.equal(h.drafts.length, 1);
assert.equal(h.drafts[0].text, 'Bild dazu');
assert.equal(h.drafts[0].image.name, 'Bild.jpg');
} finally { await h.dispose(); }
});
test('Eine verspätete Fotoauswahl verändert nach Raumwechsel keinen anderen Entwurf', async () => {
const h = harness();
await h.render(true); await h.pick(); await h.dispose(); await h.finish();
assert.equal(h.drafts.length, 0);
});