aboutsummaryrefslogtreecommitdiffstats
path: root/test/ng/sceSpecs.js
diff options
context:
space:
mode:
Diffstat (limited to 'test/ng/sceSpecs.js')
-rw-r--r--test/ng/sceSpecs.js347
1 files changed, 347 insertions, 0 deletions
diff --git a/test/ng/sceSpecs.js b/test/ng/sceSpecs.js
new file mode 100644
index 00000000..16525b8d
--- /dev/null
+++ b/test/ng/sceSpecs.js
@@ -0,0 +1,347 @@
+'use strict';
+
+describe('SCE', function() {
+
+ describe('when disabled', function() {
+ beforeEach(function() {
+ module(function($sceProvider) {
+ $sceProvider.enabled(false);
+ });
+ });
+
+ it('should provide the getter for enabled', inject(function($sce) {
+ expect($sce.isEnabled()).toBe(false);
+ }));
+
+ it('should not wrap/unwrap any value or throw exception on non-string values', inject(function($sce) {
+ var originalValue = { foo: "bar" };
+ expect($sce.trustAs($sce.JS, originalValue)).toBe(originalValue);
+ expect($sce.getTrusted($sce.JS, originalValue)).toBe(originalValue);
+ }));
+ });
+
+ describe('IE8 quirks mode', function() {
+ function runTest(enabled, documentMode, expectException) {
+ module(function($provide) {
+ $provide.value('$document', [{
+ documentMode: documentMode,
+ createElement: function() {}
+ }]);
+ $provide.value('$sceDelegate', {trustAs: null, valueOf: null, getTrusted: null});
+ });
+
+ inject(function($window, $injector) {
+ function constructSce() {
+ var sceProvider = new $SceProvider();
+ sceProvider.enabled(enabled);
+ return $injector.invoke(sceProvider.$get, sceProvider);
+ }
+
+ var origMsie = $window.msie;
+ try {
+ $window.msie = true;
+ if (expectException) {
+ expect(constructSce).toThrow(
+ '[$sce:iequirks] Strict Contextual Escaping does not support Internet Explorer ' +
+ 'version < 9 in quirks mode. You can fix this by adding the text <!doctype html> to ' +
+ 'the top of your HTML document. See http://docs.angularjs.org/api/ng.$sce for more ' +
+ 'information.');
+ } else {
+ // no exception.
+ constructSce();
+ }
+ }
+ finally {
+ $window.msie = origMsie;
+ }
+ });
+ }
+
+ it('should throw an exception when sce is enabled in quirks mode', function() {
+ runTest(true, 7, true);
+ });
+
+ it('should NOT throw an exception when sce is enabled and in standards mode', function() {
+ runTest(true, 8, false);
+ });
+
+ it('should NOT throw an exception when sce is enabled and documentMode is undefined', function() {
+ runTest(true, undefined, false);
+ });
+
+ it('should NOT throw an exception when sce is disabled even when in quirks mode', function() {
+ runTest(false, 7, false);
+ });
+
+ it('should NOT throw an exception when sce is disabled and in standards mode', function() {
+ runTest(false, 8, false);
+ });
+
+ it('should NOT throw an exception when sce is disabled and documentMode is undefined', function() {
+ runTest(false, undefined, false);
+ });
+ });
+
+ describe('when enabled', function() {
+ it('should wrap string values with TrustedValueHolder', inject(function($sce) {
+ var originalValue = 'original_value';
+ var wrappedValue = $sce.trustAs($sce.HTML, originalValue);
+ expect(typeof wrappedValue).toBe('object');
+ expect($sce.getTrusted($sce.HTML, wrappedValue)).toBe('original_value');
+ expect(function() { $sce.getTrusted($sce.CSS, wrappedValue); }).toThrow(
+ '[$sce:unsafe] Attempting to use an unsafe value in a safe context.');
+ wrappedValue = $sce.trustAs($sce.CSS, originalValue);
+ expect(typeof wrappedValue).toBe('object');
+ expect($sce.getTrusted($sce.CSS, wrappedValue)).toBe('original_value');
+ expect(function() { $sce.getTrusted($sce.HTML, wrappedValue); }).toThrow(
+ '[$sce:unsafe] Attempting to use an unsafe value in a safe context.');
+ wrappedValue = $sce.trustAs($sce.URL, originalValue);
+ expect(typeof wrappedValue).toBe('object');
+ expect($sce.getTrusted($sce.URL, wrappedValue)).toBe('original_value');
+ wrappedValue = $sce.trustAs($sce.JS, originalValue);
+ expect(typeof wrappedValue).toBe('object');
+ expect($sce.getTrusted($sce.JS, wrappedValue)).toBe('original_value');
+ }));
+
+ it('should NOT wrap non-string values', inject(function($sce) {
+ expect(function() { $sce.trustAsCss(123); }).toThrow(
+ '[$sce:itype] Attempted to trust a non-string value in a content requiring a string: ' +
+ 'Context: css');
+ }));
+
+ it('should NOT wrap unknown contexts', inject(function($sce) {
+ expect(function() { $sce.trustAs('unknown1' , '123'); }).toThrow(
+ '[$sce:icontext] Attempted to trust a value in invalid context. Context: unknown1; Value: 123');
+ }));
+
+ it('should NOT wrap undefined context', inject(function($sce) {
+ expect(function() { $sce.trustAs(undefined, '123'); }).toThrow(
+ '[$sce:icontext] Attempted to trust a value in invalid context. Context: undefined; Value: 123');
+ }));
+
+ it('should wrap undefined into undefined', inject(function($sce) {
+ expect($sce.trustAsHtml(undefined)).toBe(undefined);
+ }));
+
+ it('should unwrap undefined into undefined', inject(function($sce) {
+ expect($sce.getTrusted($sce.HTML, undefined)).toBe(undefined);
+ }));
+
+ it('should wrap null into null', inject(function($sce) {
+ expect($sce.trustAsHtml(null)).toBe(null);
+ }));
+
+ it('should unwrap null into null', inject(function($sce) {
+ expect($sce.getTrusted($sce.HTML, null)).toBe(null);
+ }));
+
+ it('should wrap "" into ""', inject(function($sce) {
+ expect($sce.trustAsHtml("")).toBe("");
+ }));
+
+ it('should unwrap null into null', inject(function($sce) {
+ expect($sce.getTrusted($sce.HTML, null)).toBe(null);
+ }));
+
+ it('should unwrap "" into ""', inject(function($sce) {
+ expect($sce.getTrusted($sce.HTML, "")).toBe("");
+ }));
+
+ it('should unwrap values and return the original', inject(function($sce) {
+ var originalValue = "originalValue";
+ var wrappedValue = $sce.trustAs($sce.HTML, originalValue);
+ expect($sce.getTrusted($sce.HTML, wrappedValue)).toBe(originalValue);
+ }));
+
+ it('should NOT unwrap values when the type is different', inject(function($sce) {
+ var originalValue = "originalValue";
+ var wrappedValue = $sce.trustAs($sce.HTML, originalValue);
+ expect(function () { $sce.getTrusted($sce.CSS, wrappedValue); }).toThrow(
+ '[$sce:unsafe] Attempting to use an unsafe value in a safe context.');
+ }));
+
+ it('should NOT unwrap values that had not been wrapped', inject(function($sce) {
+ function TrustedValueHolder(trustedValue) {
+ this.$unwrapTrustedValue = function() {
+ return trustedValue;
+ };
+ }
+ var wrappedValue = new TrustedValueHolder("originalValue");
+ expect(function() { return $sce.getTrusted($sce.HTML, wrappedValue) }).toThrow(
+ '[$sce:unsafe] Attempting to use an unsafe value in a safe context.');
+ }));
+
+ it('should implement toString on trusted values', inject(function($sce) {
+ var originalValue = '123',
+ wrappedValue = $sce.trustAsHtml(originalValue);
+ expect($sce.getTrustedHtml(wrappedValue)).toBe(originalValue);
+ expect(wrappedValue.toString()).toBe(originalValue.toString());
+ }));
+ });
+
+
+ describe('replace $sceDelegate', function() {
+ it('should override the default $sce.trustAs/valueOf/etc.', function() {
+ module(function($provide) {
+ $provide.value('$sceDelegate', {
+ trustAs: function(type, value) { return "wrapped:" + value; },
+ getTrusted: function(type, value) { return "unwrapped:" + value; },
+ valueOf: function(value) { return "valueOf:" + value; }
+ });
+ });
+
+ inject(function($sce) {
+ expect($sce.trustAsJs("value")).toBe("wrapped:value");
+ expect($sce.valueOf("value")).toBe("valueOf:value");
+ expect($sce.getTrustedJs("value")).toBe("unwrapped:value");
+ expect($sce.parseAsJs("name")({name: "chirayu"})).toBe("unwrapped:chirayu");
+ });
+ });
+ });
+
+
+ describe('$sce.parseAs', function($sce) {
+ it('should parse constant literals as trusted', inject(function($sce) {
+ expect($sce.parseAsJs('1')()).toBe(1);
+ expect($sce.parseAsJs('1', $sce.ANY)()).toBe(1);
+ expect($sce.parseAsJs('1', $sce.HTML)()).toBe(1);
+ expect($sce.parseAsJs('1', 'UNDEFINED')()).toBe(1);
+ expect($sce.parseAsJs('true')()).toBe(true);
+ expect($sce.parseAsJs('false')()).toBe(false);
+ expect($sce.parseAsJs('null')()).toBe(null);
+ expect($sce.parseAsJs('undefined')()).toBe(undefined);
+ expect($sce.parseAsJs('"string"')()).toBe("string");
+ }));
+
+ it('should NOT parse constant non-literals', inject(function($sce) {
+ // Until there's a real world use case for this, we're disallowing
+ // constant non-literals. See $SceParseProvider.
+ var exprFn = $sce.parseAsJs('1+1');
+ expect(exprFn).toThrow();
+ }));
+
+ it('should NOT return untrusted values from expression function', inject(function($sce) {
+ var exprFn = $sce.parseAs($sce.HTML, 'foo');
+ expect(function() {
+ return exprFn({}, {'foo': true})
+ }).toThrow(
+ '[$sce:unsafe] Attempting to use an unsafe value in a safe context.');
+ }));
+
+ it('should NOT return trusted values of the wrong type from expression function', inject(function($sce) {
+ var exprFn = $sce.parseAs($sce.HTML, 'foo');
+ expect(function() {
+ return exprFn({}, {'foo': $sce.trustAs($sce.JS, '123')})
+ }).toThrow(
+ '[$sce:unsafe] Attempting to use an unsafe value in a safe context.');
+ }));
+
+ it('should return trusted values from expression function', inject(function($sce) {
+ var exprFn = $sce.parseAs($sce.HTML, 'foo');
+ expect(exprFn({}, {'foo': $sce.trustAs($sce.HTML, 'trustedValue')})).toBe('trustedValue');
+ }));
+
+ it('should support shorthand methods', inject(function($sce) {
+ // Test shorthand parse methods.
+ expect($sce.parseAsHtml('1')()).toBe(1);
+ // Test short trustAs methods.
+ expect($sce.trustAsAny).toBeUndefined();
+ expect(function() {
+ // mismatched types.
+ $sce.parseAsCss('foo')({}, {'foo': $sce.trustAsHtml('1')});
+ }).toThrow(
+ '[$sce:unsafe] Attempting to use an unsafe value in a safe context.');
+ }));
+
+ });
+
+ describe('$sceDelegate resource url policies', function() {
+ function runTest(cfg, testFn) {
+ return function() {
+ module(function($sceDelegateProvider) {
+ if (cfg.whiteList !== undefined) {
+ $sceDelegateProvider.resourceUrlWhitelist(cfg.whiteList);
+ }
+ if (cfg.blackList !== undefined) {
+ $sceDelegateProvider.resourceUrlBlacklist(cfg.blackList);
+ }
+ });
+ inject(testFn);
+ }
+ }
+
+ it('should default to "self" which allows relative urls', runTest({}, function($sce, $document) {
+ expect($sce.getTrustedResourceUrl('foo/bar')).toEqual('foo/bar');
+ }));
+
+ it('should reject everything when whitelist is empty', runTest(
+ {
+ whiteList: [],
+ blackList: []
+ }, function($sce) {
+ expect(function() { $sce.getTrustedResourceUrl('#'); }).toThrow(
+ '[$sce:isecrurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: #');
+ }));
+
+ it('should match against normalized urls', runTest(
+ {
+ whiteList: [/^foo$/],
+ blackList: []
+ }, function($sce) {
+ expect(function() { $sce.getTrustedResourceUrl('foo'); }).toThrow(
+ '[$sce:isecrurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: foo');
+ }));
+
+ it('should support custom regex', runTest(
+ {
+ whiteList: [/^http:\/\/example\.com.*/],
+ blackList: []
+ }, function($sce) {
+ expect($sce.getTrustedResourceUrl('http://example.com/foo')).toEqual('http://example.com/foo');
+ expect(function() { $sce.getTrustedResourceUrl('https://example.com/foo'); }).toThrow(
+ '[$sce:isecrurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: https://example.com/foo');
+ }));
+
+ it('should support the special string "self" in whitelist', runTest(
+ {
+ whiteList: ['self'],
+ blackList: []
+ }, function($sce) {
+ expect($sce.getTrustedResourceUrl('foo')).toEqual('foo');
+ }));
+
+ it('should support the special string "self" in blacklist', runTest(
+ {
+ whiteList: [/.*/],
+ blackList: ['self']
+ }, function($sce) {
+ expect(function() { $sce.getTrustedResourceUrl('foo'); }).toThrow(
+ '[$sce:isecrurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: foo');
+ }));
+
+ it('should have blacklist override the whitelist', runTest(
+ {
+ whiteList: ['self'],
+ blackList: ['self']
+ }, function($sce) {
+ expect(function() { $sce.getTrustedResourceUrl('foo'); }).toThrow(
+ '[$sce:isecrurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: foo');
+ }));
+
+ it('should support multiple items in both lists', runTest(
+ {
+ whiteList: [/^http:\/\/example.com\/1$/, /^http:\/\/example.com\/2$/, /^http:\/\/example.com\/3$/, 'self'],
+ blackList: [/^http:\/\/example.com\/3$/, /open_redirect/],
+ }, function($sce) {
+ expect($sce.getTrustedResourceUrl('same_domain')).toEqual('same_domain');
+ expect($sce.getTrustedResourceUrl('http://example.com/1')).toEqual('http://example.com/1');
+ expect($sce.getTrustedResourceUrl('http://example.com/2')).toEqual('http://example.com/2');
+ expect(function() { $sce.getTrustedResourceUrl('http://example.com/3'); }).toThrow(
+ '[$sce:isecrurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: http://example.com/3');
+ expect(function() { $sce.getTrustedResourceUrl('open_redirect'); }).toThrow(
+ '[$sce:isecrurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL: open_redirect');
+ }));
+
+ });
+});
+