5.3 KB183 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, waitFor} from '@testing-library/react';
9import App from '../App';
10import platform from '../platform';
11import {ignoreRTL} from '../testQueries';
12import {
13 closeCommitInfoSidebar,
14 COMMIT,
15 expectMessageSentToServer,
16 openCommitInfoSidebar,
17 simulateCommits,
18 simulateMessageFromServer,
19 simulateRepoConnected,
20 simulateUncommittedChangedFiles,
21} from '../testUtils';
22
23describe('Browse repo url', () => {
24 beforeEach(() => {
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', remoteBookmarks: ['main']}),
37 COMMIT('a', 'My Commit', '1', {isDot: true}),
38 ],
39 });
40 });
41 });
42
43 function setCodeBrowserConfig(value: string | undefined) {
44 expectMessageSentToServer({type: 'getConfig', name: 'fbcodereview.code-browser-url'});
45 act(() => {
46 simulateMessageFromServer({
47 type: 'gotConfig',
48 name: 'fbcodereview.code-browser-url',
49 value,
50 });
51 });
52 }
53
54 function clickBrowseRepo() {
55 act(() => {
56 fireEvent.contextMenu(screen.getByText('main'));
57 });
58 expect(screen.getByText('Browse Repo At This Commit')).toBeInTheDocument();
59 fireEvent.click(screen.getByText('Browse Repo At This Commit'));
60 }
61
62 it('opens link to browse repo', () => {
63 setCodeBrowserConfig(undefined);
64 act(() => {
65 fireEvent.contextMenu(screen.getByText('main'));
66 });
67 expect(screen.queryByText('Browse Repo At This Commit')).not.toBeInTheDocument();
68 });
69
70 it('opens link to browse repo', async () => {
71 setCodeBrowserConfig('https://www.example.com/repo/browse/%s');
72 clickBrowseRepo();
73
74 const openLinkSpy = jest.spyOn(platform, 'openExternalLink').mockImplementation(() => {});
75 expectMessageSentToServer({
76 type: 'getRepoUrlAtHash',
77 revset: '1',
78 path: undefined,
79 });
80 act(() => {
81 simulateMessageFromServer({
82 type: 'gotRepoUrlAtHash',
83 url: {value: 'https://www.example.com/repo/browse/1/'},
84 });
85 });
86
87 await waitFor(() =>
88 expect(openLinkSpy).toHaveBeenCalledWith('https://www.example.com/repo/browse/1/'),
89 );
90 });
91
92 it('surfaces errors', async () => {
93 setCodeBrowserConfig('https://www.example.com/repo/browse/%s');
94 clickBrowseRepo();
95
96 const openLinkSpy = jest.spyOn(platform, 'openExternalLink').mockImplementation(() => {});
97 expectMessageSentToServer({
98 type: 'getRepoUrlAtHash',
99 revset: '1',
100 path: undefined,
101 });
102 act(() => {
103 simulateMessageFromServer({
104 type: 'gotRepoUrlAtHash',
105 url: {error: new Error('failed')},
106 });
107 });
108
109 await waitFor(() => {
110 expect(openLinkSpy).not.toHaveBeenCalled();
111 expect(screen.getByText('Failed to get repo URL to browse')).toBeInTheDocument();
112 });
113 });
114
115 describe('Copy file URL', () => {
116 it('copies link to file repo', async () => {
117 act(() => {
118 simulateUncommittedChangedFiles({value: [{path: 'file1.txt', status: 'M'}]});
119 });
120 setCodeBrowserConfig('https://www.example.com/repo/browse/%s');
121 act(() => {
122 fireEvent.contextMenu(screen.getByText(ignoreRTL('file1.txt')));
123 });
124 expect(screen.getByText('Copy file URL')).toBeInTheDocument();
125 fireEvent.click(screen.getByText('Copy file URL'));
126
127 expectMessageSentToServer({
128 type: 'getRepoUrlAtHash',
129 revset: '.',
130 path: 'file1.txt',
131 });
132 act(() => {
133 simulateMessageFromServer({
134 type: 'gotRepoUrlAtHash',
135 url: {value: 'https://www.example.com/repo/browse/a/file1.txt'},
136 });
137 });
138
139 await waitFor(() => {
140 const copySpy = jest.spyOn(platform, 'clipboardCopy').mockImplementation(() => {});
141 expect(copySpy).toHaveBeenCalledWith(
142 'https://www.example.com/repo/browse/a/file1.txt',
143 undefined,
144 );
145 expect(
146 screen.getByText('Copied https://www.example.com/repo/browse/a/file1.txt'),
147 ).toBeInTheDocument();
148 });
149 });
150
151 it('uses appropricate commit revset', () => {
152 act(() => {
153 openCommitInfoSidebar();
154 });
155 setCodeBrowserConfig('https://www.example.com/repo/browse/%s');
156 act(() => {
157 simulateCommits({
158 value: [
159 COMMIT('1', 'some public base', '0', {phase: 'public', remoteBookmarks: ['main']}),
160 COMMIT('a', 'My Commit', '1', {
161 isDot: true,
162 totalFileCount: 1,
163 filePathsSample: ['file2.txt'],
164 }),
165 ],
166 });
167 });
168
169 act(() => {
170 fireEvent.contextMenu(screen.getByText(ignoreRTL('file2.txt')));
171 });
172 expect(screen.getByText('Copy file URL')).toBeInTheDocument();
173 fireEvent.click(screen.getByText('Copy file URL'));
174
175 expectMessageSentToServer({
176 type: 'getRepoUrlAtHash',
177 revset: '.^',
178 path: 'file2.txt',
179 });
180 });
181 });
182});
183