Skip to content

Commit

Permalink
Throw exceptions on missing options (#156)
Browse files Browse the repository at this point in the history
* Make change to assume dest folder. Delete 2 old tests that looked for old behavior, add 2 more tests that look for new behavior

* Sort files

* Update src/RokuDeploy.ts

Co-authored-by: Bronley Plumb <[email protected]>

* Removed redundant entry.dest is null situation

* Added a few commands, not all are working correctly

* Move commands to their own file

* More command files

* Change commands to help with tests

* Add testing suite for all cli (2 tests are not working)

* Updated cli file after adding in commands and tests

* Fixed a few test cases

* Change name and input of table helper

* Totally broken code, but have the right names

* Changed name of toTable

* Make test for objectToTable

* add yargs to pacjage.json

* add package-lock.json

* add new line at eof

* Add test for coverage, also remove an unncessary '?'

* tweaks

* tweaks

* get from json stuff

* Correct imports

* Last of the fsExtra changes

* Create a load from json util, clean up cli.ts file with fleshing out comments, delete unnecessary command/tests/options, partially fix exec command

* Adding cli tests

* Delete deployAndSignPackage tests, a deleted function in rokudeploy

* Add defaultsFromJson tests

* Move some tests to utils test file, re add other functions that might have been accidentally deleted, fix some errors with fsExtra

* Change signExistingPackage to CreateSignedPackage

* Delete retrieveSignedPackage

* Move getFilePaths

* Random changes I forgot to put in the other pushes

* Change to different notation since getOutputZipFilePath and getOutputPkgPath were made private

* Change notation for normalizeDeviceInfoFieldValue since it was made privete

* Change notation for parsedManifestFromString and ParseManifest since being made private

* Change deleteInstalledChannel to deleteDevChannel, other small changes

* Add stagingDir, fix zip/deleteDevChannel/captureScreenshot function calls, delete Deploy function

* Fix commands

* change defaults from json function, fix some tests

* fix index, fix makezip, getfilepaths, sideload

* Add options from json ability to each command to each command

* remove bsconfig, fix cli file with key press commands, fix key press functions and add options

* fix getoptionsfromjson

* delete unnecessary commands, fix some tests

* change to captureScreenshot

* Fix a bunch of tests

* Fix up the last few tests and cli commands

* Changing coverage check to false

* Fix failing tests on windows

* Delete comment

* Change publish to sideload everywhere else

* Move deploy tests to test exec command

* Throw new error for wrong device id, and add test to test for it

* Delete creating variable options since it was unused

* Add function description

* Inline exec command options

* Remove retainsStagingDir, zipCallBackInfo, incrementBuildNumber, and add back tests for createPackage

* Delete convertToSquashfs, move deployAndSignPackage tests to cli, move retrieveSignedPackage tests to under createSignedPackage

* Change prepublishToStaging to stage

* Change the way close channel works

* Update src/RokuDeploy.ts

Co-authored-by: Bronley Plumb <[email protected]>

* Add outFile to Zip, delete zipPackage

* StagingDir is defaulted anyway so this error will never occur

* Delete MissingRequiredOptionError

* Add checkRequiredOptions function to test for required options

* Add checking for required options in sendKeyEvent function, start testing

* Add check for if options are part of the defined interface that they are being called with

* Add check for various required options and add tests for each one

* take out it.only in tests

* Delete old MissingRequiredOptionError tests

* fix tests

* Fix lint error

* Upgrade node to 14.7.0

* Undo last commit wrong branch

* Get rid of individual options checks

* Fixed option type in tests function

---------

Co-authored-by: Bronley Plumb <[email protected]>
  • Loading branch information
MilapNaik and TwitchBronBron authored Mar 26, 2024
1 parent e59ac91 commit ab389e0
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 101 deletions.
7 changes: 0 additions & 7 deletions src/Errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,3 @@ export class ConvertError extends Error {
Object.setPrototypeOf(this, ConvertError.prototype);
}
}

