mardi 7 mars 2017

Cannot resolve deferred promise on digest/apply

Service

angular.module('App').service('producerContactSvc', ['$http', 'configSvc', function($http, configSvc) {

  //Reset headers to avoid OPTIONS request (aka preflight)
  $http.defaults.headers.common = {};

  var _this = this;

  _this.getProducerContacts = function(producerId) {
    var endpoint = configSvc.backendUrl + '/producerContact/read?producerId=' + producerId;
    return $http.get(endpoint)
      .then(function(response) {
        return response.data;
      })
      .catch(function(response) {
        return response.data;
      });
  };

  _this.addProducerContact = function(producerContact) {
    var endpoint = configSvc.backendUrl + '/producerContact/create';
    return $http.post(endpoint, producerContact)
      .success(function(response) {
        return response.data;
      })
      .catch(function(response) {
        return response.data;
      });
  };

  _this.deleteProducerContact = function(producerContactId, producerId) {
    var endpoint = configSvc.backendUrl + '/producerContact/delete?producerContactId=' + producerContactId + '&' + 'producerId=' + producerId;
    return $http.delete(endpoint)
      .then(function(response) {
        return response.data;
      })
      .catch(function(response) {
        return response.data;
      });
  };

  _this.updateProducerContact = function(producerContact) {
    var endpoint = configSvc.backendUrl + '/producerContact/update';
    return $http.put(endpoint, producerContact)
      .then(function(response) {
        return response.data;
      })
      .catch(function(response) {
        return response.data;
      });
  };

}]);

Controller

