Merge branch 'next-minor' into develop

This commit is contained in:
Benjamin Neff 2017-08-29 02:17:47 +02:00
commit 295bb15f73
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
40 changed files with 202 additions and 163 deletions

View file

@ -15,15 +15,21 @@
* Remove tiff support from photos [#7576](https://github.com/diaspora/diaspora/pull/7576)
* Remove reference from reshares when original post is deleted [#7578](https://github.com/diaspora/diaspora/pull/7578)
* Merge migrations from before 0.6.0.0 to CreateSchema [#7580](https://github.com/diaspora/diaspora/pull/7580)
* Remove auto detection of languages with highlightjs [#7591](https://github.com/diaspora/diaspora/pull/7591)
* Move enable/disable notification icon [#7592](https://github.com/diaspora/diaspora/pull/7592)
* Use Bootstrap 3 progress-bar for polls [#7600](https://github.com/diaspora/diaspora/pull/7600)
## Bug fixes
* Fix displaying polls with long answers [#7579](https://github.com/diaspora/diaspora/pull/7579)
* Fix S3 support [#7566](https://github.com/diaspora/diaspora/pull/7566)
* Fix mixed username and timestamp with LTR/RTL scripts [#7575](https://github.com/diaspora/diaspora/pull/7575)
* Prevent users from zooming in IE Mobile [#7589](https://github.com/diaspora/diaspora/pull/7589)
* Fix recipient prefill on contacts and profile page [#7599](https://github.com/diaspora/diaspora/pull/7599)
## Features
* Ask for confirmation when leaving a submittable comment field [#7530](https://github.com/diaspora/diaspora/pull/7530)
* Show users vote in polls [#7550](https://github.com/diaspora/diaspora/pull/7550)
* Add explanation of ignore function to in-app help section [#7585](https://github.com/diaspora/diaspora/pull/7585)
# 0.7.0.0

View file

@ -8,8 +8,7 @@
breaks: true,
html: true,
linkify: true,
typographer: true,
langPrefix: ""
typographer: true
});
var inlinePlugin = window.markdownitForInline;
@ -72,10 +71,6 @@
} catch (__) {}
}
try {
return hljs.highlightAuto(str).value;
} catch (__) {}
return "";
}
});

View file

@ -80,7 +80,10 @@ app.pages.Contacts = Backbone.View.extend({
showMessageModal: function(){
$("#conversationModal").on("modal:loaded", function() {
new app.views.ConversationsForm({prefill: gon.conversationPrefill});
var people = _.pluck(app.contacts.filter(function(contact) {
return contact.inAspect(app.aspect.get("id"));
}), "person");
new app.views.ConversationsForm({prefill: people});
});
app.helpers.showModal("#conversationModal");
},

View file

@ -52,8 +52,13 @@ app.views.ConversationsForm = app.views.Base.extend({
this.setupAvatarFallback(personEl);
},
prefill: function(handles) {
handles.forEach(this.addRecipient.bind(this));
prefill: function(people) {
people.forEach(function(person) {
this.addRecipient(_.extend({
avatar: person.get("profile").avatar.small,
handle: person.get("diaspora_id")
}, person.attributes));
}, this);
},
updateContactIdsListInput: function() {

View file

@ -5,7 +5,7 @@ app.views.Poll = app.views.Base.extend({
events: {
"click .submit" : "clickSubmit",
"click .toggle_result" : "toggleResult"
"click .toggle-result": "toggleResult"
},
initialize: function() {
@ -55,7 +55,7 @@ app.views.Poll = app.views.Base.extend({
percent = Math.round(answer.vote_count / participation_count * 100);
}
var progressBar = _this.$(".poll_progress_bar[data-answerid="+answer.id+"]");
var progressBar = _this.$(".progress-bar[data-answerid=" + answer.id + "]");
_this.setProgressBarData(progressBar, percent);
});
@ -68,8 +68,8 @@ app.views.Poll = app.views.Base.extend({
pollButtons: function() {
if(!this.poll || !this.poll.post_id) {
this.$('.submit').attr('disabled', true);
this.$('.toggle_result').attr('disabled', true);
this.$(".submit").attr("disabled", true);
this.$(".toggle-result").attr("disabled", true);
}
},
@ -83,14 +83,14 @@ app.views.Poll = app.views.Base.extend({
}
this.toggleElements();
var toggle_result = this.$('.toggle_result');
var toggleResult = this.$(".toggle-result");
if(!this.toggleMode) {
toggle_result.html(Diaspora.I18n.t("poll.close_result"));
toggleResult.html(Diaspora.I18n.t("poll.close_result"));
this.toggleMode = 1;
}
else {
toggle_result.html(Diaspora.I18n.t("poll.show_result"));
toggleResult.html(Diaspora.I18n.t("poll.show_result"));
this.toggleMode = 0;
}
},

View file

@ -81,8 +81,8 @@ app.views.ProfileHeader = app.views.Base.extend({
showMessageModal: function(){
$("#conversationModal").on("modal:loaded", function() {
new app.views.ConversationsForm({prefill: gon.conversationPrefill});
});
new app.views.ConversationsForm({prefill: [this.model]});
}.bind(this));
app.helpers.showModal("#conversationModal");
}
});

View file

@ -19,9 +19,9 @@ body {
.info .tag { background-color: $gray-light; }
.poll_form .progress {
.poll-form .progress {
background-color: $gray-dark;
.bar { background-color: $gray-light; }
.progress-bar { background-color: $gray-light; }
.users-vote { background-color: $brand-primary; }
}

View file

@ -1,4 +1,4 @@
.poll_form {
.poll-form {
border-bottom: 1px solid $border-grey;
border-top: 1px solid $border-grey;
margin: 10px 0;
@ -14,38 +14,27 @@
}
.progress {
background-image: none;
box-shadow: 0 0 0;
height: 10px;
margin-bottom: 5px;
clear: both;
.bar {
background: $border-dark-grey none;
color: $text-dark-grey;
height: 100%;
text-align: left;
}
.users-vote {
background-color: $brand-primary;
}
.progress-bar { background-color: $border-dark-grey; }
.users-vote { background-color: $brand-primary; }
}
.submit[disabled] {
color: $text-grey;
cursor: default;
&:hover,
&:active {
background-image: none;
}
}
}
.poll-content {
margin-top: 5px;
.result-head {
margin-bottom: 5px;
}
[type=radio],
label {
font-weight: normal;

View file

@ -24,6 +24,16 @@
</a>
<div class='answer hideable'>{{ post_notification_a }}</div>
</div>
<div class='question opened collapsible'>
<a class='toggle' href='#'>
<h4>{{ ignore_user_q }}</h4>
</a>
<div class='answer hideable'>
<p>{{ ignore_user_a1 }}</p>
<p>{{ ignore_user_a2 }}</p>
<p>{{ ignore_user_a3 }}</p>
</div>
</div>
<div class='question opened collapsible'>
<a class='toggle' href='#'>
<h4>{{ post_report_q }}</h4>

View file

@ -29,7 +29,7 @@
<span class="section-selected">{{ title_pods }}</span>
</li>
<li>
<a href="#" class="section-unselected faq-link-posts-and-posting" data-section="posts_and_posting" data-items="hide_posts format_text insert_images">{{ title_posts_and_posting }}</a>
<a href="#" class="section-unselected faq-link-posts-and-posting" data-section="posts_and_posting" data-items="hide_posts ignore_user format_text insert_images">{{ title_posts_and_posting }}</a>
<span class="section-selected">{{ title_posts_and_posting }}</span>
</li>
<li>

View file

@ -1,8 +1,8 @@
{{#if poll}}
<div class="poll_form">
<div class="poll_head">
<div class="poll-form">
<div class="poll-head">
<strong>{{poll.question}}</strong>
<div class="poll_statistic pull-right">
<div class="poll-statistic pull-right">
{{t "poll.count" count=poll.participation_count}}
</div>
</div>
@ -12,24 +12,26 @@
{{/if}}
{{#poll.poll_answers}}
<div class="result-row">
<input type="radio" name="vote" value="{{id}}"/>
{{#if isCurrentUserVote}}
<label>
{{answer}}
<span class="label label-primary">{{t "poll.your_vote"}}</span>
</label>
{{else}}
<label>{{answer}}</label>
{{/if}}
<div class="poll-result pull-right">
<span class="percentage"></span>
({{t "poll.answer_count" count=vote_count}})
</div>
<div class="poll_progress_bar_wrapper progress">
<div class="result-head">
<input type="radio" name="vote" value="{{id}}"/>
{{#if isCurrentUserVote}}
<div class="poll_progress_bar bar users-vote" data-answerid="{{id}}" style="height: 100%"></div>
<label>
{{answer}}
<span class="label label-primary">{{t "poll.your_vote"}}</span>
</label>
{{else}}
<div class="poll_progress_bar bar" data-answerid="{{id}}" style="height: 100%"></div>
<label>{{answer}}</label>
{{/if}}
<div class="poll-result pull-right">
<span class="percentage"></span>
({{t "poll.answer_count" count=vote_count}})
</div>
</div>
<div class="progress">
{{#if isCurrentUserVote}}
<div class="progress-bar users-vote" data-answerid="{{id}}" style="height: 100%"></div>
{{else}}
<div class="progress-bar" data-answerid="{{id}}" style="height: 100%"></div>
{{/if}}
</div>
</div>
@ -39,7 +41,7 @@
{{#if preview}}
<span>{{t "poll.show_result"}}</span>
{{else}}
<a class="toggle_result" href="#">{{t "poll.show_result"}}</a>
<a class="toggle-result" href="#">{{t "poll.show_result"}}</a>
{{/if}}
</div>
<input type="submit" class="submit pull-right btn btn-default" value="{{t "poll.vote"}}"/>

View file

@ -3,12 +3,6 @@
<i class="entypo-trash"></i>
</a>
{{else}}
<a href="#" rel="nofollow" data-type="Post" class="post_report" title="{{t "report.name"}}">
<i class="entypo-warning"></i>
</a>
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
<i class="entypo-block"></i>
</a>
{{#if participation}}
<a href="#" rel="nofollow" class="destroy_participation" title="{{t "stream.disable_post_notifications"}}">
<i class="entypo-bell"></i>
@ -18,6 +12,12 @@
<i class="entypo-bell"></i>
</a>
{{/if}}
<a href="#" rel="nofollow" data-type="Post" class="post_report" title="{{t "report.name"}}">
<i class="entypo-warning"></i>
</a>
<a href="#" rel="nofollow" class="block_user" title="{{t "ignore"}}">
<i class="entypo-block"></i>
</a>
<a href="#" rel="nofollow" class="delete hide_post" title="{{t "stream.hide"}}">
<i class="entypo-cross"></i>
</a>

View file

@ -5,12 +5,6 @@
<i class="entypo-trash"></i>
</a>
{{else}}
<a href="#" data-type="Post" class="post_report" title="{{t "report.name"}}">
<i class="entypo-warning"></i>
</a>
<a href="#" data-type="post" class="block_user" title="{{t "ignore"}}">
<i class="entypo-block"></i>
</a>
{{#if participation}}
<a href="#" data-type="nofollow" class="destroy_participation" title="{{t "stream.disable_post_notifications"}}">
<i class="entypo-bell"></i>
@ -20,6 +14,12 @@
<i class="entypo-bell"></i>
</a>
{{/if}}
<a href="#" data-type="Post" class="post_report" title="{{t "report.name"}}">
<i class="entypo-warning"></i>
</a>
<a href="#" data-type="post" class="block_user" title="{{t "ignore"}}">
<i class="entypo-block"></i>
</a>
<a href="#" data-type="post" class="hide_post" title="{{t "stream.hide"}}">
<i class="entypo-cross"></i>
</a>

View file

@ -103,12 +103,6 @@ class ConversationsController < ApplicationController
render :layout => true
else
if params[:contact_id]
gon.push conversation_prefill: [current_user.contacts.find(params[:contact_id]).person.as_json]
elsif params[:aspect_id]
gon.push conversation_prefill: current_user.aspects
.find(params[:aspect_id]).contacts.map {|c| c.person.as_json }
end
render :layout => false
end
end

View file

@ -6,7 +6,7 @@ class PostsController < ApplicationController
before_action :authenticate_user!, only: %i(destroy mentionable)
before_action :set_format_if_malformed_from_status_net, only: :show
respond_to :html, :mobile, :json, :xml
respond_to :html, :mobile, :json
rescue_from Diaspora::NonPublic do
authenticate_user!

View file

@ -45,7 +45,7 @@ class Comment < ApplicationRecord
after_destroy do
self.parent.update_comments_counter
participation = author.participations.where(target_id: post.id).first
participation = author.participations.find_by(target_id: post.id)
participation.unparticipate! if participation.present?
end

View file

@ -38,10 +38,10 @@ class Conversation < ApplicationRecord
end
def set_read(user)
if visibility = self.conversation_visibilities.where(:person_id => user.person.id).first
visibility.unread = 0
visibility.save
end
visibility = conversation_visibilities.find_by(person_id: user.person.id)
return unless visibility
visibility.unread = 0
visibility.save
end
def participant_handles
@ -57,7 +57,7 @@ class Conversation < ApplicationRecord
def last_author
return unless @last_author.present? || messages.size > 0
@last_author_id ||= messages.pluck(:author_id).last
@last_author ||= Person.includes(:profile).where(id: @last_author_id).first
@last_author ||= Person.includes(:profile).find_by(id: @last_author_id)
end
def ordered_participants

View file

@ -30,7 +30,7 @@ class Like < ApplicationRecord
after_destroy do
self.parent.update_likes_counter
participation = author.participations.where(target_id: target.id).first
participation = author.participations.find_by(target_id: target.id)
participation.unparticipate! if participation.present?
end

View file

@ -15,10 +15,10 @@ class Message < ApplicationRecord
end
def increase_unread(user)
if vis = ConversationVisibility.where(:conversation_id => self.conversation_id, :person_id => user.person.id).first
vis.unread += 1
vis.save
end
vis = ConversationVisibility.find_by(conversation_id: conversation_id, person_id: user.person.id)
return unless vis
vis.unread += 1
vis.save
end
def message

View file

@ -191,7 +191,7 @@ class Person < ApplicationRecord
def self.find_from_guid_or_username(params)
p = if params[:id].present?
Person.where(:guid => params[:id]).first
Person.find_by(guid: params[:id])
elsif params[:username].present? && u = User.find_by_username(params[:username])
u.person
else

View file

@ -124,12 +124,12 @@ class Post < ApplicationRecord
def reshare_for(user)
return unless user
reshares.where(:author_id => user.person.id).first
reshares.find_by(author_id: user.person.id)
end
def like_for(user)
return unless user
likes.where(:author_id => user.person.id).first
likes.find_by(author_id: user.person.id)
end
#############

View file

@ -5,8 +5,8 @@
class Reshare < Post
belongs_to :root, class_name: "Post", foreign_key: :root_guid, primary_key: :guid, optional: true
validate :root_must_be_public
validates_presence_of :root, :on => :create
validates_uniqueness_of :root_guid, :scope => :author_id
validates :root, presence: true, on: :create, if: proc {|reshare| reshare.author.local? }
validates :root_guid, uniqueness: {scope: :author_id}, allow_nil: true
delegate :author, to: :root, prefix: true
before_validation do

View file

@ -24,7 +24,7 @@ class Service < ApplicationRecord
def first_from_omniauth( auth_hash )
@@auth = auth_hash
where( type: service_type, uid: options[:uid] ).first
find_by(type: service_type, uid: options[:uid])
end
def initialize_from_omniauth( auth_hash )

View file

@ -176,7 +176,7 @@ class User < ApplicationRecord
if pref_hash[key] == 'true'
self.user_preferences.find_or_create_by(email_type: key)
else
block = self.user_preferences.where(:email_type => key).first
block = user_preferences.find_by(email_type: key)
if block
block.destroy
end
@ -289,9 +289,9 @@ class User < ApplicationRecord
# @return [Like]
def like_for(target)
if target.likes.loaded?
return target.likes.detect{ |like| like.author_id == self.person.id }
target.likes.find {|like| like.author_id == person.id }
else
return Like.where(:author_id => self.person.id, :target_type => target.class.base_class.to_s, :target_id => target.id).first
Like.find_by(author_id: person.id, target_type: target.class.base_class.to_s, target_id: target.id)
end
end

View file

@ -28,7 +28,7 @@ module User::Querying
def block_for(person)
return nil unless person
self.blocks.where(person_id: person.id).first
blocks.find_by(person_id: person.id)
end
def aspects_with_shareable(base_class_name_or_class, shareable_id)
@ -38,7 +38,7 @@ module User::Querying
end
def contact_for_person_id(person_id)
Contact.where(:user_id => self.id, :person_id => person_id).includes(:person => :profile).first
Contact.includes(person: :profile).find_by(user_id: id, person_id: person_id)
end
# @param [Person] person

View file

@ -49,7 +49,7 @@ module User::SocialActions
def update_or_create_participation!(target)
return if target.author == person
participation = participations.where(target_id: target).first
participation = participations.find_by(target_id: target)
if participation.present?
participation.update!(count: participation.count.next)
else

View file

@ -1,2 +1 @@
= include_gon camel_case: true
= render 'conversations/new'
= render "conversations/new"

View file

@ -12,7 +12,7 @@
= render "head"
= include_color_theme "mobile"
%meta{name: "viewport", content: "width=device-width, minimum-scale=1 maximum-scale=1"}/
%meta{name: "viewport", content: "width=device-width, minimum-scale=1, maximum-scale=1, user-scalable=no"}/
%meta{name: "HandheldFriendly", content: "True"}/
%meta{name: "MobileOptimized", content: "320"}/
%meta{"http-equiv" => "cleartype", :content => "on"}/

View file

@ -402,6 +402,10 @@ en:
hide_posts_a: "If you point your mouse at the top of a post, an X appears on the right. Click it to hide the post and mute notifications about it. You can still see the post if you visit the profile page of the person who posted it."
post_notification_q: "How do I get notifications, or stop getting notifications, about a post?"
post_notification_a: "You will find a bell icon next to the X at the top right of a post. Click this to enable or disable notifications for that post."
ignore_user_q: "How do I stop someones posts from appearing in my stream?"
ignore_user_a1: "If you are currently sharing with that person, removing them from your aspects will stop many of their posts from appearing in your stream. A more complete method is to “ignore” that account. This will prevent any of their posts from appearing in your stream, and they will no longer be able to like or comment on your posts. They will, however, still be able to reshare your posts, comment on reshares of your posts, and their comments on posts by other people which appear in your stream will still be visible to you."
ignore_user_a2: "To ignore an account, click the “ignore” icon (a circle with a diagonal line through it) at the top right of one of their posts. Their posts will instantly disappear from your stream. Alternatively, go to their profile page and click the ignore icon there. You will still be able to see their posts on their profile page, or by using the single-post view."
ignore_user_a3: "A list of people you are ignoring can be found in your account settings under Privacy. To stop ignoring someone, remove them from the list on that page."
post_report_q: "How do I report an offensive post?"
post_report_a: "Click the alert triangle icon at the top right of the post to report it to your podmin. Enter a reason for reporting this post in the dialog box. Please only report posts that break our %{community_guidelines} or your pods terms of service, for example posts containing illegal content, or which are abusive or spam."
character_limit_q: "What is the character limit for posts?"
@ -940,9 +944,9 @@ en:
report:
title: "Reports overview"
post_label: "<b>Post</b>: %{content}"
comment_label: "<b>Comment</b>: %{data}"
reported_label: "<b>Reported by</b> %{person}"
post_label: "<strong>Post</strong>: %{content}"
comment_label: "<strong>Comment</strong>: %{data}"
reported_label: "<strong>Reported by</strong> %{person}"
reason_label: "Reason:"
review_link: "Mark as reviewed"
delete_link: "Delete item"

View file

@ -80,7 +80,7 @@ Feature: preview posts in the stream
| normal |
| not normal |
And I preview the post
Then I should see a ".poll_form" within ".md-preview .stream-element"
Then I should see a ".poll-form" within ".md-preview .stream-element"
And I should see a "form" within ".md-preview .stream-element"
And I close the publisher

View file

@ -46,7 +46,7 @@ Feature: posting with a poll
| normal |
| not normal |
And I press "Share"
Then I should see a ".poll_form" within ".stream-element"
Then I should see a ".poll-form" within ".stream-element"
And I should see a "form" within ".stream-element"
Scenario: vote for an option
@ -62,9 +62,9 @@ Feature: posting with a poll
And I check the first option
And I press "Vote" within ".stream-element"
Then I should see an element ".poll_progress_bar"
Then I should see an element ".progress-bar"
And I should see an element ".percentage"
And I should see "1 vote so far" within ".poll_statistic"
And I should see "1 vote so far" within ".poll-statistic"
Scenario: click to show result
Given I expand the publisher
@ -76,7 +76,7 @@ Feature: posting with a poll
| normal |
| not normal |
And I press "Share"
And I click on selector ".toggle_result"
And I click on selector ".toggle-result"
Then I should see an element ".percentage"
Scenario: validate answer input

View file

@ -19,8 +19,8 @@ When /^I fill in the following for the options:$/ do |table|
end
When /^I check the first option$/ do
page.should have_css('.poll_form input')
first(".poll_form input").click
page.should have_css(".poll-form input")
first(".poll-form input").click
end
When(/^I fill in values for the first two options$/) do

View file

@ -20,16 +20,6 @@ describe ConversationsController, :type => :controller do
get :new, params: {modal: true}
expect(response).to be_success
end
it "assigns a contact if passed a contact id" do
get :new, params: {contact_id: alice.contacts.first.id, modal: true}
expect(controller.gon.conversation_prefill).to eq([alice.contacts.first.person.as_json])
end
it "assigns a set of contacts if passed an aspect id" do
get :new, params: {aspect_id: alice.aspects.first.id, modal: true}
expect(controller.gon.conversation_prefill).to eq(alice.aspects.first.contacts.map {|c| c.person.as_json })
end
end
context "mobile" do
@ -483,7 +473,9 @@ describe ConversationsController, :type => :controller do
it "returns html of conversation" do
get :raw, params: {conversation_id: conversation.id}
expect(response).to render_template(partial: "show", locals: {conversation: conversation})
expect(response).to render_template(partial: "conversations/_show")
expect(response.body).to include conversation.subject
expect(response.body).to include conversation.messages.first.text
end
it "returns 404 when requesting non-existant conversation" do

View file

@ -93,7 +93,7 @@ describe StatusMessagesController, :type => :controller do
post :create, params: status_message_hash, format: :json
expect(response.status).to eq(201)
status_message = StatusMessage.find_by_text(text)
expect(status_message.aspect_visibilities.map(&:aspect)).to eq([@aspect1]), format: :json
expect(status_message.aspect_visibilities.map(&:aspect)).to eq([@aspect1])
end
it "takes one aspect as string in aspect_ids" do

View file

@ -290,17 +290,15 @@ describe("app.pages.Contacts", function(){
});
it("initializes app.views.ConversationsForm with correct parameters when modal is loaded", function() {
gon.conversationPrefill = [
{id: 1, name: "diaspora user", handle: "diaspora-user@pod.tld"},
{id: 2, name: "other diaspora user", handle: "other-diaspora-user@pod.tld"},
{id: 3, name: "user@pod.tld", handle: "user@pod.tld"}
];
spyOn(app.views.ConversationsForm.prototype, "initialize");
app.aspect = new app.models.Aspect(app.contacts.first().get("aspect_memberships")[0].aspect);
this.view.showMessageModal();
$("#conversationModal").trigger("modal:loaded");
expect(app.views.ConversationsForm.prototype.initialize)
.toHaveBeenCalledWith({prefill: gon.conversationPrefill});
expect(app.views.ConversationsForm.prototype.initialize).toHaveBeenCalled();
var prefill = app.views.ConversationsForm.prototype.initialize.calls.mostRecent().args[0].prefill;
var contacts = app.contacts.filter(function(contact) { return contact.inAspect(app.aspect.get("id")); });
expect(_.pluck(prefill, "id")).toEqual(contacts.map(function(contact) { return contact.person.id; }));
});
});
});

View file

@ -85,7 +85,11 @@ describe("app.views.ConversationsForm", function() {
describe("prefill", function() {
beforeEach(function() {
this.prefills = [{name: "diaspora user"}, {name: "other diaspora user"}, {name: "user"}];
this.prefills = [
factory.personWithProfile({"diaspora_id": "alice@pod.tld"}),
factory.personWithProfile({"diaspora_id": "bob@pod.tld"}),
factory.personWithProfile({"diaspora_id": "carol@pod.tld"})
];
});
it("calls addRecipient for each prefilled participant", function() {
@ -95,7 +99,14 @@ describe("app.views.ConversationsForm", function() {
var allArgsFlattened = app.views.ConversationsForm.prototype.addRecipient.calls.allArgs().map(function(arg) {
return arg[0];
});
expect(allArgsFlattened).toEqual(this.prefills);
expect(_.pluck(allArgsFlattened, "handle")).toEqual(
this.prefills.map(function(person) { return person.get("diaspora_id"); })
);
expect(_.pluck(allArgsFlattened, "avatar")).toEqual(
this.prefills.map(function(person) { return person.get("profile").avatar.small; })
);
});
});

View file

@ -8,16 +8,16 @@ describe("app.views.Poll", function(){
describe("setProgressBar", function(){
it("sets the progress bar according to the voting result", function(){
var percentage = (this.view.poll.poll_answers[0].vote_count / this.view.poll.participation_count)*100;
expect(this.view.$('.poll_progress_bar:first').css('width')).toBe(percentage+"%");
expect(this.view.$(".progress-bar:first").css("width")).toBe(percentage + "%");
expect(this.view.$(".percentage:first").text()).toBe(percentage + "%");
});
});
describe("toggleResult", function(){
it("toggles the progress bar and result", function(){
expect($(".poll_progress_bar_wrapper:first")).toBeHidden();
expect($(".progress:first")).toBeHidden();
this.view.toggleResult();
expect($(".poll_progress_bar_wrapper:first")).toBeVisible();
expect($(".progress:first")).toBeVisible();
});
});
@ -39,7 +39,7 @@ describe("app.views.Poll", function(){
var question = "<script>alert(0);</script>";
this.view.poll.question = question;
this.view.render();
expect(this.view.$('.poll_head strong').text()).toBe(question);
expect(this.view.$(".poll-head strong").text()).toBe(question);
});
});
@ -80,14 +80,14 @@ describe("app.views.Poll", function(){
it("adds 'users-vote' class to progress bar for the option the user voted for", function() {
var answer = this.view.poll.poll_answers[0];
this.view.model.set("poll_participation_answer_id", answer.id);
expect(this.view.$(".poll_progress_bar.users-vote").length).toBe(1);
expect(this.view.$(".progress-bar.users-vote").length).toBe(1);
});
it("doesn't add 'users-vote' class to progress bar of the options the user didn't vote for", function() {
var answer1 = this.view.poll.poll_answers[0];
var answer2 = this.view.poll.poll_answers[1];
this.view.model.set("poll_participation_answer_id", answer1.id);
expect(this.view.$(".poll_progress_bar[data-answerid='" + answer2.id + "']").hasClass("users-vote")).toBe(false);
expect(this.view.$(".progress-bar[data-answerid='" + answer2.id + "']").hasClass("users-vote")).toBe(false);
});
it("adds label next to the answer the user voted for", function() {

View file

@ -4,8 +4,11 @@ describe("app.views.ProfileHeader", function() {
this.model = factory.personWithProfile({
diaspora_id: "my@pod",
name: "User Name",
relationship: 'mutual',
profile: { tags: ['test'] }
relationship: "mutual",
profile: {
avatar: {small: "http://example.org/avatar.jpg"},
tags: ["test"]
}
});
this.view = new app.views.ProfileHeader({model: this.model});
loginAs(factory.userAttrs());
@ -71,17 +74,12 @@ describe("app.views.ProfileHeader", function() {
});
it("initializes app.views.ConversationsForm with correct parameters when modal is loaded", function() {
gon.conversationPrefill = [
{id: 1, name: "diaspora user", handle: "diaspora-user@pod.tld"},
{id: 2, name: "other diaspora user", handle: "other-diaspora-user@pod.tld"},
{id: 3, name: "user@pod.tld", handle: "user@pod.tld"}
];
spyOn(app.views.ConversationsForm.prototype, "initialize");
spyOn($.fn, "load").and.callFake(function(url, callback) { callback(); });
this.view.showMessageModal();
expect(app.views.ConversationsForm.prototype.initialize)
.toHaveBeenCalledWith({prefill: gon.conversationPrefill});
expect(app.views.ConversationsForm.prototype.initialize).toHaveBeenCalledWith({
prefill: [this.model]
});
});
});
});

View file

@ -138,9 +138,11 @@ var factory = {
"full_name": "bob grimm",
"gender": "robot",
"id": id,
"image_url": "http://localhost:3000/assets/user/default.png",
"image_url_medium": "http://localhost:3000/assets/user/default.png",
"image_url_small": "http://localhost:3000/assets/user/default.png",
"avatar": {
"small": "http://localhost:3000/assets/user/default.png",
"medium": "http://localhost:3000/assets/user/default.png",
"large": "http://localhost:3000/assets/user/default.png"
},
"last_name": "Grimm",
"location": "Earth",
"nsfw": false,

View file

@ -3,15 +3,46 @@ describe Reshare, type: :model do
expect(FactoryGirl.build(:reshare)).to be_valid
end
it "requires root" do
reshare = FactoryGirl.build(:reshare, root: nil)
expect(reshare).not_to be_valid
end
context "validation" do
it "requires root when the author is local" do
reshare = FactoryGirl.build(:reshare, root: nil, author: alice.person)
expect(reshare).not_to be_valid
end
it "require public root" do
reshare = FactoryGirl.build(:reshare, root: FactoryGirl.create(:status_message, public: false))
expect(reshare).not_to be_valid
expect(reshare.errors[:base]).to include("Only posts which are public may be reshared.")
it "doesn't require root when the author is remote" do
reshare = FactoryGirl.build(:reshare, root: nil, author: remote_raphael)
expect(reshare).to be_valid
end
it "require public root" do
reshare = FactoryGirl.build(:reshare, root: FactoryGirl.create(:status_message, public: false))
expect(reshare).not_to be_valid
expect(reshare.errors[:base]).to include("Only posts which are public may be reshared.")
end
it "allows two reshares without a root" do
reshare1 = FactoryGirl.create(:reshare, author: alice.person)
reshare2 = FactoryGirl.create(:reshare, author: alice.person)
reshare1.update_attributes(root_guid: nil)
reshare2.root_guid = nil
expect(reshare2).to be_valid
end
it "doesn't allow to reshare the same post twice" do
post = FactoryGirl.create(:status_message, public: true)
FactoryGirl.create(:reshare, author: alice.person, root: post)
expect(FactoryGirl.build(:reshare, author: alice.person, root: post)).not_to be_valid
end
it "allows to reshare the same post with different people" do
post = FactoryGirl.create(:status_message, public: true)
FactoryGirl.create(:reshare, author: alice.person, root: post)
expect(FactoryGirl.build(:reshare, author: bob.person, root: post)).to be_valid
end
end
it "forces public" do