Skip to content

Commit dec39b7

Browse files
author
Frederic Collonval
committed
Correct unit tests
1 parent 43d06be commit dec39b7

File tree

3 files changed

+180
-14
lines changed

3 files changed

+180
-14
lines changed

specification/Git_REST_API.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,9 @@ On failure
293293

294294
### /config - Get or set configuration options
295295

296+
If no `options` in the request, get the `options` in the response.
297+
Otherwise set the provided options (if allowed) and return `message`.
298+
296299
URL:
297300

298301
```bash
@@ -324,7 +327,11 @@ On success
324327
```bash
325328
{
326329
"code": "0",
327-
"message": "Git command output"
330+
"message"?: "Git command output",
331+
"options"?: {
332+
"key1": "value1",
333+
"keyI": "valueI"
334+
}
328335
}
329336
```
330337

src/components/BranchHeader.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export class BranchHeader extends React.Component<
7272
/** Commit all staged files */
7373
async commitAllStagedFiles(message: string, path: string): Promise<void> {
7474
try {
75-
if (message && message !== '' && (await this._hasIdentity())) {
75+
if (message && message !== '' && (await this._hasIdentity(path))) {
7676
let gitApi = new Git();
7777
const response = await gitApi.commit(message, path);
7878

@@ -288,14 +288,15 @@ export class BranchHeader extends React.Component<
288288
/**
289289
* Does the user have an known git identity.
290290
*
291+
* @param path Top repository path
291292
* @returns Success status
292293
*/
293-
private async _hasIdentity(): Promise<boolean> {
294+
private async _hasIdentity(path: string): Promise<boolean> {
294295
// If the repository path changes, check the identity
295-
if (this.props.topRepoPath !== this._previousTopRepoPath) {
296+
if (path !== this._previousTopRepoPath) {
296297
let gitApi = new Git();
297298
try {
298-
const apiResponse = await gitApi.config(this.props.topRepoPath);
299+
const apiResponse = await gitApi.config(path);
299300
if (apiResponse.ok) {
300301
const options: JSONObject = (await apiResponse.json()).options;
301302
const keys = Object.keys(options);
@@ -310,7 +311,7 @@ export class BranchHeader extends React.Component<
310311
return false;
311312
}
312313
const identity = result.value;
313-
const response = await gitApi.config(this.props.topRepoPath, {
314+
const response = await gitApi.config(path, {
314315
'user.name': identity.name,
315316
'user.email': identity.email
316317
});
@@ -320,7 +321,7 @@ export class BranchHeader extends React.Component<
320321
return false;
321322
}
322323
}
323-
this._previousTopRepoPath = this.props.topRepoPath;
324+
this._previousTopRepoPath = path;
324325
}
325326
} catch (error) {
326327
throw new Error('Fail to set your identity. ' + error.message);

tests/test-components/BranchHeader.spec.tsx

Lines changed: 165 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as apputils from '@jupyterlab/apputils';
12
import {
23
BranchHeader,
34
IBranchHeaderProps
@@ -22,7 +23,7 @@ describe('BranchHeader', () => {
2223
upstreamBranch: 'origin/master',
2324
stagedFiles: ['test-1', 'test-2'],
2425
data: ['master', 'feature-1', 'feature-2', 'patch-007'],
25-
refresh: 'update all content',
26+
refresh: function() {},
2627
disabled: false,
2728
toggleSidebar: function() {
2829
return true;
@@ -32,9 +33,11 @@ describe('BranchHeader', () => {
3233

3334
describe('#constructor()', () => {
3435
const branchHeader = new BranchHeader(props);
36+
3537
it('should construct a new branch header', () => {
3638
expect(branchHeader).toBeInstanceOf(BranchHeader);
3739
});
40+
3841
it('should set default values correctly', () => {
3942
expect(branchHeader.state.dropdownOpen).toEqual(false);
4043
expect(branchHeader.state.showCommitBox).toEqual(true);
@@ -43,26 +46,181 @@ describe('BranchHeader', () => {
4346
});
4447

4548
describe('#commitAllStagedFiles()', () => {
46-
const branchHeader = new BranchHeader(props);
47-
it('should commit when commit message is provided', () => {
49+
let branchHeader = null;
50+
51+
beforeEach(() => {
52+
branchHeader = new BranchHeader(props);
53+
});
54+
55+
it('should commit when commit message is provided', async () => {
4856
const spy = jest.spyOn(Git.prototype, 'commit');
49-
branchHeader.commitAllStagedFiles(
57+
// Mock identity look up
58+
const identity = jest.spyOn(Git.prototype, 'config').mockImplementation(
59+
() =>
60+
new Response(
61+
JSON.stringify({
62+
options: {
63+
'user.name': 'John Snow',
64+
'user.email': '[email protected]'
65+
}
66+
}),
67+
{ status: 201 }
68+
)
69+
);
70+
await branchHeader.commitAllStagedFiles(
5071
'Initial commit',
5172
'/absolute/path/to/git/repo'
5273
);
74+
expect(identity).toHaveBeenCalledTimes(1);
5375
expect(spy).toHaveBeenCalledTimes(1);
5476
expect(spy).toHaveBeenCalledWith(
5577
'Initial commit',
5678
'/absolute/path/to/git/repo'
5779
);
58-
spy.mockRestore();
80+
jest.restoreAllMocks();
5981
});
60-
it('should NOT commit when commit message is empty', () => {
82+
83+
it('should NOT commit when commit message is empty', async () => {
6184
const spy = jest.spyOn(Git.prototype, 'commit');
62-
branchHeader.commitAllStagedFiles('', props.topRepoPath);
85+
await branchHeader.commitAllStagedFiles('', props.topRepoPath);
6386
expect(spy).not.toHaveBeenCalled();
6487
spy.mockRestore();
6588
});
89+
90+
it('should prompt for user identity if user.name is unset', async () => {
91+
const spy = jest.spyOn(Git.prototype, 'commit');
92+
// Mock identity look up
93+
const identity = jest
94+
.spyOn(Git.prototype, 'config')
95+
.mockImplementation((path, options) => {
96+
if (options === undefined) {
97+
return new Response(
98+
JSON.stringify({
99+
options: {
100+
'user.email': '[email protected]'
101+
}
102+
}),
103+
{ status: 201 }
104+
);
105+
} else {
106+
return new Response('', { status: 201 });
107+
}
108+
});
109+
jest.spyOn(apputils, 'showDialog').mockReturnValue(
110+
Promise.resolve({
111+
button: {
112+
accept: true
113+
},
114+
value: {
115+
name: 'John Snow',
116+
117+
}
118+
})
119+
);
120+
121+
await branchHeader.commitAllStagedFiles(
122+
'Initial commit',
123+
'/absolute/path/to/git/repo'
124+
);
125+
expect(identity).toHaveBeenCalledTimes(2);
126+
expect(identity.mock.calls[0]).toEqual(['/absolute/path/to/git/repo']);
127+
expect(identity.mock.calls[1]).toEqual([
128+
'/absolute/path/to/git/repo',
129+
{
130+
'user.name': 'John Snow',
131+
'user.email': '[email protected]'
132+
}
133+
]);
134+
expect(spy).toHaveBeenCalledTimes(1);
135+
expect(spy).toHaveBeenCalledWith(
136+
'Initial commit',
137+
'/absolute/path/to/git/repo'
138+
);
139+
jest.restoreAllMocks();
140+
});
141+
142+
it('should prompt for user identity if user.email is unset', async () => {
143+
const spy = jest.spyOn(Git.prototype, 'commit');
144+
// Mock identity look up
145+
const identity = jest
146+
.spyOn(Git.prototype, 'config')
147+
.mockImplementation((path, options) => {
148+
if (options === undefined) {
149+
return new Response(
150+
JSON.stringify({
151+
options: {
152+
'user.name': 'John Snow'
153+
}
154+
}),
155+
{ status: 201 }
156+
);
157+
} else {
158+
return new Response('', { status: 201 });
159+
}
160+
});
161+
jest.spyOn(apputils, 'showDialog').mockReturnValue({
162+
button: {
163+
accept: true
164+
},
165+
value: {
166+
name: 'John Snow',
167+
168+
}
169+
});
170+
171+
await branchHeader.commitAllStagedFiles(
172+
'Initial commit',
173+
'/absolute/path/to/git/repo'
174+
);
175+
expect(identity).toHaveBeenCalledTimes(2);
176+
expect(identity.mock.calls[0]).toEqual(['/absolute/path/to/git/repo']);
177+
expect(identity.mock.calls[1]).toEqual([
178+
'/absolute/path/to/git/repo',
179+
{
180+
'user.name': 'John Snow',
181+
'user.email': '[email protected]'
182+
}
183+
]);
184+
expect(spy).toHaveBeenCalledTimes(1);
185+
expect(spy).toHaveBeenCalledWith(
186+
'Initial commit',
187+
'/absolute/path/to/git/repo'
188+
);
189+
jest.restoreAllMocks();
190+
});
191+
192+
it('should NOT commit if no user identity is set and the user reject the dialog', async () => {
193+
const spy = jest.spyOn(Git.prototype, 'commit');
194+
// Mock identity look up
195+
const identity = jest
196+
.spyOn(Git.prototype, 'config')
197+
.mockImplementation((path, options) => {
198+
if (options === undefined) {
199+
return new Response(
200+
JSON.stringify({
201+
options: {}
202+
}),
203+
{ status: 201 }
204+
);
205+
} else {
206+
return new Response('', { status: 201 });
207+
}
208+
});
209+
jest.spyOn(apputils, 'showDialog').mockReturnValue({
210+
button: {
211+
accept: false
212+
}
213+
});
214+
215+
await branchHeader.commitAllStagedFiles(
216+
'Initial commit',
217+
'/absolute/path/to/git/repo'
218+
);
219+
expect(identity).toHaveBeenCalledTimes(1);
220+
expect(identity).toHaveBeenCalledWith('/absolute/path/to/git/repo');
221+
expect(spy).not.toHaveBeenCalled();
222+
jest.restoreAllMocks();
223+
});
66224
});
67225

68226
describe('#updateCommitBoxState()', () => {

0 commit comments

Comments
 (0)