92 lines
2.6 KiB
TypeScript
92 lines
2.6 KiB
TypeScript
import { cleanup, render, screen } from '@testing-library/react';
|
|
import { getFunctionName } from 'convex/server';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
import { api } from '@spoon/backend/convex/_generated/api.js';
|
|
|
|
import { GithubIntegrationPanel } from '../../src/components/integrations/github-integration-panel';
|
|
|
|
const { mockUseAction, mockUseQuery } = vi.hoisted(() => ({
|
|
mockUseAction: vi.fn(),
|
|
mockUseQuery: vi.fn(),
|
|
}));
|
|
|
|
vi.mock('convex/react', () => ({
|
|
useAction: mockUseAction,
|
|
useQuery: mockUseQuery,
|
|
}));
|
|
|
|
vi.mock('sonner', () => ({
|
|
toast: {
|
|
error: vi.fn(),
|
|
success: vi.fn(),
|
|
},
|
|
}));
|
|
|
|
type ConnectionStatus = 'active' | 'needs_reauth' | 'revoked';
|
|
|
|
const setup = (status: ConnectionStatus) => {
|
|
mockUseAction.mockReturnValue(vi.fn());
|
|
const connectionName = getFunctionName(api.github.getConnection);
|
|
const installUrlName = getFunctionName(api.github.getInstallUrl);
|
|
mockUseQuery.mockImplementation((ref: Parameters<typeof getFunctionName>[0]) => {
|
|
const name = getFunctionName(ref);
|
|
if (name === connectionName) {
|
|
return {
|
|
_id: 'connection-1',
|
|
displayName: 'octocat',
|
|
installationId: '12345',
|
|
status,
|
|
};
|
|
}
|
|
if (name === installUrlName) {
|
|
return 'https://github.com/apps/spoon/installations/new';
|
|
}
|
|
return undefined;
|
|
});
|
|
};
|
|
|
|
afterEach(() => {
|
|
cleanup();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe('GithubIntegrationPanel', () => {
|
|
it('shows the reconnect warning when the connection needs re-authorization', () => {
|
|
setup('needs_reauth');
|
|
render(<GithubIntegrationPanel />);
|
|
|
|
expect(
|
|
screen.getByText(/GitHub access needs re-authorization/i),
|
|
).toBeInTheDocument();
|
|
expect(
|
|
screen.getByRole('link', { name: /reconnect github app/i }),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it('shows the removed-installation warning when the connection is revoked', () => {
|
|
setup('revoked');
|
|
render(<GithubIntegrationPanel />);
|
|
|
|
expect(
|
|
screen.getByText(/GitHub App installation removed/i),
|
|
).toBeInTheDocument();
|
|
expect(
|
|
screen.getByRole('link', { name: /reconnect github app/i }),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it('renders the normal connected state without a warning when active', () => {
|
|
setup('active');
|
|
render(<GithubIntegrationPanel />);
|
|
|
|
expect(screen.getByText('octocat')).toBeInTheDocument();
|
|
expect(
|
|
screen.queryByText(/needs re-authorization/i),
|
|
).not.toBeInTheDocument();
|
|
expect(
|
|
screen.queryByRole('link', { name: /reconnect github app/i }),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
});
|