4.9 KB140 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {CommandArg} from '../types';
9
10import {act, fireEvent, render, screen, waitFor} from '@testing-library/react';
11import App from '../App';
12import {ignoreRTL} from '../testQueries';
13import {
14 closeCommitInfoSidebar,
15 COMMIT,
16 expectMessageSentToServer,
17 resetTestMessages,
18 simulateCommits,
19 simulateRepoConnected,
20 simulateUncommittedChangedFiles,
21} from '../testUtils';
22
23describe('CopyRenameFiles', () => {
24 beforeEach(() => {
25 resetTestMessages();
26 render(<App />);
27 act(() => {
28 simulateRepoConnected();
29 closeCommitInfoSidebar();
30 expectMessageSentToServer({
31 type: 'subscribe',
32 kind: 'smartlogCommits',
33 subscriptionID: expect.anything(),
34 });
35 simulateCommits({
36 value: [
37 COMMIT('1', 'some public base', '0', {phase: 'public'}),
38 COMMIT('a', 'My Commit', '1'),
39 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
40 ],
41 });
42 });
43 });
44
45 it('shows copied files', () => {
46 act(() => {
47 simulateUncommittedChangedFiles({
48 value: [
49 {path: 'file_copy.js', status: 'A', copy: 'file.js'},
50 {path: 'path/to/file.txt', status: 'A', copy: 'path/original/copiedFrom.txt'},
51 {path: 'path/copied/file.txt', status: 'A', copy: 'path/original/file.txt'},
52 ],
53 });
54 });
55 expect(screen.getByText(ignoreRTL('file.js → file_copy.js'))).toBeInTheDocument();
56 expect(screen.getByText(ignoreRTL('copiedFrom.txt → file.txt'))).toBeInTheDocument();
57 expect(screen.getByText(ignoreRTL('original/file.txt → copied/file.txt'))).toBeInTheDocument();
58 });
59
60 it("removed files aren't hidden except for renames", () => {
61 act(() => {
62 simulateUncommittedChangedFiles({
63 value: [
64 {path: 'file_rem.js', status: 'R'},
65 {path: 'file_copy.js', status: 'A', copy: 'file_orig1.js'},
66 {path: 'file_rename.js', status: 'A', copy: 'file_orig2.js'},
67 ],
68 });
69 });
70 expect(screen.getByText(ignoreRTL('file_rem.js'))).toBeInTheDocument();
71 });
72
73 it('shows renamed files', () => {
74 act(() => {
75 simulateUncommittedChangedFiles({
76 value: [
77 {path: 'file_rename.js', status: 'A', copy: 'file.js'},
78 {path: 'file.js', status: 'R'},
79 {path: 'path/to/file.txt', status: 'A', copy: 'path/original/movedFrom.txt'},
80 {path: 'path/original/movedFrom.txt', status: 'R'},
81 {path: 'path/moved/file.txt', status: 'A', copy: 'path/original/file.txt'},
82 {path: 'path/original/file.txt', status: 'R'},
83 ],
84 });
85 });
86 expect(screen.getByText(ignoreRTL('file.js → file_rename.js'))).toBeInTheDocument();
87 expect(screen.getByText(ignoreRTL('movedFrom.txt → file.txt'))).toBeInTheDocument();
88 expect(screen.getByText(ignoreRTL('original/file.txt → moved/file.txt'))).toBeInTheDocument();
89 // removed files are visually hidden:
90 expect(screen.queryByText(ignoreRTL('file.js'))).not.toBeInTheDocument();
91 expect(screen.queryByText(ignoreRTL('movedFrom.txt'))).not.toBeInTheDocument();
92 expect(screen.queryByText(ignoreRTL('original/movedFrom.txt'))).not.toBeInTheDocument();
93 expect(screen.queryByText(ignoreRTL('path/original/movedFrom.txt'))).not.toBeInTheDocument();
94 expect(screen.queryByText(ignoreRTL('moved/file.txt'))).not.toBeInTheDocument();
95 expect(screen.queryByText(ignoreRTL('path/moved/file.txt'))).not.toBeInTheDocument();
96 });
97
98 it('selecting renamed files selects removed file as well', async () => {
99 act(() => {
100 simulateUncommittedChangedFiles({
101 value: [
102 {path: 'randomFile.txt', status: 'M'},
103 {path: 'path/moved/file.txt', status: 'A', copy: 'path/original/file.txt'},
104 {path: 'path/original/file.txt', status: 'R'},
105 ],
106 });
107 });
108
109 // deselect everything
110 act(() => {
111 fireEvent.click(screen.getByTestId('deselect-all-button'));
112 });
113 // select the renamed file
114 const modifiedFileCheckboxes = document.querySelectorAll(
115 '.changed-files .changed-file.file-modified input[type="checkbox"]',
116 );
117 act(() => {
118 fireEvent.click(modifiedFileCheckboxes[1]);
119 });
120 // create a commit
121 fireEvent.click(screen.getByTestId('quick-commit-button'));
122 await waitFor(() => {
123 expectMessageSentToServer({
124 type: 'runOperation',
125 operation: expect.objectContaining({
126 args: [
127 'commit',
128 '--addremove',
129 '--message',
130 expect.anything(),
131 // both moved and removed file are passed, even though we only selected the single moved file
132 {type: 'repo-relative-file', path: 'path/moved/file.txt'},
133 {type: 'repo-relative-file', path: 'path/original/file.txt'},
134 ] as Array<CommandArg>,
135 }),
136 });
137 });
138 });
139});
140