Skip to content
This repository was archived by the owner on Dec 15, 2022. It is now read-only.

Commit 3ec8984

Browse files
committed
Full test coverage for GitHub tab container
1 parent 9f5ec4b commit 3ec8984

File tree

2 files changed

+195
-14
lines changed

2 files changed

+195
-14
lines changed

lib/containers/github-tab-container.js

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import Refresher from '../models/refresher';
99
import GitHubTabController from '../controllers/github-tab-controller';
1010
import ObserveModel from '../views/observe-model';
1111
import RemoteSet from '../models/remote-set';
12+
import {nullRemote} from '../models/remote';
1213
import BranchSet from '../models/branch-set';
14+
import {nullBranch} from '../models/branch';
15+
import {DOTCOM} from '../models/endpoint';
1316

1417
export default class GitHubTabContainer extends React.Component {
1518
static propTypes = {
@@ -77,6 +80,8 @@ export default class GitHubTabContainer extends React.Component {
7780
});
7881
}
7982

83+
fetchToken = (loginModel, endpoint) => loginModel.getToken(endpoint.getLoginAccount());
84+
8085
render() {
8186
return (
8287
<ObserveModel model={this.props.repository} fetchData={this.fetchRepositoryData}>
@@ -85,18 +90,47 @@ export default class GitHubTabContainer extends React.Component {
8590
);
8691
}
8792

88-
renderRepositoryData = data => {
89-
if (!data || this.props.repository.isLoading()) {
93+
renderRepositoryData = repoData => {
94+
let endpoint = DOTCOM;
95+
96+
if (repoData) {
97+
repoData.githubRemotes = repoData.allRemotes.filter(remote => remote.isGithubRepo());
98+
repoData.currentBranch = repoData.branches.getHeadBranch();
99+
100+
repoData.currentRemote = repoData.githubRemotes.withName(repoData.selectedRemoteName);
101+
repoData.manyRemotesAvailable = false;
102+
if (!repoData.currentRemote.isPresent() && repoData.githubRemotes.size() === 1) {
103+
repoData.currentRemote = Array.from(repoData.githubRemotes)[0];
104+
} else if (!repoData.currentRemote.isPresent() && repoData.githubRemotes.size() > 1) {
105+
repoData.manyRemotesAvailable = true;
106+
}
107+
repoData.endpoint = endpoint = repoData.currentRemote.getEndpointOrDotcom();
108+
}
109+
110+
return (
111+
<ObserveModel model={this.props.loginModel} fetchData={this.fetchToken} fetchParams={[endpoint]}>
112+
{token => this.renderToken(token, repoData)}
113+
</ObserveModel>
114+
);
115+
}
116+
117+
renderToken(token, repoData) {
118+
if (!repoData || this.props.repository.isLoading()) {
90119
return (
91120
<GitHubTabController
92121
{...this.props}
93122
refresher={this.state.refresher}
94123

95124
allRemotes={new RemoteSet()}
125+
githubRemotes={new RemoteSet()}
126+
currentRemote={nullRemote}
96127
branches={new BranchSet()}
128+
currentBranch={nullBranch}
97129
aheadCount={0}
130+
manyRemotesAvailable={false}
98131
pushInProgress={false}
99132
isLoading={true}
133+
token={token}
100134
/>
101135
);
102136
}
@@ -108,20 +142,26 @@ export default class GitHubTabContainer extends React.Component {
108142
refresher={this.state.refresher}
109143

110144
allRemotes={new RemoteSet()}
145+
githubRemotes={new RemoteSet()}
146+
currentRemote={nullRemote}
111147
branches={new BranchSet()}
148+
currentBranch={nullBranch}
112149
aheadCount={0}
150+
manyRemotesAvailable={false}
113151
pushInProgress={false}
114152
isLoading={false}
153+
token={token}
115154
/>
116155
);
117156
}
118157

119158
return (
120159
<GitHubTabController
121-
{...data}
160+
{...repoData}
122161
{...this.props}
123162
refresher={this.state.refresher}
124163
isLoading={false}
164+
token={token}
125165
/>
126166
);
127167
}

test/containers/github-tab-container.test.js

Lines changed: 152 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import GitHubTabController from '../../lib/controllers/github-tab-controller';
77
import Repository from '../../lib/models/repository';
88
import {InMemoryStrategy} from '../../lib/shared/keytar-strategy';
99
import GithubLoginModel from '../../lib/models/github-login-model';
10+
import Remote from '../../lib/models/remote';
11+
import RemoteSet from '../../lib/models/remote-set';
12+
import Branch, {nullBranch} from '../../lib/models/branch';
13+
import BranchSet from '../../lib/models/branch-set';
1014
import RefHolder from '../../lib/models/ref-holder';
1115

1216
describe('GitHubTabContainer', function() {
@@ -37,6 +41,7 @@ describe('GitHubTabContainer', function() {
3741
repository={repository}
3842
loginModel={new GithubLoginModel(InMemoryStrategy)}
3943
rootHolder={new RefHolder()}
44+
contextLocked={false}
4045

4146
changeWorkingDirectory={() => {}}
4247
onDidChangeWorkDirs={() => {}}
@@ -45,6 +50,7 @@ describe('GitHubTabContainer', function() {
4550
openPublishDialog={() => {}}
4651
openCloneDialog={() => {}}
4752
openGitTab={() => {}}
53+
setContextLock={() => {}}
4854

4955
{...props}
5056
/>
@@ -72,10 +78,11 @@ describe('GitHubTabContainer', function() {
7278

7379
beforeEach(function() {
7480
wrapper = shallow(buildApp());
75-
const childWrapper = wrapper.find('ObserveModel').renderProp('children')(defaultRepositoryData);
81+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(defaultRepositoryData);
82+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
7683

7784
retry = sinon.spy();
78-
const refresher = childWrapper.find(GitHubTabController).prop('refresher');
85+
const refresher = tokenWrapper.find(GitHubTabController).prop('refresher');
7986
refresher.setRetryCallback(Symbol('key'), retry);
8087

8188
stubRepository(repository);
@@ -106,6 +113,13 @@ describe('GitHubTabContainer', function() {
106113
assert.isTrue(retry.called);
107114
});
108115

116+
it('preserves the observer when the repository is unchanged', function() {
117+
wrapper.setProps({});
118+
119+
simulateOperation(repository, 'fetch');
120+
assert.isTrue(retry.called);
121+
});
122+
109123
it('un-observes the repository when unmounting', function() {
110124
wrapper.unmount();
111125

@@ -114,25 +128,152 @@ describe('GitHubTabContainer', function() {
114128
});
115129
});
116130

131+
describe('before loading', function() {
132+
it('passes isLoading to the controller', async function() {
133+
const loadingRepo = new Repository(await cloneRepository());
134+
const wrapper = shallow(buildApp({repository: loadingRepo}));
135+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(null);
136+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
137+
138+
assert.isTrue(tokenWrapper.find('GitHubTabController').prop('isLoading'));
139+
});
140+
});
141+
117142
describe('while loading', function() {
118-
it('passes isLoading to its view', async function() {
143+
it('passes isLoading to the controller', async function() {
119144
const loadingRepo = new Repository(await cloneRepository());
120145
assert.isTrue(loadingRepo.isLoading());
121-
const wrapper = mount(buildApp({repository: loadingRepo}));
146+
const wrapper = shallow(buildApp({repository: loadingRepo}));
147+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(loadingRepo);
148+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
149+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
122150

123-
assert.isTrue(wrapper.find('GitHubTabController').prop('isLoading'));
151+
assert.isTrue(tokenWrapper.find('GitHubTabController').prop('isLoading'));
152+
});
153+
});
154+
155+
describe('when absent', function() {
156+
it('passes placeholder data to the controller', async function() {
157+
const absent = Repository.absent();
158+
const wrapper = shallow(buildApp({repository: absent}));
159+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(absent);
160+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
161+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
162+
const controller = tokenWrapper.find('GitHubTabController');
163+
164+
assert.strictEqual(controller.prop('allRemotes').size(), 0);
165+
assert.strictEqual(controller.prop('githubRemotes').size(), 0);
166+
assert.isFalse(controller.prop('currentRemote').isPresent());
167+
assert.strictEqual(controller.prop('branches').getNames().length, 0);
168+
assert.isFalse(controller.prop('currentBranch').isPresent());
169+
assert.strictEqual(controller.prop('aheadCount'), 0);
170+
assert.isFalse(controller.prop('manyRemotesAvailable'));
171+
assert.isFalse(controller.prop('pushInProgress'));
172+
assert.isFalse(controller.prop('isLoading'));
124173
});
125174
});
126175

127176
describe('once loaded', function() {
177+
let nonGitHub, github0, github1;
178+
let loadedRepo, singleGitHubRemoteSet, multiGitHubRemoteSet;
179+
let otherBranch, mainBranch;
180+
let branches;
181+
182+
beforeEach(async function() {
183+
loadedRepo = new Repository(await cloneRepository());
184+
await loadedRepo.getLoadPromise();
185+
186+
nonGitHub = new Remote('no', '[email protected]:abc/def.git');
187+
github0 = new Remote('yes0', '[email protected]:user/repo0.git');
188+
github1 = new Remote('yes1', '[email protected]:user/repo1.git');
189+
190+
singleGitHubRemoteSet = new RemoteSet([nonGitHub, github0]);
191+
multiGitHubRemoteSet = new RemoteSet([nonGitHub, github0, github1]);
192+
193+
otherBranch = new Branch('other');
194+
mainBranch = new Branch('main', nullBranch, nullBranch, true);
195+
branches = new BranchSet([otherBranch, mainBranch]);
196+
});
197+
198+
function installRemoteSet(remoteSet) {
199+
return Promise.all(
200+
Array.from(remoteSet, remote => loadedRepo.addRemote(remote.getName(), remote.getUrl())),
201+
);
202+
}
203+
204+
it('derives the subset of GitHub remotes', async function() {
205+
await installRemoteSet(multiGitHubRemoteSet);
206+
207+
const wrapper = shallow(buildApp({repository: loadedRepo}));
208+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(loadedRepo);
209+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
210+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
211+
const githubRemotes = tokenWrapper.find('GitHubTabController').prop('githubRemotes');
212+
213+
assert.sameMembers(Array.from(githubRemotes, remote => remote.getName()), ['yes0', 'yes1']);
214+
});
215+
216+
it('derives the current branch', async function() {
217+
const wrapper = shallow(buildApp({repository: loadedRepo}));
218+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(loadedRepo);
219+
repoData.branches = branches;
220+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
221+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
222+
const currentBranch = tokenWrapper.find('GitHubTabController').prop('currentBranch');
223+
224+
assert.strictEqual(mainBranch, currentBranch);
225+
});
226+
227+
it('identifies the current remote from the config key', async function() {
228+
await loadedRepo.setConfig('atomGithub.currentRemote', 'yes1');
229+
await installRemoteSet(multiGitHubRemoteSet);
230+
231+
const wrapper = shallow(buildApp({repository: loadedRepo}));
232+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(loadedRepo);
233+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
234+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
235+
const currentRemote = tokenWrapper.find('GitHubTabController').prop('currentRemote');
236+
237+
assert.strictEqual(currentRemote.getUrl(), github1.getUrl());
238+
});
239+
240+
it('identifies the current remote as the only GitHub remote', async function() {
241+
await installRemoteSet(singleGitHubRemoteSet);
242+
243+
const wrapper = shallow(buildApp({repository: loadedRepo}));
244+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(loadedRepo);
245+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
246+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
247+
const currentRemote = tokenWrapper.find('GitHubTabController').prop('currentRemote');
248+
249+
assert.strictEqual(currentRemote.getUrl(), github0.getUrl());
250+
});
251+
252+
it('identifies when there are multiple GitHub remotes available', async function() {
253+
await installRemoteSet(multiGitHubRemoteSet);
254+
255+
const wrapper = shallow(buildApp({repository: loadedRepo}));
256+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(loadedRepo);
257+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
258+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
259+
const controller = tokenWrapper.find('GitHubTabController');
260+
261+
assert.isFalse(controller.prop('currentRemote').isPresent());
262+
assert.isTrue(controller.prop('manyRemotesAvailable'));
263+
});
264+
128265
it('renders the controller', async function() {
129-
const workdir = await cloneRepository();
130-
const presentRepo = new Repository(workdir);
131-
await presentRepo.getLoadPromise();
132-
const wrapper = mount(buildApp({repository: presentRepo}));
266+
await installRemoteSet(singleGitHubRemoteSet);
267+
268+
const wrapper = shallow(buildApp({repository: loadedRepo}));
269+
const repoData = await wrapper.find('ObserveModel').prop('fetchData')(loadedRepo);
270+
const repoWrapper = wrapper.find('ObserveModel').renderProp('children')(repoData);
271+
const tokenWrapper = repoWrapper.find('ObserveModel').renderProp('children')('1234');
272+
const controller = tokenWrapper.find('GitHubTabController');
133273

134-
await assert.async.isFalse(wrapper.update().find('GitHubTabController').prop('isLoading'));
135-
assert.strictEqual(wrapper.find('GitHubTabController').prop('workingDirectory'), workdir);
274+
assert.isFalse(controller.prop('isLoading'));
275+
assert.isFalse(controller.prop('manyRemotesAvailable'));
276+
assert.strictEqual(controller.prop('token'), '1234');
136277
});
137278
});
138279
});

0 commit comments

Comments
 (0)