added tests for poll federation and impl for the federation itself. Still in progess
This commit is contained in:
parent
dfbe17d046
commit
fe67bdf2e7
16 changed files with 251 additions and 25 deletions
|
|
@ -183,8 +183,8 @@ app.views.Publisher = Backbone.View.extend({
|
|||
|
||||
addPollAnswer: function(){
|
||||
var clone = this.el_poll_answer.clone();
|
||||
var count_of_answers = this.el_poll_answer.size()+1;
|
||||
clone.attr("name", "poll_answer_"+count_of_answers)
|
||||
var count_of_answers = $('.poll_answer_input').size()+1;
|
||||
clone.children('.poll_answer_input').attr("name", "poll_answer_"+count_of_answers);
|
||||
this.el_poll_answer.last().after(clone);
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -322,12 +322,10 @@
|
|||
|
||||
#poll_creator_wrapper {
|
||||
display:none;
|
||||
border: 1px solid $border-dark-grey;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
.remove_poll_answer {
|
||||
display:inline-block;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
.poll_answer_input {
|
||||
display:inline-block !important;
|
||||
}
|
||||
|
|
@ -1,7 +1,15 @@
|
|||
class Poll < ActiveRecord::Base
|
||||
attr_accessible :question
|
||||
|
||||
include Diaspora::Federated::Base
|
||||
include Diaspora::Guid
|
||||
attr_accessible :question, :poll_answers
|
||||
belongs_to :status_message
|
||||
belongs_to :author, :class_name => :person, :foreign_key => :author_id
|
||||
#has_many :poll_answers
|
||||
has_many :poll_answers
|
||||
has_many :poll_participations
|
||||
|
||||
delegate :author, :author_id, :subscribers, to: :status_message
|
||||
|
||||
#forward subscribers request to status message, because a poll is just attached to a status message and is not sharable itself
|
||||
#def subscribers(user)
|
||||
# status_message.subscribers(user)
|
||||
#end
|
||||
end
|
||||
|
|
|
|||
10
app/models/poll_answer.rb
Normal file
10
app/models/poll_answer.rb
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
class PollAnswer < ActiveRecord::Base
|
||||
|
||||
include Diaspora::Federated::Base
|
||||
include Diaspora::Guid
|
||||
|
||||
belongs_to :poll
|
||||
has_many :poll_participations
|
||||
|
||||
xml_attr :answer
|
||||
end
|
||||
55
app/models/poll_participation.rb
Normal file
55
app/models/poll_participation.rb
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
class PollParticipation < ActiveRecord::Base
|
||||
|
||||
include Diaspora::Federated::Base
|
||||
|
||||
include Diaspora::Guid
|
||||
include Diaspora::Relayable
|
||||
belongs_to :poll
|
||||
belongs_to :poll_answer
|
||||
belongs_to :author, :class_name => 'Person', :foreign_key => :author_id
|
||||
xml_attr :diaspora_handle
|
||||
xml_attr :poll_answer_guid
|
||||
|
||||
def parent_class
|
||||
Poll
|
||||
end
|
||||
|
||||
def parent
|
||||
self.poll
|
||||
end
|
||||
|
||||
def poll_answer_guid
|
||||
poll_answer.guid
|
||||
end
|
||||
|
||||
def poll_answer_guid= new_poll_answer_guid
|
||||
self.poll_answer = PollAnswer.where(:guid => new_poll_answer_guid).first
|
||||
end
|
||||
|
||||
def parent= parent
|
||||
self.poll = parent
|
||||
end
|
||||
|
||||
def diaspora_handle
|
||||
self.author.diaspora_handle
|
||||
end
|
||||
|
||||
def diaspora_handle= nh
|
||||
self.author = Webfinger.new(nh).fetch
|
||||
end
|
||||
|
||||
class Generator < Federated::Generator
|
||||
def self.federated_class
|
||||
PollParticipation
|
||||
end
|
||||
|
||||
def initialize(person, target, poll_answer)
|
||||
@poll_answer = poll_answer
|
||||
super(person, target)
|
||||
end
|
||||
|
||||
def relayable_options
|
||||
{:poll => @target.poll, :poll_answer => @poll_answer}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -20,6 +20,7 @@ class StatusMessage < Post
|
|||
xml_attr :raw_message
|
||||
xml_attr :photos, :as => [Photo]
|
||||
xml_attr :location, :as => Location
|
||||
xml_attr :poll, :as => Poll
|
||||
|
||||
has_many :photos, :dependent => :destroy, :foreign_key => :status_message_guid, :primary_key => :guid
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ module User::SocialActions
|
|||
Like::Generator.new(self, target).create!(opts)
|
||||
end
|
||||
|
||||
def participate_in_poll!(target, answer, opts={})
|
||||
find_or_create_participation!(target)
|
||||
PollParticipation::Generator.new(self, target, answer).create!(opts)
|
||||
end
|
||||
|
||||
def reshare!(target, opts={})
|
||||
find_or_create_participation!(target)
|
||||
reshare = build_post(:reshare, :root_guid => target.guid)
|
||||
|
|
|
|||
|
|
@ -36,14 +36,14 @@
|
|||
= image_tag 'icons/camera.png', :alt => t('shared.publisher.upload_photos').titleize, :class => 'publisher_image'
|
||||
= hidden_field :location, :coords
|
||||
#location_container
|
||||
%br
|
||||
#poll_creator_wrapper
|
||||
= 'Poll creation'
|
||||
%br
|
||||
%br
|
||||
%input{:id => 'poll_question', :placeholder => 'Question', :name => 'poll_question'}
|
||||
%div{:class => 'poll_answer'}
|
||||
%input{:class => 'poll_answer_input', :placeholder => 'Answer', :name => 'poll_answer_1'}
|
||||
%a{:class => 'remove_poll_answer'}
|
||||
%input{:id => 'poll_question', :placeholder => 'Question', :name => 'poll_question', :class => 'span-12'}
|
||||
%div{:class => 'poll_answer span-12'}
|
||||
%input{:class => 'poll_answer_input span-8', :placeholder => 'Answer', :name => 'poll_answer_1'}
|
||||
%a{:class => 'remove_poll_answer span-3'}
|
||||
= t('shared.publisher.poll.remove_poll_answer')
|
||||
%div{:id => 'add_poll_answer', :class => 'button creation'}
|
||||
= t('shared.publisher.poll.add_poll_answer')
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ class CreatePolls < ActiveRecord::Migration
|
|||
t.string :question, :null => false
|
||||
t.belongs_to :status_message, :null => false
|
||||
t.boolean :status
|
||||
t.string :guid
|
||||
t.timestamps
|
||||
end
|
||||
add_index :polls, :status_message_id
|
||||
|
|
@ -11,6 +12,7 @@ class CreatePolls < ActiveRecord::Migration
|
|||
create_table :poll_answers do |t|
|
||||
t.string :answer, :null => false
|
||||
t.belongs_to :poll, :null => false
|
||||
t.string :guid
|
||||
end
|
||||
add_index :poll_answers, :poll_id
|
||||
|
||||
|
|
@ -18,7 +20,9 @@ class CreatePolls < ActiveRecord::Migration
|
|||
t.belongs_to :poll_answer, :null => false
|
||||
t.belongs_to :author, :null => false
|
||||
t.belongs_to :poll, :null => false
|
||||
t.datetime :time
|
||||
t.string :guid
|
||||
t.text :author_signature
|
||||
t.text :parent_author_signature
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
|
|
|||
16
db/schema.rb
16
db/schema.rb
|
|
@ -286,17 +286,20 @@ ActiveRecord::Schema.define(:version => 20140308154022) do
|
|||
create_table "poll_answers", :force => true do |t|
|
||||
t.string "answer", :null => false
|
||||
t.integer "poll_id", :null => false
|
||||
t.string "guid"
|
||||
end
|
||||
|
||||
add_index "poll_answers", ["poll_id"], :name => "index_poll_answers_on_poll_id"
|
||||
|
||||
create_table "poll_participations", :force => true do |t|
|
||||
t.integer "poll_answer_id", :null => false
|
||||
t.integer "author_id", :null => false
|
||||
t.integer "poll_id", :null => false
|
||||
t.datetime "time"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
t.integer "poll_answer_id", :null => false
|
||||
t.integer "author_id", :null => false
|
||||
t.integer "poll_id", :null => false
|
||||
t.string "guid"
|
||||
t.text "author_signature"
|
||||
t.text "parent_author_signature"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
||||
add_index "poll_participations", ["poll_id"], :name => "index_poll_participations_on_poll_id"
|
||||
|
|
@ -305,6 +308,7 @@ ActiveRecord::Schema.define(:version => 20140308154022) do
|
|||
t.string "question", :null => false
|
||||
t.integer "status_message_id", :null => false
|
||||
t.boolean "status"
|
||||
t.string "guid"
|
||||
t.datetime "created_at", :null => false
|
||||
t.datetime "updated_at", :null => false
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
module Diaspora
|
||||
module Parser
|
||||
def self.from_xml(xml)
|
||||
puts xml
|
||||
doc = Nokogiri::XML(xml) { |cfg| cfg.noblanks }
|
||||
return unless body = doc.xpath("/XML/post").children.first
|
||||
class_name = body.name.gsub('-', '/')
|
||||
|
|
|
|||
10
spec/models/poll_answer_spec.rb
Normal file
10
spec/models/poll_answer_spec.rb
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe PollAnswer do
|
||||
before :do
|
||||
describe 'validation' do
|
||||
it 'should ...' do
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
78
spec/models/poll_participation_spec.rb
Normal file
78
spec/models/poll_participation_spec.rb
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join("spec", "shared_behaviors", "relayable")
|
||||
|
||||
describe PollParticipation do
|
||||
|
||||
before do
|
||||
@alices_aspect = alice.aspects.first
|
||||
@status = bob.post(:status_message, :text => "hello", :to => bob.aspects.first.id)
|
||||
end
|
||||
|
||||
describe 'xml' do
|
||||
before do
|
||||
@poll_participant = FactoryGirl.create(:user)
|
||||
@poll_participant_aspect = @poll_participant.aspects.create(:name => "bruisers")
|
||||
connect_users(alice, @alices_aspect, @poll_participant, @poll_participant_aspect)
|
||||
@poll = Poll.new(:question => "hi")
|
||||
@poll.poll_answers.build(:answer => "a")
|
||||
@poll.poll_answers.build(:answer => "b")
|
||||
@post = alice.post :status_message, :text => "hello", :to => @alices_aspect.id
|
||||
@post.poll = @poll
|
||||
@poll_participation = @poll_participant.participate_in_poll!(@post, @poll.poll_answers.first)
|
||||
@xml = @poll_participation.to_xml.to_s
|
||||
end
|
||||
|
||||
it 'serializes the sender handle' do
|
||||
@xml.include?(@poll_participation.diaspora_handle).should be_true
|
||||
end
|
||||
|
||||
it 'serializes the poll_guid' do
|
||||
@xml.should include(@poll.guid)
|
||||
end
|
||||
|
||||
it 'serializes the poll_answer_guid' do
|
||||
@xml.should include(@poll_participation.poll_answer.guid)
|
||||
end
|
||||
|
||||
describe 'marshalling' do
|
||||
before do
|
||||
@marshalled_poll_participation = PollParticipation.from_xml(@xml)
|
||||
end
|
||||
|
||||
it 'marshals the author' do
|
||||
@marshalled_poll_participation.author.should == @poll_participant.person
|
||||
end
|
||||
|
||||
it 'marshals the answer' do
|
||||
@marshalled_poll_participation.poll_answer.should == @poll_participation.poll_answer
|
||||
end
|
||||
|
||||
it 'marshals the poll' do
|
||||
@marshalled_poll_participation.poll.should == @poll
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# describe 'it is relayable' do
|
||||
# before do
|
||||
# @poll = Poll.new
|
||||
# @poll_answer = PollAnswer.new(:answer => '1')
|
||||
# @poll_answer2 = PollAnswer.new(:answer => '1')
|
||||
# @poll.answers << [poll_answer, poll_answer2]
|
||||
# @status.poll = @poll
|
||||
|
||||
# @local_luke, @local_leia, @remote_raphael = set_up_friends
|
||||
# @remote_parent = FactoryGirl.build(:status_message, :author => @remote_raphael)
|
||||
# @local_parent = @local_luke.post :status_message, :text => "hi", :to => @local_luke.aspects.first
|
||||
|
||||
# @object_by_parent_author = @local_luke.vote!(@local_parent, @poll_answer)
|
||||
# @object_by_recipient = @local_leia.vote!(@local_parent, @poll_answer)
|
||||
# @dup_object_by_parent_author = @object_by_parent_author.dup
|
||||
|
||||
# @object_on_remote_parent = @local_luke.comment!(@remote_parent, "Yeah, it was great")
|
||||
# end
|
||||
|
||||
# let(:build_object) { alice.build_poll_participation(:poll => @poll, :poll_answer => @poll_answer) }
|
||||
# it_should_behave_like 'it is relayable'
|
||||
# end
|
||||
end
|
||||
|
|
@ -1,5 +1,22 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Poll do
|
||||
pending "add some examples to (or delete) #{__FILE__}"
|
||||
end
|
||||
before do
|
||||
@poll = Poll.new(:question => "What do you think about apples?")
|
||||
end
|
||||
|
||||
describe 'validation' do
|
||||
it 'should create no poll when it has less than two answers' do
|
||||
@poll.poll_answers << PollAnswer.new(:answer => '1')
|
||||
@poll.should_not be_valid
|
||||
end
|
||||
|
||||
it 'should create a poll when it has more than two answers' do
|
||||
@poll.poll_answers << PollAnswer.new(:answer => '1')
|
||||
@poll.poll_answers << PollAnswer.new(:answer => '2')
|
||||
@poll.should be_valid
|
||||
end
|
||||
end
|
||||
|
||||
#TODO test if delegation of subscribers works
|
||||
end
|
||||
|
|
@ -350,6 +350,31 @@ STR
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a poll' do
|
||||
before do
|
||||
@message.poll = Poll.new(coordinates: "1, 2").tap(&:save)
|
||||
@xml = @message.to_xml.to_s
|
||||
end
|
||||
|
||||
it 'serializes the location' do
|
||||
@xml.should include "location"
|
||||
@xml.should include "lat"
|
||||
@xml.should include "lng"
|
||||
end
|
||||
|
||||
describe ".from_xml" do
|
||||
before do
|
||||
@marshalled = StatusMessage.from_xml(@xml)
|
||||
end
|
||||
|
||||
it 'marshals the location' do
|
||||
@marshalled.location.should be_present
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
describe '#after_dispatch' do
|
||||
|
|
|
|||
|
|
@ -83,4 +83,14 @@ describe User::SocialActions do
|
|||
@status.reload.likes.should == likes
|
||||
end
|
||||
end
|
||||
|
||||
describe 'User#participate_in_poll!' do
|
||||
before do
|
||||
@bobs_aspect = bob.aspects.where(:name => "generic").first
|
||||
poll = Poll.new(:poll_answers => [PollAnswer.new(:answer => "1"), PollAnswer.new(:answer => "2")])
|
||||
@status = bob.post(:status_message, :text => "hello", :to => @bobs_aspect.id, :poll => poll)
|
||||
end
|
||||
it "sets the poll answer id" do
|
||||
alice.participate_in_poll!(@status, 1).poll_answer.answer.should == "1"
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue