mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-22 15:02:22 +00:00
979284b071
Change-type: patch Resolves: #1805 Signed-off-by: Scott Lowe <scott@balena.io>
210 lines
6.1 KiB
TypeScript
210 lines
6.1 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2020 Balena Ltd.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
import { BalenaReleaseNotFound } from 'balena-errors';
|
|
import { expect } from 'chai';
|
|
import * as sinon from 'sinon';
|
|
import { ExpectedError } from '../../build/errors';
|
|
import { disambiguateReleaseParam } from '../../build/utils/normalization';
|
|
|
|
describe('disambiguateReleaseParam() function', () => {
|
|
it('should reject empty values', async () => {
|
|
try {
|
|
await disambiguateReleaseParam(null as any, '');
|
|
throw new Error('should not be reached');
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceOf(ExpectedError);
|
|
expect(e.message).to.equal('Invalid release parameter');
|
|
}
|
|
});
|
|
|
|
it('should reject values containing invalid chars', async () => {
|
|
const invalidCharExamples = ' .,-_=!@#$%^&*() ';
|
|
|
|
for (const char of invalidCharExamples) {
|
|
try {
|
|
await disambiguateReleaseParam(null as any, char);
|
|
throw new Error('should not be reached');
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceOf(ExpectedError);
|
|
expect(e.message).to.equal('Invalid release parameter');
|
|
}
|
|
}
|
|
});
|
|
|
|
it('should reject non-numerical values with invalid uuid/hash lengths', async () => {
|
|
const invalidLengthValue = 'abcd';
|
|
|
|
try {
|
|
await disambiguateReleaseParam(null as any, invalidLengthValue);
|
|
throw new Error('should not be reached');
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceOf(ExpectedError);
|
|
expect(e.message).to.equal('Invalid release parameter');
|
|
}
|
|
});
|
|
|
|
it('should reject leading-zero numerical values with invalid uuid/hash lengths', async () => {
|
|
const invalidLengthValue = '01234';
|
|
|
|
try {
|
|
await disambiguateReleaseParam(null as any, invalidLengthValue);
|
|
throw new Error('should not be reached');
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceOf(ExpectedError);
|
|
expect(e.message).to.equal('Invalid release parameter');
|
|
}
|
|
});
|
|
|
|
it('should return non-numerical values with valid hash lengths as string, without SDK calls', async () => {
|
|
const uuid7 = 'a'.repeat(7);
|
|
const uuid32 = 'a'.repeat(32);
|
|
const uuid62 = 'a'.repeat(62);
|
|
const hash8 = 'a'.repeat(8);
|
|
const hash9 = 'a'.repeat(9);
|
|
const hash40 = 'a'.repeat(40);
|
|
|
|
expect(await disambiguateReleaseParam(null as any, uuid7)).to.equal(uuid7);
|
|
expect(await disambiguateReleaseParam(null as any, uuid32)).to.equal(
|
|
uuid32,
|
|
);
|
|
expect(await disambiguateReleaseParam(null as any, uuid62)).to.equal(
|
|
uuid62,
|
|
);
|
|
expect(await disambiguateReleaseParam(null as any, hash8)).to.equal(hash8);
|
|
expect(await disambiguateReleaseParam(null as any, hash9)).to.equal(hash9);
|
|
expect(await disambiguateReleaseParam(null as any, hash40)).to.equal(
|
|
hash40,
|
|
);
|
|
});
|
|
|
|
it('should return numerical, leading zero values with valid uuid/hash lengths as string, without SDK calls', async () => {
|
|
const uuid7 = '0' + '1'.repeat(6);
|
|
const uuid32 = '0' + '1'.repeat(31);
|
|
const uuid62 = '0' + '1'.repeat(61);
|
|
const hash8 = '0' + '1'.repeat(7);
|
|
const hash9 = '0' + '1'.repeat(8);
|
|
const hash40 = '0' + '1'.repeat(39);
|
|
|
|
expect(await disambiguateReleaseParam(null as any, uuid7)).to.equal(uuid7);
|
|
expect(await disambiguateReleaseParam(null as any, uuid32)).to.equal(
|
|
uuid32,
|
|
);
|
|
expect(await disambiguateReleaseParam(null as any, uuid62)).to.equal(
|
|
uuid62,
|
|
);
|
|
expect(await disambiguateReleaseParam(null as any, hash8)).to.equal(hash8);
|
|
expect(await disambiguateReleaseParam(null as any, hash9)).to.equal(hash9);
|
|
expect(await disambiguateReleaseParam(null as any, hash40)).to.equal(
|
|
hash40,
|
|
);
|
|
});
|
|
|
|
it('should return id from SDK on first call, if match is found', async () => {
|
|
const input = '1234';
|
|
const output = 1234;
|
|
const getRelease = sinon.stub().returns(Promise.resolve({ id: output }));
|
|
const sdk: any = {
|
|
models: {
|
|
release: {
|
|
get: getRelease,
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = await disambiguateReleaseParam(sdk, input);
|
|
|
|
expect(result).to.equal(output);
|
|
expect(getRelease.calledOnce).to.be.true;
|
|
expect(getRelease.getCall(0).args[0]).to.equal(parseInt(input, 10));
|
|
});
|
|
|
|
it('should return id from SDK on second call, if match is found', async () => {
|
|
const input = '1234';
|
|
const output = 1234;
|
|
const getRelease = sinon
|
|
.stub()
|
|
.onCall(0)
|
|
.returns(Promise.reject(new BalenaReleaseNotFound(input)))
|
|
.onCall(1)
|
|
.returns(Promise.resolve({ id: output }));
|
|
|
|
const sdk: any = {
|
|
models: {
|
|
release: {
|
|
get: getRelease,
|
|
},
|
|
},
|
|
};
|
|
|
|
const result = await disambiguateReleaseParam(sdk, input);
|
|
|
|
expect(result).to.equal(output);
|
|
expect(getRelease.calledTwice).to.be.true;
|
|
expect(getRelease.getCall(0).args[0]).to.equal(parseInt(input, 10));
|
|
expect(getRelease.getCall(1).args[0]).to.equal(input);
|
|
});
|
|
|
|
it('should throw error if no match found', async () => {
|
|
const input = '1234';
|
|
const getRelease = sinon
|
|
.stub()
|
|
.returns(Promise.reject(new BalenaReleaseNotFound(input)));
|
|
|
|
const sdk: any = {
|
|
models: {
|
|
release: {
|
|
get: getRelease,
|
|
},
|
|
},
|
|
};
|
|
|
|
try {
|
|
await disambiguateReleaseParam(sdk, input);
|
|
throw new Error('should not be reached');
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceOf(BalenaReleaseNotFound);
|
|
expect(getRelease.calledTwice).to.be.true;
|
|
}
|
|
});
|
|
|
|
it('should throw error if unknown error returned from SDK', async () => {
|
|
const input = '1234';
|
|
|
|
const getRelease = sinon
|
|
.stub()
|
|
.returns(Promise.reject(new Error('some error')));
|
|
|
|
const sdk: any = {
|
|
models: {
|
|
release: {
|
|
get: getRelease,
|
|
},
|
|
},
|
|
};
|
|
|
|
try {
|
|
await disambiguateReleaseParam(sdk, input);
|
|
throw new Error('should not be reached');
|
|
} catch (e) {
|
|
expect(e).to.be.an.instanceOf(Error);
|
|
expect(e.message).to.equal('some error');
|
|
expect(getRelease.calledOnce).to.be.true;
|
|
}
|
|
});
|
|
});
|