8.1 KB267 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 {act, fireEvent, render, screen, within} from '@testing-library/react';
9import App from '../App';
10import {bookmarksDataStorage} from '../BookmarksData';
11import {writeAtom} from '../jotaiUtils';
12import {
13 COMMIT,
14 closeCommitInfoSidebar,
15 expectMessageSentToServer,
16 resetTestMessages,
17 simulateCommits,
18 simulateRepoConnected,
19} from '../testUtils';
20import {succeedableRevset} from '../types';
21
22describe('Suggested Rebase button', () => {
23 beforeEach(() => {
24 resetTestMessages();
25 render(<App />);
26 act(() => {
27 simulateRepoConnected();
28 closeCommitInfoSidebar();
29 expectMessageSentToServer({
30 type: 'subscribe',
31 kind: 'smartlogCommits',
32 subscriptionID: expect.anything(),
33 });
34 simulateCommits({
35 value: [
36 COMMIT('1', 'some public base', '0', {phase: 'public'}),
37 COMMIT('a', 'My Commit', '1'),
38 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
39 ],
40 });
41 });
42 });
43
44 it('shows suggested rebase button', () => {
45 act(() => {
46 simulateCommits({
47 value: [
48 COMMIT('main', 'main', '2', {phase: 'public', remoteBookmarks: ['remote/main']}),
49 COMMIT('1', 'some public base', '0', {phase: 'public'}),
50 COMMIT('a', 'My Commit', '1'),
51 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
52 ],
53 });
54 });
55
56 expect(screen.getByText(`Rebase onto…`)).toBeInTheDocument();
57 });
58
59 it('does not show suggested rebase button on commits already on a remote bookmark', () => {
60 act(() => {
61 simulateCommits({
62 value: [
63 COMMIT('main', 'main', '2', {phase: 'public', remoteBookmarks: ['remote/main']}),
64 COMMIT('1', 'some public base', '0', {phase: 'public'}),
65 COMMIT('a', 'My Commit', '2'), // on remote/main
66 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
67 ],
68 });
69 });
70
71 expect(screen.queryByText('Rebase onto…')).not.toBeInTheDocument();
72 });
73
74 it('does not show suggested rebase button on commits already on a stable location', () => {
75 act(() => {
76 simulateCommits({
77 value: [
78 COMMIT('main', 'main', '2', {
79 phase: 'public',
80 stableCommitMetadata: [{value: 'pulled here', description: ''}],
81 }),
82 COMMIT('1', 'some public base', '0', {phase: 'public'}),
83 COMMIT('a', 'My Commit', '2'), // on stable
84 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
85 ],
86 });
87 });
88
89 expect(screen.queryByText('Rebase onto…')).not.toBeInTheDocument();
90 });
91
92 it('shows remote bookmarks as destinations in dropdown', () => {
93 act(() => {
94 simulateCommits({
95 value: [
96 COMMIT('main', 'main', '2', {
97 phase: 'public',
98 remoteBookmarks: ['remote/main'],
99 }),
100 COMMIT('1', 'some public base', '0', {phase: 'public'}),
101 COMMIT('a', 'My Commit', '1'),
102 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
103 ],
104 });
105 });
106
107 const rebaseOntoButton = screen.getByText('Rebase onto…');
108 fireEvent.click(rebaseOntoButton);
109
110 expect(
111 within(screen.getByTestId('context-menu-container')).getByText('remote/main'),
112 ).toBeInTheDocument();
113 });
114
115 it('shows stable locations as destinations in dropdown', () => {
116 act(() => {
117 simulateCommits({
118 value: [
119 COMMIT('main', 'main', '2', {
120 phase: 'public',
121 stableCommitMetadata: [{value: 'pulled here', description: ''}],
122 }),
123 COMMIT('1', 'some public base', '0', {phase: 'public'}),
124 COMMIT('a', 'My Commit', '1'),
125 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
126 ],
127 });
128 });
129
130 const rebaseOntoButton = screen.getByText(`Rebase onto…`);
131 fireEvent.click(rebaseOntoButton);
132
133 expect(
134 within(screen.getByTestId('context-menu-container')).getByText('pulled here'),
135 ).toBeInTheDocument();
136 });
137
138 it('clicking suggestion rebase runs operation', () => {
139 act(() => {
140 simulateCommits({
141 value: [
142 COMMIT('main', 'main', '2', {
143 phase: 'public',
144 remoteBookmarks: ['remote/main'],
145 }),
146 COMMIT('1', 'some public base', '0', {phase: 'public'}),
147 COMMIT('a', 'My Commit', '1'),
148 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
149 ],
150 });
151 });
152
153 const rebaseOntoButton = screen.getByText('Rebase onto…');
154 fireEvent.click(rebaseOntoButton);
155
156 const suggestion = within(screen.getByTestId('context-menu-container')).getByText(
157 'remote/main',
158 );
159 fireEvent.click(suggestion);
160
161 expectMessageSentToServer({
162 type: 'runOperation',
163 operation: expect.objectContaining({
164 args: ['rebase', '-s', succeedableRevset('a'), '-d', succeedableRevset('remote/main')],
165 }),
166 });
167 });
168
169 it('uses hash to run rebase operation if not a remote bookmark', () => {
170 act(() => {
171 simulateCommits({
172 value: [
173 COMMIT('3', 'main', '2', {
174 phase: 'public',
175 stableCommitMetadata: [{value: 'pulled here', description: ''}],
176 }),
177 COMMIT('1', 'some public base', '0', {phase: 'public'}),
178 COMMIT('a', 'My Commit', '1'),
179 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
180 ],
181 });
182 });
183
184 const rebaseOntoButton = screen.getByText('Rebase onto…');
185 fireEvent.click(rebaseOntoButton);
186
187 const suggestion = within(screen.getByTestId('context-menu-container')).getByText(
188 'pulled here',
189 );
190 fireEvent.click(suggestion);
191
192 expectMessageSentToServer({
193 type: 'runOperation',
194 operation: expect.objectContaining({
195 args: ['rebase', '-s', succeedableRevset('a'), '-d', succeedableRevset('3')],
196 }),
197 });
198 });
199
200 it('includes current stack base as a destination', () => {
201 act(() => {
202 simulateCommits({
203 value: [
204 COMMIT('3', 'main', '2', {phase: 'public'}),
205 COMMIT('x', 'Commit X', '2', {isDot: true}),
206 COMMIT('2', 'some public base 2', '0', {
207 phase: 'public',
208 remoteBookmarks: ['remote/main'],
209 }),
210 COMMIT('1', 'some public base', '0', {phase: 'public'}),
211 COMMIT('b', 'Another Commit', 'a'),
212 COMMIT('a', 'My Commit', '1'),
213 ],
214 });
215 });
216
217 const rebaseOntoButton = screen.getByText('Rebase onto…');
218 fireEvent.click(rebaseOntoButton);
219
220 const suggestion = within(screen.getByTestId('context-menu-container')).getByText(
221 /Current Stack Base \(.*\), remote\/main/,
222 );
223 fireEvent.click(suggestion);
224
225 expectMessageSentToServer({
226 type: 'runOperation',
227 operation: expect.objectContaining({
228 args: ['rebase', '-s', succeedableRevset('a'), '-d', succeedableRevset('remote/main')],
229 }),
230 });
231 });
232
233 it('deselected remote bookmarks in bookmark manager hides them as suggested rebases', () => {
234 act(() => {
235 writeAtom(bookmarksDataStorage, data => ({
236 ...data,
237 useRecommendedBookmark: false,
238 }));
239
240 simulateCommits({
241 value: [
242 COMMIT('3', 'main', '000', {phase: 'public', remoteBookmarks: ['remote/main']}),
243 COMMIT('2', 'something else', '00', {phase: 'public', remoteBookmarks: ['remote/foo']}),
244 COMMIT('1', 'base', '0', {phase: 'public'}),
245 COMMIT('a', 'My Commit', '1'),
246 COMMIT('b', 'Another Commit', 'a', {isDot: true}),
247 ],
248 });
249 });
250
251 fireEvent.click(screen.getByTestId('bookmarks-manager-button'));
252
253 const fooBookmark = within(screen.getByTestId('bookmarks-manager-dropdown')).getByText(
254 'remote/foo',
255 );
256 expect(fooBookmark).toBeInTheDocument();
257 fireEvent.click(fooBookmark); // deselect
258
259 const rebaseOntoButton = screen.getByText(`Rebase onto…`);
260 fireEvent.click(rebaseOntoButton);
261
262 expect(
263 within(screen.getByTestId('context-menu-container')).queryByText('remote/foo'),
264 ).not.toBeInTheDocument();
265 });
266});
267