mirror of
https://github.com/facebook/sapling.git
synced 2024-10-05 06:18:07 +03:00
Add tests for discarding
Summary: I noticed we had no tests for some cases here, namely: - deleting an untracked file - bulk discarding all files - bulk discarding a subset of files This is stuff affected by the commits earlier in this stack, so let's add tests for this moving forward Reviewed By: quark-zju Differential Revision: D49617784 fbshipit-source-id: 2107c4f5e7481d14bbbcfcae322c9d8c989e5455
This commit is contained in:
parent
6208ef0e0b
commit
a2a0a06e35
@ -465,6 +465,7 @@ function FileSelectionCheckbox({
|
||||
<VSCodeCheckbox
|
||||
checked={selection.isFullyOrPartiallySelected(file.path)}
|
||||
indeterminate={selection.isPartiallySelected(file.path)}
|
||||
data-testid={'file-selection-checkbox'}
|
||||
// Note: Using `onClick` instead of `onChange` since onChange apparently fires when the controlled `checked` value changes,
|
||||
// which means this fires when using "select all" / "deselect all"
|
||||
onClick={e => {
|
||||
@ -656,6 +657,7 @@ export function UncommittedChanges({place}: {place: Place}) {
|
||||
<VSCodeButton
|
||||
appearance="icon"
|
||||
disabled={noFilesSelected}
|
||||
data-testid={'discard-all-selected-button'}
|
||||
onClick={() => {
|
||||
platform.confirm(t('confirmDiscardChanges')).then(ok => {
|
||||
if (!ok) {
|
||||
@ -967,6 +969,7 @@ function FileActions({
|
||||
className="file-show-on-hover"
|
||||
key={file.path}
|
||||
appearance="icon"
|
||||
data-testid="file-action-delete"
|
||||
onClick={async () => {
|
||||
const ok = await platform.confirm(
|
||||
t('Are you sure you want to delete $file?', {replace: {$file: file.path}}),
|
||||
|
@ -14,12 +14,15 @@ import {
|
||||
simulateCommits,
|
||||
COMMIT,
|
||||
simulateUncommittedChangedFiles,
|
||||
expectMessageNOTSentToServer,
|
||||
} from '../../testUtils';
|
||||
import {CommandRunner} from '../../types';
|
||||
import {fireEvent, render, screen, within} from '@testing-library/react';
|
||||
import {act} from 'react-dom/test-utils';
|
||||
import {nextTick} from 'shared/testUtils';
|
||||
|
||||
/* eslint-disable require-await */
|
||||
|
||||
jest.mock('../../MessageBus');
|
||||
|
||||
describe('RevertOperation', () => {
|
||||
@ -61,6 +64,28 @@ describe('RevertOperation', () => {
|
||||
});
|
||||
};
|
||||
|
||||
const clickDelete = async (inside: HTMLElement, fileName: string) => {
|
||||
await act(async () => {
|
||||
const revertButton = within(
|
||||
within(inside).getByTestId(`changed-file-${fileName}`),
|
||||
).getByTestId('file-action-delete');
|
||||
expect(revertButton).toBeInTheDocument();
|
||||
fireEvent.click(revertButton);
|
||||
// confirm modal takes 1 tick to resolve
|
||||
await nextTick();
|
||||
});
|
||||
};
|
||||
|
||||
const clickCheckboxForFile = async (inside: HTMLElement, fileName: string) => {
|
||||
await act(async () => {
|
||||
const checkbox = within(within(inside).getByTestId(`changed-file-${fileName}`)).getByTestId(
|
||||
'file-selection-checkbox',
|
||||
);
|
||||
expect(checkbox).toBeInTheDocument();
|
||||
fireEvent.click(checkbox);
|
||||
});
|
||||
};
|
||||
|
||||
describe('from uncommitted changes', () => {
|
||||
beforeEach(() => {
|
||||
act(() => {
|
||||
@ -87,7 +112,7 @@ describe('RevertOperation', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('renders optimistic state while running', async () => {
|
||||
it('renders optimistic state while running revert', async () => {
|
||||
expect(
|
||||
CommitTreeListTestUtils.withinCommitTree().getByText(ignoreRTL('myFile1.txt')),
|
||||
).toBeInTheDocument();
|
||||
@ -96,6 +121,162 @@ describe('RevertOperation', () => {
|
||||
CommitTreeListTestUtils.withinCommitTree().queryByText(ignoreRTL('myFile1.txt')),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
describe('untracked files get purged', () => {
|
||||
beforeEach(() => {
|
||||
act(() => {
|
||||
simulateUncommittedChangedFiles({
|
||||
value: [
|
||||
{path: 'myFile1.txt', status: 'M'},
|
||||
{path: 'untracked.txt', status: '?'},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('runs purge for untracked uncommitted changes', async () => {
|
||||
await clickDelete(screen.getByTestId('commit-tree-root'), 'untracked.txt');
|
||||
|
||||
expectMessageSentToServer({
|
||||
type: 'runOperation',
|
||||
operation: {
|
||||
args: ['purge', '--files', {type: 'repo-relative-file', path: 'untracked.txt'}],
|
||||
id: expect.anything(),
|
||||
runner: CommandRunner.Sapling,
|
||||
trackEventName: 'PurgeOperation',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('renders optimistic state while running purge', async () => {
|
||||
expect(
|
||||
CommitTreeListTestUtils.withinCommitTree().getByText(ignoreRTL('untracked.txt')),
|
||||
).toBeInTheDocument();
|
||||
await clickDelete(screen.getByTestId('commit-tree-root'), 'untracked.txt');
|
||||
expect(
|
||||
CommitTreeListTestUtils.withinCommitTree().queryByText(ignoreRTL('untracked.txt')),
|
||||
).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('bulk discard', () => {
|
||||
let confirmSpy: jest.SpyInstance;
|
||||
beforeEach(() => {
|
||||
confirmSpy = jest.spyOn(platform, 'confirm').mockImplementation(() => Promise.resolve(true));
|
||||
act(() => {
|
||||
simulateUncommittedChangedFiles({
|
||||
value: [
|
||||
{path: 'myFile1.txt', status: 'M'},
|
||||
{path: 'myFile2.txt', status: 'M'},
|
||||
{path: 'untracked1.txt', status: '?'},
|
||||
{path: 'untracked2.txt', status: '?'},
|
||||
],
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('discards all changes with goto --clean if everything selected', async () => {
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
within(screen.getByTestId('commit-tree-root')).getByTestId('discard-all-selected-button'),
|
||||
);
|
||||
});
|
||||
|
||||
expectMessageSentToServer({
|
||||
type: 'runOperation',
|
||||
operation: {
|
||||
args: ['goto', '--clean', '.'],
|
||||
id: expect.anything(),
|
||||
runner: CommandRunner.Sapling,
|
||||
trackEventName: 'DiscardOperation',
|
||||
},
|
||||
});
|
||||
|
||||
expectMessageSentToServer({
|
||||
type: 'runOperation',
|
||||
operation: {
|
||||
args: ['purge', '--files'],
|
||||
id: expect.anything(),
|
||||
runner: CommandRunner.Sapling,
|
||||
trackEventName: 'PurgeOperation',
|
||||
},
|
||||
});
|
||||
|
||||
expect(confirmSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('discards selected changes with revert and purge', async () => {
|
||||
const commitTree = screen.getByTestId('commit-tree-root');
|
||||
await clickCheckboxForFile(commitTree, 'myFile1.txt');
|
||||
await clickCheckboxForFile(commitTree, 'untracked1.txt');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
within(screen.getByTestId('commit-tree-root')).getByTestId('discard-all-selected-button'),
|
||||
);
|
||||
});
|
||||
|
||||
expectMessageSentToServer({
|
||||
type: 'runOperation',
|
||||
operation: {
|
||||
args: ['revert', {type: 'repo-relative-file', path: 'myFile2.txt'}],
|
||||
id: expect.anything(),
|
||||
runner: CommandRunner.Sapling,
|
||||
trackEventName: 'RevertOperation',
|
||||
},
|
||||
});
|
||||
|
||||
expectMessageSentToServer({
|
||||
type: 'runOperation',
|
||||
operation: {
|
||||
args: ['purge', '--files', {type: 'repo-relative-file', path: 'untracked2.txt'}],
|
||||
id: expect.anything(),
|
||||
runner: CommandRunner.Sapling,
|
||||
trackEventName: 'PurgeOperation',
|
||||
},
|
||||
});
|
||||
|
||||
expect(confirmSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('no need to run purge if no files are untracked', async () => {
|
||||
const commitTree = screen.getByTestId('commit-tree-root');
|
||||
await clickCheckboxForFile(commitTree, 'untracked1.txt');
|
||||
await clickCheckboxForFile(commitTree, 'untracked2.txt');
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.click(
|
||||
within(screen.getByTestId('commit-tree-root')).getByTestId('discard-all-selected-button'),
|
||||
);
|
||||
});
|
||||
|
||||
expectMessageSentToServer({
|
||||
type: 'runOperation',
|
||||
operation: {
|
||||
args: [
|
||||
'revert',
|
||||
{type: 'repo-relative-file', path: 'myFile1.txt'},
|
||||
{type: 'repo-relative-file', path: 'myFile2.txt'},
|
||||
],
|
||||
id: expect.anything(),
|
||||
runner: CommandRunner.Sapling,
|
||||
trackEventName: 'RevertOperation',
|
||||
},
|
||||
});
|
||||
|
||||
expectMessageNOTSentToServer({
|
||||
type: 'runOperation',
|
||||
operation: {
|
||||
args: expect.arrayContaining(['purge', '--files']),
|
||||
id: expect.anything(),
|
||||
runner: CommandRunner.Sapling,
|
||||
trackEventName: expect.anything(),
|
||||
},
|
||||
});
|
||||
|
||||
expect(confirmSpy).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('in commit info view for a given commit', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user