UNPKG

13.1 kBJavaScriptView Raw
1var assert = require ('assert');
2var web_logic = require ('../lib/webapp/logic.js');
3var path = require ('path');
4var fs = require('fs');
5
6function getResponseForSendFile (expectedFileContains, done){
7 var res = {
8 type: function (data){
9 assert.equal("application/javascript", data);
10 },
11
12 sendfile: function (file){
13 assert.ok(file.indexOf(expectedFileContains)>-1);
14 done();
15 },
16
17 write: function (data){
18 done("not expected");
19 },
20
21 end: function (data){
22 done("not expected");
23 }
24 };
25
26 return res;
27}
28
29function getResponseForSendStatusCode (statusCode, done){
30 var res = {
31 type: function (data){
32
33 },
34
35 sendfile: function (file){
36 done('not expected');
37 },
38
39 write: function (data){
40 done("not expected");
41 },
42
43 end: function (data){
44 done("not expected");
45 },
46 send: function (status, data){
47 assert.equal(statusCode, status);
48 done();
49 }
50 };
51 return res;
52}
53
54function getResponseWriteEnd (contains, mime, done){
55 var bundle_file = "";
56 var res = {
57 type: function (data){
58 if (mime){
59 assert.equal(mime, data);
60 }
61 },
62
63 sendfile: function (file){
64 done("not expected");
65 },
66
67 write: function (data){
68 bundle_file+=data;
69 },
70
71 end: function (data){
72 if (contains){
73 if (!Array.isArray(contains)){
74 contains = [contains];
75 }
76 contains.forEach(function(match){
77 assert.ok(bundle_file.indexOf(match) > -1);
78 });
79 }
80 done();
81 }
82 };
83 return res;
84}
85
86function getResponseWriteBasic() {
87 var res = {
88 written: '',
89 write: function (data) {
90 res.written += data;
91 }
92 };
93 return res;
94}
95
96describe ('web_server', function(){
97
98 var wallboard_assets_folder = path.join(process.cwd(), "/test/fixtures/assets_folder");
99 var packagesLocalFolder = path.join(process.cwd(), "/test/fixtures/packages");
100 var packagesAtlasboardFolder = path.join(process.cwd(), "/packages");
101 var packagesWithInvalidDashboardFile = path.join(process.cwd(), "/test/fixtures/package_invalid_format");
102 var packageWithJustOneDashboard = path.join(process.cwd(), "/test/fixtures/package_with_one_dashboard");
103
104 describe ('dashboards', function(){
105
106 it('get all', function(done){
107 var res = {
108 render: function (template, data){
109 assert.equal(4, data.dashboards.length);
110 done();
111 }
112 };
113
114 web_logic.listAllDashboards([packagesLocalFolder, packagesAtlasboardFolder], {}, res);
115 });
116
117 it('redirects to dashboard page if we only have one', function(done){
118 var res = {
119 redirect: function (data){
120 assert.equal(data, "/mydashboard");
121 done();
122 },
123 render: function (template, data){
124 done("Not expected");
125 }
126 };
127
128 web_logic.listAllDashboards([packageWithJustOneDashboard], {}, res);
129 });
130
131 it('render one', function(done){
132 var res = {
133 render: function (template, data){
134 assert.ok(data.dashboardName);
135 assert.ok(data.dashboardConfig);
136 done();
137 },
138
139 send: function (data){
140 done("Not expected");
141 }
142 };
143
144 web_logic.renderDashboard([packagesLocalFolder, packagesAtlasboardFolder], "test_dashboard1", {}, res);
145 });
146
147
148 it('returns 404 if there is a dashboard with an invalid format', function(done){
149 web_logic.renderDashboard([packagesLocalFolder, packagesAtlasboardFolder, packagesWithInvalidDashboardFile], "invalid_json_file",
150 {}, getResponseForSendStatusCode(404, done));
151 });
152
153
154 it('render one - ignore path prefix - prevent path traversal issues', function(done){
155 var res = {
156 render: function (template, data){
157 assert.ok(data.dashboardName);
158 assert.ok(data.dashboardConfig);
159 done();
160 },
161
162 send: function (data){
163 done("Not expected");
164 }
165 };
166
167 web_logic.renderDashboard([packagesLocalFolder, packagesAtlasboardFolder], "../test_dashboard1", {}, res);
168 });
169
170 it('return 404 if dashboard not found', function(done){
171 web_logic.renderDashboard([packagesLocalFolder, packagesAtlasboardFolder], "tttest_dashboard1",
172 {}, getResponseForSendStatusCode(404, done));
173 });
174
175 });
176
177
178 describe ('javascript assets', function(){
179
180 describe ('for dashboard', function(){
181
182 it('return javascript assets for a certain dashboard', function(done){
183 web_logic.renderJsDashboard([packagesLocalFolder, packagesAtlasboardFolder], wallboard_assets_folder,
184 "test_dashboard1", {}, getResponseWriteEnd("Peity", "application/javascript", done));
185 });
186
187 it('returns error when requesting javascript assets for a dashboard that doesn\'t exist', function(done){
188 web_logic.renderJsDashboard([packagesLocalFolder, packagesAtlasboardFolder], wallboard_assets_folder,
189 "tttttest_dashboard1", {}, getResponseForSendStatusCode(404, done));
190 });
191
192 it('returns error when requesting javascript assets for a dashboard with incorrect format', function(done){
193 web_logic.renderJsDashboard([packagesWithInvalidDashboardFile], wallboard_assets_folder,
194 "invalid_json_file", {}, getResponseForSendStatusCode(404, done));
195 });
196
197 it('handles request when requesting javascript assets for a dashboard with no customJS field', function(done){
198 web_logic.renderJsDashboard([packagesLocalFolder, packagesAtlasboardFolder], wallboard_assets_folder,
199 "test_dashboard2", {}, getResponseForSendStatusCode(200, done));
200 });
201
202 it('handles when requesting javascript assets and file is not found', function(done){
203 web_logic.renderJsDashboard([packagesLocalFolder, packagesAtlasboardFolder], wallboard_assets_folder,
204 "other_test_dashboard1", {}, getResponseWriteEnd(null, "application/javascript", done));
205 });
206
207
208 it('return javascript assets for a certain widget', function(done){
209 web_logic.renderJsWidget([packagesLocalFolder, packagesAtlasboardFolder], "blockers", {},
210 getResponseForSendFile("widgets/blockers/blockers.js", done));
211 });
212
213
214 it('ignore path prefix - prevent path traversal issues', function(done){
215 web_logic.renderJsWidget([packagesLocalFolder, packagesAtlasboardFolder], "../../blockers", {},
216 getResponseForSendFile("widgets/blockers/blockers.js", done));
217 });
218 });
219 });
220
221
222 describe ('widget', function(){
223
224 //todo: improve this tests
225 it('return html and css', function(done){
226 web_logic.renderHtmlWidget([packagesLocalFolder, packagesAtlasboardFolder], "blockers",
227 {}, getResponseWriteEnd(["body", "<style>"], "text/html", done));
228 });
229
230 it('ignore path prefix - prevent path traversal issues', function(done){
231 web_logic.renderHtmlWidget([packagesLocalFolder, packagesAtlasboardFolder], "../../blockers",
232 {}, getResponseWriteEnd(["body", "<style>"], "text/html", done));
233 });
234
235
236 it('return error 404 if widget not found', function(done){
237 web_logic.renderHtmlWidget([packagesLocalFolder, packagesAtlasboardFolder], "bbblockers",
238 {}, getResponseForSendStatusCode(404, done));
239 });
240
241 });
242
243 describe ('widget resources', function(){
244
245 var localPackagesPath = path.join(process.cwd(),'test', 'fixtures', 'packages');
246
247 it('should return 400 if resource input is undefined', function(done){
248 web_logic.renderWidgetResource(localPackagesPath, undefined,
249 {}, getResponseForSendStatusCode(400, done));
250 });
251
252 it('should return 400 if resource input is empty', function(done){
253 web_logic.renderWidgetResource(localPackagesPath, '/',
254 {}, getResponseForSendStatusCode(400, done));
255 });
256
257 it('should return 400 if resource contains more than 3 separators', function(done){
258 web_logic.renderWidgetResource(localPackagesPath, 'package/widget/other/resource',
259 {}, getResponseForSendStatusCode(400, done));
260 });
261
262 it('should return 400 if resource contains less than 3 separators', function(done){
263 web_logic.renderWidgetResource(localPackagesPath, 'package/resource',
264 {}, getResponseForSendStatusCode(400, done));
265 });
266
267 it('should return resource if path is correct', function(done){
268 web_logic.renderWidgetResource(localPackagesPath, 'otherpackage1/blockers/resource.txt',
269 {}, getResponseForSendFile('resource.txt', done));
270 });
271
272 });
273
274 describe ('css namespacing', function(){
275
276 var localCssPath = path.join(process.cwd(), 'test', 'fixtures', 'css');
277
278 function getCss(filename) {
279 return fs.readFileSync(path.join(localCssPath, filename));
280 }
281
282 function assertContains(source, match, msg) {
283 return assert.ok(source.indexOf(match) > -1, msg);
284 }
285
286 function assertNotContains(source, match, msg) {
287 return assert.ok(source.indexOf(match) === -1, msg);
288 }
289
290 it('should namespace CSS selectors', function(){
291 var res = getResponseWriteBasic();
292 var css = getCss('basic.css');
293 web_logic._addNamespace(css, res, 'test-namespace');
294 assertContains(res.written, 'li[data-widget-id="test-namespace"] #id {', '#id');
295 assertContains(res.written, 'li[data-widget-id="test-namespace"] tag {', 'tag');
296 assertContains(res.written, 'li[data-widget-id="test-namespace"] #multiple .things {', 'multiple identifiers');
297 assertContains(res.written, 'li[data-widget-id="test-namespace"] .comma,', 'comma-separated rules (1)');
298 assertContains(res.written, 'li[data-widget-id="test-namespace"] .separated {', 'comma-separated rules (2)');
299 });
300
301 it('should handle basic media queries', function(){
302 var res = getResponseWriteBasic();
303 var css = getCss('media.css');
304 web_logic._addNamespace(css, res, 'test-namespace');
305 assertContains(res.written, 'li[data-widget-id="test-namespace"] .normal {', 'outside the media query');
306 assertContains(res.written, '@media print {', 'media query definition is unchanged');
307 assertNotContains(res.written, 'li[data-widget-id="test-namespace"] @media print {', 'media query definition is not namespaced');
308 assertContains(res.written, 'li[data-widget-id="test-namespace"] .simple {', 'inside the media query');
309 });
310
311 it('should handle complex media queries', function(){
312 var res = getResponseWriteBasic();
313 var css = getCss('media.css');
314 web_logic._addNamespace(css, res, 'test-namespace');
315 assertContains(res.written, '@media (-webkit-max-device-pixel-ratio: 1.5), (max-device-pixel-ratio: 1.5) {', 'media query definition is unchanged');
316 assertNotContains(res.written, 'li[data-widget-id="test-namespace"] @media (-webkit-max-device-pixel-ratio: 1.5), (max-device-pixel-ratio: 1.5) {', 'media query definition is not namespaced');
317 assertContains(res.written, 'li[data-widget-id="test-namespace"] .complex {', 'inside the media query');
318 });
319
320 it('should handle comments', function(){
321 var res = getResponseWriteBasic();
322 var css = getCss('comments.css');
323 web_logic._addNamespace(css, res, 'test-namespace');
324 assertContains(res.written, 'li[data-widget-id="test-namespace"] .before {', 'before a comment');
325 assertContains(res.written, 'li[data-widget-id="test-namespace"] .after {', 'after a comment');
326 assertContains(res.written, 'li[data-widget-id="test-namespace"] .contains {', 'containing a comment');
327 });
328
329 it('should handle keyframes', function(){
330 var res = getResponseWriteBasic();
331 var css = getCss('keyframes.css');
332 web_logic._addNamespace(css, res, 'test-namespace');
333 assertContains(res.written, '@keyframes standards {', 'standard syntax is valid');
334 assertNotContains(res.written, 'li[data-widget-id="test-namespace"] @keyframes vendor-prefixed {', 'standard syntax is not namespaced');
335 assertContains(res.written, '@-webkit-keyframes vendor-prefix {', 'vendor-prefixed syntax is valid');
336 assertNotContains(res.written, 'li[data-widget-id="test-namespace"] @-webkit-keyframes vendor-prefix {', 'vendor-prefixed syntax is not namespaced');
337 assertContains(res.written, '0% {\n width: 1px;\n }', 'keep frames untouched');
338 });
339
340 it('should handle font declarations', function(){
341 var res = getResponseWriteBasic();
342 var css = getCss('font-face.css');
343 web_logic._addNamespace(css, res, 'test-namespace');
344 assertContains(res.written, '@font-face {', 'is valid');
345 assertNotContains(res.written, 'li[data-widget-id="test-namespace"] @font-face {', 'not namespaced');
346 });
347
348 });
349
350});
\No newline at end of file