Skip to content

Commit ef931f1

Browse files
committed
Adding input validation checks for fingerprintName
1 parent 8e615f6 commit ef931f1

File tree

2 files changed

+101
-9
lines changed

2 files changed

+101
-9
lines changed

index.js

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,17 @@ const fs = require('fs');
22

33
function AssetFingerprint(initializerDirectory, needsFingerprint = true, fingerprintName) {
44
_validateInitializerDirectory();
5-
65
this.initializerDirectory = initializerDirectory;
6+
this.initializerPath = `${this.initializerDirectory}/asset_fingerprint.rb`;
7+
8+
if(fingerprintName) {
9+
_validateFingerprintName(fingerprintName);
10+
11+
if(_checkForExistingFingerprint(fingerprintName, this.initializerPath)) {
12+
throw new Error('The provided fingerprint name has already been used.');
13+
}
14+
}
15+
716
this.needsFingerprint = needsFingerprint;
817
this.fingerprintName = fingerprintName || 'ASSET_FINGERPRINT';
918

@@ -12,18 +21,32 @@ function AssetFingerprint(initializerDirectory, needsFingerprint = true, fingerp
1221
throw new Error('Please supply a directory path for your initializer, such as `config/initializers`.');
1322
}
1423
}
24+
25+
function _validateFingerprintName(fingerprintName) {
26+
if(!/^([A-Z]|_)*_FINGERPRINT$/.test(fingerprintName)) {
27+
throw new Error('Please supply a fingerprint name that is all caps separating words by underscores (i.e. CUSTOM_ASSET_FINGERPRINT).');
28+
}
29+
}
30+
31+
function _checkForExistingFingerprint(fingerprintName, initializerPath) {
32+
if(fs.existsSync(initializerPath)) {
33+
let file = fs.readFileSync(initializerPath, "utf8");
34+
return file.indexOf(fingerprintName) >= 0;
35+
} else {
36+
return false;
37+
}
38+
}
1539
}
1640

1741
AssetFingerprint.prototype.apply = function(compiler) {
1842
compiler.plugin('done', function(stats) {
1943
if (this.needsFingerprint) {
2044
let defaultRun = this.fingerprintName === 'ASSET_FINGERPRINT';
21-
let initializerPath = `${this.initializerDirectory}/asset_fingerprint.rb`;
2245
const newline = defaultRun ? '' : '\r\n';
2346
const fsMethod = defaultRun ? 'writeFileSync' : 'appendFileSync';
2447
let output = `${newline}${this.fingerprintName} = '${stats.hash}'`;
25-
fs[fsMethod](initializerPath, output);
26-
console.log(`asset-fingerprint-webpack-rails: updated file ${initializerPath} with ${this.fingerprintName} = ${stats.hash}`)
48+
fs[fsMethod](this.initializerPath, output);
49+
console.log(`asset-fingerprint-webpack-rails: updated file ${this.initializerPath} with ${this.fingerprintName} = ${stats.hash}`)
2750
}
2851
}.bind(this));
2952
}

spec/indexSpec.js

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@ describe("AssetFingerprint", function() {
55

66
describe("initialization", function() {
77
describe("needsFingerprint", function() {
8+
9+
beforeEach(function() {
10+
spyOn(fs, "existsSync").and.returnValue(false);
11+
spyOn(fs, "readFileSync").and.returnValue("");
12+
});
13+
814
it("should default needsFingerprint = true when no args", function() {
915
fingerprint = new AssetFingerprint('');
1016
expect(fingerprint.needsFingerprint).toBeTruthy();
@@ -27,6 +33,11 @@ describe("AssetFingerprint", function() {
2733
});
2834

2935
describe("initializer path", function() {
36+
beforeEach(function() {
37+
spyOn(fs, "existsSync").and.returnValue(false);
38+
spyOn(fs, "readFileSync").and.returnValue("");
39+
});
40+
3041
it("should set when supplied", function() {
3142
var dir = 'config/initializers';
3243
fingerprint = new AssetFingerprint(dir, true);
@@ -40,6 +51,11 @@ describe("AssetFingerprint", function() {
4051
});
4152

4253
describe("fingerprint name", function() {
54+
beforeEach(function() {
55+
spyOn(fs, "existsSync").and.returnValue(false);
56+
spyOn(fs, "readFileSync").and.returnValue("");
57+
});
58+
4359
it("should use ASSET_FINGERPRINT when no args are passed", function () {
4460
var dir = 'config/initializers';
4561
fingerprint = new AssetFingerprint(dir);
@@ -48,15 +64,68 @@ describe("AssetFingerprint", function() {
4864

4965
it("should use value when provided", function () {
5066
var dir = 'config/initializers';
51-
fingerprint = new AssetFingerprint(dir, true, "FINGERPRINT_VALUE");
52-
expect(fingerprint.fingerprintName).toEqual("FINGERPRINT_VALUE");
67+
fingerprint = new AssetFingerprint(dir, true, "TEST_FINGERPRINT");
68+
expect(fingerprint.fingerprintName).toEqual("TEST_FINGERPRINT");
69+
});
70+
});
71+
72+
describe("fingerprint name", function() {
73+
beforeEach(function() {
74+
spyOn(fs, "existsSync").and.returnValue(true);
75+
spyOn(fs, "readFileSync").and.returnValue("TEST_FINGERPRINT");
76+
});
77+
78+
it("should validate for duplicate name.", function () {
79+
var dir = 'config/initializers';
80+
fingerprint = function() { new AssetFingerprint(dir, true, "TEST_FINGERPRINT"); }
81+
expect(fingerprint).toThrowError('The provided fingerprint name has already been used.');
82+
});
83+
84+
it("should validate the file name characters.", function() {
85+
var dir = 'config/initializers';
86+
fingerprint = function() { new AssetFingerprint(dir, true, "asset_FINGERPRINT"); }
87+
expect(fingerprint).toThrowError('Please supply a fingerprint name that is all caps separating words by underscores (i.e. CUSTOM_ASSET_FINGERPRINT).');
88+
});
89+
90+
it("should validate the file name format.", function() {
91+
var dir = 'config/initializers';
92+
fingerprint = function() { new AssetFingerprint(dir, true, "BAD_VALUE"); }
93+
expect(fingerprint).toThrowError('Please supply a fingerprint name that is all caps separating words by underscores (i.e. CUSTOM_ASSET_FINGERPRINT).');
94+
});
95+
});
96+
97+
describe("fingerprint name", function() {
98+
beforeEach(function() {
99+
spyOn(fs, "existsSync").and.returnValue(true);
100+
spyOn(fs, "readFileSync").and.returnValue("ASSET_FINGERPRINT");
101+
});
102+
103+
it("should not validate for duplicate name with default arguments.", function () {
104+
var dir = 'config/initializers';
105+
fingerprint = new AssetFingerprint(dir);
106+
expect(fingerprint.fingerprintName).toEqual("ASSET_FINGERPRINT");
107+
});
108+
});
109+
110+
describe("fingerprint name", function() {
111+
beforeEach(function() {
112+
spyOn(fs, "existsSync").and.returnValue(false);
113+
spyOn(fs, "readFileSync").and.returnValue("");
114+
});
115+
116+
it("should not validate when file does not exist.", function () {
117+
var dir = 'config/initializers';
118+
fingerprint = new AssetFingerprint(dir, true, "TEST_FINGERPRINT");
119+
expect(fingerprint.fingerprintName).toEqual("TEST_FINGERPRINT");
53120
});
54121
});
55122

56123
describe("apply", function() {
57124
beforeEach(function() {
58125
spyOn(fs, "writeFileSync");
59126
spyOn(fs, "appendFileSync");
127+
spyOn(fs, "existsSync").and.returnValue(false);
128+
spyOn(fs, "readFileSync").and.returnValue("");
60129
spyOn(console, "log");
61130
});
62131

@@ -76,16 +145,16 @@ describe("AssetFingerprint", function() {
76145

77146
it("should call appendFileSync on provided fingerprint name argument", function() {
78147
var dir = 'config/initializers';
79-
fingerprint = new AssetFingerprint(dir, true, "FINGERPRINT_VALUE");
148+
fingerprint = new AssetFingerprint(dir, true, "TEST_FINGERPRINT");
80149
fingerprint.apply({
81150
plugin: function(status, callback) { callback({hash: "Z1Y2X3W4"}) }
82151
});
83152

84153
expect(fs.appendFileSync).toHaveBeenCalledWith(
85-
'config/initializers/asset_fingerprint.rb', "\r\nFINGERPRINT_VALUE = 'Z1Y2X3W4'");
154+
'config/initializers/asset_fingerprint.rb', "\r\nTEST_FINGERPRINT = 'Z1Y2X3W4'");
86155

87156
expect(console.log).toHaveBeenCalledWith(
88-
"asset-fingerprint-webpack-rails: updated file config/initializers/asset_fingerprint.rb with FINGERPRINT_VALUE = Z1Y2X3W4");
157+
"asset-fingerprint-webpack-rails: updated file config/initializers/asset_fingerprint.rb with TEST_FINGERPRINT = Z1Y2X3W4");
89158
});
90159
});
91160
});

0 commit comments

Comments
 (0)