angular.module('App').controller('producerAdminCtrl', ['$scope', '$rootScope', 'producerSvc', '$mdDialog', 'producerContactSvc', 'errorToastSvc', function($scope, $rootScope, producerSvc, $mdDialog, producerContactSvc, errorToastSvc) {
      $scope.results = false;
      $scope.producerTypeCodes = ['CX', 'FG'];
      $scope.producerId = null;
      $scope.documents = [];
      $scope.selectedDocs = [];

      $scope.producerContactRows = [];
      $scope.missingName = false;
      $scope.producerContactTypeCodes = ['MC', 'BC'];

      /**
       * Get a list of all producers on load
       */
      producerSvc.getAllProducers()
        .then(function(response) {
          if (response !== null) {

            $scope.unusedProducers = response.data;
          } else {
            $scope.noFound = true;
            $scope.results = false;
            $scope.message = 'No Data Received';
          }
        });

      /**
       * Perform a search on a producer. This will call the backend and find information about the producer searched for
       */
      $scope.search = function() {
        $scope.documents = [];
        $scope.selectedDocs = [];
        $scope.query = $scope.selectedItem.producerId;
        producerSvc.getProducer($scope.query).then(function(response) {
          if (response && response.data) {
            $scope.producer = response.data;
            $scope.producerId = $scope.query;
            $scope.producer.inactiveDate = response.data.inactiveDate === null ? null : new Date(response.data.inactiveDate);
            producerSvc.getAllDocs().then(function(response) {
              _.forEach(response, function(doc) {
                var docObject = {
                  documentId: doc.documentId,
                  documentDescription: doc.documentDescription,
                  documentName: doc.documentName,
                  selected: false
                };
                $scope.documents.push(docObject);
              });

              producerSvc.getProducerDocs($scope.producerId).then(function(response2) {
                _.forEach(response2.data, function(docProducer) {
                  var docId = docProducer.documentId;
                  _.forEach($scope.documents, function(doc) {
                    if (docId === doc.documentId) {
                      doc.selected = true;
                      $scope.selectedDocs.push(doc);
                    }
                  });
                });

                $scope.documents.sort(function(x, y) {
                  return (x.selected === y.selected) ? 0 : x.selected ? -1 : 1;
                });

                $scope.results = true;
                $scope.noFound = false;

              });

            });
          } else {
            $scope.noFound = true;
            $scope.results = false;
            $scope.message = 'No Producer Found';
          }
        });

        producerContactSvc.getProducerContacts($scope.query).then(function(response) {
          _.forEach(response, function(producerContact) {
            var producerContactObject = {
              producerContactName: producerContact.producerContactName,
              editable: false,
              producerContactEmail: producerContact.producerContactEmail,
              producerContactType: producerContact.producerContactType,
              invalid: false,
              producerContactIsNew: false,
              producerContactId: producerContact.producerContactId,
              producerId: producerContact.producerId
            };
            $scope.producerContactRows.push(producerContactObject);
          });
        });

        /**
         * Add a new producerContact to the producerContactRows array.
         */
        $scope.addProducerContact = function() {
          var producerId = '';
          var producerContactName = '';
          var producerContactEmail = '';
          var producerContactType = '';
          var producerContactObject = {
            producerId: producerId,
            producerContactName: producerContactName,
            editable: true,
            producerContactEmail: producerContactEmail,
            producerContactType: producerContactType,
            invalid: false,
            producerContactIsNew: true
          };
          $scope.producerContactRows.push(producerContactObject);
        };

        /**
         * Enable edit mode on a selected producerContact.
         * @param {number} producerContactIndex the index within the producerContactRows array of the producerContact to edit.
         */
        $scope.editProducerContact = function(producerContactIndex) {
          $scope.producerContactRows[producerContactIndex].editable = true;
        };

        /**
         * Save a selected producerContact.
         * @param {number} producerContactIndex the index within the producerContactRows array of the producerContact to save.
         */

        $scope.saveProducerContact = function(producerContactIndex) {
          if ($scope.producerContactRows[producerContactIndex].producerContactIsNew) {
            producerContactSvc.addProducerContact($scope.sanitizeProducerContact($scope.producerContactRows[producerContactIndex])).then(function(response) {
              $scope.producerContactRows[producerContactIndex].producerContactId = response.data.producerContactId;
            });

            $scope.producerContactRows[producerContactIndex].producerContactIsNew = false;
          } else {
            producerContactSvc.updateProducerContact($scope.sanitizeProducerContact($scope.producerContactRows[producerContactIndex]));
          }

          $scope.producerContactRows[producerContactIndex].editable = false;
        };

        /**
         * Prompt the user for confirmation they want to delete a producerContact.
         * @param {number} producerContactIndex the index within the producerContactRows array of the producerContact to delete.
         */
        $scope.deleteProducerContact = function(producerContactIndex, ev) {
          var deleteProducerContact = $mdDialog.confirm()
            .title('Are you sure you want to delete this ProducerContact?')
            .ariaLabel('Delete ProducerContact')
            .targetEvent(ev)
            .ok('Delete ProducerContact')
            .cancel('Cancel');
          $mdDialog.show(deleteProducerContact).then(function() {
            $scope.performDelete(producerContactIndex);
          });
        };

        /**
         * Delete a selected producerContact after verification.
         * @param {number} producerContactIndex the index within the producerContactRows array of the producerContact to delete.
         */
        $scope.performDelete = function(producerContactIndex) {
          console.log($scope.producerContactRows[producerContactIndex]);
          if (!$scope.producerContactRows[producerContactIndex].producerContactIsNew) {
            producerContactSvc.deleteProducerContact($scope.producerContactRows[producerContactIndex].producerContactId, $scope.producerId);
          }

          $scope.producerContactRows.splice(producerContactIndex, 1);
        };


        /**
         * Save the producer information to the backend
         */
        $scope.saveProducer = function() {
          var docObjects = [];
          var timestamp = new Date().getTime();
          var user = null;

          if ($rootScope.apmHeader) {
            user = $rootScope.apmHeader.userI;
          }

          _.forEach($scope.selectedDocs, function(doc) {
            var docObject = {
              documentid: doc.documentId,
              producerId: $scope.producerId,
              approvedby: user,
              dateapproved: timestamp
            };
            docObjects.push(docObject);
          });

          $scope.producer.documentList = docObjects;
          producerSvc.saveProducerInfo($scope.producer);
        };
      }]);

Test Class

describe('Test Producer Contact', function() {
  //Add an initialize here:
  var $scope;
  var $rootScope;
  var controller;

  // deferred variables
  var getProducerDefer;
  var getProducerContactsDefer;
  var addProducerContactDefer;
  var updateProducerContactDefer;
  var deleteProducerContactDefer;

  var producerContactSvc;

  var mockProducerContacts = [{
      producerContactId: '11111',
      producerId: '1111',
      producerContactName: 'abcd',
      producerContactEmail: 'abcd@abc.com',
      producerContactType: 'cc',
      editable: false,
      invalid: false,
      producerContactIsNew: false
    },
    {
      producerContactId: '11112',
      producerId: '1111',
      producerContactName: 'efgh',
      producerContactEmail: 'efgh@xyc.com',
      producerContactType: 'primary',
      editable: false,
      invalid: false,
      producerContactIsNew: false
    },
    {
      producerContactId: '12345',
      producerId: '1111',
      producerContactName: 'asdh',
      producerContactEmail: 'asdh@xyc.com',
      producerContactType: 'cc',
      editable: false,
      invalid: false,
      producerContactIsNew: false
    }
  ];

  beforeEach(module('FirstSaleApp'));

  beforeEach(inject(function($controller, producerSvc, producerContactSvc, _$q_, _$rootScope_) {
    $scope = _$rootScope_.$new();
    $rootScope = _$rootScope_;
    producerContactSvc.deleteProducerContact = function() {
      return null;
    };

    // We use the $q service to create a mock instance of defer
    getProducerDefer = _$q_.defer();
    getProducerContactsDefer = _$q_.defer();
    addProducerContactDefer = _$q_.defer();
    updateProducerContactDefer = _$q_.defer();
    deleteProducerContactDefer = _$q_.defer();

    // Use a Jasmine Spy to return the deferred promise
    spyOn(producerSvc, 'getAllProducers').and.returnValue(getProducerDefer.promise);
    spyOn(producerContactSvc, 'getProducerContacts').and.returnValue(getProducerContactsDefer.promise);
    spyOn(producerContactSvc, 'addProducerContact').and.returnValue(addProducerContactDefer.promise);
    spyOn(producerContactSvc, 'updateProducerContact').and.returnValue(updateProducerContactDefer.promise);
    spyOn(producerContactSvc, 'deleteProducerContact').and.returnValue(deleteProducerContactDefer.promise);

    $controller('producerAdminCtrl', {
      $scope: $scope,
      producerSvc: producerSvc,
      producerContactSvc: producerContactSvc
    });

    // getProducerDefer.resolve(mockProducers);
    getProducerContactsDefer.resolve(mockProducerContacts);
    //  $scope.$digest();
    $rootScope.$digest();
  }));

  it('controller exists', function() {
    expect(controller).not.toBeNull();
  });

  it('should get the producerContacts from the producerContact service', function() {

    // $scope.producerContactRows = $scope.getProducerContacts(1111);

    // The length should match
    expect($scope.producerContactRows.length).toBe(3); // <-- coming as 0

    // The values should be the same too
    // Mock 1
    expect($scope.producerContactRows[0].producerContactName).toBe(mockProducerContacts[0].producerContactName);
    expect($scope.producerContactRows[0].producerContactEmail).toBe(mockProducerContacts[0].producerContactEmail);
    expect($scope.producerContactRows[0].producerContactType).toBe(mockProducerContacts[0].producerContactType);
    expect($scope.producerContactRows[0].editable).toBeFalsy();
    expect($scope.producerContactRows[0].producerContactIsNew).toBeFalsy();

    // Mock 2
    expect($scope.producerContactRows[1].producerContactName).toBe(mockProducerContacts[1].producerContactName);
    expect($scope.producerContactRows[1].producerContactEmail).toBe(mockProducerContacts[1].producerContactEmail);
    expect($scope.producerContactRows[1].producerContactType).toBe(mockProducerContacts[1].producerContactType);
    expect($scope.producerContactRows[1].editable).toBeFalsy();
    expect($scope.producerContactRows[1].producerContactIsNew).toBeFalsy();

    // Mock 3
    expect($scope.producerContactRows[2].producerContactName).toBe(mockProducerContacts[2].producerContactName);
    expect($scope.producerContactRows[2].producerContactEmail).toBe(mockProducerContacts[2].producerContactEmail);
    expect($scope.producerContactRows[2].producerContactType).toBe(mockProducerContacts[2].producerContactType);
    expect($scope.producerContactRows[2].editable).toBeFalsy();
    expect($scope.producerContactRows[2].producerContactIsNew).toBeFalsy();

  });
});

I'm new to angularjs - I have started working on an app that uses karma and jasmine to test. I am trying to use deferred promise to stub a method call. However I don't see the data after I digest (or apply) the scope. Any help is appreciated on what I might be missing. Thanks

Aucun commentaire:

Enregistrer un commentaire