export class MissingRequiredOptionError extends Error {
constructor(message: string) {
super(message);
Object.setPrototypeOf(this, MissingRequiredOptionError.prototype);
}
}
154 changes: 80 additions & 74 deletions src/RokuDeploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { cwd, expectPathExists, expectPathNotExists, expectThrowsAsync, outDir,
import { createSandbox } from 'sinon';
import * as r from 'postman-request';
import type * as requestType from 'request';
import type { CaptureScreenshotOptions, ConvertToSquashfsOptions, CreateSignedPackageOptions, DeleteDevChannelOptions, GetDevIdOptions, GetDeviceInfoOptions, RekeyDeviceOptions, SendKeyEventOptions, SideloadOptions } from './RokuDeploy';
const request = r as typeof requestType;

const sinon = createSandbox();
Expand Down Expand Up @@ -646,11 +647,11 @@ describe('index', () => {

describe('generateBaseRequestOptions', () => {
it('uses default port', () => {
expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', password: options.password }).url).to.equal('http://1.2.3.4:80/a_b_c');
expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', password: 'password' }).url).to.equal('http://1.2.3.4:80/a_b_c');
});

it('uses overridden port', () => {
expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', packagePort: 999, password: options.password }).url).to.equal('http://1.2.3.4:999/a_b_c');
expect(rokuDeploy['generateBaseRequestOptions']('a_b_c', { host: '1.2.3.4', packagePort: 999, password: 'password' }).url).to.equal('http://1.2.3.4:999/a_b_c');
});
});

Expand Down Expand Up @@ -1058,21 +1059,6 @@ describe('index', () => {
});
});

it('should return MissingRequiredOptionError if host was not provided', async () => {
mockDoPostRequest();
try {
options.host = undefined;
await rokuDeploy.convertToSquashfs({
host: options.host,
password: 'password'
});
} catch (e) {
expect(e).to.be.instanceof(errors.MissingRequiredOptionError);
return;
}
assert.fail('Should not have succeeded');
});

it('should return ConvertError if converting failed', async () => {
mockDoPostRequest();
try {
Expand Down Expand Up @@ -1181,40 +1167,6 @@ describe('index', () => {
});
});

it('should throw error if missing rekeySignedPackage option', async () => {
try {
await rokuDeploy.rekeyDevice({
host: '1.2.3.4',
password: 'password',
rekeySignedPackage: null,
signingPassword: options.signingPassword,
rootDir: options.rootDir,
devId: options.devId
});
} catch (e) {
expect(e).to.be.instanceof(errors.MissingRequiredOptionError);
return;
}
assert.fail('Exception should have been thrown');
});

it('should throw error if missing signingPassword option', async () => {
try {
await rokuDeploy.rekeyDevice({
host: '1.2.3.4',
password: 'password',
rekeySignedPackage: options.rekeySignedPackage,
signingPassword: null,
rootDir: options.rootDir,
devId: options.devId
});
} catch (e) {
expect(e).to.be.instanceof(errors.MissingRequiredOptionError);
return;
}
assert.fail('Exception should have been thrown');
});

it('should throw error if response is not parsable', async () => {
try {
mockDoPostRequest();
Expand Down Expand Up @@ -1303,17 +1255,6 @@ describe('index', () => {
});
});

it('should return our error if signingPassword is not supplied', async () => {
await expectThrowsAsync(async () => {
await rokuDeploy.createSignedPackage({
host: '1.2.3.4',
password: 'password',
signingPassword: undefined,
stagingDir: stagingDir
});
}, 'Must supply signingPassword');
});

it('should return an error if there is a problem with the network request', async () => {
let error = new Error('Network Error');
try {
Expand Down Expand Up @@ -1401,7 +1342,7 @@ describe('index', () => {
);
});

it('should return our fallback error if neither error or package link was detected', async () => {
it('should return error if dev id does not match', async () => {
mockDoGetRequest(`
<device-info>
<keyed-developer-id>789</keyed-developer-id>
Expand Down Expand Up @@ -2099,19 +2040,19 @@ describe('index', () => {
`);

mockDoPostRequest(body);
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password }));
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' }));
});

it('throws when there is no response body', async () => {
// missing body
mockDoPostRequest(null);
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password }));
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' }));
});

it('throws when there is an empty response body', async () => {
// empty body
mockDoPostRequest();
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password }));
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' }));
});

it('throws when there is an error downloading the image from device', async () => {
Expand All @@ -2132,7 +2073,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: options.password }));
await expectThrowsAsync(rokuDeploy.captureScreenshot({ host: options.host, password: 'password' }));
});

it('handles the device returning a png', async () => {
Expand All @@ -2153,7 +2094,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password });
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password' });
expect(result).not.to.be.undefined;
expect(path.extname(result)).to.equal('.png');
expect(fsExtra.existsSync(result));
Expand All @@ -2177,7 +2118,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password });
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password' });
expect(result).not.to.be.undefined;
expect(path.extname(result)).to.equal('.jpg');
expect(fsExtra.existsSync(result));
Expand All @@ -2201,7 +2142,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: `${tempDir}/myScreenShots` });
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotDir: `${tempDir}/myScreenShots` });
expect(result).not.to.be.undefined;
expect(util.standardizePath(`${tempDir}/myScreenShots`)).to.equal(path.dirname(result));
expect(fsExtra.existsSync(result));
Expand All @@ -2225,7 +2166,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: tempDir, screenshotFile: 'my' });
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotDir: tempDir, screenshotFile: 'my' });
expect(result).not.to.be.undefined;
expect(util.standardizePath(tempDir)).to.equal(path.dirname(result));
expect(fsExtra.existsSync(path.join(tempDir, 'my.png')));
Expand All @@ -2249,7 +2190,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotDir: tempDir, screenshotFile: 'my.jpg' });
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotDir: tempDir, screenshotFile: 'my.jpg' });
expect(result).not.to.be.undefined;
expect(util.standardizePath(tempDir)).to.equal(path.dirname(result));
expect(fsExtra.existsSync(path.join(tempDir, 'my.jpg.png')));
Expand All @@ -2273,7 +2214,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password });
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password' });
expect(result).not.to.be.undefined;
expect(fsExtra.existsSync(result));
});
Expand All @@ -2296,7 +2237,7 @@ describe('index', () => {
};

mockDoPostRequest(body);
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: options.password, screenshotFile: 'myFile' });
let result = await rokuDeploy.captureScreenshot({ host: options.host, password: 'password', screenshotFile: 'myFile' });
expect(result).not.to.be.undefined;
expect(path.basename(result)).to.equal('myFile.jpg');
expect(fsExtra.existsSync(result));
Expand Down Expand Up @@ -3175,6 +3116,71 @@ describe('index', () => {
});
});

