diff --git a/app/controllers/status_messages_controller.rb b/app/controllers/status_messages_controller.rb index b4151a935a945feeee198f740265baef1316e3d2..620fa8e4044e82da055cf0f48161fb79a0a01f41 100644 --- a/app/controllers/status_messages_controller.rb +++ b/app/controllers/status_messages_controller.rb @@ -4,11 +4,12 @@ class StatusMessagesController < ApplicationController before_filter :authenticate_user! - + before_filter :remove_getting_started, :only => [:create] - respond_to :html - respond_to :mobile + respond_to :html, + :mobile, + :json # Called when a user clicks "Mention" on a profile page # @param person_id [Integer] The id of the person to be mentioned @@ -40,8 +41,7 @@ class StatusMessagesController < ApplicationController end def create - params[:status_message][:aspect_ids] = params[:aspect_ids] - + params[:status_message][:aspect_ids] = [*params[:aspect_ids]] normalize_public_flag! @status_message = current_user.build_post(:status_message, params[:status_message]) @@ -69,9 +69,9 @@ class StatusMessagesController < ApplicationController end respond_to do |format| - format.js { render :create, :status => 201} format.html { redirect_to :back} format.mobile{ redirect_to multi_path} + format.json{ render :json => @status_message.as_api_response(:backbone), :status => 201 } end else unless photos.empty? diff --git a/app/views/shared/_publisher.html.haml b/app/views/shared/_publisher.html.haml index 3651113b9fb6d5aca1250c6164cc1da21684fd9a..c9c8bda0a7d0c7bc7bda9a42b9ae172fe35bc0a4 100644 --- a/app/views/shared/_publisher.html.haml +++ b/app/views/shared/_publisher.html.haml @@ -24,7 +24,7 @@ #publisher.closed{:class => ((aspect == :profile)? 'mention_popup' : nil )} .content_creation - = form_for(StatusMessage.new, :remote => remote?, :html => {"data-type" => "json"}) do |status| + = form_for(StatusMessage.new) do |status| = status.error_messages %p %params @@ -81,7 +81,7 @@ - for aspect in all_aspects = aspect_dropdown_list_item(aspect, !all_aspects_selected?(selected_aspects) && selected_aspects.include?(aspect) ) - = status.submit t('.share'), :disable_with => t('.posting'), :class => 'button creation', :tabindex => 2 + = status.submit t('.share'), :disabled => publisher_hidden_text.blank?, :disable_with => t('.posting'), :class => 'button creation', :tabindex => 2 .facebox_content #question_mark_pane diff --git a/public/javascripts/app/collections/stream.js b/public/javascripts/app/collections/stream.js index c0de920435c66d5a0167429cd69509ea46707d00..49148dfd256710a0643dfcf5f784b3bd5098cc48 100644 --- a/public/javascripts/app/collections/stream.js +++ b/public/javascripts/app/collections/stream.js @@ -1,6 +1,7 @@ app.collections.Stream = Backbone.Collection.extend({ url: function() { - var path = document.location.pathname + ".json"; + var path = document.location.pathname; + if(this.models.length) { path += "?max_time=" + _.last(this.models).createdAt(); } diff --git a/public/javascripts/app/models/post.js b/public/javascripts/app/models/post.js index 97f8e3528c5565e9b3eec36bcce18a7d7c96129e..6288503f28830757162a525c54e52c922d70f59b 100644 --- a/public/javascripts/app/models/post.js +++ b/public/javascripts/app/models/post.js @@ -8,7 +8,11 @@ app.models.Post = Backbone.Model.extend({ }, url: function(){ - return "/posts/" + this.id; + if(this.id) { + return "/posts/" + this.id; + } else { + return "/status_messages" + } }, createdAt: function(){ diff --git a/public/javascripts/app/views/post_view.js b/public/javascripts/app/views/post_view.js index 1dbece577e88fcfb0797b35b45e07ed0984272cc..15479fb8eb8a621c011625de88bb5fb7d9450230 100644 --- a/public/javascripts/app/views/post_view.js +++ b/public/javascripts/app/views/post_view.js @@ -24,7 +24,6 @@ app.views.Post = app.views.StreamObject.extend({ initialize : function() { this.feedbackView = new app.views.Feedback({model : this.model}); this.commentStreamView = new app.views.CommentStream({ model : this.model}); - return this; }, diff --git a/public/javascripts/app/views/publisher_view.js b/public/javascripts/app/views/publisher_view.js new file mode 100644 index 0000000000000000000000000000000000000000..677128054a979a6f6f8d09b2422e02c6da652397 --- /dev/null +++ b/public/javascripts/app/views/publisher_view.js @@ -0,0 +1,82 @@ +app.views.Publisher = Backbone.View.extend({ + + el : "#publisher", + + events : { + "focus textarea" : "open", + "click #hide_publisher" : "close", + "submit form" : "createStatusMessage" + }, + + initialize : function(){ + this.collection = this.collection || new app.collections.Stream; + return this; + }, + + createStatusMessage : function(evt) { + if(evt){ evt.preventDefault(); } + + var serializedForm = $(evt.target).closest("form").serializeObject(); + + this.collection.create({ + "status_message" : { + "text" : serializedForm["status_message[text]"] + }, + "aspect_ids" : serializedForm["aspect_ids[]"] + }); + + // clear state + this.clear(); + }, + + clear : function() { + // remove form data + _.each(this.$('textarea'), function(element) { + $(element).removeClass("with_attachments") + .css("paddingBottom", "") + .val(""); + }); + + // remove photos + this.$("#photodropzone").find('li').remove(); + + // close publishing area (CSS) + this.close(); + + return this; + }, + + open : function() { + $(this.el).removeClass('closed'); + this.$("#publisher_textarea_wrapper").addClass('active'); + this.$("textarea.ac_input").css('min-height', '42px'); + + return this; + }, + + close : function() { + $(this.el).addClass("closed"); + this.$("#publisher_textarea_wrapper").removeClass("active"); + this.$("textarea.ac_input").css('min-height', ''); + + return this; + } +}); + +// jQuery helper for serializing a <form> into JSON +$.fn.serializeObject = function() +{ + var o = {}; + var a = this.serializeArray(); + $.each(a, function() { + if (o[this.name] !== undefined) { + if (!o[this.name].push) { + o[this.name] = [o[this.name]]; + } + o[this.name].push(this.value || ''); + } else { + o[this.name] = this.value || ''; + } + }); + return o; +}; diff --git a/public/javascripts/app/views/stream_object_view.js b/public/javascripts/app/views/stream_object_view.js index 05a1ade5e2957446abd6330d1284be46b724e446..4a9d269132f68ff5afd049a9ba1bb7349205e3b9 100644 --- a/public/javascripts/app/views/stream_object_view.js +++ b/public/javascripts/app/views/stream_object_view.js @@ -9,5 +9,6 @@ app.views.StreamObject = app.views.Base.extend({ destroyModel: function(evt){ if(evt){ evt.preventDefault(); } this.model.destroy(); + this.remove(); } }); diff --git a/public/javascripts/app/views/stream_view.js b/public/javascripts/app/views/stream_view.js index 4987f2421f4d10d38bc8db20cbd4a44db38c46d1..b0eadb184c8a4630678daa353d48724563d11ef2 100644 --- a/public/javascripts/app/views/stream_view.js +++ b/public/javascripts/app/views/stream_view.js @@ -7,6 +7,8 @@ app.views.Stream = Backbone.View.extend({ this.collection = this.collection || new app.collections.Stream; this.collection.bind("add", this.appendPost, this); + this.publisher = new app.views.Publisher({collection : this.collection}); + return this; }, diff --git a/public/javascripts/publisher.js b/public/javascripts/publisher.js index 499fd722ec808a8bfc8061cab212a78da4f4c33e..b6d4e4453894bffbc1bbfb0ffdcc0173b71e14ec 100644 --- a/public/javascripts/publisher.js +++ b/public/javascripts/publisher.js @@ -7,18 +7,6 @@ var Publisher = { bookmarklet : false, - close: function(){ - Publisher.form().addClass('closed'); - Publisher.form().find("#publisher_textarea_wrapper").removeClass('active'); - Publisher.form().find("textarea.ac_input").css('min-height', ''); - }, - - open: function(){ - Publisher.form().removeClass('closed'); - Publisher.form().find("#publisher_textarea_wrapper").addClass('active'); - Publisher.form().find("textarea.ac_input").css('min-height', '42px'); - Publisher.determineSubmitAvailability(); - }, cachedForm : false, form: function(){ @@ -284,8 +272,6 @@ var Publisher = { clear: function(){ this.autocompletion.mentionList.clear(); - $("#photodropzone").find('li').remove(); - $("#publisher textarea").removeClass("with_attachments").css('paddingBottom', ''); }, bindServiceIcons: function(){ @@ -439,14 +425,12 @@ var Publisher = { }); } } - //collapse publisher - Publisher.close(); - Publisher.clear(); + //Stream.setUpImageLinks(); Stream.setUpAudioLinks(); }, bindAjax: function(){ - Publisher.form().bind('submit', Publisher.beforeSubmit); + //Publisher.form().bind('submit', Publisher.beforeSubmit); Publisher.form().bind('ajax:loading', Publisher.onSubmit); Publisher.form().bind('ajax:failure', Publisher.onFailure); Publisher.form().bind('ajax:success', Publisher.onSuccess); @@ -492,14 +476,6 @@ var Publisher = { Publisher.bindServiceIcons(); Publisher.bindAspectToggles(); - /* close text area */ - Publisher.form().delegate("#hide_publisher", "click", function(){ - $.each(Publisher.form().find("textarea"), function(idx, element){ - $(element).val(""); - }); - Publisher.close(); - }); - Publisher.autocompletion.initialize(); if(Publisher.hiddenInput().val() === "") { @@ -509,10 +485,7 @@ var Publisher = { Publisher.input().keydown(Publisher.autocompletion.keyDownHandler); Publisher.input().keyup(Publisher.autocompletion.keyUpHandler); Publisher.input().mouseup(Publisher.autocompletion.keyUpHandler); - Publisher.bindAjax(); - Publisher.form().find("textarea").bind("focus", function(evt) { - Publisher.open(); - }); + //Publisher.bindAjax(); } }; diff --git a/spec/javascripts/app/collections/stream-spec.js b/spec/javascripts/app/collections/stream-spec.js index 7de1f16988018b28eb67db90d33c5084d3761d44..145c09c57c346f3ca848890388e9b4b65ffd6bf7 100644 --- a/spec/javascripts/app/collections/stream-spec.js +++ b/spec/javascripts/app/collections/stream-spec.js @@ -1,8 +1,9 @@ describe("app.collections.Stream", function() { describe("url", function() { var stream = new app.collections.Stream(), - expectedPath = document.location.pathname + ".json"; - it("returns the json path", function() { + expectedPath = document.location.pathname; + + it("returns the correct path", function() { expect(stream.url()).toEqual(expectedPath); }); diff --git a/spec/javascripts/app/views/publisher_view_spec.js b/spec/javascripts/app/views/publisher_view_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..00d0873bc1b83b9e77111d48b34d48cc4e788a45 --- /dev/null +++ b/spec/javascripts/app/views/publisher_view_spec.js @@ -0,0 +1,60 @@ +describe("app.views.Publisher", function() { + beforeEach(function() { + // should be jasmine helper + window.current_user = app.user({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}}); + + spec.loadFixture("aspects_index"); + this.view = new app.views.Publisher(); + }); + + describe("#open", function() { + it("removes the 'closed' class from the publisher element", function() { + expect($(this.view.el)).toHaveClass("closed"); + this.view.open($.Event()); + expect($(this.view.el)).not.toHaveClass("closed"); + }); + }); + + describe("#close", function() { + it("removes the 'active' class from the publisher element", function(){ + $(this.view.el).removeClass("closed"); + + expect($(this.view.el)).not.toHaveClass("closed"); + this.view.close($.Event()); + expect($(this.view.el)).toHaveClass("closed"); + }) + }); + + describe("#clear", function() { + it("calls close", function(){ + spyOn(this.view, "close"); + + this.view.clear($.Event()); + expect(this.view.close); + }) + + it("clears all textareas", function(){ + _.each(this.view.$("textarea"), function(element){ + $(element).val('this is some stuff'); + expect($(element).val()).not.toBe(""); + }); + + this.view.clear($.Event()); + + _.each(this.view.$("textarea"), function(element){ + expect($(element).val()).toBe(""); + }); + }) + + it("removes all photos from the dropzone area", function(){ + var self = this; + _.times(3, function(){ + self.view.$("#photodropzone").append($("<li>")) + }); + + expect(this.view.$("#photodropzone").html()).not.toBe(""); + this.view.clear($.Event()); + expect(this.view.$("#photodropzone").html()).toBe(""); + }) + }); +}); diff --git a/spec/javascripts/publisher-spec.js b/spec/javascripts/publisher-spec.js index 11224a4405c795aaeb7699914ede853da5cb67d5..56bebe5ffc2579ed0774c68b560f676ac56e2bf3 100644 --- a/spec/javascripts/publisher-spec.js +++ b/spec/javascripts/publisher-spec.js @@ -5,14 +5,7 @@ describe("Publisher", function() { - describe("initialize", function(){ - it("does not call close when there is prefilled text", function(){ - spec.loadFixture('aspects_index_prefill'); - spyOn(Publisher, 'close'); - Publisher.initialize(); - expect(Publisher.close).wasNotCalled(); - }); - }); + Publisher.open = function(){ this.form().removeClass("closed"); } describe("toggleCounter", function(){ beforeEach( function(){ @@ -39,7 +32,7 @@ describe("Publisher", function() { }); it('gets called on initialize', function(){ - spyOn(Publisher, 'bindAspectToggles'); + spyOn(Publisher, 'bindAspectToggles'); Publisher.initialize(); expect(Publisher.bindAspectToggles).toHaveBeenCalled(); }); @@ -172,34 +165,6 @@ describe("Publisher", function() { }); }); - describe("open", function() { - beforeEach(function() { - spec.loadFixture('aspects_index'); - Publisher.initialize(); - }); - it("removes the closed class", function() { - expect(Publisher.form().hasClass('closed')).toBeTruthy(); - Publisher.open(); - expect(Publisher.form().hasClass('closed')).toBeFalsy(); - }); - it("disables the share button", function() { - expect(Publisher.submit().attr('disabled')).toBeFalsy(); - Publisher.open(); - expect(Publisher.submit().attr('disabled')).toBeTruthy(); - }); - }); - describe("close", function() { - beforeEach(function() { - spec.loadFixture('aspects_index_prefill'); - Publisher.initialize(); - }); - it("adds the closed class", function() { - Publisher.form().removeClass('closed'); - expect(Publisher.form().hasClass('closed')).toBeFalsy(); - Publisher.close(); - expect(Publisher.form().hasClass('closed')).toBeTruthy(); - }); - }); describe("input", function(){ beforeEach(function(){ spec.loadFixture('aspects_index_prefill'); @@ -209,161 +174,173 @@ describe("Publisher", function() { expect(Publisher.input().length).toBe(1); }); }); + describe("autocompletion", function(){ describe("searchTermFromValue", function(){ - var func; - beforeEach(function(){func = Publisher.autocompletion.searchTermFromValue;}); + beforeEach(function(){ + this.func = Publisher.autocompletion.searchTermFromValue; + }); + it("returns nothing if the cursor is before the @", function(){ - expect(func('not @dan grip', 2)).toBe(''); + expect(this.func('not @dan grip', 2)).toBe(''); }); + it("returns everything up to the cursor if the cursor is a word after that @", function(){ - expect(func('not @dan grip', 13)).toBe('dan grip'); + expect(this.func('not @dan grip', 13)).toBe('dan grip'); }); + it("returns up to the cursor if the cursor is after that @", function(){ - expect(func('not @dan grip', 7)).toBe('da'); + expect(this.func('not @dan grip', 7)).toBe('da'); }); it("returns everything after an @ at the start of the line", function(){ - expect(func('@dan grip', 9)).toBe('dan grip'); + expect(this.func('@dan grip', 9)).toBe('dan grip'); }); it("returns nothing if there is no @", function(){ - expect(func('dan', 3)).toBe(''); + expect(this.func('dan', 3)).toBe(''); }); it("returns nothing for just an @", function(){ - expect(func('@', 1)).toBe(''); + expect(this.func('@', 1)).toBe(''); }); it("returns nothing if there are letters preceding the @", function(){ - expect(func('ioj@asdo', 8)).toBe(''); + expect(this.func('ioj@asdo', 8)).toBe(''); }); it("returns everything up to the cursor if there are 2 @s and the cursor is between them", function(){ - expect(func('@asdpo aoisdj @asodk', 8)).toBe('asdpo'); + expect(this.func('@asdpo aoisdj @asodk', 8)).toBe('asdpo'); }); it("returns everything from the 2nd @ up to the cursor if there are 2 @s and the cursor after them", function(){ - expect(func('@asod asdo @asd asok', 15)).toBe('asd'); + expect(this.func('@asod asdo @asd asok', 15)).toBe('asd'); }); }); - describe("onSelect", function(){ - - }); - describe("mentionList", function(){ - var visibleInput, visibleVal, - hiddenInput, hiddenVal, - list, - mention; beforeEach(function(){ spec.loadFixture('aspects_index'); - list = Publisher.autocompletion.mentionList; - visibleInput = Publisher.input(); - hiddenInput = Publisher.hiddenInput(); - mention = { visibleStart : 0, + + this.list = Publisher.autocompletion.mentionList; + this.visibleInput = Publisher.input(); + this.hiddenInput = Publisher.hiddenInput(); + this.mention = { visibleStart : 0, visibleEnd : 5, mentionString : "@{Danny; dan@pod.org}" }; - list.mentions = []; - list.push(mention); - visibleVal = "Danny loves testing javascript"; - visibleInput.val(visibleVal); - hiddenVal = "@{Danny; dan@pod.org} loves testing javascript"; - hiddenInput.val(hiddenVal); + + this.list.mentions = []; + this.list.push(this.mention); + this.visibleVal = "Danny loves testing javascript"; + this.visibleInput.val(this.visibleVal); + this.hiddenVal = "@{Danny; dan@pod.org} loves testing javascript"; + this.hiddenInput.val(this.hiddenVal); }); + describe("selectionDeleted", function(){ - var func, danny, daniel, david, darren; beforeEach(function(){ - func = list.selectionDeleted; - visibleVal = "Danny Daniel David Darren"; - visibleInput.val(visibleVal); - list.mentions = []; - danny = { + this.func = this.list.selectionDeleted; + this.visibleVal = "Danny Daniel David Darren"; + this.visibleInput.val(this.visibleVal); + this.list.mentions = []; + this.danny = { visibleStart : 0, visibleEnd : 5, mentionString : "@{Danny; danny@pod.org}" }; - daniel = { + this.daniel = { visibleStart : 6, visibleEnd : 12, mentionString : "@{Daniel; daniel@pod.org}" }; - david = { + this.david = { visibleStart : 13, visibleEnd : 18, mentionString : "@{David; david@pod.org}" }; - darren = { + this.darren = { visibleStart : 19, visibleEnd : 25, mentionString : "@{Darren; darren@pod.org}" }; - list.push(danny) - list.push(daniel) - list.push(david) - list.push(darren) + + _.each([this.danny, this.daniel, this.david, this.darren], function(person){ + this.list.push(person); + }, this); }); + it("destroys mentions within the selection", function(){ - func(4,11); - expect(list.sortedMentions()).toEqual([darren, david]) + this.func(4,11); + expect(this.list.sortedMentions()).toEqual([this.darren, this.david]) }); + it("moves remaining mentions back", function(){ - func(7,14); - var length = 11 - 4 - expect(danny.visibleStart).toBe(0); - expect(darren.visibleStart).toBe(19-length); + this.func(7,14); + var length = 11 - 4; + + expect(this.danny.visibleStart).toBe(0); + expect(this.darren.visibleStart).toBe(19-length); }); }); + describe("generateHiddenInput", function(){ it("replaces mentions in a string", function(){ - expect(list.generateHiddenInput(visibleVal)).toBe(hiddenVal); + expect(this.list.generateHiddenInput(this.visibleVal)).toBe(this.hiddenVal); }); }); + describe("push", function(){ it("adds mention to mentions array", function(){ - expect(list.mentions.length).toBe(1); - expect(list.mentions[0]).toBe(mention) + expect(this.list.mentions.length).toBe(1); + expect(this.list.mentions[0]).toBe(this.mention) }); }); + describe("mentionAt", function(){ it("returns the location of the mention at that location in the mentions array", function(){ - expect(list.mentions[list.mentionAt(3)]).toBe(mention); + expect(this.list.mentions[this.list.mentionAt(3)]).toBe(this.mention); }); + it("returns null if there is no mention", function(){ - expect(list.mentionAt(8)).toBeFalsy(); + expect(this.list.mentionAt(8)).toBeFalsy(); }); }); + describe("insertionAt", function(){ it("does nothing if there is no visible mention at that index", function(){ - list.insertionAt(8); - expect(visibleInput.val()).toBe(visibleVal); - expect(hiddenInput.val()).toBe(hiddenVal); + this.list.insertionAt(8); + expect(this.visibleInput.val()).toBe(this.visibleVal); + expect(this.hiddenInput.val()).toBe(this.hiddenVal); }); + it("deletes the mention from the hidden field if there is a mention", function(){ - list.insertionAt(3); - expect(visibleInput.val()).toBe(visibleVal); - expect(list.generateHiddenInput(visibleInput.val())).toBe(visibleVal); + this.list.insertionAt(3); + expect(this.visibleInput.val()).toBe(this.visibleVal); + expect(this.list.generateHiddenInput(this.visibleInput.val())).toBe(this.visibleVal); }); + it("deletes the mention from the list", function(){ - list.insertionAt(3); - expect(list.mentionAt(3)).toBeFalsy(); + this.list.insertionAt(3); + expect(this.list.mentionAt(3)).toBeFalsy(); }); + it("calls updateMentionLocations", function(){ mentionTwo = { visibleStart : 8, visibleEnd : 15, mentionString : "@{SomeoneElse; other@pod.org}" }; - list.push(mentionTwo); - spyOn(list, 'updateMentionLocations'); - list.insertionAt(3,4, 60); - expect(list.updateMentionLocations).toHaveBeenCalled(); + this.list.push(mentionTwo); + + spyOn(this.list, 'updateMentionLocations'); + this.list.insertionAt(3,4, 60); + expect(this.list.updateMentionLocations).toHaveBeenCalled(); }); }); + describe("updateMentionLocations", function(){ it("updates the offsets of the remaining mentions in the list", function(){ mentionTwo = { visibleStart : 8, visibleEnd : 15, mentionString : "@{SomeoneElse; other@pod.org}" }; - list.push(mentionTwo); - list.updateMentionLocations(7, 1); + this.list.push(mentionTwo); + this.list.updateMentionLocations(7, 1); expect(mentionTwo.visibleStart).toBe(9); expect(mentionTwo.visibleEnd).toBe(16); }); @@ -371,81 +348,84 @@ describe("Publisher", function() { }); describe("keyUpHandler", function(){ - var input; - var submit; beforeEach(function(){ spec.loadFixture('aspects_index'); Publisher.initialize(); - input = Publisher.input(); - submit = Publisher.submit(); + this.input = Publisher.input(); + this.submit = Publisher.submit(); Publisher.open(); }); + it("keep the share button disabled when adding only whitespaces", function(){ - expect(submit.attr('disabled')).toBeTruthy(); - input.val(' '); - input.keyup(); - expect(submit.attr('disabled')).toBeTruthy(); + expect(this.submit.attr('disabled')).toBeTruthy(); + this.input.val(' '); + this.input.keyup(); + expect(this.submit.attr('disabled')).toBeTruthy(); }); + it("enable the share button when adding non-whitespace characters", function(){ - expect(submit.attr('disabled')).toBeTruthy(); - input.val('some text'); - input.keyup(); - expect(submit.attr('disabled')).toBeFalsy(); + expect(this.submit.attr('disabled')).toBeTruthy(); + this.input.val('some text'); + this.input.keyup(); + expect(this.submit.attr('disabled')).toBeFalsy(); }); + it("should toggle share button disable/enable when playing with input", function(){ - expect(submit.attr('disabled')).toBeTruthy(); - input.val(' '); - input.keyup(); - expect(submit.attr('disabled')).toBeTruthy(); - input.val('text'); - input.keyup(); - expect(submit.attr('disabled')).toBeFalsy(); - input.val(''); - input.keyup(); - expect(submit.attr('disabled')).toBeTruthy(); + expect(this.submit.attr('disabled')).toBeTruthy(); + this.input.val(' '); + this.input.keyup(); + expect(this.submit.attr('disabled')).toBeTruthy(); + this.input.val('text'); + this.input.keyup(); + this.expect(this.submit.attr('disabled')).toBeFalsy(); + this.input.val(''); + this.input.keyup(); + expect(this.submit.attr('disabled')).toBeTruthy(); }); }); describe("addMentionToInput", function(){ - var func; - var input; - var replaceWith; beforeEach(function(){ spec.loadFixture('aspects_index'); - func = Publisher.autocompletion.addMentionToInput; - input = Publisher.input(); + this.func = Publisher.autocompletion.addMentionToInput; + this.input = Publisher.input(); + this.replaceWith = "Replace with this."; Publisher.autocompletion.mentionList.mentions = []; - replaceWith = "Replace with this."; }); + it("replaces everything up to the cursor if the cursor is a word after that @", function(){ - input.val('not @dan grip'); + this.input.val('not @dan grip'); var cursorIndex = 13; - func(input, cursorIndex, replaceWith); - expect(input.val()).toBe('not ' + replaceWith); + this.func(this.input, cursorIndex, this.replaceWith); + expect(this.input.val()).toBe('not ' + this.replaceWith); }); + it("replaces everything between @ and the cursor if the cursor is after that @", function(){ - input.val('not @dan grip'); + this.input.val('not @dan grip'); var cursorIndex = 7; - func(input, cursorIndex, replaceWith); - expect(input.val()).toBe('not ' + replaceWith + 'n grip'); + this.func(this.input, cursorIndex, this.replaceWith); + expect(this.input.val()).toBe('not ' + this.replaceWith + 'n grip'); }); + it("replaces everything up to the cursor from @ at the start of the line", function(){ - input.val('@dan grip'); + this.input.val('@dan grip'); var cursorIndex = 9; - func(input, cursorIndex, replaceWith); - expect(input.val()).toBe(replaceWith); + this.func(this.input, cursorIndex, this.replaceWith); + expect(this.input.val()).toBe(this.replaceWith); }); + it("replaces everything between the first @ and the cursor if there are 2 @s and the cursor is between them", function(){ - input.val('@asdpo aoisdj @asodk'); + this.input.val('@asdpo aoisdj @asodk'); var cursorIndex = 8; - func(input, cursorIndex, replaceWith); - expect(input.val()).toBe(replaceWith + 'aoisdj @asodk'); + this.func(this.input, cursorIndex, this.replaceWith); + expect(this.input.val()).toBe(this.replaceWith + 'aoisdj @asodk'); }); + it("replaces everything after the 2nd @ if there are 2 @s and the cursor after them", function(){ - input.val('@asod asdo @asd asok'); + this.input.val('@asod asdo @asd asok'); var cursorIndex = 15; - func(input, cursorIndex, replaceWith); - expect(input.val()).toBe('@asod asdo ' + replaceWith + ' asok'); + this.func(this.input, cursorIndex, this.replaceWith); + expect(this.input.val()).toBe('@asod asdo ' + this.replaceWith + ' asok'); }); }); });