mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-08-08 09:43:03 +02:00
Polish off all our gross edges around frontend/backend Public name management
This commit is contained in:
@@ -3,6 +3,7 @@ import { describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import { ChatHeader } from '../components/ChatHeader';
|
||||
import type { Channel, Contact, Conversation, Favorite, PathDiscoveryResponse } from '../types';
|
||||
import { PUBLIC_CHANNEL_KEY } from '../utils/publicChannel';
|
||||
|
||||
function makeChannel(key: string, name: string, isHashtag: boolean): Channel {
|
||||
return { key, name, is_hashtag: isHashtag, on_radio: false, last_read_at: null };
|
||||
@@ -169,6 +170,25 @@ describe('ChatHeader key visibility', () => {
|
||||
expect(onToggleNotifications).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('hides the delete button for the canonical Public channel', () => {
|
||||
const channel = makeChannel(PUBLIC_CHANNEL_KEY, 'Public', false);
|
||||
const conversation: Conversation = { type: 'channel', id: PUBLIC_CHANNEL_KEY, name: 'Public' };
|
||||
|
||||
render(<ChatHeader {...baseProps} conversation={conversation} channels={[channel]} />);
|
||||
|
||||
expect(screen.queryByRole('button', { name: 'Delete' })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('still shows the delete button for non-canonical channels named Public', () => {
|
||||
const key = 'AB'.repeat(16);
|
||||
const channel = makeChannel(key, 'Public', false);
|
||||
const conversation: Conversation = { type: 'channel', id: key, name: 'Public' };
|
||||
|
||||
render(<ChatHeader {...baseProps} conversation={conversation} channels={[channel]} />);
|
||||
|
||||
expect(screen.getByRole('button', { name: 'Delete' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('opens path discovery modal for contacts and runs the request on demand', async () => {
|
||||
const pubKey = '21'.repeat(32);
|
||||
const contact: Contact = {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { Sidebar } from '../components/Sidebar';
|
||||
import { CONTACT_TYPE_REPEATER, type Channel, type Contact, type Favorite } from '../types';
|
||||
import { getStateKey, type ConversationTimes } from '../utils/conversationState';
|
||||
import { PUBLIC_CHANNEL_KEY } from '../utils/publicChannel';
|
||||
|
||||
function makeChannel(key: string, name: string): Channel {
|
||||
return {
|
||||
@@ -316,4 +317,38 @@ describe('Sidebar section summaries', () => {
|
||||
expect(getContactsOrder()).toEqual(['Zed', 'Amy']);
|
||||
expect(getRepeatersOrder()).toEqual(['Zulu Relay', 'Alpha Relay']);
|
||||
});
|
||||
|
||||
it('pins only the canonical Public channel to the top of channel sorting', () => {
|
||||
const publicChannel = makeChannel(PUBLIC_CHANNEL_KEY, 'Public');
|
||||
const fakePublic = makeChannel('DD'.repeat(16), 'Public');
|
||||
const alphaChannel = makeChannel('CC'.repeat(16), '#alpha');
|
||||
const onSelectConversation = vi.fn();
|
||||
|
||||
render(
|
||||
<Sidebar
|
||||
contacts={[]}
|
||||
channels={[fakePublic, alphaChannel, publicChannel]}
|
||||
activeConversation={null}
|
||||
onSelectConversation={onSelectConversation}
|
||||
onNewMessage={vi.fn()}
|
||||
lastMessageTimes={{}}
|
||||
unreadCounts={{}}
|
||||
mentions={{}}
|
||||
showCracker={false}
|
||||
crackerRunning={false}
|
||||
onToggleCracker={vi.fn()}
|
||||
onMarkAllRead={vi.fn()}
|
||||
favorites={[]}
|
||||
legacySortOrder="alpha"
|
||||
/>
|
||||
);
|
||||
|
||||
fireEvent.click(screen.getAllByText('Public')[0]);
|
||||
|
||||
expect(onSelectConversation).toHaveBeenCalledWith({
|
||||
type: 'channel',
|
||||
id: PUBLIC_CHANNEL_KEY,
|
||||
name: 'Public',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
resolveContactFromHashToken,
|
||||
} from '../utils/urlHash';
|
||||
import type { Channel, Contact } from '../types';
|
||||
import { PUBLIC_CHANNEL_KEY } from '../utils/publicChannel';
|
||||
|
||||
describe('parseHashConversation', () => {
|
||||
let originalHash: string;
|
||||
@@ -149,7 +150,7 @@ describe('parseHashConversation', () => {
|
||||
describe('resolveChannelFromHashToken', () => {
|
||||
const channels: Channel[] = [
|
||||
{
|
||||
key: 'ABCDEF0123456789ABCDEF0123456789',
|
||||
key: PUBLIC_CHANNEL_KEY,
|
||||
name: 'Public',
|
||||
is_hashtag: false,
|
||||
on_radio: true,
|
||||
@@ -172,13 +173,13 @@ describe('resolveChannelFromHashToken', () => {
|
||||
];
|
||||
|
||||
it('prefers stable key lookup (case-insensitive)', () => {
|
||||
const result = resolveChannelFromHashToken('abcdef0123456789abcdef0123456789', channels);
|
||||
expect(result?.key).toBe('ABCDEF0123456789ABCDEF0123456789');
|
||||
const result = resolveChannelFromHashToken(PUBLIC_CHANNEL_KEY.toLowerCase(), channels);
|
||||
expect(result?.key).toBe(PUBLIC_CHANNEL_KEY);
|
||||
});
|
||||
|
||||
it('supports legacy name-based hash lookup', () => {
|
||||
it('resolves legacy Public hashes to the canonical Public key', () => {
|
||||
const result = resolveChannelFromHashToken('Public', channels);
|
||||
expect(result?.key).toBe('ABCDEF0123456789ABCDEF0123456789');
|
||||
expect(result?.key).toBe(PUBLIC_CHANNEL_KEY);
|
||||
});
|
||||
|
||||
it('supports legacy hashtag hash without leading #', () => {
|
||||
|
||||
Reference in New Issue
Block a user