| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | // Imports
 | 
					
						
							|  |  |  | import * as cp from 'child_process'; | 
					
						
							|  |  |  | import {EventEmitter} from 'events'; | 
					
						
							|  |  |  | import * as fs from 'fs'; | 
					
						
							| 
									
										
										
										
											2017-06-17 21:22:44 +03:00
										 |  |  | import * as path from 'path'; | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | import * as shell from 'shelljs'; | 
					
						
							| 
									
										
										
										
											2017-06-25 22:13:03 +03:00
										 |  |  | import {SHORT_SHA_LEN} from '../../lib/common/constants'; | 
					
						
							| 
									
										
										
										
											2018-08-27 18:07:25 +03:00
										 |  |  | import {Logger} from '../../lib/common/utils'; | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  | import {BuildCreator} from '../../lib/preview-server/build-creator'; | 
					
						
							|  |  |  | import {ChangedPrVisibilityEvent, CreatedBuildEvent} from '../../lib/preview-server/build-events'; | 
					
						
							|  |  |  | import {PreviewServerError} from '../../lib/preview-server/preview-error'; | 
					
						
							|  |  |  | import {expectToBePreviewServerError} from './helpers'; | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Tests
 | 
					
						
							|  |  |  | describe('BuildCreator', () => { | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |   const pr = 9; | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |   const sha = '9'.repeat(40); | 
					
						
							| 
									
										
										
										
											2017-06-25 22:13:03 +03:00
										 |  |  |   const shortSha = sha.substr(0, SHORT_SHA_LEN); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |   const archive = 'snapshot.tar.gz'; | 
					
						
							| 
									
										
										
										
											2017-03-01 15:16:38 +02:00
										 |  |  |   const buildsDir = 'builds/dir'; | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |   const hiddenPrDir = path.join(buildsDir, `hidden--${pr}`); | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |   const publicPrDir = path.join(buildsDir, `${pr}`); | 
					
						
							| 
									
										
										
										
											2017-06-25 22:13:03 +03:00
										 |  |  |   const hiddenShaDir = path.join(hiddenPrDir, shortSha); | 
					
						
							|  |  |  |   const publicShaDir = path.join(publicPrDir, shortSha); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |   let bc: BuildCreator; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(() => bc = new BuildCreator(buildsDir)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('constructor()', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should throw if \'buildsDir\' is missing or empty', () => { | 
					
						
							|  |  |  |       expect(() => new BuildCreator('')).toThrowError('Missing or empty required parameter \'buildsDir\'!'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should extend EventEmitter', () => { | 
					
						
							|  |  |  |       expect(bc).toEqual(jasmine.any(BuildCreator)); | 
					
						
							|  |  |  |       expect(bc).toEqual(jasmine.any(EventEmitter)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(Object.getPrototypeOf(bc)).toBe(BuildCreator.prototype); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |   describe('create()', () => { | 
					
						
							|  |  |  |     let bcEmitSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let bcExistsSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let bcExtractArchiveSpy: jasmine.Spy; | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |     let bcUpdatePrVisibilitySpy: jasmine.Spy; | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |     let shellMkdirSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let shellRmSpy: jasmine.Spy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       bcEmitSpy = spyOn(bc, 'emit'); | 
					
						
							|  |  |  |       bcExistsSpy = spyOn(bc as any, 'exists'); | 
					
						
							|  |  |  |       bcExtractArchiveSpy = spyOn(bc as any, 'extractArchive'); | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |       bcUpdatePrVisibilitySpy = spyOn(bc, 'updatePrVisibility'); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       shellMkdirSpy = spyOn(shell, 'mkdir'); | 
					
						
							|  |  |  |       shellRmSpy = spyOn(shell, 'rm'); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |     [true, false].forEach(isPublic => { | 
					
						
							|  |  |  |       const prDir = isPublic ? publicPrDir : hiddenPrDir; | 
					
						
							|  |  |  |       const shaDir = isPublic ? publicShaDir : hiddenShaDir; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       it('should return a promise', done => { | 
					
						
							|  |  |  |         const promise = bc.create(pr, sha, archive, isPublic); | 
					
						
							|  |  |  |         promise.then(done);   // Do not complete the test (and release the spies) synchronously
 | 
					
						
							|  |  |  |                               // to avoid running the actual `extractArchive()`.
 | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |         expect(promise).toEqual(jasmine.any(Promise)); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       it('should update the PR\'s visibility first if necessary', done => { | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |         bcUpdatePrVisibilitySpy.and.callFake(() => expect(shellMkdirSpy).not.toHaveBeenCalled()); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         bc.create(pr, sha, archive, isPublic). | 
					
						
							|  |  |  |           then(() => { | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |             expect(bcUpdatePrVisibilitySpy).toHaveBeenCalledWith(pr, isPublic); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |             expect(shellMkdirSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |           }). | 
					
						
							|  |  |  |           then(done); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       it('should create the build directory (and any parent directories)', done => { | 
					
						
							|  |  |  |         bc.create(pr, sha, archive, isPublic). | 
					
						
							|  |  |  |           then(() => expect(shellMkdirSpy).toHaveBeenCalledWith('-p', shaDir)). | 
					
						
							|  |  |  |           then(done); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       it('should extract the archive contents into the build directory', done => { | 
					
						
							|  |  |  |         bc.create(pr, sha, archive, isPublic). | 
					
						
							|  |  |  |           then(() => expect(bcExtractArchiveSpy).toHaveBeenCalledWith(archive, shaDir)). | 
					
						
							|  |  |  |           then(done); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       it('should emit a CreatedBuildEvent on success', done => { | 
					
						
							|  |  |  |         let emitted = false; | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |         bcEmitSpy.and.callFake((type: string, evt: CreatedBuildEvent) => { | 
					
						
							|  |  |  |           expect(type).toBe(CreatedBuildEvent.type); | 
					
						
							|  |  |  |           expect(evt).toEqual(jasmine.any(CreatedBuildEvent)); | 
					
						
							|  |  |  |           expect(evt.pr).toBe(+pr); | 
					
						
							| 
									
										
										
										
											2017-06-25 22:13:03 +03:00
										 |  |  |           expect(evt.sha).toBe(shortSha); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |           expect(evt.isPublic).toBe(isPublic); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           emitted = true; | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |         bc.create(pr, sha, archive, isPublic). | 
					
						
							|  |  |  |           then(() => expect(emitted).toBe(true)). | 
					
						
							|  |  |  |           then(done); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       describe('on error', () => { | 
					
						
							|  |  |  |         let existsValues: {[dir: string]: boolean}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         beforeEach(() => { | 
					
						
							|  |  |  |           existsValues = { | 
					
						
							|  |  |  |             [prDir]: false, | 
					
						
							|  |  |  |             [shaDir]: false, | 
					
						
							|  |  |  |           }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           bcExistsSpy.and.callFake((dir: string) => existsValues[dir]); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |         it('should abort and skip further operations if changing the PR\'s visibility fails', done => { | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |           const mockError = new PreviewServerError(543, 'Test'); | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |           bcUpdatePrVisibilitySpy.and.callFake(() => Promise.reject(mockError)); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(err => { | 
					
						
							|  |  |  |             expect(err).toBe(mockError); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |             expect(bcExistsSpy).not.toHaveBeenCalled(); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |             expect(shellMkdirSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcExtractArchiveSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should abort and skip further operations if the build does already exist', done => { | 
					
						
							|  |  |  |           existsValues[shaDir] = true; | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(err => { | 
					
						
							| 
									
										
										
										
											2017-08-03 11:40:39 +03:00
										 |  |  |             const publicOrNot = isPublic ? 'public' : 'non-public'; | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |             expectToBePreviewServerError(err, 409, `Request to overwrite existing ${publicOrNot} directory: ${shaDir}`); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |             expect(shellMkdirSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcExtractArchiveSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should detect existing build directory after visibility change', done => { | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |           bcUpdatePrVisibilitySpy.and.callFake(() => existsValues[prDir] = existsValues[shaDir] = true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           expect(bcExistsSpy(prDir)).toBe(false); | 
					
						
							|  |  |  |           expect(bcExistsSpy(shaDir)).toBe(false); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(err => { | 
					
						
							| 
									
										
										
										
											2017-08-03 11:40:39 +03:00
										 |  |  |             const publicOrNot = isPublic ? 'public' : 'non-public'; | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |             expectToBePreviewServerError(err, 409, `Request to overwrite existing ${publicOrNot} directory: ${shaDir}`); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |             expect(shellMkdirSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcExtractArchiveSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should abort and skip further operations if it fails to create the directories', done => { | 
					
						
							|  |  |  |           shellMkdirSpy.and.throwError(''); | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(() => { | 
					
						
							|  |  |  |             expect(shellMkdirSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcExtractArchiveSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should abort and skip further operations if it fails to extract the archive', done => { | 
					
						
							|  |  |  |           bcExtractArchiveSpy.and.throwError(''); | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(() => { | 
					
						
							|  |  |  |             expect(shellMkdirSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcExtractArchiveSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should delete the PR directory (for new PR)', done => { | 
					
						
							|  |  |  |           bcExtractArchiveSpy.and.throwError(''); | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(() => { | 
					
						
							|  |  |  |             expect(shellRmSpy).toHaveBeenCalledWith('-rf', prDir); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should delete the SHA directory (for existing PR)', done => { | 
					
						
							|  |  |  |           existsValues[prDir] = true; | 
					
						
							|  |  |  |           bcExtractArchiveSpy.and.throwError(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(() => { | 
					
						
							|  |  |  |             expect(shellRmSpy).toHaveBeenCalledWith('-rf', shaDir); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |         it('should reject with an PreviewServerError', done => { | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |           // tslint:disable-next-line: no-string-throw
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |           shellMkdirSpy.and.callFake(() => { throw 'Test'; }); | 
					
						
							|  |  |  |           bc.create(pr, sha, archive, isPublic).catch(err => { | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |             expectToBePreviewServerError(err, 500, `Error while creating preview at: ${shaDir}\nTest`); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |         it('should pass PreviewServerError instances unmodified', done => { | 
					
						
							|  |  |  |           shellMkdirSpy.and.callFake(() => { throw new PreviewServerError(543, 'Test'); }); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |           bc.create(pr, sha, archive, isPublic).catch(err => { | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |             expectToBePreviewServerError(err, 543, 'Test'); | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('updatePrVisibility()', () => { | 
					
						
							|  |  |  |     let bcEmitSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let bcExistsSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let bcListShasByDate: jasmine.Spy; | 
					
						
							|  |  |  |     let shellMvSpy: jasmine.Spy; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       bcEmitSpy = spyOn(bc, 'emit'); | 
					
						
							|  |  |  |       bcExistsSpy = spyOn(bc as any, 'exists'); | 
					
						
							|  |  |  |       bcListShasByDate = spyOn(bc as any, 'listShasByDate'); | 
					
						
							|  |  |  |       shellMvSpy = spyOn(shell, 'mv'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       bcExistsSpy.and.returnValues(Promise.resolve(true), Promise.resolve(false)); | 
					
						
							|  |  |  |       bcListShasByDate.and.returnValue([]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return a promise', done => { | 
					
						
							|  |  |  |       const promise = bc.updatePrVisibility(pr, true); | 
					
						
							|  |  |  |       promise.then(done);   // Do not complete the test (and release the spies) synchronously
 | 
					
						
							|  |  |  |                             // to avoid running the actual `extractArchive()`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(promise).toEqual(jasmine.any(Promise)); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     [true, false].forEach(makePublic => { | 
					
						
							|  |  |  |       const oldPrDir = makePublic ? hiddenPrDir : publicPrDir; | 
					
						
							|  |  |  |       const newPrDir = makePublic ? publicPrDir : hiddenPrDir; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should rename the directory', done => { | 
					
						
							|  |  |  |         bc.updatePrVisibility(pr, makePublic). | 
					
						
							|  |  |  |           then(() => expect(shellMvSpy).toHaveBeenCalledWith(oldPrDir, newPrDir)). | 
					
						
							|  |  |  |           then(done); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('when the visibility is updated', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should resolve to true', done => { | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic). | 
					
						
							|  |  |  |             then(result => expect(result).toBe(true)). | 
					
						
							|  |  |  |             then(done); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should rename the directory', done => { | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic). | 
					
						
							|  |  |  |             then(() => expect(shellMvSpy).toHaveBeenCalledWith(oldPrDir, newPrDir)). | 
					
						
							|  |  |  |             then(done); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should emit a ChangedPrVisibilityEvent on success', done => { | 
					
						
							|  |  |  |           let emitted = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           bcEmitSpy.and.callFake((type: string, evt: ChangedPrVisibilityEvent) => { | 
					
						
							|  |  |  |             expect(type).toBe(ChangedPrVisibilityEvent.type); | 
					
						
							|  |  |  |             expect(evt).toEqual(jasmine.any(ChangedPrVisibilityEvent)); | 
					
						
							|  |  |  |             expect(evt.pr).toBe(+pr); | 
					
						
							|  |  |  |             expect(evt.shas).toEqual(jasmine.any(Array)); | 
					
						
							|  |  |  |             expect(evt.isPublic).toBe(makePublic); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             emitted = true; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic). | 
					
						
							|  |  |  |             then(() => expect(emitted).toBe(true)). | 
					
						
							|  |  |  |             then(done); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should include all shas in the emitted event', done => { | 
					
						
							|  |  |  |           const shas = ['foo', 'bar', 'baz']; | 
					
						
							|  |  |  |           let emitted = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |           bcListShasByDate.and.callFake(() => Promise.resolve(shas)); | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |           bcEmitSpy.and.callFake((type: string, evt: ChangedPrVisibilityEvent) => { | 
					
						
							|  |  |  |             expect(bcListShasByDate).toHaveBeenCalledWith(newPrDir); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(type).toBe(ChangedPrVisibilityEvent.type); | 
					
						
							|  |  |  |             expect(evt).toEqual(jasmine.any(ChangedPrVisibilityEvent)); | 
					
						
							|  |  |  |             expect(evt.pr).toBe(+pr); | 
					
						
							|  |  |  |             expect(evt.shas).toBe(shas); | 
					
						
							|  |  |  |             expect(evt.isPublic).toBe(makePublic); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             emitted = true; | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic). | 
					
						
							|  |  |  |             then(() => expect(emitted).toBe(true)). | 
					
						
							|  |  |  |             then(done); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should do nothing if the visibility is already up-to-date', done => { | 
					
						
							|  |  |  |         bcExistsSpy.and.callFake((dir: string) => dir === newPrDir); | 
					
						
							|  |  |  |         bc.updatePrVisibility(pr, makePublic). | 
					
						
							|  |  |  |           then(result => { | 
					
						
							|  |  |  |             expect(result).toBe(false); | 
					
						
							|  |  |  |             expect(shellMvSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcListShasByDate).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |           }). | 
					
						
							|  |  |  |           then(done); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should do nothing if the PR directory does not exist', done => { | 
					
						
							|  |  |  |         bcExistsSpy.and.returnValue(false); | 
					
						
							|  |  |  |         bc.updatePrVisibility(pr, makePublic). | 
					
						
							|  |  |  |           then(result => { | 
					
						
							|  |  |  |             expect(result).toBe(false); | 
					
						
							|  |  |  |             expect(shellMvSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcListShasByDate).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |           }). | 
					
						
							|  |  |  |           then(done); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       describe('on error', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should abort and skip further operations if both directories exist', done => { | 
					
						
							|  |  |  |           bcExistsSpy.and.returnValue(true); | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic).catch(err => { | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |             expectToBePreviewServerError(err, 409, | 
					
						
							|  |  |  |               `Request to move '${oldPrDir}' to existing directory '${newPrDir}'.`); | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |             expect(shellMvSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcListShasByDate).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should abort and skip further operations if it fails to rename the directory', done => { | 
					
						
							|  |  |  |           shellMvSpy.and.throwError(''); | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic).catch(() => { | 
					
						
							|  |  |  |             expect(shellMvSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcListShasByDate).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should abort and skip further operations if it fails to list the SHAs', done => { | 
					
						
							|  |  |  |           bcListShasByDate.and.throwError(''); | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic).catch(() => { | 
					
						
							|  |  |  |             expect(shellMvSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcListShasByDate).toHaveBeenCalled(); | 
					
						
							|  |  |  |             expect(bcEmitSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |         it('should reject with an PreviewServerError', done => { | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |           // tslint:disable-next-line: no-string-throw
 | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |           shellMvSpy.and.callFake(() => { throw 'Test'; }); | 
					
						
							|  |  |  |           bc.updatePrVisibility(pr, makePublic).catch(err => { | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |             expectToBePreviewServerError(err, 500, | 
					
						
							|  |  |  |                 `Error while making PR ${pr} ${makePublic ? 'public' : 'hidden'}.\nTest`); | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |         it('should pass PreviewServerError instances unmodified', done => { | 
					
						
							|  |  |  |           shellMvSpy.and.callFake(() => { throw new PreviewServerError(543, 'Test'); }); | 
					
						
							| 
									
										
										
										
											2017-06-26 13:31:15 +03:00
										 |  |  |           bc.updatePrVisibility(pr, makePublic).catch(err => { | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |             expectToBePreviewServerError(err, 543, 'Test'); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |             done(); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |         }); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Protected methods
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('exists()', () => { | 
					
						
							|  |  |  |     let fsAccessSpy: jasmine.Spy; | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |     let fsAccessCbs: ((v?: any) => void)[]; | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       fsAccessCbs = []; | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |       fsAccessSpy = spyOn(fs, 'access').and.callFake((_: string, cb: (v?: any) => void) => fsAccessCbs.push(cb)); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return a promise', () => { | 
					
						
							|  |  |  |       expect((bc as any).exists('foo')).toEqual(jasmine.any(Promise)); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should call \'fs.access()\' with the specified argument', () => { | 
					
						
							|  |  |  |       (bc as any).exists('foo'); | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |       expect(fsAccessSpy).toHaveBeenCalledWith('foo', jasmine.any(Function)); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should resolve with \'true\' if \'fs.access()\' succeeds', done => { | 
					
						
							|  |  |  |       Promise. | 
					
						
							|  |  |  |         all([(bc as any).exists('foo'), (bc as any).exists('bar')]). | 
					
						
							|  |  |  |         then(results => expect(results).toEqual([true, true])). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       fsAccessCbs[0](); | 
					
						
							|  |  |  |       fsAccessCbs[1](null); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should resolve with \'false\' if \'fs.access()\' errors', done => { | 
					
						
							|  |  |  |       Promise. | 
					
						
							|  |  |  |         all([(bc as any).exists('foo'), (bc as any).exists('bar')]). | 
					
						
							|  |  |  |         then(results => expect(results).toEqual([false, false])). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       fsAccessCbs[0]('Error'); | 
					
						
							|  |  |  |       fsAccessCbs[1](new Error()); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('extractArchive()', () => { | 
					
						
							|  |  |  |     let consoleWarnSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let shellChmodSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let shellRmSpy: jasmine.Spy; | 
					
						
							|  |  |  |     let cpExecSpy: jasmine.Spy; | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |     let cpExecCbs: ((...args: any[]) => void)[]; | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       cpExecCbs = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-27 18:07:25 +03:00
										 |  |  |       consoleWarnSpy = spyOn(Logger.prototype, 'warn'); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       shellChmodSpy = spyOn(shell, 'chmod'); | 
					
						
							|  |  |  |       shellRmSpy = spyOn(shell, 'rm'); | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |       cpExecSpy = spyOn(cp, 'exec').and.callFake((_: string, cb: (...args: any[]) => void) => cpExecCbs.push(cb)); | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return a promise', () => { | 
					
						
							|  |  |  |       expect((bc as any).extractArchive('foo', 'bar')).toEqual(jasmine.any(Promise)); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should "gunzip" and "untar" the input file into the output directory', () => { | 
					
						
							|  |  |  |       const cmd = 'tar --extract --gzip --directory "output/dir" --file "input/file"'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       (bc as any).extractArchive('input/file', 'output/dir'); | 
					
						
							|  |  |  |       expect(cpExecSpy).toHaveBeenCalledWith(cmd, jasmine.any(Function)); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should log (as a warning) any stderr output if extracting succeeded', done => { | 
					
						
							|  |  |  |       (bc as any).extractArchive('foo', 'bar'). | 
					
						
							| 
									
										
										
										
											2018-08-27 18:07:25 +03:00
										 |  |  |         then(() => expect(consoleWarnSpy).toHaveBeenCalledWith('This is stderr')). | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |         then(done); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cpExecCbs[0](null, 'This is stdout', 'This is stderr'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should make the build directory non-writable', done => { | 
					
						
							|  |  |  |       (bc as any).extractArchive('foo', 'bar'). | 
					
						
							|  |  |  |         then(() => expect(shellChmodSpy).toHaveBeenCalledWith('-R', 'a-w', 'bar')). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cpExecCbs[0](); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |     it('should delete the build artifact file on success', done => { | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |       (bc as any).extractArchive('input/file', 'output/dir'). | 
					
						
							|  |  |  |         then(() => expect(shellRmSpy).toHaveBeenCalledWith('-f', 'input/file')). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cpExecCbs[0](); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('on error', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should abort and skip further operations if it fails to extract the archive', done => { | 
					
						
							|  |  |  |         (bc as any).extractArchive('foo', 'bar').catch((err: any) => { | 
					
						
							|  |  |  |           expect(shellChmodSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(shellRmSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(err).toBe('Test'); | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         cpExecCbs[0]('Test'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should abort and skip further operations if it fails to make non-writable', done => { | 
					
						
							|  |  |  |         (bc as any).extractArchive('foo', 'bar').catch((err: any) => { | 
					
						
							|  |  |  |           expect(shellChmodSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(shellRmSpy).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(err).toBe('Test'); | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |         shellChmodSpy.and.callFake(() => { | 
					
						
							|  |  |  |           // tslint:disable-next-line: no-string-throw
 | 
					
						
							|  |  |  |           throw 'Test'; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |         cpExecCbs[0](); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-15 13:47:45 +01:00
										 |  |  |       it('should abort and reject if it fails to remove the build artifact file', done => { | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |         (bc as any).extractArchive('foo', 'bar').catch((err: any) => { | 
					
						
							|  |  |  |           expect(shellChmodSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(shellRmSpy).toHaveBeenCalled(); | 
					
						
							|  |  |  |           expect(err).toBe('Test'); | 
					
						
							|  |  |  |           done(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-23 15:24:04 +03:00
										 |  |  |         shellRmSpy.and.callFake(() => { | 
					
						
							|  |  |  |           // tslint:disable-next-line: no-string-throw
 | 
					
						
							|  |  |  |           throw 'Test'; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  |         cpExecCbs[0](); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   describe('listShasByDate()', () => { | 
					
						
							|  |  |  |     let shellLsSpy: jasmine.Spy; | 
					
						
							|  |  |  |     const lsResult = (name: string, mtimeMs: number, isDirectory = true) => ({ | 
					
						
							|  |  |  |       isDirectory: () => isDirectory, | 
					
						
							|  |  |  |       mtime: new Date(mtimeMs), | 
					
						
							|  |  |  |       name, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     beforeEach(() => { | 
					
						
							|  |  |  |       shellLsSpy = spyOn(shell, 'ls').and.returnValue([]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return a promise', done => { | 
					
						
							|  |  |  |       const promise = (bc as any).listShasByDate('input/dir'); | 
					
						
							|  |  |  |       promise.then(done);   // Do not complete the test (and release the spies) synchronously
 | 
					
						
							|  |  |  |                             // to avoid running the actual `ls()`.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(promise).toEqual(jasmine.any(Promise)); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should `ls()` files with their metadata', done => { | 
					
						
							|  |  |  |       (bc as any).listShasByDate('input/dir'). | 
					
						
							|  |  |  |         then(() => expect(shellLsSpy).toHaveBeenCalledWith('-l', 'input/dir')). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should reject if listing files fails', done => { | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |       shellLsSpy.and.callFake(() => Promise.reject('Test')); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       (bc as any).listShasByDate('input/dir').catch((err: string) => { | 
					
						
							|  |  |  |         expect(err).toBe('Test'); | 
					
						
							|  |  |  |         done(); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should return the filenames', done => { | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |       shellLsSpy.and.callFake(() => Promise.resolve([ | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |         lsResult('foo', 100), | 
					
						
							|  |  |  |         lsResult('bar', 200), | 
					
						
							|  |  |  |         lsResult('baz', 300), | 
					
						
							|  |  |  |       ])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       (bc as any).listShasByDate('input/dir'). | 
					
						
							|  |  |  |         then((shas: string[]) => expect(shas).toEqual(['foo', 'bar', 'baz'])). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should sort by date', done => { | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |       shellLsSpy.and.callFake(() => Promise.resolve([ | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |         lsResult('foo', 300), | 
					
						
							|  |  |  |         lsResult('bar', 100), | 
					
						
							|  |  |  |         lsResult('baz', 200), | 
					
						
							|  |  |  |       ])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       (bc as any).listShasByDate('input/dir'). | 
					
						
							|  |  |  |         then((shas: string[]) => expect(shas).toEqual(['bar', 'baz', 'foo'])). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should not break with ShellJS\' custom `sort()` method', done => { | 
					
						
							|  |  |  |       const mockArray = [ | 
					
						
							|  |  |  |         lsResult('foo', 300), | 
					
						
							|  |  |  |         lsResult('bar', 100), | 
					
						
							|  |  |  |         lsResult('baz', 200), | 
					
						
							|  |  |  |       ]; | 
					
						
							|  |  |  |       mockArray.sort = jasmine.createSpy('sort'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |       shellLsSpy.and.callFake(() => Promise.resolve(mockArray)); | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |       (bc as any).listShasByDate('input/dir'). | 
					
						
							|  |  |  |         then((shas: string[]) => { | 
					
						
							|  |  |  |           expect(shas).toEqual(['bar', 'baz', 'foo']); | 
					
						
							|  |  |  |           expect(mockArray.sort).not.toHaveBeenCalled(); | 
					
						
							|  |  |  |         }). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should only include directories', done => { | 
					
						
							| 
									
										
										
										
											2018-05-10 13:56:07 +01:00
										 |  |  |       shellLsSpy.and.callFake(() => Promise.resolve([ | 
					
						
							| 
									
										
										
										
											2017-06-19 01:15:07 +03:00
										 |  |  |         lsResult('foo', 100), | 
					
						
							|  |  |  |         lsResult('bar', 200, false), | 
					
						
							|  |  |  |         lsResult('baz', 300), | 
					
						
							|  |  |  |       ])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       (bc as any).listShasByDate('input/dir'). | 
					
						
							|  |  |  |         then((shas: string[]) => expect(shas).toEqual(['foo', 'baz'])). | 
					
						
							|  |  |  |         then(done); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-06 20:40:28 +02:00
										 |  |  | }); |