Use Bootstrap modal for new aspect form

This commit is contained in:
Steffen van Bergerem 2015-04-04 05:20:18 +02:00
parent 4812dc7a23
commit 75ef9f47d0
25 changed files with 412 additions and 157 deletions

View file

@ -1,7 +1,7 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
app.collections.Aspects = Backbone.Collection.extend({ app.collections.Aspects = Backbone.Collection.extend({
model: app.models.Aspect, model: app.models.AspectSelection,
selectedAspects: function(attribute){ selectedAspects: function(attribute){
return _.pluck(_.filter(this.toJSON(), function(a){ return _.pluck(_.filter(this.toJSON(), function(a){

View file

@ -1,9 +1,5 @@
// @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later
app.models.Aspect = Backbone.Model.extend({ app.models.Aspect = Backbone.Model.extend({
toggleSelected: function(){ urlRoot: "/aspects"
this.set({'selected' : !this.get('selected')}, {async: false});
}
}); });
// @license-end // @license-end

View file

@ -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

View file

@ -16,8 +16,12 @@ app.pages.Contacts = Backbone.View.extend({
this.chat_toggle = $("#chat_privilege_toggle .entypo"); this.chat_toggle = $("#chat_privilege_toggle .entypo");
this.stream = opts.stream; this.stream = opts.stream;
this.stream.render(); this.stream.render();
$("#people_stream.contacts .header .entypo").tooltip({ 'placement': 'bottom'}); $("#people_stream.contacts .header .entypo").tooltip({"placement": "bottom"});
$(document).on('ajax:success', 'form.edit_aspect', this.updateAspectName); $(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() { toggleChatPrivilege: function() {
@ -26,13 +30,13 @@ app.pages.Contacts = Backbone.View.extend({
.removeClass("enabled") .removeClass("enabled")
.removeAttr("data-original-title") .removeAttr("data-original-title")
.attr("title", Diaspora.I18n.t("contacts.aspect_chat_is_not_enabled")) .attr("title", Diaspora.I18n.t("contacts.aspect_chat_is_not_enabled"))
.tooltip({'placement': 'bottom'}); .tooltip({"placement": "bottom"});
} else { } else {
this.chat_toggle.tooltip("destroy") this.chat_toggle.tooltip("destroy")
.addClass("enabled") .addClass("enabled")
.removeAttr("data-original-title") .removeAttr("data-original-title")
.attr("title", Diaspora.I18n.t("contacts.aspect_chat_is_enabled")) .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") .tooltip("destroy")
.removeAttr("data-original-title") .removeAttr("data-original-title")
.attr("title", Diaspora.I18n.t("contacts.aspect_list_is_not_visible")) .attr("title", Diaspora.I18n.t("contacts.aspect_list_is_not_visible"))
.tooltip({'placement': 'bottom'}); .tooltip({"placement": "bottom"});
} }
else { else {
this.visibility_toggle.removeClass("lock") this.visibility_toggle.removeClass("lock")
@ -51,7 +55,7 @@ app.pages.Contacts = Backbone.View.extend({
.tooltip("destroy") .tooltip("destroy")
.removeAttr("data-original-title") .removeAttr("data-original-title")
.attr("title", Diaspora.I18n.t("contacts.aspect_list_is_visible")) .attr("title", Diaspora.I18n.t("contacts.aspect_list_is_visible"))
.tooltip({'placement': 'bottom'}); .tooltip({"placement": "bottom"});
} }
}, },

View file

@ -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

View file

@ -13,12 +13,20 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({
events: { events: {
"click ul.aspect_membership.dropdown-menu > li.aspect_selector": "_clickHandler", "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() { initialize: function() {
this.list_item = null; this.list_item = null;
this.dropdown = 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 // decide what to do when clicked
@ -140,6 +148,9 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({
this._toggleCheckbox(target); this._toggleCheckbox(target);
this._updateButton('green'); this._updateButton('green');
}, },
showModal: function() {
this.$("#newAspectModal").modal("show");
}
}); });
// @license-end // @license-end

View file

@ -6,18 +6,26 @@ app.views.AspectsList = app.views.Base.extend({
el: '#aspects_list', el: '#aspects_list',
events: { events: {
'click .toggle_selector' : 'toggleAll' "click .toggle_selector" : "toggleAll"
},
subviews : {
"#newAspectContainer" : "aspectCreateView"
}, },
initialize: function() { initialize: function() {
this.collection.on('change', this.toggleSelector, this); this.collection.on("change", this.toggleSelector, this);
this.collection.on('change', this.updateStreamTitle, this); this.collection.on("change", this.updateStreamTitle, this);
this.collection.on('aspectStreamFetched', this.updateAspectList, 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() { postRenderTemplate: function() {
this.collection.each(this.appendAspect, this); this.collection.each(this.appendAspect, this);
this.$('a[rel*=facebox]').facebox();
this.updateStreamTitle(); this.updateStreamTitle();
this.toggleSelector(); this.toggleSelector();
}, },
@ -67,6 +75,6 @@ app.views.AspectsList = app.views.Base.extend({
hideAspectsList: function() { hideAspectsList: function() {
this.$el.empty(); this.$el.empty();
}, }
}); });
// @license-end // @license-end

View file

@ -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;
}
}

View file

@ -0,0 +1,40 @@
<div class="modal hide fade" id="newAspectModal" tabindex="-1" role="dialog" aria-labelledby="newAspectModalLabel" aria-hidden="true">
<div class="modal-header">
<button class="close" type="button" data-dismiss="modal" aria-hidden="true">&times;</button>
<h3 id="newAspectModalLabel">{{ t "aspects.create.add_a_new_aspect" }}</h3>
</div>
<div class="modal-body">
<form>
<fieldset>
{{#if addPersonId}}
<input id="aspect_person_id" type="hidden" value="{{ personId }}">
{{/if}}
<div class="control-group">
<label for="aspect_name">{{ t "aspects.name" }}</label>
<input id="aspect_name" class="input-block-level" maxlength=20 type="text">
</div>
<div class="control-group">
<label for="aspect_contacts_visible" class="checkbox inline">
<input id="aspect_contacts_visible" type="checkbox">
{{ t "aspects.make_aspect_list_visible" }}
</label>
</div>
</fieldset>
</form>
</div>
<div class="modal-footer">
<div class="btn" data-dismiss="modal" aria-hidden="true">
{{ t "cancel" }}
</div>
<div class="btn creation">
{{ t "create" }}
</div>
</div>
</div>

View file

@ -4,5 +4,8 @@
</a> </a>
</li> </li>
<li class="hoverable"> <li class="hoverable">
<a href="/aspects/new" class="selectable new_aspect" rel="facebox">{{ t "aspect_navigation.add_an_aspect" }}</a> <a href="#" class="selectable new_aspect" data-toggle="modal" data-target="#newAspectModal">
{{ t "aspect_navigation.add_an_aspect" }}
</a>
<div id="newAspectContainer"></div>
</li> </li>

View file

@ -11,35 +11,15 @@ class AspectsController < ApplicationController
def create def create
@aspect = current_user.aspects.build(aspect_params) @aspect = current_user.aspects.build(aspect_params)
aspecting_person_id = params[:aspect][:person_id] aspecting_person_id = params[:person_id]
if @aspect.save if @aspect.save
flash[:notice] = I18n.t('aspects.create.success', :name => @aspect.name) if aspecting_person_id.present?
if current_user.getting_started || request.referer.include?("contacts")
redirect_to :back
elsif aspecting_person_id.present?
connect_person_to_aspect(aspecting_person_id) connect_person_to_aspect(aspecting_person_id)
else
redirect_to contacts_path(:a_id => @aspect.id)
end end
render json: {id: @aspect.id, name: @aspect.name}
else else
respond_to do |format| render nothing: true, status: 422
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 }
end end
end end

View file

@ -23,4 +23,9 @@
%li.divider %li.divider
%li.newItem %li.newItem
.add_aspect .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

View file

@ -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) =>");

View file

@ -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'

View file

@ -21,8 +21,11 @@
= aspect = aspect
%li.new_aspect %li.new_aspect
%a{:href => new_aspect_path, :rel => "facebox"} %a{ "data-toggle" => "modal", "data-target" => "#newAspectModal", href: "#"}
= t('aspects.aspect_listings.add_an_aspect') = t("aspects.aspect_listings.add_an_aspect")
#newAspectContainer
-# JS
%li.only_sharing{:class => ("active" if params["set"] == "only_sharing")} %li.only_sharing{:class => ("active" if params["set"] == "only_sharing")}
%a{:href => contacts_path(:set => "only_sharing")} %a{:href => contacts_path(:set => "only_sharing")}

View file

@ -1,14 +1,14 @@
%h3 %h3
= t('contacts.index.title') = t("contacts.index.title")
= render 'contacts/aspect_listings' = render "contacts/aspect_listings"
%hr %hr
- if AppConfig.settings.community_spotlight.enable? - if AppConfig.settings.community_spotlight.enable?
.text-center.spotlight .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 .text-center
.btn.btn-link{ 'data-toggle' => 'modal', 'data-target' => '#invitationsModal'} .btn.btn-link{ "data-toggle" => "modal", "data-target" => "#invitationsModal"}
= t('invitations.new.invite_someone_to_join') = t("invitations.new.invite_someone_to_join")
= render 'shared/modal', = render "shared/modal",
:path => new_user_invitation_path, path: new_user_invitation_path,
:id => 'invitationsModal', id: "invitationsModal",
:title => t('invitations.new.invite_someone_to_join') title: t("invitations.new.invite_someone_to_join")

View file

@ -5,8 +5,10 @@
en: en:
javascripts: javascripts:
cancel: "Cancel"
confirm_dialog: "Are you sure?" confirm_dialog: "Are you sure?"
confirm_unload: "Please confirm that you want to leave this page. Data you have entered wont be saved." confirm_unload: "Please confirm that you want to leave this page. Data you have entered wont be saved."
create: "Create"
delete: "Delete" delete: "Delete"
ignore: "Ignore" ignore: "Ignore"
report: report:
@ -26,6 +28,15 @@ en:
comma: "," comma: ","
edit: "Edit" edit: "Edit"
no_results: "No results found" 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: timeago:
prefixAgo: "" prefixAgo: ""
prefixFromNow: "" prefixFromNow: ""

View file

@ -66,8 +66,8 @@ Feature: following and being followed
And I press the first ".aspect_membership_dropdown .dropdown-toggle" And I press the first ".aspect_membership_dropdown .dropdown-toggle"
And I press the first "a" within ".add_aspect" And I press the first "a" within ".add_aspect"
And I fill in "Name" with "Super People" in the modal window And I fill in "aspect_name" with "Super People" in the aspect creation modal
And I press "Create" in the modal window And I click on selector ".btn.creation" in the aspect creation modal
When I go to the home page When I go to the home page
Then I should have 1 contact in "Super People" Then I should have 1 contact in "Super People"

View file

@ -8,16 +8,16 @@ Feature: User manages contacts
Given I am signed in Given I am signed in
And I am on the contacts page And I am on the contacts page
And I follow "+ Add an aspect" And I follow "+ Add an aspect"
And I fill in "Name" with "Dorm Mates" in the modal window And I fill in "aspect_name" with "Dorm Mates" in the aspect creation modal
And I press "Create" in the modal window And I click on selector ".btn.creation" in the aspect creation modal
Then I should see "Dorm Mates" within "#aspect_nav" Then I should see "Dorm Mates" within "#aspect_nav"
Scenario: creating an aspect from homepage Scenario: creating an aspect from homepage
Given I am signed in Given I am signed in
And I go to the aspects page And I go to the aspects page
When I follow "Add an aspect" When I follow "Add an aspect"
And I fill in "Name" with "losers" in the modal window And I fill in "aspect_name" with "losers" in the aspect creation modal
And I press "Create" in the modal window And I click on selector ".btn.creation" in the aspect creation modal
Then I should see "losers" within "#aspect_nav" Then I should see "losers" within "#aspect_nav"
Scenario: deleting an aspect from contacts index Scenario: deleting an aspect from contacts index

View file

@ -82,6 +82,12 @@ When /^I press the aspect dropdown$/ do
click_aspect_dropdown click_aspect_dropdown
end end
When /^(.*) in the aspect creation modal$/ do |action|
within("#newAspectModal") do
step action
end
end
And /^I toggle the aspect "([^"]*)"$/ do |name| And /^I toggle the aspect "([^"]*)"$/ do |name|
toggle_aspect(name) toggle_aspect(name)
end end

View file

@ -16,25 +16,6 @@ describe AspectsController, :type => :controller do
request.env["HTTP_REFERER"] = 'http://' + request.host request.env["HTTP_REFERER"] = 'http://' + request.host
end 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 describe "#show" do
it "succeeds" do it "succeeds" do
get :show, 'id' => @alices_aspect_1.id.to_s get :show, 'id' => @alices_aspect_1.id.to_s
@ -50,30 +31,32 @@ describe AspectsController, :type => :controller do
context "with valid params" do context "with valid params" do
it "creates an aspect" do it "creates an aspect" do
expect(alice.aspects.count).to eq(2) 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) expect(alice.reload.aspects.count).to eq(3)
end end
it "redirects to the aspect's contact page" do
post :create, "aspect" => {"name" => "new aspect"} it "returns the created aspect as json" do
expect(response).to redirect_to(contacts_path(:a_id => Aspect.find_by_name("new aspect").id)) 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 end
context "with person_id param" do context "with person_id param" do
it "creates a contact if one does not already exist" do it "creates a contact if one does not already exist" do
expect { 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 { }.to change {
alice.contacts.count alice.contacts.count
}.by(1) }.by(1)
end end
it "adds a new contact to the new aspect" do 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) expect(alice.aspects.find_by_name("new").contacts.count).to eq(1)
end end
it "adds an existing contact to the new aspect" do 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) expect(alice.aspects.find_by_name("new").contacts.count).to eq(1)
end end
end end
@ -82,12 +65,13 @@ describe AspectsController, :type => :controller do
context "with invalid params" do context "with invalid params" do
it "does not create an aspect" do it "does not create an aspect" do
expect(alice.aspects.count).to eq(2) expect(alice.aspects.count).to eq(2)
post :create, "aspect" => {"name" => ""} post :create, aspect: {name: ""}
expect(alice.reload.aspects.count).to eq(2) expect(alice.reload.aspects.count).to eq(2)
end end
it "goes back to the page you came from" do
post :create, "aspect" => {"name" => ""} it "responds with 422" do
expect(response).to redirect_to(:back) post :create, aspect: {name: ""}
expect(response.status).to eq(422)
end end
end end
end end

View file

@ -1,13 +1,13 @@
describe("app.models.Aspect", function(){ describe("app.models.AspectSelection", function(){
describe("#toggleSelected", function(){ describe("#toggleSelected", function(){
it("should select the aspect", 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(); this.aspect.toggleSelected();
expect(this.aspect.get("selected")).toBeTruthy(); expect(this.aspect.get("selected")).toBeTruthy();
}); });
it("should deselect the aspect", function(){ 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(); this.aspect.toggleSelected();
expect(this.aspect.get("selected")).toBeFalsy(); expect(this.aspect.get("selected")).toBeFalsy();
}); });

View file

@ -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 */
});
});
});
});

View file

@ -1,6 +1,6 @@
describe("app.views.Aspect", function(){ describe("app.views.Aspect", function(){
beforeEach(function(){ beforeEach(function(){
this.aspect = factory.aspect({selected:true}); this.aspect = factory.aspectSelection({selected:true});
this.view = new app.views.Aspect({ model: this.aspect }); this.view = new app.views.Aspect({ model: this.aspect });
}); });

View file

@ -192,6 +192,10 @@ var factory = {
return new app.models.Aspect(this.aspectAttrs(overrides)); return new app.models.Aspect(this.aspectAttrs(overrides));
}, },
aspectSelection: function(overrides) {
return new app.models.AspectSelection(this.aspectAttrs(overrides));
},
preloads: function(overrides) { preloads: function(overrides) {
var defaults = { var defaults = {
aspect_ids: [] aspect_ids: []