diff --git a/app/assets/javascripts/app/collections/aspects.js b/app/assets/javascripts/app/collections/aspects.js index 1e284274b..7b25d33b5 100644 --- a/app/assets/javascripts/app/collections/aspects.js +++ b/app/assets/javascripts/app/collections/aspects.js @@ -1,7 +1,7 @@ // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later app.collections.Aspects = Backbone.Collection.extend({ - model: app.models.Aspect, + model: app.models.AspectSelection, selectedAspects: function(attribute){ return _.pluck(_.filter(this.toJSON(), function(a){ diff --git a/app/assets/javascripts/app/models/aspect.js b/app/assets/javascripts/app/models/aspect.js index 7ff651d84..b9c476806 100644 --- a/app/assets/javascripts/app/models/aspect.js +++ b/app/assets/javascripts/app/models/aspect.js @@ -1,9 +1,5 @@ // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later - app.models.Aspect = Backbone.Model.extend({ - toggleSelected: function(){ - this.set({'selected' : !this.get('selected')}, {async: false}); - } + urlRoot: "/aspects" }); // @license-end - diff --git a/app/assets/javascripts/app/models/aspect_selection.js b/app/assets/javascripts/app/models/aspect_selection.js new file mode 100644 index 000000000..fac37c91d --- /dev/null +++ b/app/assets/javascripts/app/models/aspect_selection.js @@ -0,0 +1,7 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later +app.models.AspectSelection = Backbone.Model.extend({ + toggleSelected: function(){ + this.set({"selected" : !this.get("selected")}, {async: false}); + } +}); +// @license-end diff --git a/app/assets/javascripts/app/pages/contacts.js b/app/assets/javascripts/app/pages/contacts.js index 996a5898b..4ae44878b 100644 --- a/app/assets/javascripts/app/pages/contacts.js +++ b/app/assets/javascripts/app/pages/contacts.js @@ -16,8 +16,12 @@ app.pages.Contacts = Backbone.View.extend({ this.chat_toggle = $("#chat_privilege_toggle .entypo"); this.stream = opts.stream; this.stream.render(); - $("#people_stream.contacts .header .entypo").tooltip({ 'placement': 'bottom'}); - $(document).on('ajax:success', 'form.edit_aspect', this.updateAspectName); + $("#people_stream.contacts .header .entypo").tooltip({"placement": "bottom"}); + $(document).on("ajax:success", "form.edit_aspect", this.updateAspectName); + app.events.on("aspect:create", function(){ window.location.reload() }); + + this.aspectCreateView = new app.views.AspectCreate({ el: $("#newAspectContainer") }); + this.aspectCreateView.render(); }, toggleChatPrivilege: function() { @@ -26,13 +30,13 @@ app.pages.Contacts = Backbone.View.extend({ .removeClass("enabled") .removeAttr("data-original-title") .attr("title", Diaspora.I18n.t("contacts.aspect_chat_is_not_enabled")) - .tooltip({'placement': 'bottom'}); + .tooltip({"placement": "bottom"}); } else { this.chat_toggle.tooltip("destroy") .addClass("enabled") .removeAttr("data-original-title") .attr("title", Diaspora.I18n.t("contacts.aspect_chat_is_enabled")) - .tooltip({'placement': 'bottom'}); + .tooltip({"placement": "bottom"}); } }, @@ -43,7 +47,7 @@ app.pages.Contacts = Backbone.View.extend({ .tooltip("destroy") .removeAttr("data-original-title") .attr("title", Diaspora.I18n.t("contacts.aspect_list_is_not_visible")) - .tooltip({'placement': 'bottom'}); + .tooltip({"placement": "bottom"}); } else { this.visibility_toggle.removeClass("lock") @@ -51,7 +55,7 @@ app.pages.Contacts = Backbone.View.extend({ .tooltip("destroy") .removeAttr("data-original-title") .attr("title", Diaspora.I18n.t("contacts.aspect_list_is_visible")) - .tooltip({'placement': 'bottom'}); + .tooltip({"placement": "bottom"}); } }, diff --git a/app/assets/javascripts/app/views/aspect_create_view.js b/app/assets/javascripts/app/views/aspect_create_view.js new file mode 100644 index 000000000..4ef77c808 --- /dev/null +++ b/app/assets/javascripts/app/views/aspect_create_view.js @@ -0,0 +1,63 @@ +// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later +app.views.AspectCreate = app.views.Base.extend({ + + templateName: "aspect_create_modal", + + events: { + "click .btn.creation": "createAspect" + }, + + initialize: function(opts) { + this._personId = _.has(opts, "personId") ? opts.personId : null; + }, + + presenter: function() { + return _.extend(this.defaultPresenter(), { + addPersonId: this._personId !== null, + personId : this._personId + }); + }, + + postRenderTemplate: function() { + this.modal = this.$(".modal"); + }, + + _contactsVisible: function() { + return this.$("#aspect_contacts_visible").is(":checked"); + }, + + _name: function() { + return this.$("#aspect_name").val(); + }, + + createAspect: function() { + var aspect = new app.models.Aspect({ + "person_id": this._personId, + "name": this._name(), + "contacts_visible": this._contactsVisible() + }); + + var self = this; + aspect.on("sync", function(response) { + var aspectId = response.get("id"), + aspectName = response.get("name"); + + self.modal.modal("hide"); + app.events.trigger("aspect:create", aspectId); + Diaspora.page.flashMessages.render({ + "success": true, + "notice": Diaspora.I18n.t("aspects.create.success", {"name": aspectName}) + }); + }); + + aspect.on("error", function() { + self.modal.modal("hide"); + Diaspora.page.flashMessages.render({ + "success": false, + "notice": Diaspora.I18n.t("aspects.create.failure") + }); + }); + return aspect.save(); + } +}); +// @license-end diff --git a/app/assets/javascripts/app/views/aspect_membership_view.js b/app/assets/javascripts/app/views/aspect_membership_view.js index d22452421..4d8d52367 100644 --- a/app/assets/javascripts/app/views/aspect_membership_view.js +++ b/app/assets/javascripts/app/views/aspect_membership_view.js @@ -13,12 +13,20 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({ events: { "click ul.aspect_membership.dropdown-menu > li.aspect_selector": "_clickHandler", - "keypress ul.aspect_membership.dropdown-menu > li.aspect_selector": "_clickHandler" + "keypress ul.aspect_membership.dropdown-menu > li.aspect_selector": "_clickHandler", + "click ul.aspect_membership.dropdown-menu > li.newItem": "showModal" }, initialize: function() { this.list_item = null; this.dropdown = null; + if (this.$(".newAspectContainer").length > 0) { + this.aspectCreateView = new app.views.AspectCreate({ + el: this.$(".newAspectContainer"), + personId: this.$("ul.dropdown-menu").data("person_id") + }); + this.aspectCreateView.render(); + } }, // decide what to do when clicked @@ -140,6 +148,9 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({ this._toggleCheckbox(target); this._updateButton('green'); }, + + showModal: function() { + this.$("#newAspectModal").modal("show"); + } }); // @license-end - diff --git a/app/assets/javascripts/app/views/aspects_list_view.js b/app/assets/javascripts/app/views/aspects_list_view.js index 29cdf45a5..c0e5646f7 100644 --- a/app/assets/javascripts/app/views/aspects_list_view.js +++ b/app/assets/javascripts/app/views/aspects_list_view.js @@ -6,18 +6,26 @@ app.views.AspectsList = app.views.Base.extend({ el: '#aspects_list', events: { - 'click .toggle_selector' : 'toggleAll' + "click .toggle_selector" : "toggleAll" + }, + + subviews : { + "#newAspectContainer" : "aspectCreateView" }, initialize: function() { - this.collection.on('change', this.toggleSelector, this); - this.collection.on('change', this.updateStreamTitle, this); - this.collection.on('aspectStreamFetched', this.updateAspectList, this); + this.collection.on("change", this.toggleSelector, this); + this.collection.on("change", this.updateStreamTitle, this); + this.collection.on("aspectStreamFetched", this.updateAspectList, this); + app.events.on("aspect:create", function(id) { window.location = "/contacts?a_id=" + id }); + }, + + aspectCreateView: function() { + return new app.views.AspectCreate(); }, postRenderTemplate: function() { this.collection.each(this.appendAspect, this); - this.$('a[rel*=facebox]').facebox(); this.updateStreamTitle(); this.toggleSelector(); }, @@ -67,6 +75,6 @@ app.views.AspectsList = app.views.Base.extend({ hideAspectsList: function() { this.$el.empty(); - }, + } }); // @license-end diff --git a/app/assets/stylesheets/aspects.scss b/app/assets/stylesheets/aspects.scss index 1aac43f70..3c9b1ac22 100644 --- a/app/assets/stylesheets/aspects.scss +++ b/app/assets/stylesheets/aspects.scss @@ -30,18 +30,3 @@ } } } - -#new_aspect { - .checkbox { - margin: 0px; - } - - label[for="aspect_contacts_visible"], - label[for="aspect_chat_enabled"] { - display: inline; - } - - .bottom_submit_section { - padding-top: 20px; - } -} diff --git a/app/assets/templates/aspect_create_modal_tpl.jst.hbs b/app/assets/templates/aspect_create_modal_tpl.jst.hbs new file mode 100644 index 000000000..bcb326553 --- /dev/null +++ b/app/assets/templates/aspect_create_modal_tpl.jst.hbs @@ -0,0 +1,40 @@ + diff --git a/app/assets/templates/aspects-list_tpl.jst.hbs b/app/assets/templates/aspects-list_tpl.jst.hbs index 5f29f9313..9883ad5b3 100644 --- a/app/assets/templates/aspects-list_tpl.jst.hbs +++ b/app/assets/templates/aspects-list_tpl.jst.hbs @@ -4,5 +4,8 @@
  • - {{ t "aspect_navigation.add_an_aspect" }} + + {{ t "aspect_navigation.add_an_aspect" }} + +
  • diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb index 73b23724b..77e8bfc4a 100644 --- a/app/controllers/aspects_controller.rb +++ b/app/controllers/aspects_controller.rb @@ -11,35 +11,15 @@ class AspectsController < ApplicationController def create @aspect = current_user.aspects.build(aspect_params) - aspecting_person_id = params[:aspect][:person_id] + aspecting_person_id = params[:person_id] if @aspect.save - flash[:notice] = I18n.t('aspects.create.success', :name => @aspect.name) - - if current_user.getting_started || request.referer.include?("contacts") - redirect_to :back - elsif aspecting_person_id.present? + if aspecting_person_id.present? connect_person_to_aspect(aspecting_person_id) - else - redirect_to contacts_path(:a_id => @aspect.id) end + render json: {id: @aspect.id, name: @aspect.name} else - respond_to do |format| - format.js { render :text => I18n.t('aspects.create.failure'), :status => 422 } - format.html do - flash[:error] = I18n.t('aspects.create.failure') - redirect_to :back - end - end - end - end - - def new - @aspect = Aspect.new - @person_id = params[:person_id] - @remote = params[:remote] == "true" - respond_to do |format| - format.html { render :layout => false } + render nothing: true, status: 422 end end diff --git a/app/views/aspect_memberships/_aspect_membership_dropdown.haml b/app/views/aspect_memberships/_aspect_membership_dropdown.haml index 04650a4d8..ba4ee2fd1 100644 --- a/app/views/aspect_memberships/_aspect_membership_dropdown.haml +++ b/app/views/aspect_memberships/_aspect_membership_dropdown.haml @@ -23,4 +23,9 @@ %li.divider %li.newItem .add_aspect - = link_to t('contacts.index.add_a_new_aspect'), new_aspect_path(:person_id => person.id, :remote => true), :rel => 'facebox' + %a{ href: "#" } + = t("contacts.index.add_a_new_aspect") + + - if (dropdown_may_create_new_aspect && defined?(person) && person) + .newAspectContainer + -# JS diff --git a/app/views/aspects/create.js.erb b/app/views/aspects/create.js.erb deleted file mode 100644 index 0004d8e52..000000000 --- a/app/views/aspects/create.js.erb +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (c) 2010-2011, Diaspora Inc. This file is -// licensed under the Affero General Public License version 3 or later. See -// the COPYRIGHT file. - -// TODO create the aspect and the new aspect membership via Backbone.js and then -// remove this view! - -if( app.aspectMemberships ) { - var dropdown = $("ul.dropdown_list[data-person_id=<%= @person.id %>]"); - $('.newItem', dropdown).before("<%= escape_javascript( aspect_dropdown_list_item(@aspect, @contact.aspects.include?(@aspect))) %>"); - - app.aspectMemberships.dropdown = dropdown; - app.aspectMemberships.updateSummary(); - - $('#profile .dropdown').toggleClass("active"); -} - -$.facebox.close(); -app.events.trigger('aspect:create', "<%= escape_javascript(@aspect.id) =>"); diff --git a/app/views/aspects/new.haml b/app/views/aspects/new.haml deleted file mode 100644 index 54d1ffae9..000000000 --- a/app/views/aspects/new.haml +++ /dev/null @@ -1,26 +0,0 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. - --# Using row to enforce a non-percentual width on span6 -.row - .span6 - #facebox_header - %h3 - = t('contacts.index.add_a_new_aspect') - - = form_for(Aspect.new, :remote => @remote) do |aspect| - = aspect.error_messages - - if @person_id - = aspect.hidden_field :person_id, :value => @person_id - %p - = aspect.label :name , t('.name') - = aspect.text_field :name, :maxlength => 20 - - %p.checkbox_select - = aspect.check_box :contacts_visible, :checked => false, class: 'checkbox' - = aspect.label :contacts_visible, t('aspects.edit.make_aspect_list_visible') - - .bottom_submit_section - = submit_tag t('cancel'), :class => 'btn', :type => :reset, :rel => "close" - = aspect.submit t('.create'), :class => 'btn creation' diff --git a/app/views/contacts/_aspect_listings.haml b/app/views/contacts/_aspect_listings.haml index a9b9be9b8..2e0d98945 100644 --- a/app/views/contacts/_aspect_listings.haml +++ b/app/views/contacts/_aspect_listings.haml @@ -21,8 +21,11 @@ = aspect %li.new_aspect - %a{:href => new_aspect_path, :rel => "facebox"} - = t('aspects.aspect_listings.add_an_aspect') + %a{ "data-toggle" => "modal", "data-target" => "#newAspectModal", href: "#"} + = t("aspects.aspect_listings.add_an_aspect") + + #newAspectContainer + -# JS %li.only_sharing{:class => ("active" if params["set"] == "only_sharing")} %a{:href => contacts_path(:set => "only_sharing")} diff --git a/app/views/contacts/_sidebar.html.haml b/app/views/contacts/_sidebar.html.haml index 45d14e1ce..5b9411a02 100644 --- a/app/views/contacts/_sidebar.html.haml +++ b/app/views/contacts/_sidebar.html.haml @@ -1,14 +1,14 @@ %h3 - = t('contacts.index.title') -= render 'contacts/aspect_listings' + = t("contacts.index.title") += render "contacts/aspect_listings" %hr - if AppConfig.settings.community_spotlight.enable? .text-center.spotlight - = link_to t('contacts.spotlight.community_spotlight'), community_spotlight_path, :class => "btn btn-link" + = link_to t("contacts.spotlight.community_spotlight"), community_spotlight_path, class: "btn btn-link" .text-center - .btn.btn-link{ 'data-toggle' => 'modal', 'data-target' => '#invitationsModal'} - = t('invitations.new.invite_someone_to_join') - = render 'shared/modal', - :path => new_user_invitation_path, - :id => 'invitationsModal', - :title => t('invitations.new.invite_someone_to_join') + .btn.btn-link{ "data-toggle" => "modal", "data-target" => "#invitationsModal"} + = t("invitations.new.invite_someone_to_join") + = render "shared/modal", + path: new_user_invitation_path, + id: "invitationsModal", + title: t("invitations.new.invite_someone_to_join") diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index cf869a965..a970052fe 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -5,8 +5,10 @@ en: javascripts: + cancel: "Cancel" confirm_dialog: "Are you sure?" confirm_unload: "Please confirm that you want to leave this page. Data you have entered won’t be saved." + create: "Create" delete: "Delete" ignore: "Ignore" report: @@ -26,6 +28,15 @@ en: comma: "," edit: "Edit" no_results: "No results found" + + aspects: + make_aspect_list_visible: "Make contacts in this aspect visible to each other?" + name: "Name" + create: + add_a_new_aspect: "Add a new aspect" + success: "Your new aspect <%= name %> was created" + failure: "Aspect creation failed." + timeago: prefixAgo: "" prefixFromNow: "" diff --git a/features/desktop/connects_users.feature b/features/desktop/connects_users.feature index f73906ac9..f6ac162a8 100644 --- a/features/desktop/connects_users.feature +++ b/features/desktop/connects_users.feature @@ -66,8 +66,8 @@ Feature: following and being followed And I press the first ".aspect_membership_dropdown .dropdown-toggle" And I press the first "a" within ".add_aspect" - And I fill in "Name" with "Super People" in the modal window - And I press "Create" in the modal window + And I fill in "aspect_name" with "Super People" in the aspect creation modal + And I click on selector ".btn.creation" in the aspect creation modal When I go to the home page Then I should have 1 contact in "Super People" diff --git a/features/desktop/manages_aspects.feature b/features/desktop/manages_aspects.feature index 4eb10aadb..1d4f7e1df 100644 --- a/features/desktop/manages_aspects.feature +++ b/features/desktop/manages_aspects.feature @@ -8,16 +8,16 @@ Feature: User manages contacts Given I am signed in And I am on the contacts page And I follow "+ Add an aspect" - And I fill in "Name" with "Dorm Mates" in the modal window - And I press "Create" in the modal window + And I fill in "aspect_name" with "Dorm Mates" in the aspect creation modal + And I click on selector ".btn.creation" in the aspect creation modal Then I should see "Dorm Mates" within "#aspect_nav" Scenario: creating an aspect from homepage Given I am signed in And I go to the aspects page When I follow "Add an aspect" - And I fill in "Name" with "losers" in the modal window - And I press "Create" in the modal window + And I fill in "aspect_name" with "losers" in the aspect creation modal + And I click on selector ".btn.creation" in the aspect creation modal Then I should see "losers" within "#aspect_nav" Scenario: deleting an aspect from contacts index diff --git a/features/step_definitions/aspects_steps.rb b/features/step_definitions/aspects_steps.rb index 10357c4d4..620c56b40 100644 --- a/features/step_definitions/aspects_steps.rb +++ b/features/step_definitions/aspects_steps.rb @@ -82,6 +82,12 @@ When /^I press the aspect dropdown$/ do click_aspect_dropdown end +When /^(.*) in the aspect creation modal$/ do |action| + within("#newAspectModal") do + step action + end +end + And /^I toggle the aspect "([^"]*)"$/ do |name| toggle_aspect(name) end diff --git a/spec/controllers/aspects_controller_spec.rb b/spec/controllers/aspects_controller_spec.rb index ea4ec0501..65d413fde 100644 --- a/spec/controllers/aspects_controller_spec.rb +++ b/spec/controllers/aspects_controller_spec.rb @@ -16,25 +16,6 @@ describe AspectsController, :type => :controller do request.env["HTTP_REFERER"] = 'http://' + request.host end - - describe "#new" do - it "renders a remote form if remote is true" do - get :new, "remote" => "true" - expect(response).to be_success - expect(response.body).to match(/#{Regexp.escape('data-remote="true"')}/) - end - it "renders a non-remote form if remote is false" do - get :new, "remote" => "false" - expect(response).to be_success - expect(response.body).not_to match(/#{Regexp.escape('data-remote="true"')}/) - end - it "renders a non-remote form if remote is missing" do - get :new - expect(response).to be_success - expect(response.body).not_to match(/#{Regexp.escape('data-remote="true"')}/) - end - end - describe "#show" do it "succeeds" do get :show, 'id' => @alices_aspect_1.id.to_s @@ -50,30 +31,32 @@ describe AspectsController, :type => :controller do context "with valid params" do it "creates an aspect" do expect(alice.aspects.count).to eq(2) - post :create, "aspect" => {"name" => "new aspect"} + post :create, aspect: {name: "new aspect"} expect(alice.reload.aspects.count).to eq(3) end - it "redirects to the aspect's contact page" do - post :create, "aspect" => {"name" => "new aspect"} - expect(response).to redirect_to(contacts_path(:a_id => Aspect.find_by_name("new aspect").id)) + + it "returns the created aspect as json" do + post :create, aspect: {name: "new aspect"} + expect(JSON.parse(response.body)["id"]).to eq Aspect.find_by_name("new aspect").id + expect(JSON.parse(response.body)["name"]).to eq "new aspect" end context "with person_id param" do it "creates a contact if one does not already exist" do expect { - post :create, :format => 'js', :aspect => {:name => "new", :person_id => eve.person.id} + post :create, format: "js", person_id: eve.person.id, aspect: {name: "new"} }.to change { alice.contacts.count }.by(1) end it "adds a new contact to the new aspect" do - post :create, :format => 'js', :aspect => {:name => "new", :person_id => eve.person.id} + post :create, format: "js", person_id: eve.person.id, aspect: {name: "new"} expect(alice.aspects.find_by_name("new").contacts.count).to eq(1) end it "adds an existing contact to the new aspect" do - post :create, :format => 'js', :aspect => {:name => "new", :person_id => bob.person.id} + post :create, format: "js", person_id: bob.person.id, aspect: {name: "new"} expect(alice.aspects.find_by_name("new").contacts.count).to eq(1) end end @@ -82,12 +65,13 @@ describe AspectsController, :type => :controller do context "with invalid params" do it "does not create an aspect" do expect(alice.aspects.count).to eq(2) - post :create, "aspect" => {"name" => ""} + post :create, aspect: {name: ""} expect(alice.reload.aspects.count).to eq(2) end - it "goes back to the page you came from" do - post :create, "aspect" => {"name" => ""} - expect(response).to redirect_to(:back) + + it "responds with 422" do + post :create, aspect: {name: ""} + expect(response.status).to eq(422) end end end diff --git a/spec/javascripts/app/models/aspect_spec.js b/spec/javascripts/app/models/aspect_selection_spec.js similarity index 60% rename from spec/javascripts/app/models/aspect_spec.js rename to spec/javascripts/app/models/aspect_selection_spec.js index 72ab56047..8d974e05b 100644 --- a/spec/javascripts/app/models/aspect_spec.js +++ b/spec/javascripts/app/models/aspect_selection_spec.js @@ -1,13 +1,13 @@ -describe("app.models.Aspect", function(){ +describe("app.models.AspectSelection", function(){ describe("#toggleSelected", function(){ it("should select the aspect", function(){ - this.aspect = new app.models.Aspect({ name: 'John Doe', selected: false }); + this.aspect = new app.models.AspectSelection({ name: "John Doe", selected: false }); this.aspect.toggleSelected(); expect(this.aspect.get("selected")).toBeTruthy(); }); it("should deselect the aspect", function(){ - this.aspect = new app.models.Aspect({ name: 'John Doe', selected: true }); + this.aspect = new app.models.AspectSelection({ name: "John Doe", selected: true }); this.aspect.toggleSelected(); expect(this.aspect.get("selected")).toBeFalsy(); }); diff --git a/spec/javascripts/app/views/aspect_create_view_spec.js b/spec/javascripts/app/views/aspect_create_view_spec.js new file mode 100644 index 000000000..bbd17446f --- /dev/null +++ b/spec/javascripts/app/views/aspect_create_view_spec.js @@ -0,0 +1,190 @@ +describe("app.views.AspectCreate", function() { + beforeEach(function() { + app.events.off("aspect:create"); + // disable jshint camelcase for i18n + /* jshint camelcase: false */ + Diaspora.I18n.load({ + aspects: { + make_aspect_list_visible: "Make contacts in this aspect visible to each other?", + name: "Name", + create: { + add_a_new_aspect: "Add a new aspect", + success: "Your new aspect <%= name %> was created", + failure: "Aspect creation failed." + } + } + }); + /* jshint camelcase: true */ + }); + + context("without a person id", function() { + beforeEach(function() { + this.view = new app.views.AspectCreate(); + }); + + describe("#render", function() { + beforeEach(function() { + this.view.render(); + }); + + it("should show the aspect creation form inside a modal", function() { + expect(this.view.$("#newAspectModal.modal").length).toBe(1); + expect(this.view.$("#newAspectModal form").length).toBe(1); + expect(this.view.$("#newAspectModal input#aspect_name").length).toBe(1); + expect(this.view.$("#newAspectModal input#aspect_contacts_visible").length).toBe(1); + expect(this.view.$("#newAspectModal .btn.creation").length).toBe(1); + }); + + it("shouldn't show a hidden person id input", function() { + expect(this.view.$("#newAspectModal input#aspect_person_id").length).toBe(0); + }); + }); + + + describe("#createAspect", function() { + beforeEach(function() { + this.view.render(); + }); + + it("should send the correct name to the server", function() { + var name = "New aspect name"; + this.view.$("input#aspect_name").val(name); + this.view.createAspect(); + var obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + expect(obj.name).toBe(name); + }); + + it("should send the correct contacts_visible to the server", function() { + this.view.createAspect(); + var obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + /* jshint camelcase: false */ + expect(obj.contacts_visible).toBeFalsy(); + /* jshint camelcase: true */ + + this.view.$("input#aspect_contacts_visible").prop("checked", true); + this.view.createAspect(); + obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + /* jshint camelcase: false */ + expect(obj.contacts_visible).toBeTruthy(); + /* jshint camelcase: true */ + }); + + it("should send person_id = null to the server", function() { + this.view.createAspect(); + var obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + /* jshint camelcase: false */ + expect(obj.person_id).toBe(null); + /* jshint camelcase: true */ + }); + + context("with a successfull request", function() { + beforeEach(function() { + this.response = { + status: 200, + responseText: JSON.stringify({id: 1337, name: "new name"}) + }; + }); + + it("should hide the modal", function() { + this.view.$(".modal").modal("show"); + expect(this.view.$(".modal")).toHaveClass("in"); + this.view.createAspect(); + jasmine.Ajax.requests.mostRecent().respondWith(this.response); + expect(this.view.$(".modal")).not.toHaveClass("in"); + }); + + it("should display a flash message", function() { + this.view.createAspect(); + jasmine.Ajax.requests.mostRecent().respondWith(this.response); + expect($("[id^=\"flash\"]")).toBeSuccessFlashMessage( + Diaspora.I18n.t("aspects.create.success", {name: "new name"}) + ); + }); + }); + + context("with a failing request", function() { + beforeEach(function() { + this.response = { status: 422 }; + }); + + it("should hide the modal", function() { + this.view.$(".modal").modal("show"); + expect(this.view.$(".modal")).toHaveClass("in"); + this.view.createAspect(); + jasmine.Ajax.requests.mostRecent().respondWith(this.response); + expect(this.view.$(".modal")).not.toHaveClass("in"); + }); + + it("should display a flash message", function() { + this.view.createAspect(); + jasmine.Ajax.requests.mostRecent().respondWith(this.response); + expect($("[id^=\"flash\"]")).toBeErrorFlashMessage( + Diaspora.I18n.t("aspects.create.failure") + ); + }); + }); + }); + }); + + context("with a person id", function() { + beforeEach(function() { + this.view = new app.views.AspectCreate({personId: "42"}); + }); + + describe("#render", function() { + beforeEach(function() { + this.view.render(); + }); + + it("should show the aspect creation form inside a modal", function() { + expect(this.view.$("#newAspectModal.modal").length).toBe(1); + expect(this.view.$("#newAspectModal form").length).toBe(1); + expect(this.view.$("#newAspectModal input#aspect_name").length).toBe(1); + expect(this.view.$("#newAspectModal input#aspect_contacts_visible").length).toBe(1); + expect(this.view.$("#newAspectModal .btn.creation").length).toBe(1); + }); + + it("should show a hidden person id input", function() { + expect(this.view.$("#newAspectModal input#aspect_person_id").length).toBe(1); + expect(this.view.$("#newAspectModal input#aspect_person_id").prop("value")).toBe("42"); + }); + }); + + describe("#createAspect", function() { + beforeEach(function() { + this.view.render(); + }); + + it("should send the correct name to the server", function() { + var name = "New aspect name"; + this.view.$("input#aspect_name").val(name); + this.view.createAspect(); + var obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + expect(obj.name).toBe(name); + }); + + it("should send the correct contacts_visible to the server", function() { + this.view.createAspect(); + var obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + /* jshint camelcase: false */ + expect(obj.contacts_visible).toBeFalsy(); + /* jshint camelcase: true */ + + this.view.$("input#aspect_contacts_visible").prop("checked", true); + this.view.createAspect(); + obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + /* jshint camelcase: false */ + expect(obj.contacts_visible).toBeTruthy(); + /* jshint camelcase: true */ + }); + + it("should send the correct person_id to the server", function() { + this.view.createAspect(); + var obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); + /* jshint camelcase: false */ + expect(obj.person_id).toBe("42"); + /* jshint camelcase: true */ + }); + }); + }); +}); diff --git a/spec/javascripts/app/views/aspect_view_spec.js b/spec/javascripts/app/views/aspect_view_spec.js index 9f3a98cb1..12ce36941 100644 --- a/spec/javascripts/app/views/aspect_view_spec.js +++ b/spec/javascripts/app/views/aspect_view_spec.js @@ -1,6 +1,6 @@ describe("app.views.Aspect", function(){ beforeEach(function(){ - this.aspect = factory.aspect({selected:true}); + this.aspect = factory.aspectSelection({selected:true}); this.view = new app.views.Aspect({ model: this.aspect }); }); diff --git a/spec/javascripts/helpers/factory.js b/spec/javascripts/helpers/factory.js index c3efcafb7..428cb1ec6 100644 --- a/spec/javascripts/helpers/factory.js +++ b/spec/javascripts/helpers/factory.js @@ -192,6 +192,10 @@ var factory = { return new app.models.Aspect(this.aspectAttrs(overrides)); }, + aspectSelection: function(overrides) { + return new app.models.AspectSelection(this.aspectAttrs(overrides)); + }, + preloads: function(overrides) { var defaults = { aspect_ids: []