Skip to content

Commit 79b0b40

Browse files
committed
added validation
1 parent 4ae37a2 commit 79b0b40

File tree

4 files changed

+195
-37
lines changed

4 files changed

+195
-37
lines changed

index.js

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
"use strict";
22

33
const { CeaserCipherTransform } = require("./cipher");
4+
const {
5+
ensureValidForBuffer,
6+
ensureValidForString,
7+
ensureValidKey,
8+
} = require("./validate");
49

510
/**
611
* Encrypt a string using Caesar Cipher
7-
*
12+
*
813
* @param {string} str
914
* @param {number} key
1015
* @returns string
1116
*/
1217
function encryptString(str, key) {
18+
ensureValidForString(str, key);
19+
1320
return str
1421
.split("")
1522
.map((s) => s.charCodeAt(0) + (key % 26))
@@ -19,12 +26,14 @@ function encryptString(str, key) {
1926

2027
/**
2128
* Decrypt a string using Caesar Cipher
22-
*
29+
*
2330
* @param {string} str
2431
* @param {number} key
2532
* @returns string
2633
*/
2734
function decryptString(str, key) {
35+
ensureValidForString(str, key);
36+
2837
return str
2938
.split("")
3039
.map((s) => s.charCodeAt(0) - (key % 26))
@@ -34,61 +43,59 @@ function decryptString(str, key) {
3443

3544
/**
3645
* Encrypt a buffer array using Caesar Cipher
37-
*
46+
*
3847
* @param {Buffer} buffer
3948
* @param {number} key
4049
* @returns buffer
4150
*/
4251
function encrypt(buffer, key) {
43-
return buffer
44-
.map((byte) => byte + (key % 26));
52+
ensureValidForBuffer(buffer, key);
53+
return buffer.map((byte) => byte + (key % 26));
4554
}
4655

4756
/**
4857
* Decrypt a buffer array using Caesar Cipher
49-
*
58+
*
5059
* @param {Buffer} buffer
5160
* @param {number} key
5261
* @returns buffer
5362
*/
5463
function decrypt(buffer, key) {
55-
return buffer
56-
.map((byte) => byte - (key % 26));
64+
ensureValidForBuffer(buffer, key);
65+
return buffer.map((byte) => byte - (key % 26));
5766
}
5867

59-
6068
class EncryptTransform extends CeaserCipherTransform {
61-
62-
/**
63-
* Transform stream for encryption using Caesar Cipher
64-
*
65-
* @param {number} key Encryption key
66-
*/
67-
constructor(key) {
68-
super();
69-
this.key = key;
70-
}
69+
/**
70+
* Transform stream for encryption using Caesar Cipher
71+
*
72+
* @param {number} key Encryption key
73+
*/
74+
constructor(key) {
75+
super();
76+
ensureValidKey(key);
77+
this.key = key;
78+
}
7179
}
7280

7381
class DecryptTransform extends CeaserCipherTransform {
74-
75-
/**
76-
* Transform stream for decryption using Caesar Cipher
77-
*
78-
* @param {number} key Decryption key
79-
*/
80-
constructor(key) {
81-
super();
82-
this.key = -key;
83-
}
82+
/**
83+
* Transform stream for decryption using Caesar Cipher
84+
*
85+
* @param {number} key Decryption key
86+
*/
87+
constructor(key) {
88+
super();
89+
ensureValidKey(key);
90+
this.key = -key;
91+
}
8492
}
8593

8694
module.exports = {
87-
encrypt,
88-
decrypt,
89-
encryptString,
90-
decryptString,
91-
EncryptTransform,
92-
DecryptTransform
93-
}
94-
95+
encrypt,
96+
decrypt,
97+
encryptString,
98+
decryptString,
99+
EncryptTransform,
100+
DecryptTransform,
101+
};

test/empty.txt

Whitespace-only changes.

test/validations.test.js

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
const {
2+
encrypt,
3+
decrypt,
4+
encryptString,
5+
decryptString,
6+
EncryptTransform,
7+
DecryptTransform,
8+
} = require("..");
9+
const fs = require("fs");
10+
const readFile = require('util').promisify(fs.readFile);
11+
const path = require("path");
12+
const assert = require("assert");
13+
const { after } = require("mocha");
14+
15+
const emptyFile = path.join(__dirname, "./empty.txt");
16+
const inputFile = path.join(__dirname, "./test.txt");
17+
const outputFile = path.join(__dirname, "./output1.txt");
18+
19+
describe("@gykh/caesar-cipher", function () {
20+
describe("Validaton", function () {
21+
it("should throw error for empty file", async function () {
22+
const data = await readFile(emptyFile);
23+
assert.throws(() => encrypt(data, 3));
24+
assert.throws(() => decrypt(data, 3));
25+
});
26+
it("should throw error for invalid data", function () {
27+
const data = undefined;
28+
assert.throws(() => encrypt(data, 3));
29+
assert.throws(() => decrypt(data, 3));
30+
});
31+
it("should throw error for empty string", function () {
32+
const data = "";
33+
assert.throws(() => encryptString(data, 3));
34+
assert.throws(() => decryptString(data, 3));
35+
});
36+
it("should throw error for long string", function () {
37+
const data = makeString(1001);
38+
assert.throws(() => encryptString(data, 3));
39+
assert.throws(() => decryptString(data, 3));
40+
});
41+
it("should throw error for no/invalid key", function () {
42+
const data = "test";
43+
assert.throws(() => encryptString(data));
44+
assert.throws(() => encryptString(data, 'sa'));
45+
assert.throws(() => decryptString(data));
46+
assert.throws(() => decryptString(data, 'sa'));
47+
assert.throws(() => decryptString(data, 26));
48+
assert.throws(() => decryptString(data, -1));
49+
});
50+
it("should throw error for invalid transform key", function () {
51+
assert.throws(() => new EncryptTransform());
52+
assert.throws(() => new EncryptTransform("as"));
53+
assert.throws(() => new DecryptTransform());
54+
assert.throws(() => new DecryptTransform("as"));
55+
assert.throws(() => new DecryptTransform(26));
56+
assert.throws(() => new DecryptTransform(-1));
57+
});
58+
it("should throw error for invalid transform", function (done) {
59+
const encTransform = new EncryptTransform(3);
60+
const decTransform = new DecryptTransform(3);
61+
62+
const stream = fs.createReadStream(emptyFile)
63+
.pipe(encTransform)
64+
.pipe(decTransform)
65+
.pipe(fs.createWriteStream(outputFile));
66+
67+
stream.on("error", (err) => assert.ok(false, err.message));
68+
stream.on("finish", done);
69+
});
70+
71+
after(() => {
72+
if (fs.existsSync(outputFile)) {
73+
fs.unlinkSync(outputFile);
74+
}
75+
});
76+
});
77+
});
78+
79+
function makeString(/** @type {number} */ minLength) {
80+
var result = 'a';
81+
while (result.length < minLength) {
82+
result += result;
83+
}
84+
return result;
85+
}

validate.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/**
2+
* Check for valid key
3+
*
4+
* @param {number} key Shift key
5+
*/
6+
function ensureValidKey(key) {
7+
if (!key) {
8+
throw new Error("Key is required");
9+
}
10+
11+
if (typeof key !== 'number') {
12+
throw new Error("Key should be a number")
13+
}
14+
15+
if (0 > key || key > 25) {
16+
throw new Error("Key should be within the range of 0 - 25");
17+
}
18+
}
19+
20+
/**
21+
* Validation for encryptString and decryptString
22+
*
23+
* @param {String} str String input value
24+
* @param {number} key Shift key
25+
*/
26+
function ensureValidForString (str, key) {
27+
if (!str) {
28+
throw new Error("Str is required");
29+
}
30+
31+
if (typeof str !== 'string' || str.length === 0) {
32+
throw new Error("Str is invalid");
33+
}
34+
35+
if (str.length > 1000) {
36+
throw new Error("Input too large, use EncryptTransform / DecryptTransform instead");
37+
}
38+
39+
ensureValidKey(key);
40+
}
41+
42+
/**
43+
* Validation for encrypt and decrypt functions
44+
*
45+
* @param {Buffer} buffer Buffer input value
46+
* @param {number} key Shift key
47+
*/
48+
function ensureValidForBuffer (buffer, key) {
49+
if (!buffer) {
50+
throw new Error("Buffer is required");
51+
}
52+
53+
if (!(buffer instanceof Buffer) || buffer.length === 0) {
54+
throw new Error("Buffer is invalid");
55+
}
56+
57+
if (buffer.length > 1000) {
58+
throw new Error("Input too large, use EncryptTransform / DecryptTransform instead");
59+
}
60+
}
61+
62+
module.exports = {
63+
ensureValidKey,
64+
ensureValidForString,
65+
ensureValidForBuffer
66+
}

0 commit comments

Comments
 (0)