226 lines
7.4 KiB
JavaScript
226 lines
7.4 KiB
JavaScript
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS-IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
goog.provide('goog.soyTest');
|
|
goog.setTestOnly('goog.soyTest');
|
|
|
|
goog.require('goog.dom');
|
|
goog.require('goog.dom.NodeType');
|
|
goog.require('goog.dom.TagName');
|
|
goog.require('goog.functions');
|
|
goog.require('goog.soy');
|
|
/** @suppress {extraRequire} */
|
|
goog.require('goog.soy.testHelper');
|
|
goog.require('goog.testing.PropertyReplacer');
|
|
goog.require('goog.testing.jsunit');
|
|
|
|
var stubs;
|
|
|
|
function setUp() {
|
|
stubs = new goog.testing.PropertyReplacer();
|
|
}
|
|
|
|
function tearDown() {
|
|
stubs.reset();
|
|
}
|
|
|
|
function testRenderElement() {
|
|
var testDiv = goog.dom.createElement(goog.dom.TagName.DIV);
|
|
goog.soy.renderElement(testDiv, example.multiRootTemplate, {name: 'Boo'});
|
|
assertEquals('<div>Hello</div><div>Boo</div>', elementToInnerHtml(testDiv));
|
|
}
|
|
|
|
|
|
function testRenderElementWithNoTemplateData() {
|
|
var testDiv = goog.dom.createElement(goog.dom.TagName.DIV);
|
|
goog.soy.renderElement(testDiv, example.noDataTemplate);
|
|
assertEquals('<div>Hello</div>', elementToInnerHtml(testDiv));
|
|
}
|
|
|
|
|
|
function testRenderAsFragmentTextNode() {
|
|
var fragment = goog.soy.renderAsFragment(
|
|
example.textNodeTemplate, {name: 'Boo'});
|
|
assertEquals(goog.dom.NodeType.TEXT, fragment.nodeType);
|
|
assertEquals('Boo', fragmentToHtml(fragment));
|
|
}
|
|
|
|
|
|
function testRenderAsFragmentInjectedData() {
|
|
var fragment = goog.soy.renderAsFragment(example.injectedDataTemplate,
|
|
{name: 'Boo'}, {name: 'ijBoo'});
|
|
assertEquals(goog.dom.NodeType.TEXT, fragment.nodeType);
|
|
assertEquals('BooijBoo', fragmentToHtml(fragment));
|
|
}
|
|
|
|
|
|
function testRenderAsFragmentSingleRoot() {
|
|
var fragment = goog.soy.renderAsFragment(
|
|
example.singleRootTemplate, {name: 'Boo'});
|
|
assertEquals(goog.dom.NodeType.ELEMENT, fragment.nodeType);
|
|
assertEquals(goog.dom.TagName.SPAN, fragment.tagName);
|
|
assertEquals('Boo', fragment.innerHTML);
|
|
}
|
|
|
|
|
|
function testRenderAsFragmentMultiRoot() {
|
|
var fragment = goog.soy.renderAsFragment(
|
|
example.multiRootTemplate, {name: 'Boo'});
|
|
assertEquals(goog.dom.NodeType.DOCUMENT_FRAGMENT, fragment.nodeType);
|
|
assertEquals('<div>Hello</div><div>Boo</div>', fragmentToHtml(fragment));
|
|
}
|
|
|
|
|
|
function testRenderAsFragmentNoData() {
|
|
var fragment = goog.soy.renderAsFragment(example.noDataTemplate);
|
|
assertEquals(goog.dom.NodeType.ELEMENT, fragment.nodeType);
|
|
assertEquals('<div>Hello</div>', fragmentToHtml(fragment));
|
|
}
|
|
|
|
|
|
function testRenderAsElementTextNode() {
|
|
var elem = goog.soy.renderAsElement(example.textNodeTemplate, {name: 'Boo'});
|
|
assertEquals(goog.dom.NodeType.ELEMENT, elem.nodeType);
|
|
assertEquals(goog.dom.TagName.DIV, elem.tagName);
|
|
assertEquals('Boo', elementToInnerHtml(elem));
|
|
}
|
|
|
|
function testRenderAsElementInjectedData() {
|
|
var elem = goog.soy.renderAsElement(example.injectedDataTemplate,
|
|
{name: 'Boo'}, {name: 'ijBoo'});
|
|
assertEquals(goog.dom.NodeType.ELEMENT, elem.nodeType);
|
|
assertEquals(goog.dom.TagName.DIV, elem.tagName);
|
|
assertEquals('BooijBoo', elementToInnerHtml(elem));
|
|
}
|
|
|
|
|
|
function testRenderAsElementSingleRoot() {
|
|
var elem = goog.soy.renderAsElement(
|
|
example.singleRootTemplate, {name: 'Boo'});
|
|
assertEquals(goog.dom.NodeType.ELEMENT, elem.nodeType);
|
|
assertEquals(goog.dom.TagName.SPAN, elem.tagName);
|
|
assertEquals('Boo', elementToInnerHtml(elem));
|
|
}
|
|
|
|
|
|
function testRenderAsElementMultiRoot() {
|
|
var elem = goog.soy.renderAsElement(example.multiRootTemplate, {name: 'Boo'});
|
|
assertEquals(goog.dom.NodeType.ELEMENT, elem.nodeType);
|
|
assertEquals(goog.dom.TagName.DIV, elem.tagName);
|
|
assertEquals('<div>Hello</div><div>Boo</div>', elementToInnerHtml(elem));
|
|
}
|
|
|
|
function testRenderAsElementWithNoData() {
|
|
var elem = goog.soy.renderAsElement(example.noDataTemplate);
|
|
assertEquals('Hello', elementToInnerHtml(elem));
|
|
}
|
|
|
|
|
|
/**
|
|
* Asserts that the function throws an error for unsafe templates.
|
|
* @param {Function} function Callback to test.
|
|
*/
|
|
function assertUnsafeTemplateOutputErrorThrown(func) {
|
|
stubs.set(goog.asserts, 'ENABLE_ASSERTS', true);
|
|
assertContains('Soy template output is unsafe for use as HTML',
|
|
assertThrows(func).message);
|
|
stubs.set(goog.asserts, 'ENABLE_ASSERTS', false);
|
|
assertEquals('zSoyz', func());
|
|
}
|
|
|
|
function testAllowButEscapeUnsanitizedText() {
|
|
var div = goog.dom.createElement(goog.dom.TagName.DIV);
|
|
goog.soy.renderElement(div, example.unsanitizedTextTemplate);
|
|
assertEquals('I <3 Puppies & Kittens', div.innerHTML);
|
|
var fragment = goog.soy.renderAsFragment(example.unsanitizedTextTemplate);
|
|
assertEquals('I <3 Puppies & Kittens', fragment.nodeValue);
|
|
assertEquals('I <3 Puppies & Kittens',
|
|
goog.soy.renderAsElement(example.unsanitizedTextTemplate).innerHTML);
|
|
}
|
|
|
|
function testRejectSanitizedCss() {
|
|
assertUnsafeTemplateOutputErrorThrown(function() {
|
|
goog.soy.renderAsElement(example.sanitizedCssTemplate);
|
|
});
|
|
}
|
|
|
|
function testRejectSanitizedCss() {
|
|
assertUnsafeTemplateOutputErrorThrown(function() {
|
|
return goog.soy.renderAsElement(
|
|
example.templateSpoofingSanitizedContentString).innerHTML;
|
|
});
|
|
}
|
|
|
|
function testRejectStringTemplatesWhenModeIsSet() {
|
|
stubs.set(goog.soy, 'REQUIRE_STRICT_AUTOESCAPE', true);
|
|
assertUnsafeTemplateOutputErrorThrown(function() {
|
|
return goog.soy.renderAsElement(example.noDataTemplate).innerHTML;
|
|
});
|
|
}
|
|
|
|
function testAcceptSanitizedHtml() {
|
|
assertEquals('Hello World', goog.dom.getTextContent(
|
|
goog.soy.renderAsElement(example.sanitizedHtmlTemplate)));
|
|
}
|
|
|
|
function testRejectSanitizedHtmlAttributes() {
|
|
// Attributes context has nothing to do with html.
|
|
assertUnsafeTemplateOutputErrorThrown(function() {
|
|
return goog.dom.getTextContent(
|
|
goog.soy.renderAsElement(example.sanitizedHtmlAttributesTemplate));
|
|
});
|
|
}
|
|
|
|
function testAcceptNonObject() {
|
|
// Some templates, or things that spoof templates in unit tests, might return
|
|
// non-strings in unusual cases.
|
|
assertEquals('null', goog.dom.getTextContent(
|
|
goog.soy.renderAsElement(goog.functions.constant(null))));
|
|
}
|
|
|
|
function testDebugAssertionWithBadFirstTag() {
|
|
try {
|
|
goog.soy.renderAsElement(example.tableRowTemplate);
|
|
// Expect no exception in production code.
|
|
assert(!goog.DEBUG);
|
|
} catch (e) {
|
|
// Expect exception in debug code.
|
|
assert(goog.DEBUG);
|
|
// Make sure to let the developer know which tag caused the problem.
|
|
assertContains('<tr>', e.message);
|
|
}
|
|
|
|
try {
|
|
goog.soy.renderAsFragment(example.tableRowTemplate);
|
|
// Expect no exception in production code.
|
|
assert(!goog.DEBUG);
|
|
} catch (e) {
|
|
// Expect exception in debug code.
|
|
assert(goog.DEBUG);
|
|
// Make sure to let the developer know which tag caused the problem.
|
|
assertContains('<tr>', e.message);
|
|
}
|
|
|
|
try {
|
|
goog.soy.renderAsElement(example.colGroupTemplateCaps);
|
|
// Expect no exception in production code.
|
|
assert(!goog.DEBUG);
|
|
} catch (e) {
|
|
// Expect exception in debug code.
|
|
assert(goog.DEBUG);
|
|
// Make sure to let the developer know which tag caused the problem.
|
|
assertContains('<COLGROUP>', e.message);
|
|
}
|
|
}
|