Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I test AngularJS trusted html with Jasmine?

I would like to use Jasmine to ensure an html data value has been correctly trusted by AngularJS.

Code

The code below fetches an article via an external api and uses Angular's $sce to trust the html content held in article.Body.

getArticle: ->
    defer = @$q.defer()
    @getContent(url).then (result) =>
        article = result.data
        article.Body = @$sce.trustAsHtml article.Body
        defer.resolve article
    defer.promise

This code works and, as I step through it, I can see the data is returned and the html property article.Body has been correctly trusted. Now I would like to write a unit-test that confirms this.

Unit-Test

Here is my attempt at the jasmine unit-test:

describe 'when getArticle is called with valid articleId', ->
    it "should call getContent and return article with trusted html", ->
        getContentDefer = @$q.defer()
        spyOn(@contentService, 'getContent').andReturn getContentDefer.promise

        article = {Id:'1', Body: '<div>test</div>'}  

        @contentService.getArticle(article.Id).then (response) =>
            expect(response.Body instanceof TrustedValueHolderType).toBeTruthy()

        getContentDefer.resolve {data:article}
        @$rootScope.$digest()

You can see that I am attempting to ensure that the returned response.Body is an instance of the AngularJS type: TrustedValueHolderType. I do not know if this is a good idea but anyway, it does not work and I receive the following error:

ReferenceError: TrustedValueHolderType is not defined

I was hoping there was a neat way, perhaps a boolean flag, that I could use to determine whether the article.Body is trusted html or just a plain html string.

Update

The accepted answer below (thanks @avowkind) gave me the hint I needed. The trick is to use the $sce.getTrustedHtml() method which takes the TrustedValueHolderType and returns the original html value. Perfect.

Passing Unit-Test

ddescribe 'getArticle', ->
    it "should return an article with trusted html", ->
        getContentDefer = @$q.defer()
        spyOn(@contentService, 'getContent').andReturn getContentDefer.promise
        body = '<div>test</div>'
        article = {Id:'1', Body: body}
        @contentService.getArticle(article.Id, @token).then (response) =>
            expect(@$sce.getTrustedHtml(response.Body)).toEqual(body)
like image 333
biofractal Avatar asked Nov 13 '13 12:11

biofractal


People also ask

What is Jasmine in AngularJS?

Jasmine is a behavior driven development framework for JavaScript that has become the most popular choice for testing AngularJS applications. Jasmine provides functions to help with structuring your tests and also making assertions.

What is testing in AngularJS?

Angularjs unit testing is the basic need for any application. It ensures the application's quality and demonstrates its capabilities to the users.


1 Answers

I am able to jasmine unit test my filter by using $sce.getTrustedHtml on the output of the filter. This works fine if you know how to inject the $sce service into the test.

e.g

/** 
 * A filter used to wrap code in the <pre> tag
 */ 
myApp.filter( 'code', ['$sce', function($sce) {
      return function(input) {
          var html = (input != "")? '<pre>' + input + '</pre>' : input;
          return $sce.trustAsHtml(html);
          
      };
}]);

// test output
it('wraps pre around input: ', function() {
   expect($sce.getTrustedHtml(codeFilter("Hello"))).toEqual("<pre>Hello</pre>");
} );

This works for my local system tests. However I tried to build an example fiddle with it http://jsfiddle.net/avowkind/vfWr3/1/

and this returns an error:

Unknown provider: $sceProvider <- $sce

if anyone can fix the fiddle that would be great.

like image 180
avowkind Avatar answered Sep 22 '22 03:09

avowkind