Jasmine tests

This commit is contained in:
augier 2015-11-23 19:58:51 +01:00 committed by Steffen van Bergerem
parent f1e8c57c26
commit b1d60d7c9a
6 changed files with 628 additions and 100 deletions

View file

@ -8,8 +8,8 @@
app.views.PublisherMention = app.views.SearchBase.extend({
KEYS: {
BACKSPACE: 8, TAB: 9, RETURN: 13, ESC: 27, LEFT: 37, UP: 38,
RIGHT: 39, DOWN: 40, COMMA: 188, SPACE: 32, HOME: 36, END: 35
PASTE: 118, BACKSPACE: 8, TAB: 9, RETURN: 13, ESC: 27, LEFT: 37,
UP: 38, RIGHT: 39, DOWN: 40, COMMA: 188, SPACE: 32, HOME: 36, END: 35
},
settings: {
@ -23,33 +23,13 @@ app.views.PublisherMention = app.views.SearchBase.extend({
}
},
utils: {
setCaretPosition: function(domNode, caretPos){
if(domNode.createTextRange){
var range = domNode.createTextRange();
range.move("character", caretPos);
range.select();
} else{
if(domNode.selectionStart){
domNode.focus();
domNode.setSelectionRange(caretPos, caretPos);
} else{
domNode.focus();
}
}
},
rtrim: function(string){
return string.replace(/\s+$/, "");
}
},
events: {
"keydown #status_message_fake_text": "onInputBoxKeyDown",
"keypress #status_message_fake_text": "onInputBoxKeyPress",
"input #status_message_fake_text": "onInputBoxInput",
"click #status_message_fake_text": "onInputBoxClick",
"blur #status_message_fake_text": "onInputBoxBlur"
"blur #status_message_fake_text": "onInputBoxBlur",
"paste #status_message_fake_text": "onInputBoxPaste"
},
initialize: function(){
@ -66,21 +46,24 @@ app.views.PublisherMention = app.views.SearchBase.extend({
this.elmMentionsOverlay = $(this.settings.templates.mentionsOverlay());
this.elmMentionsOverlay.prependTo(this.elmWrapperBox);
this.bindMentionningEvents();
this.completeSetup(this.getTypeaheadInput());
this.$el.find(".twitter-typeahead").css({position: "absolute", left: "-1px"});
this.$el.find(".twitter-typeahead .tt-menu").css("margin-top", 0);
},
bindMentionningEvents: function(){
var self = this;
this.getSearchInput().on("typeahead:select", function(evt, datum){
this.getTypeaheadInput().on("typeahead:select", function(evt, datum){
self.processMention(datum);
self.resetMentionBox();
self.addToFilteredResults(datum);
});
this.getSearchInput().on("typeahead:render", function(){
this.getTypeaheadInput().on("typeahead:render", function(){
self.select(self.$(".tt-menu .tt-suggestion").first());
});
this.completeSetup(this.getSearchInput());
this.$el.find(".twitter-typeahead").css({position: "absolute", left: "-1px"});
this.$el.find(".twitter-typeahead .tt-menu").css("margin-top", 0);
},
clearBuffer: function(){
@ -110,12 +93,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({
processMention: function(mention){
var currentMessage = this.getInputBoxValue();
// Using a regex to figure out positions
var regex = new RegExp("\\" + this.settings.triggerChar + this.currentDataQuery, "gi");
regex.exec(currentMessage);
var startCaretPosition = regex.lastIndex - this.currentDataQuery.length - 1;
var currentCaretPosition = regex.lastIndex;
var currentCaretPosition = this.getCaretPosition();
var startCaretPosition = currentCaretPosition - (this.currentDataQuery.length + 1);
var start = currentMessage.substr(0, startCaretPosition);
var end = currentMessage.substr(currentCaretPosition, currentMessage.length);
@ -135,7 +114,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
// Set correct focus and selection
this.elmInputBox.focus();
this.utils.setCaretPosition(this.elmInputBox[0], startEndIndex);
this.setCaretPosition(startEndIndex);
},
updateValues: function(){
@ -153,7 +132,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
var textSyntax = self.settings.templates.mentionItemSyntax(mention);
syntaxMessage = syntaxMessage.replace(mentionVal, textSyntax);
var textHighlight = self.settings.templates.mentionItemHighlight({ name: _.escape(mention.name) });
var textHighlight = self.settings.templates.mentionItemHighlight({name: _.escape(mention.name)});
mentionText = mentionText.replace(mentionVal, textHighlight);
});
@ -174,7 +153,11 @@ app.views.PublisherMention = app.views.SearchBase.extend({
_.each(persons, function(person){
self.addMention(person);
self.addToFilteredResults(person);
self.elmInputBox.val(self.mentionChar + person.name);
var text = self.mentionChar + person.name;
if(self.elmInputBox.val().length !== 0){
text = self.elmInputBox.val() + " " + text;
}
self.elmInputBox.val(text);
self.updateValues();
});
},
@ -210,7 +193,8 @@ app.views.PublisherMention = app.views.SearchBase.extend({
},
onInputBoxKeyPress: function(e){
if(e.keyCode !== this.KEYS.BACKSPACE){
// Excluding ctrl+v from key press event in firefox
if(!((e.which === this.KEYS.PASTE && e.ctrlKey) || (e.keyCode === this.KEYS.BACKSPACE))){
var typedValue = String.fromCharCode(e.which || e.keyCode);
this.inputBuffer.push(typedValue);
}
@ -223,7 +207,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
var triggerCharIndex = _.lastIndexOf(this.inputBuffer, this.settings.triggerChar);
if(triggerCharIndex > -1){
this.currentDataQuery = this.inputBuffer.slice(triggerCharIndex + 1).join("");
this.currentDataQuery = this.utils.rtrim(this.currentDataQuery);
this.currentDataQuery = this.rtrim(this.currentDataQuery);
this.showMentionBox();
}
@ -232,7 +216,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
onInputBoxKeyDown: function(e){
// This also matches HOME/END on OSX which is CMD+LEFT, CMD+RIGHT
if(e.keyCode === this.KEYS.LEFT || e.keyCode === this.KEYS.RIGHT ||
e.keyCode === this.KEYS.HOME || e.keyCode === this.KEYS.END){
e.keyCode === this.KEYS.HOME || e.keyCode === this.KEYS.END){
_.defer(this.clearBuffer);
// IE9 doesn't fire the oninput event when backspace or delete is pressed. This causes the highlighting
@ -268,7 +252,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
case this.KEYS.RETURN:
case this.KEYS.TAB:
if(this.getSelected().size() === 1){
this.getSelected().click();
this.getSelected().click();
return false;
}
break;
@ -284,6 +268,15 @@ app.views.PublisherMention = app.views.SearchBase.extend({
this.resetMentionBox();
},
onInputBoxPaste: function(evt){
var pastedData = evt.originalEvent.clipboardData.getData("text/plain");
var dataArray = pastedData.split("");
var self = this;
_.each(dataArray, function(value){
self.inputBuffer.push(value);
});
},
reset: function(){
this.elmInputBox.val("");
this.mentionsCollection.length = 0;
@ -292,13 +285,13 @@ app.views.PublisherMention = app.views.SearchBase.extend({
},
showMentionBox: function(){
this.getSearchInput().typeahead("val", this.currentDataQuery);
this.getSearchInput().typeahead("open");
this.getTypeaheadInput().typeahead("val", this.currentDataQuery);
this.getTypeaheadInput().typeahead("open");
},
resetMentionBox: function(){
this.getSearchInput().typeahead("val", "");
this.getSearchInput().typeahead("close");
this.getTypeaheadInput().typeahead("val", "");
this.getTypeaheadInput().typeahead("close");
},
getInputBoxValue: function(){
@ -309,7 +302,7 @@ app.views.PublisherMention = app.views.SearchBase.extend({
return this.$el.find(".tt-menu").is(":visible");
},
getSearchInput: function(){
getTypeaheadInput: function(){
if(this.$el.find(".typeahead-mention-box").length === 0){
this.elmInputBox.after("<input class='typeahead-mention-box hidden' type='text'/>");
}
@ -318,5 +311,18 @@ app.views.PublisherMention = app.views.SearchBase.extend({
getTextForSubmit: function(){
return this.mentionsCollection.length ? this.elmInputBox.data("messageText") : this.getInputBoxValue();
},
setCaretPosition: function(caretPos){
this.elmInputBox[0].focus();
this.elmInputBox[0].setSelectionRange(caretPos, caretPos);
},
getCaretPosition: function(){
return this.elmInputBox[0].selectionStart;
},
rtrim: function(string){
return string.replace(/\s+$/, "");
}
});

View file

@ -98,18 +98,19 @@ app.views.SearchBase = app.views.Base.extend({
*/
bindSelectionEvents: function(){
var self = this;
var onover = function(evt){
var isSuggestion = $(evt.target).is(".tt-suggestion");
var suggestion = isSuggestion ? $(evt.target) : $(evt.target).parent(".tt-suggestion");
if(suggestion){
var onover = function(suggestion){
return function(){
self.select(suggestion);
}
};
};
this.typeaheadElement.on("typeahead:render", function(){
self.$(".tt-menu *").off("mouseover", onover);
self.$(".tt-menu .tt-suggestion").on("mouseover", onover);
self.$(".tt-menu .tt-suggestion *").on("mouseover", onover);
self.$(".tt-menu *").off("mouseover");
self.$(".tt-menu .tt-suggestion").each(function(){
var $suggestion = $(this);
$suggestion.on("mouseover", onover($suggestion));
$suggestion.find("*").on("mouseover", onover($suggestion));
});
});
},

View file

@ -17,7 +17,12 @@
}
.container-fluid{ padding: 0; }
.mentions-autocomplete-list ul { width: 100% !important; }
.twitter-typeahead {
width: calc(100% + 2px);
.tt-menu { width: 100%; }
}
form {
margin: 0;

View file

@ -0,0 +1,322 @@
describe("app.views.PublisherMention", function(){
beforeEach(function(){
spec.content().html(
"<div id='publisher'>" +
"<textarea id='status_message_fake_text'></textarea>" +
"</div>");
});
describe("initialize", function(){
beforeEach(function(){
spyOn(app.views.PublisherMention.prototype, "completeSetup").and.callThrough();
spyOn(app.views.PublisherMention.prototype, "bindMentionningEvents").and.callThrough();
this.view = new app.views.PublisherMention({ el: "#publisher" });
});
it("initializes object properties", function(){
expect(this.view.mentionsCollection).toEqual([]);
expect(this.view.inputBuffer).toEqual([]);
expect(this.view.currentDataQuery).toBe("");
expect(this.view.mentionChar).toBe("\u200B");
});
it("calls completeSetup", function(){
expect(app.views.PublisherMention.prototype.completeSetup).toHaveBeenCalledWith(this.view.getTypeaheadInput());
expect(app.views.PublisherMention.prototype.bindMentionningEvents).toHaveBeenCalled();
});
it("initializes html elements", function(){
expect(this.view.$(".typeahead-mention-box").length).toBe(1);
expect(this.view.$(".mentions-input-box").length).toBe(1);
expect(this.view.$(".mentions-box").length).toBe(1);
expect(this.view.$(".mentions").length).toBe(1);
});
});
describe("bindMentionningEvents", function(){
beforeEach(function(){
spyOn(app.views.PublisherMention.prototype, "processMention");
spyOn(app.views.PublisherMention.prototype, "resetMentionBox");
spyOn(app.views.PublisherMention.prototype, "addToFilteredResults");
this.view = new app.views.PublisherMention({ el: "#publisher" });
this.view.bloodhound.add([
{"person": true, "name":"user1", "handle":"user1@pod.tld"},
{"person": true, "name":"user2", "handle":"user2@pod.tld"}
]);
});
it("highlights the first item when rendering results", function(){
this.view.getTypeaheadInput().typeahead("val", "user");
this.view.getTypeaheadInput().typeahead("open");
expect(this.view.$(".tt-suggestion").first()).toHaveClass("tt-cursor");
});
it("process mention when clicking a result", function(){
this.view.getTypeaheadInput().typeahead("val", "user");
this.view.getTypeaheadInput().typeahead("open");
this.view.$(".tt-suggestion").first().click();
expect(app.views.PublisherMention.prototype.processMention).toHaveBeenCalled();
expect(app.views.PublisherMention.prototype.resetMentionBox).toHaveBeenCalled();
expect(app.views.PublisherMention.prototype.addToFilteredResults).toHaveBeenCalled();
});
});
describe("updateMentionsCollection", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
});
it("removes person from mention collection if not mentionned anymore", function(){
this.view.mentionsCollection.push({name: "user1"});
expect(this.view.mentionsCollection.length).toBe(1);
this.view.updateMentionsCollection();
expect(this.view.mentionsCollection.length).toBe(0);
});
it("removes item from mention collection if not a person", function(){
this.view.mentionsCollection.push({});
expect(this.view.mentionsCollection.length).toBe(1);
this.view.updateMentionsCollection();
expect(this.view.mentionsCollection.length).toBe(0);
});
});
describe("addMention", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
});
it("add person to mentionned people", function(){
expect(this.view.mentionsCollection.length).toBe(0);
this.view.addMention({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.mentionsCollection.length).toBe(1);
expect(this.view.mentionsCollection[0]).toEqual({
/* jshint camelcase: false */
"name":"user1", "handle":"user1@pod.tld", diaspora_id: "user1@pod.tld"});
/* jshint camelcase: true */
});
it("does not add mention if not a person", function(){
expect(this.view.mentionsCollection.length).toBe(0);
this.view.addMention();
expect(this.view.mentionsCollection.length).toBe(0);
this.view.addMention({});
expect(this.view.mentionsCollection.length).toBe(0);
this.view.addMention({"name": "user1"});
expect(this.view.mentionsCollection.length).toBe(0);
this.view.addMention({"handle":"user1@pod.tld"});
expect(this.view.mentionsCollection.length).toBe(0);
});
});
describe("getTypeaheadInput", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
});
it("inserts typeahead input if it does not already exist", function(){
this.view.getTypeaheadInput().remove();
expect(this.view.$(".typeahead-mention-box").length).toBe(0);
this.view.getTypeaheadInput();
expect(this.view.$(".typeahead-mention-box").length).toBe(1);
});
});
describe("processMention", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
this.view.elmInputBox.val("@user1 Text before @user1 text after");
this.view.currentDataQuery = "user1";
this.view.elmInputBox[0].setSelectionRange(25, 25);
});
it("add person to mentionned people", function(){
spyOn(this.view, "addMention");
this.view.processMention({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.addMention).toHaveBeenCalledWith({"name":"user1", "handle":"user1@pod.tld"});
});
it("cleans buffers", function(){
spyOn(this.view, "clearBuffer");
spyOn(this.view, "resetMentionBox");
this.view.processMention({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.clearBuffer).toHaveBeenCalled();
expect(this.view.resetMentionBox).toHaveBeenCalled();
expect(this.view.currentDataQuery).toBe("");
});
it("correctly formats the text", function(){
spyOn(this.view, "updateValues");
this.view.processMention({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.updateValues).toHaveBeenCalled();
expect(this.view.getInputBoxValue()).toBe("@user1 Text before " + this.view.mentionChar + "user1 text after");
});
it("places the caret at the right position", function(){
this.view.processMention({"name":"user1WithLongName", "handle":"user1@pod.tld"});
var expectedCaretPosition = ("@user1 Text before " + this.view.mentionChar + "user1WithLongName").length;
expect(this.view.elmInputBox[0].selectionStart).toBe(expectedCaretPosition);
});
});
describe("updateValues", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
this.view.elmInputBox.val("@user1 Text before " + this.view.mentionChar + "user1\ntext after");
this.view.mentionsCollection.push({"name":"user1", "handle":"user1@pod.tld"});
});
it("filters mention from future results", function(){
spyOn(this.view, "clearFilteredResults");
spyOn(this.view, "addToFilteredResults");
this.view.updateValues();
expect(this.view.clearFilteredResults).toHaveBeenCalled();
expect(this.view.addToFilteredResults).toHaveBeenCalledWith({"name":"user1", "handle":"user1@pod.tld"});
});
it("formats message text data with correct mentionning syntax", function(){
this.view.updateValues();
expect(this.view.elmInputBox.data("messageText")).toBe("@user1 Text before @{user1 ; user1@pod.tld}\ntext after");
});
it("formats overlay text to HTML", function(){
this.view.updateValues();
expect(this.view.elmMentionsOverlay.find("div > div").html())
.toBe("@user1 Text before <strong><span>user1</span></strong><br>text after");
});
});
describe("prefillMention", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
spyOn(this.view, "addMention");
spyOn(this.view, "addToFilteredResults");
spyOn(this.view, "updateValues");
});
it("prefills one mention", function(){
this.view.prefillMention([{"name":"user1", "handle":"user1@pod.tld"}]);
expect(this.view.addMention).toHaveBeenCalledWith({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.addToFilteredResults)
.toHaveBeenCalledWith({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.updateValues).toHaveBeenCalled();
expect(this.view.getInputBoxValue()).toBe(this.view.mentionChar + "user1");
});
it("prefills multiple mentions", function(){
this.view.prefillMention([
{"name":"user1", "handle":"user1@pod.tld"},
{"name":"user2", "handle":"user2@pod.tld"}
]);
expect(this.view.addMention).toHaveBeenCalledWith({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.addMention).toHaveBeenCalledWith({"name":"user2", "handle":"user2@pod.tld"});
expect(this.view.addToFilteredResults).toHaveBeenCalledWith({"name":"user1", "handle":"user1@pod.tld"});
expect(this.view.addToFilteredResults).toHaveBeenCalledWith({"name":"user2", "handle":"user2@pod.tld"});
expect(this.view.updateValues).toHaveBeenCalled();
expect(this.view.getInputBoxValue()).toBe(this.view.mentionChar + "user1 " + this.view.mentionChar + "user2");
});
});
describe("onInputBoxPaste", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
});
it("add person to mentionned people", function(){
var pasteEvent = {originalEvent: {clipboardData: {getData: function(){
return "Pasted text";
}}}};
this.view.onInputBoxPaste(pasteEvent);
expect(this.view.inputBuffer).toEqual(["P", "a", "s", "t", "e", "d", " ", "t", "e", "x", "t"]);
});
});
describe("reset", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
spyOn(this.view, "clearFilteredResults");
spyOn(this.view, "updateValues");
});
it("resets the mention box", function(){
this.view.reset();
expect(this.view.elmInputBox.val()).toBe("");
expect(this.view.mentionsCollection.length).toBe(0);
expect(this.view.clearFilteredResults).toHaveBeenCalled();
expect(this.view.updateValues).toHaveBeenCalled();
});
});
describe("showMentionBox", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
this.view.bloodhound.add([
{"person": true, "name":"user1", "handle":"user1@pod.tld"}
]);
this.view.currentDataQuery = "user1";
});
it("shows the mention box", function(){
expect(this.view.$(".tt-menu").is(":visible")).toBe(false);
expect(this.view.$(".tt-menu .tt-suggestion").length).toBe(0);
this.view.showMentionBox();
expect(this.view.$(".tt-menu").is(":visible")).toBe(true);
expect(this.view.$(".tt-menu .tt-suggestion").length).toBe(1);
});
});
describe("resetMentionBox", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
this.view.bloodhound.add([
{"person": true, "name":"user1", "handle":"user1@pod.tld"}
]);
});
it("resets results and closes mention box", function(){
this.view.getTypeaheadInput().typeahead("val", "user");
this.view.getTypeaheadInput().typeahead("open");
expect(this.view.$(".tt-menu").is(":visible")).toBe(true);
expect(this.view.$(".tt-menu .tt-suggestion").length >= 1).toBe(true);
this.view.resetMentionBox();
expect(this.view.$(".tt-menu").is(":visible")).toBe(false);
expect(this.view.$(".tt-menu .tt-suggestion").length).toBe(0);
});
});
describe("getInputBoxValue", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
});
it("returns trimmed text", function(){
this.view.elmInputBox.val("Text with trailing spaces ");
expect(this.view.getInputBoxValue()).toBe("Text with trailing spaces");
});
});
describe("getTextForSubmit", function(){
beforeEach(function(){
this.view = new app.views.PublisherMention({ el: "#publisher" });
this.view.bloodhound.add([
{"person": true, "name":"user1", "handle":"user1@pod.tld"}
]);
});
it("returns text with mention syntax if someone is mentionned", function(){
this.view.getTypeaheadInput().typeahead("val", "user");
this.view.getTypeaheadInput().typeahead("open");
this.view.$(".tt-suggestion").first().click();
expect(this.view.getTextForSubmit()).toBe("@{user1 ; user1@pod.tld}");
});
it("returns normal text if nobody is mentionned", function(){
this.view.elmInputBox.data("messageText", "Bad text");
this.view.elmInputBox.val("Good text");
expect(this.view.getTextForSubmit()).toBe("Good text");
});
});
});

View file

@ -0,0 +1,183 @@
describe("app.views.SearchBase", function() {
beforeEach(function(){
spec.content().html(
"<form action='/search' id='search_people_form'><input id='q' name='q' type='search'></input></form>"
);
});
describe("completeSetup", function(){
it("calls setupBloodhound", function(){
spyOn(app.views.SearchBase.prototype, "setupBloodhound").and.callThrough();
var view = new app.views.SearchBase({el: "#search_people_form"});
view.completeSetup();
expect(app.views.SearchBase.prototype.setupBloodhound).toHaveBeenCalled();
});
it("calls setupTypeahead", function(){
spyOn(app.views.SearchBase.prototype, "setupTypeahead");
var view = new app.views.SearchBase({el: "#search_people_form"});
view.completeSetup();
expect(app.views.SearchBase.prototype.setupTypeahead).toHaveBeenCalled();
});
it("calls bindSelectionEvents", function(){
spyOn(app.views.SearchBase.prototype, "bindSelectionEvents");
var view = new app.views.SearchBase({el: "#search_people_form"});
view.completeSetup();
expect(app.views.SearchBase.prototype.bindSelectionEvents).toHaveBeenCalled();
});
it("initializes the results to filter", function(){
spyOn(app.views.SearchBase.prototype, "bindSelectionEvents");
var view = new app.views.SearchBase({el: "#search_people_form"});
view.completeSetup();
expect(view.resultsTofilter.length).toBe(0);
});
});
describe("setupBloodhound", function(){
beforeEach(function(){
this.view = new app.views.SearchBase({el: "#search_people_form"});
this.syncCallback = function(){};
this.asyncCallback = function(){};
});
context("when performing a local search with 1 filtered result", function(){
beforeEach(function(){
this.view.completeSetup(this.view.$("#q"));
this.view.bloodhound.add([
{"id":1,"guid":"1","name":"user1","handle":"user1@pod.tld","url":"/people/1"},
{"id":2,"guid":"2","name":"user2","handle":"user2@pod.tld","url":"/people/2"}
]);
});
it("should not return the filtered result", function(){
spyOn(this, "syncCallback");
spyOn(this, "asyncCallback");
this.view.bloodhound.customSearch("user", this.syncCallback, this.asyncCallback);
expect(this.syncCallback).toHaveBeenCalledWith([
{"id":1,"guid":"1","name":"user1","handle":"user1@pod.tld","url":"/people/1"},
{"id":2,"guid":"2","name":"user2","handle":"user2@pod.tld","url":"/people/2"}
]);
expect(this.asyncCallback).not.toHaveBeenCalled();
this.view.addToFilteredResults({"id":1,"guid":"1","name":"user1","handle":"user1@pod.tld","url":"/people/1"});
this.view.bloodhound.customSearch("user", this.syncCallback, this.asyncCallback);
expect(this.syncCallback).toHaveBeenCalledWith(
[{"id":2,"guid":"2","name":"user2","handle":"user2@pod.tld","url":"/people/2"}]);
expect(this.asyncCallback).not.toHaveBeenCalled();
});
});
});
describe("transformBloodhoundResponse", function() {
beforeEach(function() {
this.view = new app.views.SearchBase({ el: "#search_people_form" });
});
context("with persons", function() {
beforeEach(function() {
this.response = [{name: "Person", handle: "person@pod.tld"},{name: "User", handle: "user@pod.tld"}];
});
it("sets data.person to true", function() {
expect(this.view.transformBloodhoundResponse(this.response)).toEqual([
{name: "Person", handle: "person@pod.tld", person: true},
{name: "User", handle: "user@pod.tld", person: true}
]);
});
});
context("with hashtags", function() {
beforeEach(function() {
this.response = [{name: "#tag"}, {name: "#hashTag"}];
});
it("sets data.hashtag to true and adds the correct URL", function() {
expect(this.view.transformBloodhoundResponse(this.response)).toEqual([
{name: "#tag", hashtag: true, url: Routes.tag("tag")},
{name: "#hashTag", hashtag: true, url: Routes.tag("hashTag")}
]);
});
});
});
describe("bindSelectionEvents", function(){
beforeEach(function() {
this.view = new app.views.SearchBase({ el: "#search_people_form" });
this.view.completeSetup(this.view.$("#q"));
this.view.bloodhound.add([
{"person": true, "name":"user1", "handle":"user1@pod.tld"},
{"person": true, "name":"user2", "handle":"user2@pod.tld"}
]);
});
context("bind over events", function(){
it("binds over event only once", function(){
this.view.$("#q").trigger("focusin");
this.view.$("#q").val("user");
this.view.$("#q").trigger("keypress");
this.view.$("#q").trigger("input");
this.view.$("#q").trigger("focus");
var numBindedEvents = $._data(this.view.$(".tt-menu .tt-suggestion")[0], "events").mouseover.length;
expect(numBindedEvents).toBe(1);
this.view.$("#q").trigger("focusout");
this.view.$("#q").trigger("focusin");
this.view.$("#q").val("user");
this.view.$("#q").trigger("keypress");
this.view.$("#q").trigger("input");
this.view.$("#q").trigger("focus");
numBindedEvents = $._data(this.view.$(".tt-menu .tt-suggestion")[0], "events").mouseover.length;
expect(numBindedEvents).toBe(1);
});
it("highlights the result when overing it", function(){
this.view.$("#q").trigger("focusin");
this.view.$("#q").val("user");
this.view.$("#q").trigger("keypress");
this.view.$("#q").trigger("input");
this.view.$("#q").trigger("focus");
this.view.$(".tt-menu .tt-suggestion").first().trigger("mouseover");
expect(this.view.$(".tt-menu .tt-suggestion").first()).toHaveClass("tt-cursor");
});
});
});
describe("addToFilteredResults", function(){
beforeEach(function() {
this.view = new app.views.SearchBase({ el: "#search_people_form" });
this.view.completeSetup(this.view.$("#q"));
});
context("when item is a person", function(){
it("add the item to filtered results", function(){
this.view.addToFilteredResults({handle: "user@pod.tld"});
expect(this.view.resultsTofilter.length).toBe(1);
});
});
context("when item is not a person", function(){
it("does not add the item to filtered results", function(){
this.view.addToFilteredResults({});
expect(this.view.resultsTofilter.length).toBe(0);
});
});
});
describe("clearFilteredResults", function(){
beforeEach(function() {
this.view = new app.views.SearchBase({ el: "#search_people_form" });
this.view.completeSetup(this.view.$("#q"));
});
context("clear filtered results", function(){
it("clears the filtered results list", function(){
this.view.addToFilteredResults({handle: "user@pod.tld"});
expect(this.view.resultsTofilter.length).toBe(1);
this.view.clearFilteredResults();
expect(this.view.resultsTofilter.length).toBe(0);
});
});
});
});

View file

@ -1,21 +1,63 @@
describe("app.views.Search", function() {
describe("app.views.Search", function(){
beforeEach(function(){
spec.content().html(
"<form action='/search' id='search_people_form'><input id='q' name='q' type='search'></input></form>"
"<form action='/search' id='search_people_form'><input id='q' name='q' type='search'/></form>"
);
});
describe("initialize", function() {
it("calls setupBloodhound", function() {
spyOn(app.views.Search.prototype, "setupBloodhound").and.callThrough();
new app.views.Search({ el: "#search_people_form" });
expect(app.views.Search.prototype.setupBloodhound).toHaveBeenCalled();
describe("initialize", function(){
it("calls completeSetup", function(){
spyOn(app.views.Search.prototype, "completeSetup").and.callThrough();
var view = new app.views.Search({el: "#search_people_form"});
expect(app.views.Search.prototype.completeSetup).toHaveBeenCalledWith(view.getTypeaheadElement());
});
it("calls setupTypeahead", function() {
spyOn(app.views.Search.prototype, "setupTypeahead");
new app.views.Search({ el: "#search_people_form" });
expect(app.views.Search.prototype.setupTypeahead).toHaveBeenCalled();
it("calls bindMoreSelectionEvents", function(){
spyOn(app.views.Search.prototype, "bindMoreSelectionEvents").and.callThrough();
new app.views.Search({el: "#search_people_form"});
expect(app.views.Search.prototype.bindMoreSelectionEvents).toHaveBeenCalled();
});
});
describe("bindMoreSelectionEvents", function(){
beforeEach(function() {
this.view = new app.views.Search({ el: "#search_people_form" });
this.view.bloodhound.add([
{"person": true, "name":"user1", "handle":"user1@pod.tld"},
{"person": true, "name":"user2", "handle":"user2@pod.tld"}
]);
});
context("bind mouseleave event", function(){
it("binds mouseleave event only once", function(){
this.view.$("#q").trigger("focusin");
this.view.$("#q").val("user");
this.view.$("#q").trigger("keypress");
this.view.$("#q").trigger("input");
this.view.$("#q").trigger("focus");
var numBindedEvents = $._data(this.view.$(".tt-menu")[0], "events").mouseout.length;
expect(numBindedEvents).toBe(1);
this.view.$("#q").trigger("focusout");
this.view.$("#q").trigger("focusin");
this.view.$("#q").val("user");
this.view.$("#q").trigger("keypress");
this.view.$("#q").trigger("input");
this.view.$("#q").trigger("focus");
numBindedEvents = $._data(this.view.$(".tt-menu")[0], "events").mouseout.length;
expect(numBindedEvents).toBe(1);
});
it("remove result highlight when leaving results list", function(){
this.view.$("#q").trigger("focusin");
this.view.$("#q").val("user");
this.view.$("#q").trigger("keypress");
this.view.$("#q").trigger("input");
this.view.$("#q").trigger("focus");
this.view.$(".tt-menu .tt-suggestion").first().trigger("mouseover");
expect(this.view.$(".tt-menu .tt-suggestion").first()).toHaveClass("tt-cursor");
this.view.$(".tt-menu").first().trigger("mouseleave");
expect(this.view.$(".tt-menu .tt-cursor").length).toBe(0);
});
});
});
@ -44,35 +86,4 @@ describe("app.views.Search", function() {
});
});
});
describe("transformBloodhoundResponse" , function() {
beforeEach(function() {
this.view = new app.views.Search({ el: "#search_people_form" });
});
context("with persons", function() {
beforeEach(function() {
this.response = [{name: "Person", handle: "person@pod.tld"},{name: "User", handle: "user@pod.tld"}];
});
it("sets data.person to true", function() {
expect(this.view.transformBloodhoundResponse(this.response)).toEqual([
{name: "Person", handle: "person@pod.tld", person: true},
{name: "User", handle: "user@pod.tld", person: true}
]);
});
});
context("with hashtags", function() {
beforeEach(function() {
this.response = [{name: "#tag"}, {name: "#hashTag"}];
});
it("sets data.hashtag to true and adds the correct URL", function() {
expect(this.view.transformBloodhoundResponse(this.response)).toEqual([
{name: "#tag", hashtag: true, url: Routes.tag("tag")},
{name: "#hashTag", hashtag: true, url: Routes.tag("hashTag")}
]);
});
});
});
});