title: Angularjs unit test resolve promise inside custom directive with external template
body: <p>I have a custom directive that uses an external template and is passed data from a service. I decided to ensure that the promise was resolved before modifying the data, which was fine in the actual code but broke my unit tests, which is annoying. I have tried a number of variations but am now stuck. I am using 'ng-html2js' preprocessor.</p>
  
  <p>Here is the unit test</p>
  
  <pre><code>describe('ccAccordion', function () {
  var elm, scope, deferred, promise, things;
  beforeEach(module('ccAccordion'));
  // load the templates
  beforeEach(module('components/accordion/accordion.html'));
  
  beforeEach(inject(function ($rootScope, $compile, $q) {
      elm = angular.element(
        '&lt;cc-accordion items="genres"&gt;&lt;/cc-accordion&gt;'
        );
      scope = $rootScope;
      things = [{
              title: 'Scifi',
              description: 'Scifi description'
          }, {
              title: 'Comedy',
              description: 'Comedy description'
          }];
  
      deferred = $q.defer();
      promise = deferred.promise;
  
      promise.then(function (things) {
          scope.items = things;   
      });
  
      // Simulate resolving of promise
      deferred.resolve(things);
  
      // Propagate promise resolution to 'then' functions using $apply().
      scope.$apply();
  
      // compile the template?
      $compile(elm)(scope);
      scope.$digest();
  }));
  
  it('should create clickable titles', function () {
      var titles = elm.find('.cc-accord h2');
  
      expect(titles.length).toBe(2);
      expect(titles.eq(0).text().trim()).toBe('Scifi');
      expect(titles.eq(1).text().trim()).toBe('Comedy');
  });
  </code></pre>
  
  <p>I have left out the custom addMatchers and the rest of the tests. The error I get is </p>
  
  <pre><code>TypeError: 'undefined' is not an object (evaluating 'scope.items.$promise')
  </code></pre>
  
  <p>Here is the directive</p>
  
  <pre><code>var ccAccordion = angular.module("ccAccordion", []);
  ccAccordion.directive("ccAccordion", function () {
  return {
      restrict: "AE",
      templateUrl: "components/accordion/accordion.html",
      scope: {
          items: "="
      },
      link: function (scope) {
          scope.items.$promise.then(function (items) {
              angular.forEach(scope.items, function (item) {
                  item.selected = false;
              });
              items[0].selected = true;
          });
  
          scope.select = function (desiredItem) {
              (desiredItem.selected === true) ? desiredItem.selected = false : desiredItem.selected = true;
              angular.forEach(scope.items, function (item) {
                  if (item !== desiredItem) {
                      item.selected = false;
                  }
              });
          };
  
      }
  };
  </code></pre>
  
  <p>});</p>
  
  <p>This is where the directive is used in main.html</p>
  
  <pre><code>&lt;cc-accordion items="genres"&gt;&lt;/cc-accordion&gt;
  </code></pre>
  
  <p>In the main controller the genres service is passed in ie</p>
  
  <pre><code> angular.module('magicApp')
  .controller('GenresCtrl', ['$scope', 'BREAKPOINTS', 'Genre', 
  function ($scope, BREAKPOINTS, Genre) {
      $scope.bp = BREAKPOINTS;
      $scope.genres = Genre.query();
  }]);
  </code></pre>