describe('checkRequiredOptions', () => {
async function testRequiredOptions(action: string, requiredOptions: Partial<RokuDeployOptions>, testedOption: string) {
const newOptions = { ...requiredOptions };
delete newOptions[testedOption];
await expectThrowsAsync(async () => {
await rokuDeploy[action](newOptions);
}, `Missing required option: ${testedOption}`);
}

it('throws error when sendKeyEvent is missing required options', async () => {
const requiredOptions: Partial<SendKeyEventOptions> = { host: '1.2.3.4', key: 'string' };
await testRequiredOptions('sendKeyEvent', requiredOptions, 'host');
await testRequiredOptions('sendKeyEvent', requiredOptions, 'key');
});

it('throws error when sideload is missing required options', async () => {
const requiredOptions: Partial<SideloadOptions> = { host: '1.2.3.4', password: 'abcd' };
await testRequiredOptions('sideload', requiredOptions, 'host');
await testRequiredOptions('sideload', requiredOptions, 'password');
});

it('throws error when convertToSquashfs is missing required options', async () => {
const requiredOptions: Partial<ConvertToSquashfsOptions> = { host: '1.2.3.4', password: 'abcd' };
await testRequiredOptions('convertToSquashfs', requiredOptions, 'host');
await testRequiredOptions('convertToSquashfs', requiredOptions, 'password');
});

it('throws error when rekeyDevice is missing required options', async () => {
const requiredOptions: Partial<RekeyDeviceOptions> = { host: '1.2.3.4', password: 'abcd', rekeySignedPackage: 'abcd', signingPassword: 'abcd' };
await testRequiredOptions('rekeyDevice', requiredOptions, 'host');
await testRequiredOptions('rekeyDevice', requiredOptions, 'password');
await testRequiredOptions('rekeyDevice', requiredOptions, 'rekeySignedPackage');
await testRequiredOptions('rekeyDevice', requiredOptions, 'signingPassword');
});

it('throws error when createSignedPackage is missing required options', async () => {
const requiredOptions: Partial<CreateSignedPackageOptions> = { host: '1.2.3.4', password: 'abcd', signingPassword: 'abcd' };
await testRequiredOptions('createSignedPackage', requiredOptions, 'host');
await testRequiredOptions('createSignedPackage', requiredOptions, 'password');
await testRequiredOptions('createSignedPackage', requiredOptions, 'signingPassword');
});

it('throws error when deleteDevChannel is missing required options', async () => {
const requiredOptions: Partial<DeleteDevChannelOptions> = { host: '1.2.3.4', password: 'abcd' };
await testRequiredOptions('deleteDevChannel', requiredOptions, 'host');
await testRequiredOptions('deleteDevChannel', requiredOptions, 'password');
});

it('throws error when captureScreenshot is missing required options', async () => {
const requiredOptions: Partial<CaptureScreenshotOptions> = { host: '1.2.3.4', password: 'abcd' };
await testRequiredOptions('captureScreenshot', requiredOptions, 'host');
await testRequiredOptions('captureScreenshot', requiredOptions, 'password');
});

it('throws error when getDeviceInfo is missing required options', async () => {
const requiredOptions: Partial<GetDeviceInfoOptions> = { host: '1.2.3.4' };
await testRequiredOptions('getDeviceInfo', requiredOptions, 'host');
});

it('throws error when getDevId is missing required options', async () => {
const requiredOptions: Partial<GetDevIdOptions> = { host: '1.2.3.4' };
await testRequiredOptions('getDevId', requiredOptions, 'host');
});
});

describe('downloadFile', () => {
it('waits for the write stream to finish writing before resolving', async () => {
let downloadFileIsResolved = false;
Expand Down
Loading

0 comments on commit ab389e0

Please sign in to comment.