oy-vey
Version:
React utilities for building server-side email templates.
235 lines (205 loc) • 7.74 kB
JavaScript
;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _Oy = require('../Oy');
var _Oy2 = _interopRequireDefault(_Oy);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
describe('Oy', function () {
beforeEach(function () {
// TODO: Don't swallow all warnings by default.
console.warn = function () {/* no-op by default */};
});
it('should expose PropTypes and renderTemplate', function () {
expect(_Oy2.default.PropTypes).toBeDefined();
expect(_Oy2.default.renderTemplate).toBeDefined();
});
it('should expose PropTypes validation rules', function () {
expect(_Oy2.default.PropTypes.EmptyTDRule).toBeDefined();
expect(_Oy2.default.PropTypes.HrefAbsoluteURLRule).toBeDefined();
expect(_Oy2.default.PropTypes.ImgAltTextRule).toBeDefined();
expect(_Oy2.default.PropTypes.ImgAltTextStyleRule).toBeDefined();
expect(_Oy2.default.PropTypes.ImgDimensionsRule).toBeDefined();
expect(_Oy2.default.PropTypes.ShorthandFontRule).toBeDefined();
expect(_Oy2.default.PropTypes.SixCharacterHexBackgroundColorRule).toBeDefined();
expect(_Oy2.default.PropTypes.SrcAbsoluteURLRule).toBeDefined();
expect(_Oy2.default.PropTypes.TableBorderRule).toBeDefined();
expect(_Oy2.default.PropTypes.TableCellPaddingRule).toBeDefined();
expect(_Oy2.default.PropTypes.TableCellSpacingRule).toBeDefined();
});
it('should expose Table, TBody, TR, TD, Img, and A', function () {
expect(_Oy2.default.Table).toBeDefined();
expect(_Oy2.default.TBody).toBeDefined();
expect(_Oy2.default.TR).toBeDefined();
expect(_Oy2.default.TD).toBeDefined();
expect(_Oy2.default.Img).toBeDefined();
expect(_Oy2.default.A).toBeDefined();
});
it('should additionally export components directly', function () {
expect(_Oy.Table).toBeDefined();
expect(_Oy.TBody).toBeDefined();
expect(_Oy.TR).toBeDefined();
expect(_Oy.TD).toBeDefined();
expect(_Oy.Img).toBeDefined();
expect(_Oy.A).toBeDefined();
});
it('should use provided base template generator by default', function () {
var shouldThrow = function shouldThrow() {
_Oy2.default.renderTemplate(_react2.default.createElement(
'h1',
null,
'Testing'
), {
title: 'Foo bar'
});
};
expect(shouldThrow).toThrow();
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(
'h1',
null,
'Testing'
), {
title: 'Foo bar',
previewText: 'Baz qux',
headCSS: '.foo { color: red; }',
bgColor: '#FF0000'
});
expect(rawHTML).toContain('<title>Foo bar</title>');
expect(rawHTML).toContain('Baz qux');
expect(rawHTML).toContain('<h1>Testing</h1>');
expect(rawHTML).toContain('.foo{color:red}');
expect(rawHTML).toContain('bgcolor="#FF0000"');
});
it('should use custom base template generator', function () {
var generateCustomTemplate = function generateCustomTemplate() {
return '<h1>Testing 123</h1>';
};
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(
'h1',
null,
'test'
), {}, generateCustomTemplate);
expect(rawHTML).toEqual('<h1>Testing 123</h1>');
});
it('should warn on outputs larger than 100KB', function () {
console.warn = jasmine.createSpy('log');
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(
'p',
null,
Array(1024 * 101).join('.')
), {
title: 'Foo bar',
previewText: 'Baz qux'
});
expect(console.warn).toHaveBeenCalled();
});
it('should set default dir attribute when generating default template', function () {
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(
'h1',
null,
'Testing'
), {
title: 'Foo bar',
previewText: 'Baz qux'
});
expect(rawHTML).toContain('dir="ltr"');
expect(rawHTML).not.toContain('lang');
});
it('should set overriding dir attribute when generating default template', function () {
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(
'h1',
null,
'Testing'
), {
title: 'Foo bar',
previewText: 'Baz qux',
dir: 'rtl'
});
expect(rawHTML).toContain('dir="rtl"');
expect(rawHTML).not.toContain('lang');
});
it('should set lang attribute when generating default template', function () {
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(
'h1',
null,
'Testing'
), {
title: 'Foo bar',
previewText: 'Baz qux',
lang: 'fr'
});
expect(rawHTML).toContain('dir="ltr"');
expect(rawHTML).toContain('lang="fr"');
});
it('should consume the component as the first parameter', function () {
var Foo = function Foo() {
return _react2.default.createElement(
'div',
null,
'should be rendered'
);
};
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(Foo, null), {
title: 'A title',
previewText: 'Some preview text.',
headCSS: '.foo { color: red; }'
});
expect(rawHTML).toContain('should be rendered');
expect(rawHTML).toContain('.foo{color:red}');
});
it('should escape the template options for the new renderTemplate structure', function () {
var Foo = function Foo() {
return _react2.default.createElement(
'div',
null,
'should be rendered'
);
};
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(Foo, null), {
title: '</title><meta http-equiv="Content-Type" content="text/html charset="ISO-8859-1" /><title>',
previewText: '<script>alert(\'evil\')</script>'
});
expect(rawHTML).toContain('should be rendered');
expect(rawHTML).toContain('</title><meta http-equiv="Content-Type" content="text/html charset="ISO-8859-1" /><title>');
expect(rawHTML).toContain('<script>alert(\'evil\')</script>');
});
it('should throw on unsafe css', function () {
var Foo = function Foo() {
return _react2.default.createElement(
'div',
null,
'should be rendered'
);
};
var shouldThrowBecauseOfMozBinding = function shouldThrowBecauseOfMozBinding() {
_Oy2.default.renderTemplate(_react2.default.createElement(Foo, null), {
title: 'foo',
previewText: 'bar',
headCSS: 'body{-moz-binding: url("http://www.website.com/xss.xml#test")}'
});
};
var shouldThrowBecauseOfExpression = function shouldThrowBecauseOfExpression() {
_Oy2.default.renderTemplate(_react2.default.createElement(Foo, null), {
title: 'foo',
previewText: 'bar',
headCSS: 'body{xss:expr/*XSS*/ession(alert("XSS"))}'
});
};
expect(shouldThrowBecauseOfMozBinding).toThrow();
expect(shouldThrowBecauseOfExpression).toThrow();
});
it('should raise warning on basic validation error', function () {
console.error = jasmine.createSpy('propType');
var FooA = function FooA() {
return _react2.default.createElement(
_Oy2.default.A,
{ href: 'example.com' },
'a link'
);
};
var rawHTML = _Oy2.default.renderTemplate(_react2.default.createElement(FooA, null), {
title: 'Foo bar',
previewText: 'Baz qux'
});
expect(console.error).toHaveBeenCalledWith('Warning: Failed %s type: %s%s', 'prop', 'Relative links can break (i.e. if recipients are outside the company network) and make your content unavailable to view', jasmine.any(String));
});
});