powerbi-visuals-tools 4.0.4 → 4.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Changelog.md +8 -0
- package/certs/PowerBICustomVisualTest_private.key +28 -0
- package/certs/PowerBICustomVisualTest_public.crt +19 -0
- package/config.json +35 -1
- package/lib/VisualGenerator.js +0 -95
- package/package.json +3 -3
- package/spec/.jshintrc +5 -0
- package/spec/clean-tests.js +31 -0
- package/spec/e2e/pbivizCertSpec.js +56 -0
- package/spec/e2e/pbivizInfoSpec.js +82 -0
- package/spec/e2e/pbivizNewSpec.js +265 -0
- package/spec/e2e/pbivizPackageSpec.js +670 -0
- package/spec/e2e/pbivizStartSpec.js +380 -0
- package/spec/e2e/pbivizWebpackVerSpec.js +102 -0
- package/spec/e2e/utils.js +63 -0
- package/spec/helpers/FileSystem.js +173 -0
- package/spec/jasmine-runner.js +36 -0
- package/spec/support/jasmine.json +11 -0
- package/templates/visuals/default/capabilities.json +2 -7
- package/templates/visuals/default/package.json +2 -2
- package/templates/visuals/default/pbiviz.json +1 -1
- package/templates/visuals/default/src/settings.ts +54 -3
- package/templates/visuals/default/src/visual.ts +14 -17
- package/templates/visuals/rhtml/capabilities.json +2 -1
- package/templates/visuals/rhtml/package.json +2 -2
- package/templates/visuals/rhtml/pbiviz.json +1 -1
- package/templates/visuals/rhtml/src/settings.ts +28 -3
- package/templates/visuals/rhtml/src/visual.ts +29 -23
- package/templates/visuals/rvisual/capabilities.json +2 -1
- package/templates/visuals/rvisual/package.json +2 -2
- package/templates/visuals/rvisual/pbiviz.json +1 -1
- package/templates/visuals/rvisual/src/settings.ts +28 -3
- package/templates/visuals/rvisual/src/visual.ts +13 -15
- package/templates/visuals/slicer/capabilities.json +2 -1
- package/templates/visuals/slicer/package.json +2 -2
- package/templates/visuals/slicer/pbiviz.json +1 -1
- package/templates/visuals/slicer/src/settings.ts +29 -3
- package/templates/visuals/slicer/src/visual.ts +14 -17
- package/templates/visuals/table/capabilities.json +2 -1
- package/templates/visuals/table/package.json +2 -2
- package/templates/visuals/table/pbiviz.json +1 -1
- package/templates/visuals/table/src/settings.ts +23 -3
- package/templates/visuals/table/src/visual.ts +18 -16
- package/.eslintrc.json +0 -313
- package/.gitattributes +0 -4
- package/.github/workflows/build.yml +0 -32
- package/.github/workflows/codeql-analysis.yml +0 -54
- package/.snyk +0 -4
- package/.vscode/launch.json +0 -74
- package/.vscode/settings.json +0 -3
|
@@ -0,0 +1,670 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Power BI Visual CLI
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) Microsoft Corporation
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
* MIT License
|
|
7
|
+
*
|
|
8
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
* of this software and associated documentation files (the ""Software""), to deal
|
|
10
|
+
* in the Software without restriction, including without limitation the rights
|
|
11
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
* furnished to do so, subject to the following conditions:
|
|
14
|
+
*
|
|
15
|
+
* The above copyright notice and this permission notice shall be included in
|
|
16
|
+
* all copies or substantial portions of the Software.
|
|
17
|
+
*
|
|
18
|
+
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
24
|
+
* THE SOFTWARE.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
"use strict";
|
|
28
|
+
|
|
29
|
+
const fs = require('fs-extra');
|
|
30
|
+
const path = require('path');
|
|
31
|
+
const async = require('async');
|
|
32
|
+
const JSZip = require('jszip');
|
|
33
|
+
const lodashIsEqual = require('lodash.isequal');
|
|
34
|
+
|
|
35
|
+
const FileSystem = require('../helpers/FileSystem.js');
|
|
36
|
+
const writeMetadata = require("./utils").writeMetadata;
|
|
37
|
+
|
|
38
|
+
const tempPath = FileSystem.getTempPath();
|
|
39
|
+
const startPath = process.cwd();
|
|
40
|
+
|
|
41
|
+
describe("E2E - pbiviz package", () => {
|
|
42
|
+
|
|
43
|
+
let visualName = 'visualname';
|
|
44
|
+
let visualPath = path.join(tempPath, visualName);
|
|
45
|
+
let visualPbiviz = {};
|
|
46
|
+
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
FileSystem.resetTempDirectory();
|
|
49
|
+
process.chdir(tempPath);
|
|
50
|
+
FileSystem.runPbiviz('new', visualName);
|
|
51
|
+
process.chdir(visualPath);
|
|
52
|
+
FileSystem.runCMDCommand('npm i', visualPath);
|
|
53
|
+
|
|
54
|
+
writeMetadata(visualPath);
|
|
55
|
+
|
|
56
|
+
visualPbiviz = JSON.parse(fs.readFileSync(path.join(visualPath, 'pbiviz.json'), { encoding: "utf8" }));
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
afterEach(() => {
|
|
60
|
+
process.chdir(startPath);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
afterAll(() => {
|
|
64
|
+
process.chdir(startPath);
|
|
65
|
+
FileSystem.deleteTempDirectory();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("Should throw error if not in the visual root", () => {
|
|
69
|
+
let error;
|
|
70
|
+
process.chdir(tempPath);
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
FileSystem.runPbiviz('package');
|
|
74
|
+
} catch (e) {
|
|
75
|
+
error = e;
|
|
76
|
+
}
|
|
77
|
+
expect(error).toBeDefined();
|
|
78
|
+
expect(error.status).toBe(1);
|
|
79
|
+
expect(error.message).toContain("Error: pbiviz.json not found. You must be in the root of a visual project to run this command");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("Should throw error if there is nothing to produce", () => {
|
|
83
|
+
let error;
|
|
84
|
+
process.chdir(tempPath);
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
FileSystem.runPbiviz('package', '--no-pbiviz');
|
|
88
|
+
} catch (e) {
|
|
89
|
+
error = e;
|
|
90
|
+
}
|
|
91
|
+
expect(error).toBeDefined();
|
|
92
|
+
expect(error.status).toBe(1);
|
|
93
|
+
expect(error.message).toContain("Nothing to build. Cannot use --no-pbiviz without --resources");
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it("Should create a pbiviz file and no resources folder with no flags", () => {
|
|
97
|
+
FileSystem.runPbiviz('package');
|
|
98
|
+
|
|
99
|
+
let pbivizPath = path.join(visualPath, 'dist', visualPbiviz.visual.guid + "." + visualPbiviz.visual.version + '.pbiviz');
|
|
100
|
+
let resourcesPath = path.join(visualPath, 'dist', 'resources');
|
|
101
|
+
|
|
102
|
+
let resourcesError;
|
|
103
|
+
try {
|
|
104
|
+
fs.accessSync(resourcesPath);
|
|
105
|
+
} catch (e) {
|
|
106
|
+
resourcesError = e;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
expect(resourcesError).toBeDefined();
|
|
110
|
+
expect(resourcesError.code).toBe('ENOENT');
|
|
111
|
+
expect(fs.statSync(pbivizPath).isFile()).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("Should create a pbiviz file and resource folder with --resources flag", () => {
|
|
115
|
+
FileSystem.runPbiviz('package', false, '--resources');
|
|
116
|
+
|
|
117
|
+
let pbivizPath = path.join(visualPath, 'dist', visualPbiviz.visual.guid + "." + visualPbiviz.visual.version + '.pbiviz');
|
|
118
|
+
let resourcesPath = path.join(visualPath, 'dist', 'resources');
|
|
119
|
+
|
|
120
|
+
expect(fs.statSync(pbivizPath).isFile()).toBe(true);
|
|
121
|
+
expect(fs.statSync(resourcesPath).isDirectory()).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it("Should not create pbiviz file with --no-pbiviz flag", () => {
|
|
125
|
+
FileSystem.runPbiviz('package', false, '--no-pbiviz --resources');
|
|
126
|
+
|
|
127
|
+
let pbivizPath = path.join(visualPath, 'dist', visualPbiviz.visual.guid + "." + visualPbiviz.visual.version + '.pbiviz');
|
|
128
|
+
let resourcesPath = path.join(visualPath, 'dist', 'resources');
|
|
129
|
+
|
|
130
|
+
let pbivizError;
|
|
131
|
+
try {
|
|
132
|
+
fs.accessSync(pbivizPath);
|
|
133
|
+
} catch (e) {
|
|
134
|
+
pbivizError = e;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
expect(pbivizError).toBeDefined();
|
|
138
|
+
expect(pbivizError.code).toBe('ENOENT');
|
|
139
|
+
expect(fs.statSync(resourcesPath).isDirectory()).toBe(true);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("Should correctly generate pbiviz file", (done) => {
|
|
143
|
+
FileSystem.runPbiviz('package');
|
|
144
|
+
|
|
145
|
+
let visualConfig = fs.readJsonSync(path.join(visualPath, 'pbiviz.json')).visual;
|
|
146
|
+
let visualCapabilities = fs.readJsonSync(path.join(visualPath, 'capabilities.json'));
|
|
147
|
+
let pbivizPath = path.join(visualPath, 'dist', visualPbiviz.visual.guid + "." + visualPbiviz.visual.version + '.pbiviz');
|
|
148
|
+
let pbivizResourcePath = `resources/${visualConfig.guid}.pbiviz.json`;
|
|
149
|
+
|
|
150
|
+
let zipContents = fs.readFileSync(pbivizPath);
|
|
151
|
+
let jszip = new JSZip();
|
|
152
|
+
jszip.loadAsync(zipContents)
|
|
153
|
+
.then((zip) => {
|
|
154
|
+
async.parallel([
|
|
155
|
+
//check package.json
|
|
156
|
+
(next) => {
|
|
157
|
+
zip.file('package.json').async('string')
|
|
158
|
+
.then((content) => {
|
|
159
|
+
let data = JSON.parse(content);
|
|
160
|
+
expect(data.resources.length).toBe(1);
|
|
161
|
+
expect(data.resources[0].file).toBe(pbivizResourcePath);
|
|
162
|
+
expect(data.visual).toEqual(visualConfig);
|
|
163
|
+
next();
|
|
164
|
+
})
|
|
165
|
+
.catch(next);
|
|
166
|
+
},
|
|
167
|
+
//check pbiviz
|
|
168
|
+
(next) => {
|
|
169
|
+
zip.file(pbivizResourcePath).async('string')
|
|
170
|
+
.then((content) => {
|
|
171
|
+
let data = JSON.parse(content);
|
|
172
|
+
expect(data.visual).toEqual(visualConfig);
|
|
173
|
+
expect(data.capabilities).toEqual(visualCapabilities);
|
|
174
|
+
expect(data.content.js).toBeDefined();
|
|
175
|
+
expect(data.content.js.length).toBeGreaterThan(0);
|
|
176
|
+
expect(data.content.css).toBeDefined();
|
|
177
|
+
expect(data.content.iconBase64).toBeDefined();
|
|
178
|
+
expect(data.content.iconBase64.length).toBeGreaterThan(0);
|
|
179
|
+
next();
|
|
180
|
+
})
|
|
181
|
+
.catch(next);
|
|
182
|
+
}
|
|
183
|
+
], error => {
|
|
184
|
+
if (error) { throw error; }
|
|
185
|
+
done();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("Should correctly generate resources folder", () => {
|
|
192
|
+
FileSystem.runPbiviz('package', false, '--no-pbiviz --resources');
|
|
193
|
+
|
|
194
|
+
let visualConfig = fs.readJsonSync(path.join(visualPath, 'pbiviz.json')).visual;
|
|
195
|
+
let visualCapabilities = fs.readJsonSync(path.join(visualPath, 'capabilities.json'));
|
|
196
|
+
let resourcesPath = path.join(visualPath, 'dist', 'resources');
|
|
197
|
+
let pbivizPath = path.join(resourcesPath, visualPbiviz.visual.guid + '.pbiviz.json');
|
|
198
|
+
|
|
199
|
+
expect(fs.statSync(resourcesPath).isDirectory()).toBe(true);
|
|
200
|
+
expect(fs.statSync(path.join(resourcesPath, 'visual.prod.js')).isFile()).toBe(true);
|
|
201
|
+
expect(fs.statSync(path.join(resourcesPath, 'visual.prod.css')).isFile()).toBe(true);
|
|
202
|
+
expect(fs.statSync(pbivizPath).isFile()).toBe(true);
|
|
203
|
+
|
|
204
|
+
let pbiviz = fs.readJsonSync(pbivizPath);
|
|
205
|
+
expect(pbiviz.visual).toEqual(visualConfig);
|
|
206
|
+
expect(pbiviz.capabilities).toEqual(visualCapabilities);
|
|
207
|
+
expect(pbiviz.content.js).toBeDefined();
|
|
208
|
+
expect(pbiviz.content.css).toBeDefined();
|
|
209
|
+
expect(pbiviz.content.iconBase64).toBeDefined();
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// tets can't check the minification, because in input the plugin gets minified version,
|
|
213
|
+
// plugin can't create two version js file for compare
|
|
214
|
+
xit("Should minify assets by default", () => {
|
|
215
|
+
FileSystem.runPbiviz('package', false, '--resources --no-pbiviz');
|
|
216
|
+
|
|
217
|
+
let js = fs.statSync(path.join(visualPath, 'dist', 'resources', 'visual.js'));
|
|
218
|
+
|
|
219
|
+
let prodJs = fs.statSync(path.join(visualPath, 'dist', 'resources', 'visual.prod.js'));
|
|
220
|
+
|
|
221
|
+
expect(js.size).toBeGreaterThan(prodJs.size);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it("Should skip minification with --no-minify flag", () => {
|
|
225
|
+
FileSystem.runPbiviz('package', false, '--resources --no-pbiviz --no-minify');
|
|
226
|
+
|
|
227
|
+
let js = fs.statSync(path.join(visualPath, 'dist', 'resources', 'visual.js'));
|
|
228
|
+
|
|
229
|
+
let prodJs = fs.statSync(path.join(visualPath, 'dist', 'resources', 'visual.prod.js'));
|
|
230
|
+
|
|
231
|
+
expect(js.size).toBe(prodJs.size);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it("Should set all versions in metadata equal", (done) => {
|
|
235
|
+
let visualVersion = "1.2.3";
|
|
236
|
+
|
|
237
|
+
let pbivizJsonPath = path.join(visualPath, 'pbiviz.json');
|
|
238
|
+
let pbiviz = fs.readJsonSync(pbivizJsonPath);
|
|
239
|
+
pbiviz.visual.version = visualVersion;
|
|
240
|
+
fs.writeFileSync(pbivizJsonPath, JSON.stringify(pbiviz));
|
|
241
|
+
FileSystem.runCMDCommand('npm i', visualPath);
|
|
242
|
+
FileSystem.runPbiviz('package');
|
|
243
|
+
|
|
244
|
+
let visualConfig = fs.readJsonSync(path.join(visualPath, 'pbiviz.json')).visual;
|
|
245
|
+
let pbivizPath = path.join(visualPath, 'dist', visualPbiviz.visual.guid + "." + pbiviz.visual.version + '.pbiviz');
|
|
246
|
+
let pbivizResourcePath = `resources/${visualConfig.guid}.pbiviz.json`;
|
|
247
|
+
|
|
248
|
+
let zipContents = fs.readFileSync(pbivizPath);
|
|
249
|
+
let jszip = new JSZip();
|
|
250
|
+
jszip.loadAsync(zipContents)
|
|
251
|
+
.then((zip) => {
|
|
252
|
+
async.parallel([
|
|
253
|
+
//check package.json
|
|
254
|
+
next => {
|
|
255
|
+
zip.file('package.json').async('string')
|
|
256
|
+
.then((content) => {
|
|
257
|
+
let data = JSON.parse(content);
|
|
258
|
+
expect(data.visual.version).toEqual(visualVersion);
|
|
259
|
+
expect(data.version).toEqual(visualVersion);
|
|
260
|
+
next();
|
|
261
|
+
})
|
|
262
|
+
.catch(next);
|
|
263
|
+
},
|
|
264
|
+
//check pbiviz
|
|
265
|
+
next => {
|
|
266
|
+
zip.file(pbivizResourcePath).async('string')
|
|
267
|
+
.then((content) => {
|
|
268
|
+
let data = JSON.parse(content);
|
|
269
|
+
expect(data.visual.version).toEqual(visualVersion);
|
|
270
|
+
next();
|
|
271
|
+
})
|
|
272
|
+
.catch(next);
|
|
273
|
+
}
|
|
274
|
+
], error => {
|
|
275
|
+
if (error) { throw error; }
|
|
276
|
+
done();
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it("Should correctly generate pbiviz file with stringResources localization", (done) => {
|
|
283
|
+
const resourceStringLocalization =
|
|
284
|
+
{
|
|
285
|
+
"locale": "ru-RU",
|
|
286
|
+
"values": {
|
|
287
|
+
"formattingGeneral": "Общие настройки",
|
|
288
|
+
"formattingGeneralOrientation": "Ориентация",
|
|
289
|
+
"formattingGeneralOrientationVertical": "Вертикальная"
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
const validStringResources =
|
|
293
|
+
{
|
|
294
|
+
"ru-RU": {
|
|
295
|
+
"formattingGeneral": "Общие настройки",
|
|
296
|
+
"formattingGeneralOrientation": "Ориентация",
|
|
297
|
+
"formattingGeneralOrientationVertical": "Вертикальная"
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
mkDirPromise('stringResources')
|
|
302
|
+
.then(() => writeJsonPromise('stringResources/ru-RU.json', resourceStringLocalization))
|
|
303
|
+
.then(() =>
|
|
304
|
+
readJsonPromise('pbiviz.json')
|
|
305
|
+
)
|
|
306
|
+
.then((pbivizJson) => {
|
|
307
|
+
pbivizJson.stringResources = ["stringResources/ru-RU.json"];
|
|
308
|
+
return writeJsonPromise('pbiviz.json', pbivizJson);
|
|
309
|
+
})
|
|
310
|
+
.then(() =>
|
|
311
|
+
FileSystem.runPbiviz('package', false, '--no-pbiviz --no-minify --resources')
|
|
312
|
+
)
|
|
313
|
+
.then(() =>
|
|
314
|
+
readJsonPromise(path.join(visualPath, 'dist', 'resources', visualPbiviz.visual.guid + '.pbiviz.json'))
|
|
315
|
+
)
|
|
316
|
+
.then((pbivizJson) => {
|
|
317
|
+
expect(lodashIsEqual(pbivizJson.stringResources, validStringResources)).toBeTruthy();
|
|
318
|
+
done();
|
|
319
|
+
})
|
|
320
|
+
.catch((err) => {
|
|
321
|
+
expect(err).toBe(null);
|
|
322
|
+
done();
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
it("Should correctly generate pbiviz file with RESJSON localization", (done) => {
|
|
327
|
+
const ResJsonEngLocalization =
|
|
328
|
+
{
|
|
329
|
+
"formattingGeneral": "General",
|
|
330
|
+
"formattingGeneralOrientation": "Orientation",
|
|
331
|
+
"formattingGeneralOrientationVertical": "Vertical"
|
|
332
|
+
};
|
|
333
|
+
const ResJsonRuLocalization =
|
|
334
|
+
{
|
|
335
|
+
"formattingGeneral": "Общие настройки",
|
|
336
|
+
"formattingGeneralOrientation": "Ориентация",
|
|
337
|
+
"formattingGeneralOrientationVertical": "Вертикальная"
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
const validStringResources =
|
|
341
|
+
{
|
|
342
|
+
"en-US": {
|
|
343
|
+
"formattingGeneral": "General",
|
|
344
|
+
"formattingGeneralOrientation": "Orientation",
|
|
345
|
+
"formattingGeneralOrientationVertical": "Vertical"
|
|
346
|
+
},
|
|
347
|
+
"ru-RU": {
|
|
348
|
+
"formattingGeneral": "Общие настройки",
|
|
349
|
+
"formattingGeneralOrientation": "Ориентация",
|
|
350
|
+
"formattingGeneralOrientationVertical": "Вертикальная"
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
mkDirPromise('stringResources')
|
|
354
|
+
.then(() =>
|
|
355
|
+
Promise.all([
|
|
356
|
+
mkDirPromise('stringResources/en-US')
|
|
357
|
+
.then(() => writeJsonPromise('stringResources/en-US/resources.resjson', ResJsonEngLocalization)),
|
|
358
|
+
mkDirPromise('stringResources/ru-RU')
|
|
359
|
+
.then(() => writeJsonPromise('stringResources/ru-RU/resources.resjson', ResJsonRuLocalization))
|
|
360
|
+
]))
|
|
361
|
+
.then(() =>
|
|
362
|
+
FileSystem.runPbiviz('package', false, '--no-pbiviz --no-minify --resources')
|
|
363
|
+
)
|
|
364
|
+
.then(() =>
|
|
365
|
+
readJsonPromise(path.join(visualPath, 'dist', 'resources', visualPbiviz.visual.guid + '.pbiviz.json'))
|
|
366
|
+
)
|
|
367
|
+
.then((pbivizJson) => {
|
|
368
|
+
expect(lodashIsEqual(pbivizJson.stringResources, validStringResources)).toBeTruthy();
|
|
369
|
+
done();
|
|
370
|
+
})
|
|
371
|
+
.catch((err) => {
|
|
372
|
+
expect(err).toBe(null);
|
|
373
|
+
done();
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
it("Should correctly generate pbiviz file with RESJSON and stringResources localizations", (done) => {
|
|
378
|
+
const resourceStringRuLocalization =
|
|
379
|
+
{
|
|
380
|
+
"locale": "ru-RU",
|
|
381
|
+
"values": {
|
|
382
|
+
"formattingGeneral": "Главные настройки",
|
|
383
|
+
"formattingGeneralOrientation": "Ориентация",
|
|
384
|
+
"formattingHeaderFontColor": "Цвет шрифта",
|
|
385
|
+
"formattingHeaderBackground": "Цвет фона"
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
|
|
389
|
+
const ResJsonEngLocalization =
|
|
390
|
+
{
|
|
391
|
+
"formattingGeneral": "General",
|
|
392
|
+
"formattingGeneralOrientation": "Orientation",
|
|
393
|
+
"formattingGeneralOrientationVertical": "Vertical"
|
|
394
|
+
};
|
|
395
|
+
const ResJsonRuLocalization =
|
|
396
|
+
{
|
|
397
|
+
"formattingGeneral": "Общие настройки",
|
|
398
|
+
"formattingGeneralOrientation": "Ориентация",
|
|
399
|
+
"formattingGeneralOrientationVertical": "Вертикальная"
|
|
400
|
+
};
|
|
401
|
+
|
|
402
|
+
const validStringResources =
|
|
403
|
+
{
|
|
404
|
+
"en-US": {
|
|
405
|
+
"formattingGeneral": "General",
|
|
406
|
+
"formattingGeneralOrientation": "Orientation",
|
|
407
|
+
"formattingGeneralOrientationVertical": "Vertical"
|
|
408
|
+
},
|
|
409
|
+
"ru-RU": {
|
|
410
|
+
"formattingGeneral": "Общие настройки",
|
|
411
|
+
"formattingGeneralOrientation": "Ориентация",
|
|
412
|
+
"formattingHeaderFontColor": "Цвет шрифта",
|
|
413
|
+
"formattingHeaderBackground": "Цвет фона",
|
|
414
|
+
"formattingGeneralOrientationVertical": "Вертикальная"
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
mkDirPromise('stringResources')
|
|
419
|
+
.then(() =>
|
|
420
|
+
Promise.all([
|
|
421
|
+
mkDirPromise('stringResources/en-US')
|
|
422
|
+
.then(() => writeJsonPromise('stringResources/en-US/resources.resjson', ResJsonEngLocalization)),
|
|
423
|
+
mkDirPromise('stringResources/ru-RU')
|
|
424
|
+
.then(() => writeJsonPromise('stringResources/ru-RU/resources.resjson', ResJsonRuLocalization)),
|
|
425
|
+
writeJsonPromise('stringResources/ru-RU.json', resourceStringRuLocalization)
|
|
426
|
+
]))
|
|
427
|
+
.then(() => readJsonPromise('pbiviz.json'))
|
|
428
|
+
.then((pbivizJson) => {
|
|
429
|
+
pbivizJson.stringResources = ["stringResources/ru-RU.json"];
|
|
430
|
+
return writeJsonPromise('pbiviz.json', pbivizJson);
|
|
431
|
+
})
|
|
432
|
+
.then(() =>
|
|
433
|
+
FileSystem.runPbiviz('package', false, '--no-pbiviz --no-minify --resources')
|
|
434
|
+
)
|
|
435
|
+
.then(() => readJsonPromise(path.join(visualPath, 'dist', 'resources', visualPbiviz.visual.guid + '.pbiviz.json')))
|
|
436
|
+
.then((pbivizJson) => {
|
|
437
|
+
expect(lodashIsEqual(pbivizJson.stringResources, validStringResources)).toBeTruthy();
|
|
438
|
+
done();
|
|
439
|
+
})
|
|
440
|
+
.catch((err) => {
|
|
441
|
+
expect(err).toBe(null);
|
|
442
|
+
done();
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
function mkDirPromise(path) {
|
|
449
|
+
return new Promise((resolve, reject) => fs.mkdir(path, (err) => {
|
|
450
|
+
if (err) {
|
|
451
|
+
reject(err);
|
|
452
|
+
} else {
|
|
453
|
+
resolve();
|
|
454
|
+
}
|
|
455
|
+
}));
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
function readJsonPromise(path) {
|
|
459
|
+
return new Promise((resolve, reject) => fs.readJSON(path, (err, jsonObject) => {
|
|
460
|
+
if (err) {
|
|
461
|
+
reject(err);
|
|
462
|
+
} else {
|
|
463
|
+
resolve(jsonObject);
|
|
464
|
+
}
|
|
465
|
+
}));
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function writeJsonPromise(path, jsonObject) {
|
|
469
|
+
return new Promise((resolve, reject) => fs.writeJSON(path, jsonObject, (err) => {
|
|
470
|
+
if (err) {
|
|
471
|
+
reject(err);
|
|
472
|
+
} else {
|
|
473
|
+
resolve();
|
|
474
|
+
}
|
|
475
|
+
}));
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function testMissingScript(fname) {
|
|
479
|
+
let error;
|
|
480
|
+
fs.unlinkSync(fname);
|
|
481
|
+
|
|
482
|
+
try {
|
|
483
|
+
FileSystem.runPbiviz('package');
|
|
484
|
+
} catch (e) {
|
|
485
|
+
error = e;
|
|
486
|
+
}
|
|
487
|
+
expect(error).toBeDefined();
|
|
488
|
+
expect(error.status).toBe(1);
|
|
489
|
+
expect(error.message).toContain("Failed updating visual capabilities");
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
function testErrorInDependencies() {
|
|
493
|
+
let error;
|
|
494
|
+
let invalidDependencies = [
|
|
495
|
+
{
|
|
496
|
+
invalidPropertyName: "ddd"
|
|
497
|
+
}
|
|
498
|
+
];
|
|
499
|
+
|
|
500
|
+
fs.writeFileSync('dependencies.json', JSON.stringify(invalidDependencies));
|
|
501
|
+
|
|
502
|
+
try {
|
|
503
|
+
FileSystem.runPbiviz('package');
|
|
504
|
+
} catch (e) {
|
|
505
|
+
error = e;
|
|
506
|
+
}
|
|
507
|
+
expect(error).toBeDefined();
|
|
508
|
+
expect(error.status).toBe(1);
|
|
509
|
+
expect(error.message).toContain("JSON dependencies.json : instance is not of a type(s) object");
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function testPbivizPackage(done, visualPath, visualName, scriptSourceDefault, removeDependencies) {
|
|
513
|
+
if (removeDependencies) {
|
|
514
|
+
fs.unlinkSync('dependencies.json');
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
FileSystem.runPbiviz('package');
|
|
518
|
+
|
|
519
|
+
let visualConfig = fs.readJsonSync(path.join(visualPath, 'pbiviz.json')).visual;
|
|
520
|
+
let visualCapabilities = fs.readJsonSync(path.join(visualPath, 'capabilities.json'));
|
|
521
|
+
let pbivizPath = path.join(visualPath, 'dist', visualName + '.pbiviz');
|
|
522
|
+
let pbivizResourcePath = `resources/${visualConfig.guid}.pbiviz.json`;
|
|
523
|
+
|
|
524
|
+
visualCapabilities.dataViewMappings[0].scriptResult.script.scriptSourceDefault = scriptSourceDefault;
|
|
525
|
+
|
|
526
|
+
let dependencies = '';
|
|
527
|
+
if (!removeDependencies) {
|
|
528
|
+
dependencies = fs.readJsonSync(path.join(visualPath, 'dependencies.json'));
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
let zipContents = fs.readFileSync(pbivizPath);
|
|
532
|
+
let jszip = new JSZip();
|
|
533
|
+
jszip.loadAsync(zipContents)
|
|
534
|
+
.then((zip) => {
|
|
535
|
+
async.parallel([
|
|
536
|
+
//check package.json
|
|
537
|
+
(next) => {
|
|
538
|
+
zip.file('package.json').async('string')
|
|
539
|
+
.then((content) => {
|
|
540
|
+
let data = JSON.parse(content);
|
|
541
|
+
expect(data.resources.length).toBe(1);
|
|
542
|
+
expect(data.resources[0].file).toBe(pbivizResourcePath);
|
|
543
|
+
expect(data.visual).toEqual(visualConfig);
|
|
544
|
+
next();
|
|
545
|
+
})
|
|
546
|
+
.catch(next);
|
|
547
|
+
},
|
|
548
|
+
//check pbiviz
|
|
549
|
+
(next) => {
|
|
550
|
+
zip.file(pbivizResourcePath).async('string')
|
|
551
|
+
.then((content) => {
|
|
552
|
+
let data = JSON.parse(content);
|
|
553
|
+
expect(data.visual).toEqual(visualConfig);
|
|
554
|
+
expect(data.capabilities).toEqual(visualCapabilities);
|
|
555
|
+
expect(data.content.js).toBeDefined();
|
|
556
|
+
expect(data.content.css).toBeDefined();
|
|
557
|
+
expect(data.content.iconBase64).toBeDefined();
|
|
558
|
+
if (!removeDependencies) {
|
|
559
|
+
expect(data.dependencies).toEqual(dependencies);
|
|
560
|
+
}
|
|
561
|
+
next();
|
|
562
|
+
})
|
|
563
|
+
.catch(next);
|
|
564
|
+
}
|
|
565
|
+
], error => {
|
|
566
|
+
if (error) { throw error; }
|
|
567
|
+
done();
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// new tools doesn't support R visuals build. coming soon
|
|
574
|
+
xdescribe("E2E - pbiviz package for R Visual template", () => {
|
|
575
|
+
|
|
576
|
+
let visualName = 'visualname';
|
|
577
|
+
let visualPath = path.join(tempPath, visualName);
|
|
578
|
+
|
|
579
|
+
beforeEach(() => {
|
|
580
|
+
FileSystem.resetTempDirectory();
|
|
581
|
+
process.chdir(tempPath);
|
|
582
|
+
FileSystem.runPbiviz('new', visualName, '--template rvisual');
|
|
583
|
+
process.chdir(visualPath);
|
|
584
|
+
FileSystem.runCMDCommand('npm i', visualPath);
|
|
585
|
+
});
|
|
586
|
+
|
|
587
|
+
afterEach(() => {
|
|
588
|
+
process.chdir(startPath);
|
|
589
|
+
});
|
|
590
|
+
|
|
591
|
+
afterAll(() => {
|
|
592
|
+
process.chdir(startPath);
|
|
593
|
+
FileSystem.deleteTempDirectory();
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
it("Should throw error if script.r file is missing", () => {
|
|
597
|
+
testMissingScript('script.r');
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
it("Should throw error if dependencies file is not valid", () => {
|
|
601
|
+
testErrorInDependencies();
|
|
602
|
+
});
|
|
603
|
+
|
|
604
|
+
it("Should correctly generate pbiviz file for R Visual template - no dependencies file", (done) => {
|
|
605
|
+
let scriptSourceDefault = fs.readFileSync(path.join(visualPath, 'script.r')).toString();
|
|
606
|
+
let removeDependencies = true;
|
|
607
|
+
testPbivizPackage(done, visualPath, visualName, scriptSourceDefault, removeDependencies);
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
it("Should correctly generate pbiviz file for R Visual template", (done) => {
|
|
611
|
+
let scriptSourceDefault = fs.readFileSync(path.join(visualPath, 'script.r')).toString();
|
|
612
|
+
let removeDependencies = false;
|
|
613
|
+
testPbivizPackage(done, visualPath, visualName, scriptSourceDefault, removeDependencies);
|
|
614
|
+
});
|
|
615
|
+
});
|
|
616
|
+
|
|
617
|
+
// new tools doesn't support R visuals build. coming soon
|
|
618
|
+
xdescribe("E2E - pbiviz package for R HTML template", () => {
|
|
619
|
+
|
|
620
|
+
let visualName = 'visualname';
|
|
621
|
+
let visualPath = path.join(tempPath, visualName);
|
|
622
|
+
|
|
623
|
+
function getScriptSourceDefault() {
|
|
624
|
+
let FlattenScriptContent = fs.readFileSync(path.join(visualPath, 'r_files/flatten_HTML.r')).toString();
|
|
625
|
+
let scriptContent = fs.readFileSync(path.join(visualPath, 'script.r')).toString();
|
|
626
|
+
let pattern = "source('./r_files/flatten_HTML.r')";
|
|
627
|
+
return scriptContent.replace(pattern, FlattenScriptContent);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
beforeEach(() => {
|
|
631
|
+
FileSystem.resetTempDirectory();
|
|
632
|
+
process.chdir(tempPath);
|
|
633
|
+
FileSystem.runPbiviz('new', visualName, '--template rhtml');
|
|
634
|
+
process.chdir(visualPath);
|
|
635
|
+
FileSystem.runCMDCommand('npm i', visualPath);
|
|
636
|
+
});
|
|
637
|
+
|
|
638
|
+
afterEach(() => {
|
|
639
|
+
process.chdir(startPath);
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
afterAll(() => {
|
|
643
|
+
process.chdir(startPath);
|
|
644
|
+
FileSystem.deleteTempDirectory();
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
it("Should throw error if script.r file is missing", () => {
|
|
648
|
+
testMissingScript('script.r');
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it("Should throw error if flatten_HTML.r file is missing", () => {
|
|
652
|
+
testMissingScript('r_files/flatten_HTML.r');
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
it("Should throw error if dependencies file is not valid", () => {
|
|
656
|
+
testErrorInDependencies();
|
|
657
|
+
});
|
|
658
|
+
|
|
659
|
+
it("Should correctly generate pbiviz file for R HTML template - no dependencies file", (done) => {
|
|
660
|
+
let scriptSourceDefault = getScriptSourceDefault();
|
|
661
|
+
let removeDependencies = true;
|
|
662
|
+
testPbivizPackage(done, visualPath, visualName, scriptSourceDefault, removeDependencies);
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
it("Should correctly generate pbiviz file for R HTML template", (done) => {
|
|
666
|
+
let scriptSourceDefault = getScriptSourceDefault();
|
|
667
|
+
let removeDependencies = false;
|
|
668
|
+
testPbivizPackage(done, visualPath, visualName, scriptSourceDefault, removeDependencies);
|
|
669
|
+
});
|
|
670
|
+
});
|