mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
fix tests
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
export function generateHTMLForArch(arch) {
|
||||
export async function generateHTMLForArch(arch) {
|
||||
// Use a dummy manifest. None of these paths will be read from the filesystem, but css / js should be handled differently
|
||||
const manifest = [
|
||||
{
|
||||
@@ -50,5 +50,29 @@ export function generateHTMLForArch(arch) {
|
||||
},
|
||||
});
|
||||
|
||||
return boilerplate.toHTML();
|
||||
|
||||
const { start, stream, end } = boilerplate.toHTML();
|
||||
|
||||
const body = await toString(stream);
|
||||
|
||||
return start + body + end;
|
||||
};
|
||||
|
||||
|
||||
function toString(stream) {
|
||||
return new Promise((success, fail) => {
|
||||
var string = ''
|
||||
stream.on('readable', function(buffer) {
|
||||
var part = buffer.read().toString();
|
||||
string += part;
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
success(string)
|
||||
});
|
||||
|
||||
stream.on('error', function(error) {
|
||||
fail(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2,62 +2,69 @@ import { parse, serialize } from 'parse5';
|
||||
|
||||
import { generateHTMLForArch } from './test-lib';
|
||||
|
||||
const html = generateHTMLForArch('web.browser');
|
||||
const start = async () => {
|
||||
const html = await generateHTMLForArch('web.browser');
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - well-formed html", function (test) {
|
||||
const formatted = serialize(parse(html));
|
||||
test.isTrue(formatted.replace(/\s/g, '') === html.replace(/\s/g, ''));
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - well-formed html", function (test) {
|
||||
const formatted = serialize(parse(html));
|
||||
test.isTrue(formatted.replace(/\s/g, '') === html.replace(/\s/g, ''));
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include htmlAttributes", function (test) {
|
||||
test.matches(html, /foo="foobar"/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include htmlAttributes", function (test) {
|
||||
test.matches(html, /foo="foobar"/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - escape htmlAttributes", function (test) {
|
||||
test.matches(html, /gems="&""/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - escape htmlAttributes", function (test) {
|
||||
test.matches(html, /gems="&""/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - escape js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - escape js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - escape css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - escape css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - call rewriteHook", function (test) {
|
||||
test.matches(html, /\+rewritten_url=true/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - call rewriteHook", function (test) {
|
||||
test.matches(html, /\+rewritten_url=true/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include runtime config", function (test) {
|
||||
test.matches(html, /<script[^<>]*>[^<>]*__meteor_runtime_config__ =.*decodeURIComponent\(config123\)/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.browser - include runtime config", function (test) {
|
||||
test.matches(html, /<script[^<>]*>[^<>]*__meteor_runtime_config__ =.*decodeURIComponent\(config123\)/);
|
||||
});
|
||||
|
||||
// https://github.com/meteor/meteor/issues/9149
|
||||
Tinytest.add(
|
||||
"boilerplate-generator-tests - web.browser - properly render boilerplate " +
|
||||
"elements when _.template settings are overridden",
|
||||
function (test) {
|
||||
import { _ } from 'meteor/underscore';
|
||||
_.templateSettings = {
|
||||
interpolate: /\{\{(.+?)\}\}/g
|
||||
};
|
||||
const newHtml = generateHTMLForArch('web.browser');
|
||||
test.matches(newHtml, /foo="foobar"/);
|
||||
test.matches(newHtml, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
test.matches(newHtml, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
test.matches(newHtml, /<script>var a/);
|
||||
test.matches(
|
||||
newHtml,
|
||||
/<script[^<>]*>[^<>]*__meteor_runtime_config__ =.*decodeURIComponent\(config123\)/
|
||||
);
|
||||
}
|
||||
);
|
||||
// https://github.com/meteor/meteor/issues/9149
|
||||
Tinytest.addAsync(
|
||||
"boilerplate-generator-tests - web.browser - properly render boilerplate " +
|
||||
"elements when _.template settings are overridden",
|
||||
function (test, onComplete) {
|
||||
const run = async () => {
|
||||
import { _ } from 'meteor/underscore';
|
||||
_.templateSettings = {
|
||||
interpolate: /\{\{(.+?)\}\}/g
|
||||
};
|
||||
const newHtml = await generateHTMLForArch('web.browser');
|
||||
test.matches(newHtml, /foo="foobar"/);
|
||||
test.matches(newHtml, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
test.matches(newHtml, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
test.matches(newHtml, /<script>var a/);
|
||||
test.matches(
|
||||
newHtml,
|
||||
/<script[^<>]*>[^<>]*__meteor_runtime_config__ =.*decodeURIComponent\(config123\)/
|
||||
);
|
||||
}
|
||||
run().then(onComplete);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
start();
|
||||
|
||||
@@ -2,53 +2,62 @@ import { parse, serialize } from 'parse5';
|
||||
|
||||
import { generateHTMLForArch } from './test-lib';
|
||||
|
||||
const html = generateHTMLForArch('web.cordova');
|
||||
const start = async () => {
|
||||
|
||||
const html = await generateHTMLForArch('web.cordova');
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - well-formed html", function (test) {
|
||||
const formatted = serialize(parse(html));
|
||||
test.isTrue(formatted.replace(/\s/g, '') === html.replace(/\s/g, ''));
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - well-formed html", function (test) {
|
||||
const formatted = serialize(parse(html));
|
||||
test.isTrue(formatted.replace(/\s/g, '') === html.replace(/\s/g, ''));
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - include js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - include js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - escape js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - escape js", function (test) {
|
||||
test.matches(html, /<script[^<>]*src="[^<>]*templating[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - include css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - include css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - escape css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - escape css", function (test) {
|
||||
test.matches(html, /<link[^<>]*href="[^<>]*bootstrap[^<>]*&v="1"[^<>]*">/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - do not call rewriteHook", function (test) {
|
||||
test.notMatches(html, /\+rewritten_url=true/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - do not call rewriteHook", function (test) {
|
||||
test.notMatches(html, /\+rewritten_url=true/);
|
||||
});
|
||||
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - include runtime config", function (test) {
|
||||
test.matches(html, /<script[^<>]*>[^<>]*\n[^<>]*__meteor_runtime_config__ =[^<>]*decodeURIComponent\(config123\)\)/);
|
||||
});
|
||||
Tinytest.add("boilerplate-generator-tests - web.cordova - include runtime config", function (test) {
|
||||
test.matches(html, /<script[^<>]*>[^<>]*\n[^<>]*__meteor_runtime_config__ =[^<>]*decodeURIComponent\(config123\)\)/);
|
||||
});
|
||||
|
||||
// https://github.com/meteor/meteor/issues/9149
|
||||
Tinytest.add(
|
||||
"boilerplate-generator-tests - web.cordova - properly render boilerplate " +
|
||||
"elements when _.template settings are overridden",
|
||||
function (test) {
|
||||
import { _ } from 'meteor/underscore';
|
||||
_.templateSettings = {
|
||||
interpolate: /\{\{(.+?)\}\}/g
|
||||
};
|
||||
const newHtml = generateHTMLForArch('web.cordova');
|
||||
test.matches(newHtml, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
test.matches(newHtml, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
test.matches(newHtml, /<script>var a/);
|
||||
test.matches(
|
||||
newHtml,
|
||||
/<script[^<>]*>[^<>]*__meteor_runtime_config__ =.*decodeURIComponent\(config123\)/
|
||||
);
|
||||
}
|
||||
);
|
||||
// https://github.com/meteor/meteor/issues/9149
|
||||
Tinytest.addAsync(
|
||||
"boilerplate-generator-tests - web.cordova - properly render boilerplate " +
|
||||
"elements when _.template settings are overridden",
|
||||
function (test, onComplete) {
|
||||
const run = async () => {
|
||||
import { _ } from 'meteor/underscore';
|
||||
_.templateSettings = {
|
||||
interpolate: /\{\{(.+?)\}\}/g
|
||||
};
|
||||
const newHtml = await generateHTMLForArch('web.cordova');
|
||||
test.matches(newHtml, /<link[^<>]*href="[^<>]*bootstrap[^<>]*">/);
|
||||
test.matches(newHtml, /<script[^<>]*src="[^<>]*templating[^<>]*">/);
|
||||
test.matches(newHtml, /<script>var a/);
|
||||
test.matches(
|
||||
newHtml,
|
||||
/<script[^<>]*>[^<>]*__meteor_runtime_config__ =.*decodeURIComponent\(config123\)/
|
||||
);
|
||||
}
|
||||
|
||||
run().then(onComplete)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
start();
|
||||
|
||||
@@ -45,18 +45,22 @@ WebAppInternals.registerBoilerplateDataCallback(
|
||||
if (html) {
|
||||
reallyMadeChanges = true;
|
||||
const start = magic.slice(lastStart, loc.endOffset);
|
||||
const end = magic.slice(loc.endOffset);
|
||||
stream
|
||||
.append(start)
|
||||
.append(html)
|
||||
.append(end)
|
||||
.append(null);
|
||||
lastStart = loc.endOffset;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
});
|
||||
parser.on("endTag", (name, location) => {
|
||||
if (location.endOffset === html.length) {
|
||||
// reached the end of the template
|
||||
const end = magic.slice(lastStart);
|
||||
stream.append(end).append(null);
|
||||
}
|
||||
})
|
||||
|
||||
data[property] = stream;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,26 @@ import { WebAppInternals } from "meteor/webapp";
|
||||
import { onPageLoad } from "meteor/server-render";
|
||||
import { parse } from "parse5";
|
||||
|
||||
// convert a stream to a string via promise
|
||||
function toString(stream) {
|
||||
return new Promise((success, fail) => {
|
||||
var string = ''
|
||||
stream.on('data', function(data) {
|
||||
string += data.toString();
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
success(string)
|
||||
});
|
||||
|
||||
stream.on('error', function(error) {
|
||||
fail(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
const skeleton = `
|
||||
<h1>Look, Ma... static HTML!</h1>
|
||||
<div id="container-2"></div>
|
||||
@@ -11,94 +31,102 @@ const skeleton = `
|
||||
</div>
|
||||
</p>`;
|
||||
|
||||
Tinytest.add('server-render - boilerplate', function (test) {
|
||||
// This test is not a very good demonstration of the server-render
|
||||
// abstraction. In normal usage, you would call renderIntoElementById
|
||||
// and not think about the rest of this stuff. The extra complexity owes
|
||||
// to the trickiness of testing this package without using a real
|
||||
// browser to parse the resulting HTTP response.
|
||||
Tinytest.addAsync('server-render - boilerplate', function (test, onComplete) {
|
||||
const run = async () => {
|
||||
// This test is not a very good demonstration of the server-render
|
||||
// abstraction. In normal usage, you would call renderIntoElementById
|
||||
// and not think about the rest of this stuff. The extra complexity owes
|
||||
// to the trickiness of testing this package without using a real
|
||||
// browser to parse the resulting HTTP response.
|
||||
|
||||
const realCallback =
|
||||
// Use the underlying abstraction to set the static HTML skeleton.
|
||||
WebAppInternals.registerBoilerplateDataCallback(
|
||||
"meteor/server-render",
|
||||
(request, data, arch) => {
|
||||
if (request.isServerRenderTest) {
|
||||
test.equal(arch, "web.browser");
|
||||
test.equal(request.url, "/server-render/test");
|
||||
data.body = skeleton;
|
||||
const realCallback =
|
||||
// Use the underlying abstraction to set the static HTML skeleton.
|
||||
WebAppInternals.registerBoilerplateDataCallback(
|
||||
"meteor/server-render",
|
||||
(request, data, arch) => {
|
||||
if (request.isServerRenderTest) {
|
||||
test.equal(arch, "web.browser");
|
||||
test.equal(request.url, "/server-render/test");
|
||||
data.body = skeleton;
|
||||
}
|
||||
return realCallback.call(this, request, data, arch);
|
||||
}
|
||||
return realCallback.call(this, request, data, arch);
|
||||
}
|
||||
);
|
||||
);
|
||||
|
||||
const callback1 = onPageLoad(sink => {
|
||||
sink.renderIntoElementById("container-1", "<oyez/>");
|
||||
});
|
||||
const callback1 = onPageLoad(sink => {
|
||||
sink.renderIntoElementById("container-1", "<oyez/>");
|
||||
});
|
||||
|
||||
// This callback is async, and that's fine because
|
||||
// WebAppInternals.getBoilerplate is able to yield. Internally the
|
||||
// webapp package uses a function called getBoilerplateAsync, so the
|
||||
// Fiber power-tools need not be involved in typical requests.
|
||||
const callback2 = onPageLoad(async sink => {
|
||||
sink.renderIntoElementById(
|
||||
"container-2",
|
||||
(await "oy") + (await "ez")
|
||||
);
|
||||
});
|
||||
// This callback is async, and that's fine because
|
||||
// WebAppInternals.getBoilerplate is able to yield. Internally the
|
||||
// webapp package uses a function called getBoilerplateAsync, so the
|
||||
// Fiber power-tools need not be involved in typical requests.
|
||||
const callback2 = onPageLoad(async sink => {
|
||||
sink.renderIntoElementById(
|
||||
"container-2",
|
||||
(await "oy") + (await "ez")
|
||||
);
|
||||
});
|
||||
|
||||
try {
|
||||
const boilerplate = WebAppInternals.getBoilerplate({
|
||||
isServerRenderTest: true,
|
||||
browser: { name: "fake" },
|
||||
url: "/server-render/test"
|
||||
}, "web.browser");
|
||||
try {
|
||||
const { start, stream, end } = WebAppInternals.getBoilerplate({
|
||||
isServerRenderTest: true,
|
||||
browser: { name: "fake" },
|
||||
url: "/server-render/test"
|
||||
}, "web.browser");
|
||||
|
||||
const ids = [];
|
||||
const seen = new Set;
|
||||
|
||||
function walk(node) {
|
||||
if (node && ! seen.has(node)) {
|
||||
seen.add(node);
|
||||
const body = await toString(stream);
|
||||
const boilerplate = start + "\n" + body + "\n" + end;
|
||||
|
||||
if (node.nodeName === "div" && node.attrs) {
|
||||
node.attrs.some(attr => {
|
||||
if (attr.name === "id") {
|
||||
const id = attr.value;
|
||||
const ids = [];
|
||||
const seen = new Set;
|
||||
|
||||
if (id === "container-1") {
|
||||
test.equal(node.childNodes[0].nodeName, "oyez");
|
||||
ids.push(id);
|
||||
} else if (id === "container-2") {
|
||||
const child = node.childNodes[0];
|
||||
test.equal(child.nodeName, "#text");
|
||||
test.equal(child.value.trim(), "oyez");
|
||||
ids.push(id);
|
||||
function walk(node) {
|
||||
if (node && ! seen.has(node)) {
|
||||
seen.add(node);
|
||||
|
||||
if (node.nodeName === "div" && node.attrs) {
|
||||
node.attrs.some(attr => {
|
||||
if (attr.name === "id") {
|
||||
const id = attr.value;
|
||||
|
||||
if (id === "container-1") {
|
||||
test.equal(node.childNodes[0].nodeName, "oyez");
|
||||
ids.push(id);
|
||||
} else if (id === "container-2") {
|
||||
const child = node.childNodes[0];
|
||||
test.equal(child.nodeName, "#text");
|
||||
test.equal(child.value.trim(), "oyez");
|
||||
ids.push(id);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (node.childNodes) {
|
||||
node.childNodes.forEach(walk)
|
||||
if (node.childNodes) {
|
||||
node.childNodes.forEach(walk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
walk(parse(boilerplate));
|
||||
|
||||
test.equal(ids, ["container-2", "container-1"]);
|
||||
|
||||
} finally {
|
||||
// Cleanup to minimize interference with other tests:
|
||||
WebAppInternals.registerBoilerplateDataCallback(
|
||||
"meteor/server-render",
|
||||
realCallback
|
||||
);
|
||||
|
||||
onPageLoad.remove(callback1);
|
||||
onPageLoad.remove(callback2);
|
||||
}
|
||||
|
||||
walk(parse(boilerplate));
|
||||
|
||||
test.equal(ids, ["container-2", "container-1"]);
|
||||
|
||||
} finally {
|
||||
// Cleanup to minimize interference with other tests:
|
||||
WebAppInternals.registerBoilerplateDataCallback(
|
||||
"meteor/server-render",
|
||||
realCallback
|
||||
);
|
||||
|
||||
onPageLoad.remove(callback1);
|
||||
onPageLoad.remove(callback2);
|
||||
}
|
||||
|
||||
run().then(onComplete).catch(console.error);
|
||||
});
|
||||
|
||||
@@ -85,7 +85,6 @@ function appendContent(object, property, content) {
|
||||
} else if ((content = content && content.toString("utf8"))) {
|
||||
object[property] = (object[property] || "") + content;
|
||||
madeChanges = true;
|
||||
// should we join streams here?
|
||||
}
|
||||
return madeChanges;
|
||||
}
|
||||
|
||||
@@ -811,7 +811,6 @@ function runWebAppServer() {
|
||||
headers = {...headers, ...newHeaders };
|
||||
}
|
||||
|
||||
console.log("setting status code")
|
||||
res.writeHead(statusCode, headers);
|
||||
res.write(start);
|
||||
stream.pipe(res, { end: false })
|
||||
|
||||
@@ -8,6 +8,24 @@ var hash = crypto.createHash('sha1');
|
||||
hash.update(additionalScript);
|
||||
var additionalScriptPathname = hash.digest('hex') + ".js";
|
||||
|
||||
// convert a stream to a string via promise
|
||||
function toString(stream) {
|
||||
return new Promise((success, fail) => {
|
||||
var string = ''
|
||||
stream.on('data', function(data) {
|
||||
string += data.toString();
|
||||
});
|
||||
|
||||
stream.on('end', function() {
|
||||
success(string)
|
||||
});
|
||||
|
||||
stream.on('error', function(error) {
|
||||
fail(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Mock the 'res' object that gets passed to connect handlers. This mock
|
||||
// just records any utf8 data written to the response and returns it
|
||||
// when you call `mockResponse.getBody()`.
|
||||
@@ -66,132 +84,155 @@ Tinytest.add("webapp - content-type header", function (test) {
|
||||
"application/javascript; charset=utf-8");
|
||||
});
|
||||
|
||||
Tinytest.add("webapp - additional static javascript", function (test) {
|
||||
var origInlineScriptsAllowed = WebAppInternals.inlineScriptsAllowed();
|
||||
Tinytest.addAsync("webapp - additional static javascript", function (test, onComplete) {
|
||||
const run = async () => {
|
||||
var origInlineScriptsAllowed = WebAppInternals.inlineScriptsAllowed();
|
||||
|
||||
var staticFilesOpts = {
|
||||
staticFiles: {},
|
||||
clientDir: "/"
|
||||
};
|
||||
var staticFilesOpts = {
|
||||
staticFiles: {},
|
||||
clientDir: "/"
|
||||
};
|
||||
|
||||
// It's okay to set this global state because we're not going to yield
|
||||
// before settng it back to what it was originally.
|
||||
WebAppInternals.setInlineScriptsAllowed(true);
|
||||
// It's okay to set this global state because we're not going to yield
|
||||
// before settng it back to what it was originally.
|
||||
WebAppInternals.setInlineScriptsAllowed(true);
|
||||
|
||||
(function () {
|
||||
var boilerplate = WebAppInternals.getBoilerplate({
|
||||
browser: "doesn't-matter",
|
||||
url: "also-doesnt-matter"
|
||||
}, "web.browser");
|
||||
await (async function () {
|
||||
const { start, stream, end } = WebAppInternals.getBoilerplate({
|
||||
browser: "doesn't-matter",
|
||||
url: "also-doesnt-matter"
|
||||
}, "web.browser");
|
||||
|
||||
// When inline scripts are allowed, the script should be inlined.
|
||||
test.isTrue(boilerplate.indexOf(additionalScript) !== -1);
|
||||
const body = await toString(stream);
|
||||
const boilerplate = start + body + end;
|
||||
|
||||
// And the script should not be served as its own separate resource,
|
||||
// meaning that the static file handler should pass on this request.
|
||||
var res = new MockResponse();
|
||||
var req = new http.IncomingMessage();
|
||||
req.headers = {};
|
||||
req.method = "GET";
|
||||
req.url = "/" + additionalScriptPathname;
|
||||
var nextCalled = false;
|
||||
WebAppInternals.staticFilesMiddleware(
|
||||
staticFilesOpts, req, res, function () {
|
||||
nextCalled = true;
|
||||
});
|
||||
test.isTrue(nextCalled);
|
||||
})();
|
||||
// When inline scripts are allowed, the script should be inlined.
|
||||
test.isTrue(boilerplate.indexOf(additionalScript) !== -1);
|
||||
|
||||
// When inline scripts are disallowed, the script body should not be
|
||||
// inlined, and the script should be included in a <script src="..">
|
||||
// tag.
|
||||
WebAppInternals.setInlineScriptsAllowed(false);
|
||||
// And the script should not be served as its own separate resource,
|
||||
// meaning that the static file handler should pass on this request.
|
||||
var res = new MockResponse();
|
||||
var req = new http.IncomingMessage();
|
||||
req.headers = {};
|
||||
req.method = "GET";
|
||||
req.url = "/" + additionalScriptPathname;
|
||||
var nextCalled = false;
|
||||
WebAppInternals.staticFilesMiddleware(
|
||||
staticFilesOpts, req, res, function () {
|
||||
nextCalled = true;
|
||||
});
|
||||
test.isTrue(nextCalled);
|
||||
|
||||
(function () {
|
||||
var boilerplate = WebAppInternals.getBoilerplate({
|
||||
browser: "doesn't-matter",
|
||||
url: "also-doesnt-matter"
|
||||
}, "web.browser");
|
||||
})();
|
||||
|
||||
// The script contents itself should not be present; the pathname
|
||||
// where the script is served should be.
|
||||
test.isTrue(boilerplate.indexOf(additionalScript) === -1);
|
||||
test.isTrue(boilerplate.indexOf(additionalScriptPathname) !== -1);
|
||||
// When inline scripts are disallowed, the script body should not be
|
||||
// inlined, and the script should be included in a <script src="..">
|
||||
// tag.
|
||||
WebAppInternals.setInlineScriptsAllowed(false);
|
||||
|
||||
// And the static file handler should serve the script at that pathname.
|
||||
var res = new MockResponse();
|
||||
var req = new http.IncomingMessage();
|
||||
req.headers = {};
|
||||
req.method = "GET";
|
||||
req.url = "/" + additionalScriptPathname;
|
||||
WebAppInternals.staticFilesMiddleware(staticFilesOpts, req, res,
|
||||
function () { });
|
||||
var resBody = res.getBody();
|
||||
test.isTrue(resBody.indexOf(additionalScript) !== -1);
|
||||
test.equal(res.statusCode, 200);
|
||||
})();
|
||||
await (async function () {
|
||||
const { start, stream, end } = WebAppInternals.getBoilerplate({
|
||||
browser: "doesn't-matter",
|
||||
browser: "doesn't-matter",
|
||||
url: "also-doesnt-matter"
|
||||
}, "web.browser");
|
||||
|
||||
WebAppInternals.setInlineScriptsAllowed(origInlineScriptsAllowed);
|
||||
const body = await toString(stream);
|
||||
const boilerplate = start + body + end;
|
||||
|
||||
// The script contents itself should not be present; the pathname
|
||||
// where the script is served should be.
|
||||
test.isTrue(boilerplate.indexOf(additionalScript) === -1);
|
||||
test.isTrue(boilerplate.indexOf(additionalScriptPathname) !== -1);
|
||||
|
||||
// And the static file handler should serve the script at that pathname.
|
||||
var res = new MockResponse();
|
||||
var req = new http.IncomingMessage();
|
||||
req.headers = {};
|
||||
req.method = "GET";
|
||||
req.url = "/" + additionalScriptPathname;
|
||||
WebAppInternals.staticFilesMiddleware(staticFilesOpts, req, res,
|
||||
function () { });
|
||||
var resBody = res.getBody();
|
||||
test.isTrue(resBody.indexOf(additionalScript) !== -1);
|
||||
test.equal(res.statusCode, 200);
|
||||
})();
|
||||
|
||||
WebAppInternals.setInlineScriptsAllowed(origInlineScriptsAllowed);
|
||||
}
|
||||
|
||||
run().then(onComplete);
|
||||
});
|
||||
|
||||
// Regression test: `generateBoilerplateInstance` should not change
|
||||
// `__meteor_runtime_config__`.
|
||||
Tinytest.add("webapp - generating boilerplate should not change runtime config", function (test) {
|
||||
// Set a dummy key in the runtime config served in the
|
||||
// boilerplate. Test that the dummy key appears in the boilerplate,
|
||||
// but not in __meteor_runtime_config__ after generating the
|
||||
// boilerplate.
|
||||
Tinytest.addAsync("webapp - generating boilerplate should not change runtime config", function (test, onComplete) {
|
||||
const run = async () => {
|
||||
// Set a dummy key in the runtime config served in the
|
||||
// boilerplate. Test that the dummy key appears in the boilerplate,
|
||||
// but not in __meteor_runtime_config__ after generating the
|
||||
// boilerplate.
|
||||
|
||||
test.isFalse(__meteor_runtime_config__.WEBAPP_TEST_KEY);
|
||||
test.isFalse(__meteor_runtime_config__.WEBAPP_TEST_KEY);
|
||||
|
||||
var boilerplate = WebAppInternals.generateBoilerplateInstance(
|
||||
"web.browser",
|
||||
[], // empty manifest
|
||||
{ runtimeConfigOverrides: { WEBAPP_TEST_KEY: true } }
|
||||
);
|
||||
var boilerplate = WebAppInternals.generateBoilerplateInstance(
|
||||
"web.browser",
|
||||
[], // empty manifest
|
||||
{ runtimeConfigOverrides: { WEBAPP_TEST_KEY: true } }
|
||||
);
|
||||
|
||||
var boilerplateHtml = boilerplate.toHTML();
|
||||
test.isFalse(boilerplateHtml.indexOf("WEBAPP_TEST_KEY") === -1);
|
||||
const { start, stream, end } = boilerplate.toHTML();
|
||||
const body = await toString(stream);
|
||||
const boilerplateHtml = start + stream + end;
|
||||
test.isFalse(boilerplateHtml.indexOf("WEBAPP_TEST_KEY") === -1);
|
||||
|
||||
test.isFalse(__meteor_runtime_config__.WEBAPP_TEST_KEY);
|
||||
test.isFalse(__meteor_runtime_config__.WEBAPP_TEST_KEY);
|
||||
};
|
||||
run().then(onComplete);
|
||||
});
|
||||
|
||||
Tinytest.add("webapp - WebAppInternals.registerBoilerplateDataCallback", function (test) {
|
||||
const key = "from webapp_tests.js";
|
||||
let callCount = 0;
|
||||
Tinytest.addAsync("webapp - WebAppInternals.registerBoilerplateDataCallback", function (test, onComplete) {
|
||||
const run = async () => {
|
||||
const key = "from webapp_tests.js";
|
||||
let callCount = 0;
|
||||
|
||||
function callback(request, data, arch) {
|
||||
test.equal(arch, "web.browser");
|
||||
test.equal(request.url, "http://example.com");
|
||||
test.equal(data.dynamicHead.indexOf("so dynamic"), 0);
|
||||
test.equal(data.body, "");
|
||||
data.body = "<div>oyez</div>";
|
||||
++callCount;
|
||||
}
|
||||
function callback(request, data, arch) {
|
||||
test.equal(arch, "web.browser");
|
||||
test.equal(request.url, "http://example.com");
|
||||
test.equal(data.dynamicHead.indexOf("so dynamic"), 0);
|
||||
test.equal(data.body, "");
|
||||
data.body = "<div>oyez</div>";
|
||||
++callCount;
|
||||
}
|
||||
|
||||
WebAppInternals.registerBoilerplateDataCallback(key, callback);
|
||||
WebAppInternals.registerBoilerplateDataCallback(key, callback);
|
||||
|
||||
test.equal(callCount, 0);
|
||||
test.equal(callCount, 0);
|
||||
|
||||
const req = new http.IncomingMessage();
|
||||
req.url = "http://example.com";
|
||||
req.browser = { name: "headless" };
|
||||
req.dynamicHead = "so dynamic";
|
||||
const req = new http.IncomingMessage();
|
||||
req.url = "http://example.com";
|
||||
req.browser = { name: "headless" };
|
||||
req.dynamicHead = "so dynamic";
|
||||
|
||||
const html = WebAppInternals.getBoilerplate(req, "web.browser");
|
||||
const { start, stream, end } = WebAppInternals.getBoilerplate(req, "web.browser");
|
||||
const body = await toString(stream);
|
||||
|
||||
test.equal(callCount, 1);
|
||||
const html = start + "\n" + body + "\n" + end;
|
||||
|
||||
test.isTrue(html.indexOf([
|
||||
"<body>",
|
||||
"<div>oyez</div>"
|
||||
].join("\n")) >= 0);
|
||||
test.equal(callCount, 1);
|
||||
|
||||
test.equal(
|
||||
// Make sure this callback doesn't get called again after this test.
|
||||
WebAppInternals.registerBoilerplateDataCallback(key, null),
|
||||
callback
|
||||
);
|
||||
test.isTrue(html.indexOf([
|
||||
"<body>",
|
||||
"<div>oyez</div>"
|
||||
].join("\n")) >= 0);
|
||||
|
||||
test.equal(
|
||||
// Make sure this callback doesn't get called again after this test.
|
||||
WebAppInternals.registerBoilerplateDataCallback(key, null),
|
||||
callback
|
||||
);
|
||||
};
|
||||
run().then(onComplete);
|
||||
});
|
||||
|
||||
// Support 'named pipes' (strings) as ports for support of Windows Server /
|
||||
|
||||
Reference in New Issue
Block a user