Похоже, что я не могу получить ссылку на правильную область при выполнении тестов по директивам с выделенной областью . Просто чтобы быть ясным, у меня нет этой проблемы для тестов, которые наследуют область.Проблемы при тестировании директив с изолированной областью
Проблема показывает себя, когда для вызова $httpBackend.expectPOST()
я указываю ожидаемые данные.
$httpBackend.expectPOST('/notes/'+scope.note.id+'/replies', {
content: 'This is the reply' /*** TEST PASSES IF EXPECTED POST DATA IS NOT SET ***/
}).respond(200, {
id: 11,
noteId: 199,
content: 'This is the reply'
});
Когда я звоню elem.find('[ng-click="saveReply()"]').click()
, область saveReply() является называется, но ни один из данных, который был установлен получает представлен таким образом, если указать ожидаемые данные, которые он терпит неудачу, но если я не указываю ожидаемые данные, которые он передает. Очевидно, чтобы иметь более полные тесты, я бы хотел выполнить первое.
Как уже упоминалось выше, метод saveReply() вызывается после вызова метода click(). Это заставило бы думать, что надлежащее связывание областей на месте, но если я непосредственно установил переменную области видимости, она все еще не видна в методе области видимости. Возможно, именно здесь проблема/решение ...
Я бы подумал, что требуемая ссылка на сферу может быть получена через elem.scope()
, но когда я делаю это, elem.scope() совпадает с $ rootScope.
// FAILS
expect(elem.scope().$id).not.toEqual($rootScope.$id);
Любые идеи?
'use strict';
describe('Note directive', function() {
var scope, elem;
var compile = function($compile, $rootScope, PhotoService) {
spyOn(PhotoService, 'profilePhotoUrl').andReturn('mypic.jpg');
scope = $rootScope;
scope.note = {
id: 199,
content: 'This is the note',
author: {
firstName: 'Jim',
lastName: 'Smith',
name: 'Jim Smith',
profilePhotoName: 'mypic.jpg'
},
replies: [
{id: 99, content: 'you should not see this on initial load', author: {
firstName: 'Jim', lastName: 'Smith', name: 'Jim Smith', profilePhotoName: 'mypic.jpg'}
},
{id: 99, content: 'but you should see this one', author: {
firstName: 'Jim', lastName: 'Smith', name: 'Jim Smith', profilePhotoName: 'mypic.jpg'}
}
]
};
elem = $compile('<note data="note"></note>')(scope);
scope.$digest();
};
var stubCurrentUser = function ($httpBackend) {
$httpBackend.expectGET('/users/me').respond({id: 99, name: 'Jim Smith', role: 'owner'});
};
beforeEach(module('woddy'));
beforeEach(module('directive_templates'));
beforeEach(inject(stubCurrentUser, compile));
iit('allows the user to reply to a note', inject(function ($httpBackend) {
$httpBackend.expectPOST('/notes/'+scope.note.id+'/replies', {
content: 'This is the reply' /*** TEST PASSES IF EXPECTED POST DATA IS NOT SET ***/
}).respond(200, {
id: 11,
noteId: 199,
content: 'This is the reply'
});
expect(elem.find('[ng-repeat="reply in note.replies"]').length).toBe(2);
elem.find('[ng-click="reply()"]').click();
scope.$digest();
elem.find('[ng-model="content"]').text("This is the reply");
scope.$digest();
elem.find('[ng-click="saveReply()"]').click();
$httpBackend.flush();
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
scope.$digest();
expect(elem.find('[ng-repeat="reply in note.replies"]').length).toBe(3);
}));
});
Директива
'use strict';
angular.module('woddy').directive('note', function() {
return {
restrict: 'E',
scope: {
note: '=data'
},
templateUrl: '/dashboard/note.html',
controller: function($scope, PhotoService, Reply, CurrentUser) {
$scope.state = 'show';
$scope.showAllReplies = false;
CurrentUser.get().then(function(user) {
$scope.currentUser = user;
});
/**
* Reply on the note
*/
$scope.reply = function() {
$scope.content = '';
$scope.state = 'add';
};
/**
* Revert back to the default view
*/
$scope.reset = function() {
$scope.content = 'Add a comment...';
$scope.state = 'show';
};
$scope.saveReply = function() {
console.log("It is calling the method")
var reply = new Reply({
noteId: $scope.note.id,
content: $scope.content
});
reply.$save(function() {
var author = $scope.currentUser;
$scope.note.replies.push({
content: $scope.content,
author: {
id: author.id,
name: author.name,
photoName: author.photoName,
gender: author.gender
}
});
$scope.reset();
});
};
}
};
});
Посмотреть
<div class="note box">
<img class="author" ng-src="{{authorPhotoUrl()}}" alt="{{note.author.name}}"/>
<div class="details">
<div class="name" ng-bind="note.author.name"></div>
<div class="timestamp" timestamp="{{note.timestamp}}"></div>
</div>
<div class="content" ng-bind-html="note.content"></div>
<div class="note-replies" ng-if="note.replies.length > 0">
<div class="links">
<span>{{note.replies.length}} {{note.replies.length == 1 ? 'Comment' : 'Comments'}}</span>
<a href="#" ng-show="!showAllReplies && note.replies.length > 1" ng-click="showAllReplies = true">Show Comments</a>
<a href="#" ng-show="showAllReplies && note.replies.length > 1" ng-click="showAllReplies = false">Hide Comments</a>
</div>
<div class="replies">
<div class="reply" ng-repeat="reply in note.replies" ng-show="showAllReplies || $last">
<img ng-src="{{replyAuthorPhotoUrl(reply.author)}}" alt="{{reply.author.name}}">
<div class="reply-details">
<span class="name" ng-bind="reply.author.name"></span>
<span class="timestamp" timestamp="{{reply.timestamp}}"></span>
<div class="content" ng-bind-html="reply.content"></div>
</div>
</div>
</div>
</div>
<div class="reply-form">
<div class="reply-content" ng-click="reply()" contenteditable="true" ng-model="content">Add a comment...</div>
<form ng-show="state == 'add'">
<div class="text-right">
<button class="secondary" ng-click="reset()">Cancel</button>
<button ng-click="saveReply()">Comment</button>
</div>
</form>
</div>
</div>
Это один из ответов, которые я получил от совета IRC, но в этом случае isolateScope() возвращает нуль. Проблема в том, почему игнорируются значения значений элемента формы. ex 'elem.find ('[ng-model =" content "]'). text (" Это ответ ")' // это значение не попадает в httpBackend – chris
У вас есть пользовательский '' 'contenteditable '' 'директива? Угловое не поддерживает '' 'contenteditable''' из коробки, хотя есть много примеров. Проблема документирована [здесь] (https://github.com/angular/angular.js/issues/528) – rgaskill
Я делаю и хорошо работает при использовании приложения через браузер, однако это все данные, а не только контент-ориентированные связанные данные, которые не отправляются. – chris