Files
upstream-rocketchat/apps/meteor/client/components/GazzodownText.spec.tsx
upstream-mirror 30810eecd7
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s
snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:21:02 +05:00

230 lines
7.7 KiB
TypeScript

import { Markup } from '@rocket.chat/gazzodown';
import { mockAppRoot } from '@rocket.chat/mock-providers';
import { render, screen } from '@testing-library/react';
import GazzodownText from './GazzodownText';
import { useMessageListHighlights } from './message/list/MessageListContext';
jest.mock('@rocket.chat/ui-client', () => ({
useFeaturePreview: () => false,
}));
jest.mock('@rocket.chat/fuselage-hooks', () => ({
useLocalStorage: () => ['en', jest.fn()],
}));
jest.mock('./message/list/MessageListContext', () => ({
useMessageListHighlights: jest.fn(),
useMessageListShowRealName: jest.fn(() => false),
}));
jest.mock('../lib/utils/fireGlobalEvent', () => ({
fireGlobalEvent: jest.fn(),
}));
jest.mock('../views/room/hooks/useGoToRoom', () => ({
useGoToRoom: jest.fn(),
}));
const mockUseMessageListHighlights = useMessageListHighlights as jest.MockedFunction<typeof useMessageListHighlights>;
const wrapper = mockAppRoot().withUserPreference('useEmojis', true).withSetting('UI_Use_Real_Name', false).withJohnDoe();
const HighlightTester = ({ text }: { text: string }) => {
return (
<Markup
tokens={[
{
type: 'PARAGRAPH',
value: [{ type: 'PLAIN_TEXT', value: text }],
},
]}
/>
);
};
describe('GazzodownText highlights', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should highlight Russian word "тест" in the middle of a sentence', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'тест' }] as any);
render(
<GazzodownText>
<HighlightTester text='Это тест сообщения' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
// Expect that the highlighted element wraps exactly "тест"
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^тест$/i);
});
it('should highlight Russian word "тест" at the beginning of a sentence', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'тест' }] as any);
render(
<GazzodownText>
<HighlightTester text='Тест сообщения' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^тест$/i);
});
it('should not highlight "тест" when it is part of a larger word', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'тест' }] as any);
render(
<GazzodownText>
<HighlightTester text='Тестирование сообщения' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
expect(screen.queryByTitle('Highlighted_chosen_word')).not.toBeInTheDocument();
});
it('should highlight Russian word "тест" at the end of a sentence', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'тест' }] as any);
render(
<GazzodownText>
<HighlightTester text='Сообщение тест' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^тест$/i);
});
it('should highlight English word "test" regardless of its position', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'test' }] as any);
render(
<GazzodownText>
<HighlightTester text='This is a test message' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^test$/i);
});
it('should highlight all occurrences of the highlighted word in different positions', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'test' }] as any);
render(
<GazzodownText>
<HighlightTester text='test is at the beginning, in the middle test, and at the end test' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
const highlightedElements = screen.getAllByTitle('Highlighted_chosen_word');
// Expect three separate highlights.
expect(highlightedElements.length).toBe(3);
highlightedElements.forEach((el) => {
expect(el).toHaveTextContent(/^test$/i);
});
});
it('should highlight the highlighted word in a multiline text', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'test' }] as any);
const multilineText = `First line
Test line
Another line with test
in it.`;
render(
<GazzodownText>
<HighlightTester text={multilineText} />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
const highlightedElements = screen.getAllByTitle('Highlighted_chosen_word');
// At least two occurrences are expected: one for "Test" (capitalized) and one for "test"
expect(highlightedElements.length).toBeGreaterThanOrEqual(2);
// Verify that the highlighted texts match "test" (case-insensitive)
highlightedElements.forEach((el) => {
expect(el.textContent).toMatch(/^test$/i);
});
});
it('should highlight highlighted word when surrounded by colons', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'test' }] as any);
render(
<GazzodownText>
<HighlightTester text='This is :test: inside colons' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
// The highlighted element should contain only "test"
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^test$/i);
});
it('should highlight highlighted word when colon is at the start', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'test' }] as any);
render(
<GazzodownText>
<HighlightTester text='This is :test with colon at the start' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
// The highlighted element should contain only "test"
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^test$/i);
});
it('should highlight highlighted word when colon is at the end', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'test' }] as any);
render(
<GazzodownText>
<HighlightTester text='This is test: with colon at end' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
// The highlighted element should contain only "test"
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^test$/i);
});
it('should highlight multiple different highlighted words in the same text', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'test' }, { highlight: 'highlight' }] as any);
render(
<GazzodownText>
<HighlightTester text='This test message should highlight the word highlight in multiple places: test and highlight.' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
const highlightedElements = screen.getAllByTitle('Highlighted_chosen_word');
expect(highlightedElements.length).toBe(5);
const texts = highlightedElements.map((el) => el.textContent?.toLowerCase());
expect(texts).toEqual(expect.arrayContaining(['test', 'highlight']));
});
it('should highlight a word containing special characters like "-", "_", ".", "/", "=", "!", ":', () => {
// The highlight word includes special characters.
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'te-st_te.st/te=te!st:' }] as any);
const testText = 'This message contains te-st_te.st/te=te!st: as a highlighted word.';
render(
<GazzodownText>
<HighlightTester text={testText} />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^te-st_te\.st\/te=te!st:$/i);
});
it('should highlight the word in a case-insensitive manner', () => {
mockUseMessageListHighlights.mockReturnValue([{ highlight: 'Test' }] as any);
render(
<GazzodownText>
<HighlightTester text='This is a test message' />
</GazzodownText>,
{ wrapper: wrapper.build() },
);
expect(screen.getByTitle('Highlighted_chosen_word')).toHaveTextContent(/^test$/i);
});
});