refactor: rename Server → Space across entire codebase
Renames all domain terminology from "Server" to "Space" throughout the application — database schema, API routes, shared types, stores, components, and UI strings. Files renamed: ServerSidebar → SpaceSidebar, CreateServer → CreateSpace, JoinServer → JoinSpace, ServerSettings → SpaceSettings, serverStore → spaceStore, routes/servers → routes/spaces.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { JoinSpaceModal } from './JoinSpace';
|
||||
import { useUIStore } from '../../stores/uiStore';
|
||||
import { useSpaceStore } from '../../stores/spaceStore';
|
||||
|
||||
const mockNavigate = vi.fn();
|
||||
vi.mock('react-router-dom', async () => {
|
||||
const actual = await vi.importActual('react-router-dom');
|
||||
return {
|
||||
...actual,
|
||||
useNavigate: () => mockNavigate,
|
||||
};
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mockNavigate.mockClear();
|
||||
useUIStore.setState({ activeModal: null });
|
||||
useSpaceStore.setState({
|
||||
spaces: [],
|
||||
currentSpaceId: null,
|
||||
});
|
||||
});
|
||||
|
||||
function renderModal() {
|
||||
return render(
|
||||
<MemoryRouter>
|
||||
<JoinSpaceModal />
|
||||
</MemoryRouter>
|
||||
);
|
||||
}
|
||||
|
||||
describe('JoinSpaceModal', () => {
|
||||
it('does not render when activeModal is not "joinSpace"', () => {
|
||||
useUIStore.setState({ activeModal: null });
|
||||
renderModal();
|
||||
expect(screen.queryByText('Join a Space')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('renders the form when opened', () => {
|
||||
useUIStore.setState({ activeModal: 'joinSpace' });
|
||||
renderModal();
|
||||
expect(screen.getByText('Join a Space')).toBeInTheDocument();
|
||||
expect(screen.getByPlaceholderText('e.g. abc123')).toBeInTheDocument();
|
||||
expect(screen.getByText('Join Space')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('shows validation error when submitting empty code', async () => {
|
||||
const user = userEvent.setup();
|
||||
useUIStore.setState({ activeModal: 'joinSpace' });
|
||||
renderModal();
|
||||
|
||||
const submitButton = screen.getByText('Join Space');
|
||||
await user.click(submitButton);
|
||||
|
||||
expect(screen.getByText('Invite code is required')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('calls joinByCode with the entered invite code and navigates on success', async () => {
|
||||
const user = userEvent.setup();
|
||||
const mockJoinByCode = vi.fn().mockResolvedValue({ id: 'new-space-id', name: 'Test Space' });
|
||||
useUIStore.setState({ activeModal: 'joinSpace' });
|
||||
useSpaceStore.setState({ joinByCode: mockJoinByCode });
|
||||
|
||||
renderModal();
|
||||
|
||||
// Type invite code
|
||||
const input = screen.getByPlaceholderText('e.g. abc123');
|
||||
await user.type(input, 'my-invite-code');
|
||||
|
||||
// Click join
|
||||
const submitButton = screen.getByText('Join Space');
|
||||
await user.click(submitButton);
|
||||
|
||||
// joinByCode should be called with the code
|
||||
await waitFor(() => {
|
||||
expect(mockJoinByCode).toHaveBeenCalledWith('my-invite-code');
|
||||
});
|
||||
|
||||
// Should navigate to the new space
|
||||
await waitFor(() => {
|
||||
expect(mockNavigate).toHaveBeenCalledWith('/channels/new-space-id');
|
||||
});
|
||||
|
||||
// Modal should close (activeModal becomes null)
|
||||
expect(useUIStore.getState().activeModal).toBeNull();
|
||||
});
|
||||
|
||||
it('shows error message when joinByCode fails', async () => {
|
||||
const user = userEvent.setup();
|
||||
const mockJoinByCode = vi.fn().mockRejectedValue(new Error('Invalid invite code'));
|
||||
useUIStore.setState({ activeModal: 'joinSpace' });
|
||||
useSpaceStore.setState({ joinByCode: mockJoinByCode });
|
||||
|
||||
renderModal();
|
||||
|
||||
const input = screen.getByPlaceholderText('e.g. abc123');
|
||||
await user.type(input, 'bad-code');
|
||||
|
||||
const submitButton = screen.getByText('Join Space');
|
||||
await user.click(submitButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Invalid invite code')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user