fix(git): resolve blank nested-repo surfaces; add repository pickers
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.
This commit is contained in:
@@ -0,0 +1,69 @@
|
||||
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...');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user