The resolution gate on the pull-request, walkthrough, and mobile changes surfaces stayed on forever (rootIsGitRepo stays false on a non-repo root) while NestedRepoResolutionStates exits once the selected repository probes as a repository, so those surfaces rendered nothing. The gate now shows resolution states only while the operating directory has not proven to be a repository, matching GitView. Extract GitHeader's repository switcher into git/NestedRepoPicker and mount it in the diff toolbar, a new slim header in the pull-request view, the walkthrough header, and the mobile changes header. The pick is shared per root, so every surface follows. The walkthrough tab mounts keep-alive and hidden; it now receives a visible prop so discovery waits until the tab is actually opened. Add component tests for the shared resolution states.
70 lines
2.5 KiB
TypeScript
70 lines
2.5 KiB
TypeScript
import React from 'react';
|
|
import { describe, expect, test } from 'bun:test';
|
|
import { renderToStaticMarkup } from 'react-dom/server';
|
|
|
|
import { I18nProvider } from '@/lib/i18n';
|
|
|
|
import { NestedRepoResolutionStates } from './NestedRepoResolutionStates';
|
|
|
|
const render = (props: React.ComponentProps<typeof NestedRepoResolutionStates>): string =>
|
|
renderToStaticMarkup(
|
|
<I18nProvider>
|
|
<NestedRepoResolutionStates {...props} />
|
|
</I18nProvider>,
|
|
);
|
|
|
|
const baseProps = {
|
|
onRetryDiscovery: () => {},
|
|
};
|
|
|
|
describe('NestedRepoResolutionStates', () => {
|
|
test('renders nothing while the root has not probed as a non-repository', () => {
|
|
for (const rootIsGitRepo of [null, true] as const) {
|
|
const markup = render({ ...baseProps, rootIsGitRepo, resolvedIsGitRepo: null, nestedRepos: undefined });
|
|
expect(markup).toBe('');
|
|
}
|
|
});
|
|
|
|
test('renders nothing once the operating directory resolved as a repository', () => {
|
|
const markup = render({
|
|
...baseProps,
|
|
rootIsGitRepo: false,
|
|
resolvedIsGitRepo: true,
|
|
nestedRepos: ['/root/one'],
|
|
});
|
|
expect(markup).toBe('');
|
|
});
|
|
|
|
test('shows the discovering state before discovery has run', () => {
|
|
const markup = render({ ...baseProps, rootIsGitRepo: false, resolvedIsGitRepo: null, nestedRepos: undefined });
|
|
expect(markup).toContain('Looking for Git repositories...');
|
|
});
|
|
|
|
test('shows the failure state with a retry when discovery failed', () => {
|
|
const markup = render({ ...baseProps, rootIsGitRepo: false, resolvedIsGitRepo: null, nestedRepos: null });
|
|
expect(markup).toContain('Could not scan for Git repositories');
|
|
expect(markup).toContain('Retry');
|
|
});
|
|
|
|
test('shows the plain not-a-repository state with no retry when unsupported', () => {
|
|
const markup = render({ ...baseProps, rootIsGitRepo: false, resolvedIsGitRepo: null, nestedRepos: 'unsupported' });
|
|
expect(markup).toContain('This directory is not a Git repository');
|
|
expect(markup).not.toContain('Retry');
|
|
});
|
|
|
|
test('treats an empty discovery like the not-a-repository state', () => {
|
|
const markup = render({ ...baseProps, rootIsGitRepo: false, resolvedIsGitRepo: null, nestedRepos: [] });
|
|
expect(markup).toContain('This directory is not a Git repository');
|
|
});
|
|
|
|
test('holds a checking state while repositories are found but unresolved', () => {
|
|
const markup = render({
|
|
...baseProps,
|
|
rootIsGitRepo: false,
|
|
resolvedIsGitRepo: null,
|
|
nestedRepos: ['/root/one', '/root/two'],
|
|
});
|
|
expect(markup).toContain('Checking repository...');
|
|
});
|
|
});
|