diff --git a/plugins/pairwise/README b/plugins/pairwise/README
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/pairwise/README
diff --git a/plugins/pairwise/controllers/pairwise_plugin_admin_controller.rb b/plugins/pairwise/controllers/pairwise_plugin_admin_controller.rb
new file mode 100644
index 0000000..6b5489c
--- /dev/null
+++ b/plugins/pairwise/controllers/pairwise_plugin_admin_controller.rb
@@ -0,0 +1,14 @@
+class PairwisePluginAdminController < AdminController
+ append_view_path File.join(File.dirname(__FILE__) + '/../views')
+
+ def index
+ @settings ||= Noosfero::Plugin::Settings.new(environment, PairwisePlugin, params[:settings])
+ if request.post?
+ @settings.api_host = nil if @settings.api_host.blank?
+ @settings.username = nil if @settings.username.blank?
+ @settings.password = nil if @settings.password.blank?
+ @settings.save!
+ redirect_to :action => 'index'
+ end
+ end
+end
diff --git a/plugins/pairwise/controllers/profile/pairwise_plugin_profile_controller.rb b/plugins/pairwise/controllers/profile/pairwise_plugin_profile_controller.rb
new file mode 100644
index 0000000..d9b9ddd
--- /dev/null
+++ b/plugins/pairwise/controllers/profile/pairwise_plugin_profile_controller.rb
@@ -0,0 +1,151 @@
+class PairwisePluginProfileController < ProfileController
+ append_view_path File.join(File.dirname(__FILE__) + '/../../views')
+
+ def prompt
+ prompt_id = params[:prompt_id]
+ @pairwise_content = find_content(params)
+ embeded = params.has_key?("embeded")
+ source = params[:source]
+ locals = {:source => source, :pairwise_content => @pairwise_content, :embeded => embeded, :source => source, :prompt_id => prompt_id }
+ if embeded
+ render 'content_viewer/prompt.rhtml', :layout => "embeded", :locals => locals
+ else
+ render 'content_viewer/prompt.rhtml', :locals => locals
+ end
+ end
+
+ #FIXME reuse
+ def load_prompt
+ @pairwise_content = find_content(params)
+ if request.xhr?
+ render 'content_viewer/prompt.rjs'
+ else
+ redirect_to after_action_url
+ end
+ end
+
+ def choose
+ @pairwise_content = find_content(params)
+ vote = @pairwise_content.vote_to(params[:prompt_id], params[:direction], user_identifier, params[:appearance_id])
+ if request.xhr?
+ render 'content_viewer/prompt.rjs'
+ else
+ redirect_to after_action_url
+ end
+ end
+
+ def skip_prompt
+ raise _('Invalid request') unless params.has_key?('prompt_id')
+ raise _('Invalid request') unless params.has_key?('appearance_id')
+ @pairwise_content = find_content(params)
+ reason = params[:reason]
+ skip = @pairwise_content.skip_prompt(params[:prompt_id], user_identifier, params[:appearance_id], reason)
+ if request.xhr?
+ render 'content_viewer/prompt.rjs'
+ else
+ redirect_to after_action_url
+ end
+
+ end
+
+ def result
+ @embeded = params.has_key?("embeded")
+ @page = @pairwise_content = find_content(params)
+
+ if request.xhr?
+ render 'content_viewer/result'
+ else
+ render 'pairwise_plugin_profile/result'
+ end
+ end
+
+ def prompt_tab
+ @embeded = params.has_key?("embeded")
+ @pairwise_content = find_content(params)
+ render 'content_viewer/prompt_tab', :locals => {:pairwise_content => @pairwise_content}
+ end
+
+ def suggest_idea
+ flash_target = request.xhr? ? flash.now : flash
+
+ if user.nil?
+ flash_target[:error] = _("Only logged user could suggest new ideas")
+ else
+ @page = @pairwise_content = find_content(params)
+ @embeded = params.has_key?("embeded")
+ @source = params[:source]
+ begin
+ if @page.add_new_idea(params[:idea][:text], user_identifier)
+ flash_target[:notice] = _("Thanks for your contributtion!")
+ else
+ if(@page.allow_new_ideas?)
+ flash_target[:error] = _("Unfortunatelly, we are not able to register your idea.")
+ else
+ flash_target[:notice] = _("Unfortunatelly, new ideas are not allowed anymore.")
+ end
+ end
+ rescue Exception => e
+ flash_target[:error] = _(e.message)
+ end
+ end
+ if request.xhr?
+ render 'suggestion_form'
+ else
+ redirect_to after_action_url
+ end
+ end
+
+ protected
+
+ def find_content(params)
+ @pairwise_content ||= profile.articles.find(params[:id])
+ end
+
+ def after_action_url(prompt_id = nil)
+ if params.has_key?("embeded")
+ redirect_target = {
+ :controller => :pairwise_plugin_profile,
+ :action => 'prompt',
+ :id => find_content(params).id,
+ :question_id => find_content(params).pairwise_question_id,
+ :prompt_id => params[:prompt_id],
+ :embeded => 1
+ }
+ if params.has_key?("source")
+ redirect_target.merge!(:source => params[:source])
+ end
+ redirect_target
+ else
+ find_content(params).url
+ end
+ end
+
+ def is_external_vote
+ params.has_key?("source") && !params[:source].empty?
+ end
+
+ def external_source
+ params[:source]
+ end
+
+ def user_identifier
+ if user.nil?
+ is_external_vote ? "#{external_source}-#{request.session_options[:id]}" : "participa-#{request.session_options[:id]}"
+ else
+ user.identifier
+ end
+ end
+
+ def process_error_message message
+ message
+ end
+
+
+ def redirect_to_error_page(message)
+ message = URI.escape(CGI.escape(process_error_message(message)),'.')
+ redirect_to "/profile/#{profile.identifier}/plugin/pairwise/error_page?message=#{message}"
+ end
+
+
+end
+
diff --git a/plugins/pairwise/controllers/profile/pairwise_plugin_suggestions_controller.rb b/plugins/pairwise/controllers/profile/pairwise_plugin_suggestions_controller.rb
new file mode 100644
index 0000000..055fb31
--- /dev/null
+++ b/plugins/pairwise/controllers/profile/pairwise_plugin_suggestions_controller.rb
@@ -0,0 +1,80 @@
+require 'will_paginate/array'
+
+class PairwisePluginSuggestionsController < ProfileController
+
+ append_view_path File.join(File.dirname(__FILE__) + '/../../views')
+
+ before_filter :load_pairwise_question
+
+ def index
+ return no_result if @pairwise_content.nil?
+ return no_result if @pairwise_content.question.nil?
+ @choices = list_choices
+ @choices = WillPaginate::Collection.create(params[:page] || 1, 20, @choices.length) do |pager|
+ pager.replace(@choices.slice(pager.offset, pager.per_page))
+ end
+ end
+
+ def edit
+ return no_result if @pairwise_content.nil?
+ return no_result if @pairwise_content.question.nil?
+ @choice = @pairwise_content.find_choice params[:choice_id]
+ end
+
+ def update
+ return no_result if @pairwise_content.nil?
+ if @pairwise_content.update_choice(params[:choice][:id], params[:choice][:data], params[:choice][:active])
+ redirect_to :action => :index, :id => @pairwise_content.id, :pending => params[:pending]
+ else
+ @choice = @pairwise_content.find_choice params[:choice][:id]
+ @choice.data = params[:choice][:data]
+ flash[:error] = @pairwise_content.errors.full_messages
+ render :edit
+ end
+ end
+
+ def approve
+ return no_result if @pairwise_content.nil?
+ if @pairwise_content.approve_choice(params[:choice_id])
+ redirect_to :action => :index, :id => @pairwise_content.id, :page => params[:page], :pending => params[:pending]
+ else
+ flash[:error] = @pairwise_content.errors.full_messages
+ redirect_to :action => :index, :id => @pairwise_content.id, :page => params[:page], :pending => params[:pending]
+ end
+ end
+
+ def inactivate
+ return no_result if @pairwise_content.nil?
+ @pairwise_content.inactivate(params[:choice_id])
+ redirect_to :action => :index, :id => @pairwise_content.id, :page => params[:page], :pending => params[:pending]
+ end
+
+ def reprove
+ return no_result if @pairwise_content.nil?
+ @pairwise_content.flag_choice(params[:choice_id])
+ redirect_to :action => :index, :id => @pairwise_content.id, :page => params[:page], :pending => params[:pending]
+ end
+
+private
+
+ def list_choices
+ if '1'.eql?(params[:pending])
+ if '1'.eql?(params[:reproved])
+ @pairwise_content.reproved_choices(params[:filter], params[:order])
+ else
+ @pairwise_content.pending_choices(params[:filter], params[:order])
+ end
+ else
+ @pairwise_content.raw_choices(params[:filter], params[:order])
+ end
+ end
+
+ def no_result
+ render :no_result
+ end
+
+ def load_pairwise_question
+ @pairwise_content ||= profile.articles.find(params[:id])
+ render_access_denied unless @pairwise_content.allow_edit?(user)
+ end
+end
diff --git a/plugins/pairwise/controllers/public/pairwise_plugin_public_controller.rb b/plugins/pairwise/controllers/public/pairwise_plugin_public_controller.rb
new file mode 100644
index 0000000..f214636
--- /dev/null
+++ b/plugins/pairwise/controllers/public/pairwise_plugin_public_controller.rb
@@ -0,0 +1,24 @@
+class PairwisePluginPublicController < PublicController
+ append_view_path File.join(File.dirname(__FILE__) + '/../../views')
+
+ #before_filter :login_required, :only => :select_community
+
+ def index
+ question_id = params[:id]
+ client = PairwiseClient.new params[:profile_id]
+ question = client.question_with_prompt(question_id, visitor_id)
+
+ render :index
+ end
+
+ def results
+ question_id = params[:id]
+ client = PairwiseClient.new params[:profile_id]
+ end
+
+ def vote
+ question_id = paarms[:id]
+ client = PairwiseClient.new params[:profile_id]
+ redirect_to :index
+ end
+end
diff --git a/plugins/pairwise/db/migrate/20140221110000_create_pairwise_choices_related.rb b/plugins/pairwise/db/migrate/20140221110000_create_pairwise_choices_related.rb
new file mode 100644
index 0000000..f465c4e
--- /dev/null
+++ b/plugins/pairwise/db/migrate/20140221110000_create_pairwise_choices_related.rb
@@ -0,0 +1,15 @@
+class CreatePairwiseChoicesRelated < ActiveRecord::Migration
+ def self.up
+ create_table :pairwise_plugin_choices_related do |t|
+ t.integer :choice_id
+ t.integer :parent_choice_id
+ t.references :question
+ t.references :user
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :pairwise_plugin_choices_related
+ end
+end
\ No newline at end of file
diff --git a/plugins/pairwise/dependencies.rb b/plugins/pairwise/dependencies.rb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/pairwise/dependencies.rb
diff --git a/plugins/pairwise/install.rb b/plugins/pairwise/install.rb
new file mode 100644
index 0000000..88e67fa
--- /dev/null
+++ b/plugins/pairwise/install.rb
@@ -0,0 +1,2 @@
+system "gem install --user-install webmock -v 1.17"
+system "gem install --user-install vcr -v 2.8.0"
\ No newline at end of file
diff --git a/plugins/pairwise/lib/ext/profile.rb b/plugins/pairwise/lib/ext/profile.rb
new file mode 100644
index 0000000..e883cdb
--- /dev/null
+++ b/plugins/pairwise/lib/ext/profile.rb
@@ -0,0 +1,5 @@
+require_dependency 'profile'
+
+Profile.class_eval do
+ has_many :questions, :source => 'articles', :class_name => 'PairwisePlugin::PairwiseContent', :order => 'start_date'
+end
\ No newline at end of file
diff --git a/plugins/pairwise/lib/pairwise/choice.rb b/plugins/pairwise/lib/pairwise/choice.rb
new file mode 100644
index 0000000..b24d5cd
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise/choice.rb
@@ -0,0 +1,5 @@
+class Pairwise::Choice < ActiveResource::Base
+ extend Pairwise::Resource
+ self.element_name = "choice"
+
+end
\ No newline at end of file
diff --git a/plugins/pairwise/lib/pairwise/client.rb b/plugins/pairwise/lib/pairwise/client.rb
new file mode 100644
index 0000000..32540b3
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise/client.rb
@@ -0,0 +1,197 @@
+class Pairwise::Client
+
+ private_class_method :new
+
+ ###
+ # constructor for a pairwise client
+ # local_identifier is the id of the question owner in the client app side
+ def initialize(local_identifier)
+ @local_identifier = local_identifier
+ end
+
+ # creates a new question in pairwise
+ def create_question(name, ideas = [])
+ ideas = ideas.join("\n") if ideas.is_a? Array
+ q = Pairwise::Question.create({
+ :name => name,
+ :visitor_identifier => @local_identifier.to_s,
+ :local_identifier => @local_identifier.to_s,
+ :ideas => ideas
+ })
+ q.it_should_autoactivate_ideas = true
+ q.active = true
+ q.save
+ q
+ end
+
+ def toggle_autoactivate_ideas(question, value)
+ question.it_should_autoactivate_ideas = value
+ question.save
+ end
+
+ def add_choice(question_id, choice_text, visitor=nil)
+ question = Pairwise::Question.find question_id
+ raise Pairwise::Error.new("Question not found in pairwise") if question.nil?
+ visitor_identifier = visitor.blank? ? @local_identifier.to_s : visitor
+ choice_args = {
+ :question_id => question_id,
+ :local_identifier => @local_identifier.to_s,
+ :visitor_identifier => visitor_identifier,
+ :data => choice_text
+ }
+ Pairwise::Choice.create(choice_args)
+ end
+
+ def update_question(question_id, name)
+ question = Pairwise::Question.find question_id
+ question.name = name
+ question.save
+ end
+
+ def update_choice(question, choice_id, choice_data, active)
+ choice = Pairwise::Choice.find(choice_id, :params => {:question_id => question.id })
+ raise N_("Invalid choice id") unless choice
+ raise Pairwise::Error.new N_("Empty choice text") if choice_data.empty?
+ unless choice_data.eql?(choice.data) && choice.active.eql?(active)
+ choice.data = choice_data
+ choice.active = active
+ choice.save
+ end
+ end
+
+ def approve_choice(question, choice_id)
+ choice = Pairwise::Choice.find(choice_id, :params => {:question_id => question.id})
+ raise N_("Invalid choice id") unless choice
+ choice.active = true
+ choice.save
+ end
+
+ def flag_choice(question, choice_id, reason)
+ choice = Pairwise::Choice.find(choice_id, :params => {:question_id => question.id})
+ raise N_("Invalid choice id") unless choice
+
+ choice.put(:flag,
+ :visitor_identifier => @local_identifier.to_s,
+ :explanation => reason)
+ end
+
+ # finds a question by a given id
+ def find_question_by_id(question_id)
+ question = Pairwise::Question.find question_id
+ return question #if question.local_identifier == @local_identifier.to_s
+ end
+
+ # returns all questions in pairwise owned by the local_identifier user
+ def questions
+ questions = Pairwise::Question.find(:all, :params => {:creator => @local_identifier})
+ questions.select {|q| q if q.local_identifier == @local_identifier.to_s }
+ end
+
+ # get a question with a prompt, visitor_id (id of logged user) should be provided
+ def question_with_prompt(question_id, visitor_id = "guest", prompt_id=nil)
+ question = Pairwise::Question.find_with_prompt(question_id, @local_identifier, visitor_id)
+ return question #if question.local_identifier == @local_identifier.to_s
+ end
+
+ # register votes in response to a prompt to a pairwise question
+ def vote(question_id, prompt_id, direction, visitor="guest", appearance_lookup=nil)
+ prompt = Pairwise::Prompt.find(prompt_id, :params => {:question_id => question_id})
+ begin
+ vote = prompt.post(:vote,
+ :question_id => question_id,
+ :vote => {
+ :direction => direction,
+ :visitor_identifier => visitor,
+ :appearance_lookup => appearance_lookup
+ },
+ :next_prompt => {
+ :with_appearance => true,
+ :with_visitor_stats => true,
+ :visitor_identifier => visitor
+ })
+ Hash.from_xml(vote.body)
+ rescue ActiveResource::ResourceInvalid => e
+ raise Pairwise::Error.new(_("Vote not registered. Please check if all the necessary parameters were passed."))
+ end
+ end
+
+ def skip_prompt(question_id, prompt_id, visitor="guest", appearance_lookup=nil, reason=nil)
+ prompt = Pairwise::Prompt.find(prompt_id, :params => {:question_id => question_id})
+ begin
+ skip = prompt.post(:skip, :question_id => question_id,
+ :skip => {
+ :appearance_lookup => appearance_lookup,
+ :visitor_identifier => visitor,
+ :skip_reason => (reason.nil? ? 'some not informed reason' : reason)
+ },
+ :next_prompt => {
+ :with_appearance => true,
+ :with_visitor_stats => true,
+ :visitor_identifier => visitor
+ }
+ )
+ Hash.from_xml(skip.body)
+ rescue ActiveResource::ResourceInvalid => e
+ raise Pairwise::Error.new(_("Could not skip vote. Check the parameters"))
+ end
+ end
+
+ # skips a prompt
+ def skip(prompt_id, question_id, visitor_id = "guest", appearance_lookup = nil)
+ prompt = Pairwise::Prompt.find(prompt_id, :params => {:question_id => question_id})
+ skip = prompt.post(:skip,
+ :question_id => question_id,
+ :skip => {
+ :visitor_identifier => visitor_id,
+ :appearance_lookup => appearance_lookup
+ },
+ :next_prompt => {
+ :with_appearance => true,
+ :with_visitor_stats => true,
+ :visitor_identifier => visitor_id
+ })
+
+ end
+
+ def pairwise_config
+ options = environment.settings[:pairwise_plugin]
+ [:api_host, :username, :password].each do |key|
+ if options.keys.include?(key.to_s)
+ Pairwise::ResourceSettings[key] = options[key.to_s]
+ end
+ end
+
+ end
+
+ def self.build(local_identifier, settings)
+ if settings.nil?
+ error_message = "#{_("Plugin was not configured")}. #{_("Please contact the administrator")}"
+ raise Pairwise::Error.new error_message
+ end
+ [Pairwise::Question, Pairwise::Prompt, Pairwise::Choice, Pairwise::Visitor].each do | klas |
+ if([Pairwise::Prompt, Pairwise::Choice].include?(klas))
+ klas.site = settings[:api_host] + "questions/:question_id/"
+ else
+ klas.site = settings[:api_host]
+ end
+ klas.user = settings[:username]
+ klas.password = settings[:password]
+ end
+ new local_identifier
+ end
+
+ def add_new_idea(question_id, text, visitor=nil)
+ raise _("Idea text is empty") if text.empty?
+ question = Pairwise::Question.find question_id
+ raise Pairwise::Error.new("Question not found in pairwise") if question.nil?
+ visitor_identifier = visitor.blank? ? @local_identifier.to_s : visitor
+ choice_args = {
+ :question_id => question_id,
+ :local_identifier => @local_identifier.to_s,
+ :visitor_identifier => visitor_identifier,
+ :data => text
+ }
+ return Pairwise::Choice.create(choice_args)
+ end
+end
+
diff --git a/plugins/pairwise/lib/pairwise/error.rb b/plugins/pairwise/lib/pairwise/error.rb
new file mode 100644
index 0000000..491b9b1
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise/error.rb
@@ -0,0 +1,2 @@
+class Pairwise::Error < StandardError
+end
diff --git a/plugins/pairwise/lib/pairwise/prompt.rb b/plugins/pairwise/lib/pairwise/prompt.rb
new file mode 100644
index 0000000..9fae179
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise/prompt.rb
@@ -0,0 +1,7 @@
+class Pairwise::Prompt < ActiveResource::Base
+ extend Pairwise::Resource
+ self.element_name = "prompt"
+ # extend Resource
+ # self.site = self.site + "questions/:question_id/"
+ #attr_accessor :name, :question_text, :question_ideas
+end
diff --git a/plugins/pairwise/lib/pairwise/question.rb b/plugins/pairwise/lib/pairwise/question.rb
new file mode 100644
index 0000000..8eda11e
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise/question.rb
@@ -0,0 +1,108 @@
+class Pairwise::Question < ActiveResource::Base
+ extend Pairwise::Resource
+
+ self.element_name = "question"
+
+ def get_choices(filter=nil, order=nil)
+ Pairwise::Choice.find(
+ :all,
+ :params => {
+ :question_id => self.id,
+ :filter => filter,
+ :order => order
+ })
+ end
+
+ def choices_include_inactive
+ Pairwise::Choice.find(:all, :params => {:question_id => self.id , :include_inactive => true})
+ end
+
+ def pending_choices(filter=nil, order=nil)
+ find_options = {
+ :question_id => self.id,
+ :include_inactive => true,
+ :inactive_ignore_flagged => 1,
+ :filter => filter,
+ :order => order
+ }
+
+ Pairwise::Choice.find(:all, :params => find_options)
+ end
+
+ def reproved_choices(filter=nil, order=nil)
+ find_options = {
+ :question_id => self.id,
+ :include_inactive => true,
+ :reproved => 1,
+ :filter => filter,
+ :order => order
+ }
+
+ Pairwise::Choice.find(:all, :params => find_options)
+ end
+
+ def find_choice(id)
+ Pairwise::Choice.find(id, :params => {:question_id => self.id, :include_inactive => true })
+ end
+
+ alias_method :choices, :get_choices
+
+ def has_choice_with_text?(text)
+ return filter_choices_with_text(text).size > 0
+ end
+
+ def get_choice_with_text(text)
+ choices_selected = filter_choices_with_text(text)
+ nil if choices_selected.size == 0
+ choices_selected.first
+ end
+
+ def filter_choices_with_text(text)
+ get_choices.select { |c| c if c.data.eql?(text) }
+ end
+
+ # return visitors whom suggested ideas
+ def get_ideas_contributors(options=nil)
+ options = {:page => 1}
+ options.merge!(options) if options.is_a? Hash
+ Pairwise::Visitor.find(:all, :params => {:question_id => id, :ideas_count => 1, :page => options[:page]})
+ end
+
+ def add_choice(text, visitor=nil)
+ if(visitor.nil?)
+ Pairwise::Choice.create(:data => text, :question_id => self.id, :active => "true")
+ else
+ Pairwise::Choice.create(:data => text, :question_id => self.id, :active => "true", :visitor_identifier => visitor)
+ end
+ end
+
+ def self.find_with_prompt(id, creator_id, visitor_id)#, prompt_id=nil)
+ question = Pairwise::Question.find(id,
+ :params => {
+ :creator_id => creator_id,
+ :with_prompt => true,
+ :with_appearance => true,
+ :visitor_identifier => visitor_id
+ })
+ question.set_prompt(Pairwise::Prompt.find(question.picked_prompt_id, :params => {:question_id => id}))
+ question
+ end
+
+ def set_prompt(prompt_object)
+ @prompt = prompt_object
+ end
+
+ def prompt
+ @prompt
+ end
+
+ def appearance_id
+ if attributes["appearance_id"]
+ attributes["appearance_id"]
+ elsif prompt and prompt.respond_to? :appearance_id
+ prompt.appearance_id
+ else
+ nil
+ end
+ end
+end
diff --git a/plugins/pairwise/lib/pairwise/resource.rb b/plugins/pairwise/lib/pairwise/resource.rb
new file mode 100644
index 0000000..1a16621
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise/resource.rb
@@ -0,0 +1,22 @@
+module Pairwise::Resource
+ %w(site user password).each do |attr|
+ define_method(attr) do
+ Thread.current["#{name}.active_resource.#{attr}"]
+ end
+
+ if attr.eql?('site')
+ define_method("#{attr}=") do |site|
+ @connection = nil
+ site_uri = create_site_uri_from(site)
+ Thread.current["#{name}.active_resource.site"] = site_uri
+ Thread.current["#{name}.active_resource.user"] = URI.decode(site_uri.user) if site_uri.user
+ Thread.current["#{name}.active_resource.password"] = URI.decode(site_uri.password) if site_uri.password
+ end
+ else
+ define_method("#{attr}=") do |val|
+ @connection = nil
+ Thread.current["#{name}.active_resource.#{attr}"] = val
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/plugins/pairwise/lib/pairwise/visitor.rb b/plugins/pairwise/lib/pairwise/visitor.rb
new file mode 100644
index 0000000..be4d217
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise/visitor.rb
@@ -0,0 +1,5 @@
+class Pairwise::Visitor < ActiveResource::Base
+ extend Pairwise::Resource
+ self.element_name = "visitor"
+
+end
diff --git a/plugins/pairwise/lib/pairwise_plugin.rb b/plugins/pairwise/lib/pairwise_plugin.rb
new file mode 100644
index 0000000..bfcc968
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin.rb
@@ -0,0 +1,37 @@
+class PairwisePlugin < Noosfero::Plugin
+
+ def self.plugin_name
+ "PairwisePlugin"
+ end
+
+ def self.plugin_description
+ _("A plugin that add a pairwise client feature to noosfero.")
+ end
+
+ # def self.extra_blocks
+ # {
+ # PairwiseBlock => {:type => ['community', 'profile'] }
+ # }
+ # end
+
+ def self.extra_blocks
+ { PairwisePlugin::QuestionsGroupListBlock => {} }
+ end
+
+ def content_types
+ [PairwisePlugin::PairwiseContent]
+ # if context.profile.is_a?(Community)
+ # else
+ # []
+ # end
+ end
+
+ def stylesheet?
+ true
+ end
+
+ def js_files
+ 'javascripts/pairwise.js'
+ end
+
+end
diff --git a/plugins/pairwise/lib/pairwise_plugin/choices_related.rb b/plugins/pairwise/lib/pairwise_plugin/choices_related.rb
new file mode 100644
index 0000000..ff5688a
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin/choices_related.rb
@@ -0,0 +1,12 @@
+class PairwisePlugin::ChoicesRelated < Noosfero::Plugin::ActiveRecord
+ set_table_name "pairwise_plugin_choices_related"
+ belongs_to :question, :class_name => 'PairwisePlugin::PairwiseContent'
+ belongs_to :user
+
+ validates_presence_of :question, :choice_id, :parent_choice_id
+
+ def self.related_choices_for choice_id
+ PairwisePlugin::ChoicesRelated.find_all_by_choice_id(choice_id) + PairwisePlugin::ChoicesRelated.find_all_by_parent_choice_id(choice_id)
+ end
+
+end
diff --git a/plugins/pairwise/lib/pairwise_plugin/helpers/suggestions_helper.rb b/plugins/pairwise/lib/pairwise_plugin/helpers/suggestions_helper.rb
new file mode 100644
index 0000000..d8395e0
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin/helpers/suggestions_helper.rb
@@ -0,0 +1,73 @@
+module PairwisePlugin::Helpers::SuggestionsHelper
+
+ def pagination_for_choices(choices)
+ pagination_links choices,
+ :params => {
+ :controller => 'pairwise_plugin_suggestions',
+ :action => :index,
+ :profile => profile.identifier
+ }
+ end
+
+ def link_to_sort_choices(pairwise_content, label, sort_by)
+
+ sort_order = "asc"
+
+ if params[:order]
+
+ order = params[:order]
+
+ if order[:sort_by] == sort_by
+ case order[:sort_order]
+ when 'asc'
+ sort_order = 'desc'
+ when 'desc'
+ sort_order = 'asc'
+ else
+ sort_order = 'asc'
+ end
+ end
+
+ end
+
+ link_to label, :action => "index", :id => pairwise_content.id, :pending => params[:pending], :reproved => params[:reproved], :order => {:sort_by => sort_by, :sort_order => sort_order}
+ end
+
+ def class_to_order_column(title, order=nil)
+ if order
+ sort_by = title == order[:sort_by] ? "selected_column" : "not_selected_column"
+
+ #raise sort_by.inspect
+
+ case order[:sort_order]
+ when 'asc'
+ sort_order = "soDescending"
+ when 'desc'
+ sort_order = "soAscending"
+ else
+ sort_order = "soAscending"
+ end
+
+ if (title == order[:sort_by])
+ style = "#{sort_by} #{sort_order}"
+ else
+ style = "#{sort_by}"
+ end
+ else
+ style = "not_selected_column"
+ end
+ end
+
+ def link_to_edit_choice(pairwise_content, choice)
+ link_to _("Edit"), :action => "edit", :id => pairwise_content.id, :choice_id => choice.id
+ end
+
+ def link_to_approve_choice(pairwise_content, choice, params)
+ link_to _("Approve"), :action => "approve", :id => pairwise_content.id, :choice_id => choice.id,:page => params[:page], :pending => params[:pending]
+ end
+
+ def link_to_reprove_idea(pairwise_content, choice, reason, params)
+ link_to _("Reprove"), :action => "reprove", :reason => reason || 'reprove' , :id => pairwise_content.id, :choice_id => choice.id,:page => params[:page], :pending => params[:pending]
+ end
+
+end
\ No newline at end of file
diff --git a/plugins/pairwise/lib/pairwise_plugin/helpers/viewer_helper.rb b/plugins/pairwise/lib/pairwise_plugin/helpers/viewer_helper.rb
new file mode 100644
index 0000000..59b9719
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin/helpers/viewer_helper.rb
@@ -0,0 +1,175 @@
+module PairwisePlugin::Helpers::ViewerHelper
+
+ def pairwise_plugin_stylesheet
+ plugin_style_sheet_path = PairwisePlugin.public_path('style.css')
+ stylesheet_link_tag plugin_style_sheet_path, :cache => "cache/plugins-#{Digest::MD5.hexdigest plugin_style_sheet_path.to_s}"
+ end
+
+ def choose_left_link(pairwise_content, question, prompt, embeded = false, source = nil, appearance_id = nil)
+ link_target = {:controller => 'pairwise_plugin_profile',
+ :profile => pairwise_content.profile.identifier,
+ :action => 'choose', :id => pairwise_content.id,:question_id => question.id , :prompt_id => prompt.id,
+ :choice_id => prompt.left_choice_id , :direction => 'left', :appearance_id => appearance_id}
+ link_target.merge!(:embeded => 1) if embeded
+ link_target.merge!(:source => source) if source
+ loading_javascript = pairwise_spinner_show_function_call(pairwise_content) + pairwise_hide_skip_call(pairwise_content)
+ link_to_remote prompt.left_choice_text, :loading => loading_javascript, :url => link_target
+ end
+
+ def skip_vote_open_function(pairwise_content)
+ link_to_function _('Skip vote'), "jQuery(\"#skip_vote_reasons_#{pairwise_content.id}\").slideToggle()"
+ end
+
+ def skip_vote_link(pairwise_content, question, prompt, embeded = false, source = nil, appearance_id = nil, reason = nil)
+ link_target = {:controller => 'pairwise_plugin_profile',
+ :profile => pairwise_content.profile.identifier,
+ :action => 'skip_prompt', :id => pairwise_content.id,:question_id => question.id , :prompt_id => prompt.id,
+ :appearance_id => appearance_id}
+ link_target.merge!(:embeded => 1) if embeded
+ link_target.merge!(:source => source) if source
+ link_target.merge!(:appearance_id => appearance_id) if appearance_id
+ link_target.merge!(:reason => reason) if reason
+ link_text = reason ? reason : _('Skip vote')
+ if reason
+ loading_javascript = pairwise_spinner_show_function_call(pairwise_content) + pairwise_hide_skip_call(pairwise_content)
+ "
" + link_to_remote(link_text, :loading => loading_javascript, :url => link_target) + ""
+ else
+ link_to_remote(link_text, link_target)
+ end
+ end
+
+ def pairwise_spinner_id(pairwise_content)
+ return "pairwise_spinner#{pairwise_content.id}"
+ end
+ def pairwise_spinner(pairwise_content)
+ text = content_tag :h5, _('Processing... please wait.')
+ content_tag :div, text, :class => "spinner", :id => pairwise_spinner_id(pairwise_content)
+ end
+
+ def pairwise_spinner_show_function_call(pairwise_content)
+ pairwise_spinner_show_function_name(pairwise_content) + "();"
+ end
+
+ def pairwise_hide_skip_call(pairwise_content)
+ "jQuery('#skip_vote_reasons_#{pairwise_content.id}').hide();"
+ end
+
+ def pairwise_spinner_show_function_name(pairwise_content)
+ "jQuery('##{pairwise_spinner_id(pairwise_content)}').fadeIn"
+ end
+
+
+ def pairwise_spinner_hide_function_call(pairwise_content)
+ pairwise_spinner_hide_function_name(pairwise_content) + "();"
+ end
+
+ def pairwise_spinner_hide_function_name(pairwise_content)
+ "jQuery('##{pairwise_spinner_id(pairwise_content)}').fadeOut"
+ end
+
+ def pairwise_user_identifier(user)
+ if user.nil?
+ is_external_vote ? "#{params[:source]}-#{request.session_options[:id]}" : "participa-#{request.session_options[:id]}"
+ else
+ user.identifier
+ end
+ end
+
+ def pairwise_embeded_code(pairwise_content)
+ embeded_url = url_for({:controller => "pairwise_plugin_profile",
+ :profile => pairwise_content.profile.identifier,
+ :action => "prompt",
+ :id => pairwise_content.id,
+ :question_id => pairwise_content.question.id,
+ :embeded => 1,
+ :source => "SOURCE_NAME",
+ :only_path => false})
+ embeded_code = ""
+
+ label = "
"
+ label += content_tag :h5, _('Pairwise Embeded')
+ textarea = text_area_tag 'embeded_code', embeded_code, {:style => "width: 100%; background-color: #ccc; font-weight:bold", :rows => 7}
+ hint = content_tag :quote, _("You can put this iframe in your site. Replace source param with your site address and make any needed adjusts in width and height.")
+ label + textarea + hint + "
"
+ end
+
+ def choose_right_link(pairwise_content, question, prompt, embeded = false, source = nil, appearance_id = nil)
+ link_target = { :controller => 'pairwise_plugin_profile',
+ :profile => pairwise_content.profile.identifier,
+ :action => 'choose', :id => pairwise_content.id, :question_id => question.id , :prompt_id => prompt.id,
+ :choice_id => prompt.right_choice_id , :direction => 'right' , :appearance_id => appearance_id}
+ link_target.merge!(:embeded => 1) if embeded
+ link_target.merge!(:source => source) if source
+ loading_javascript = pairwise_spinner_show_function_call(pairwise_content) + pairwise_hide_skip_call(pairwise_content)
+ link_to_remote prompt.right_choice_text, :loading => loading_javascript, :url => link_target
+ end
+
+ def pairwise_edit_link(label, pairwise_content)
+ link_target = myprofile_path(:controller => :cms, :profile => pairwise_content.profile.identifier, :action => :edit, :id => pairwise_content.id)
+ link_to label, link_target
+ end
+
+ def pairwise_result_link(label, pairwise_content, embeded = false, options = {})
+ link_target = pairwise_content.result_url
+ link_target.merge!(:embeded => 1) if embeded
+ link_to label, link_target, options
+ end
+
+ def pairwise_tab_remote_link(label, link_target, pairwise_content, embeded = false, options = {})
+ link_target.merge!(:embeded => 1) if embeded
+ loading_javascript = pairwise_spinner_show_function_call(pairwise_content) + pairwise_hide_skip_call(pairwise_content)
+ link_to_remote label, :loading => loading_javascript, :url => link_target, :html => options
+ end
+
+ def pairwise_suggestion_url(question, embeded = false, source = nil)
+ target = { :controller => :pairwise_plugin_profile, :profile => question.profile.identifier,:action => 'suggest_idea', :id => question.id }
+ target.merge!({ :embeded => 1 }) if embeded
+ target.merge!({ :source => source }) if source
+ target
+ end
+
+ def is_external_vote
+ params.has_key?("source") && !params[:source].empty?
+ end
+
+ def ideas_management_link(label, pairwise_content, user)
+ return "" unless user
+ return "" unless pairwise_content.allow_edit?(user)
+ link_to label, :controller => :pairwise_plugin_suggestions, :profile => pairwise_content.profile.identifier, :action => :index, :id => pairwise_content.id
+ end
+
+ def has_param_pending_choices?
+ params.has_key?("pending") && "1".eql?(params[:pending])
+ end
+
+ def has_param_reproved_choices?
+ params.has_key?("reproved") && "1".eql?(params[:reproved])
+ end
+
+ def choices_showing_text
+ ideas_or_suggestions_text = has_param_pending_choices? ? "Suggestions" : "Ideas"
+ _("Showing") + " " + ideas_or_suggestions_text
+ end
+
+ def pairwise_span_arrow(index)
+ content_tag :span, '', :class => (index == 0 ? 'active' : '')
+ end
+
+ def pairwise_group_row_classes(index)
+ index == 0 ? 'row' : 'row secondary'
+ end
+
+ def pairwise_group_content_body(index, pairwise_content, prompt_id = nil)
+ style = (index > 0) ? 'display:none' : ''
+ content_tag :div, :class => "pairwise_inner_body", :id => "pairwise_inner_body_#{pairwise_content.id}", :style => style do
+ render :partial => 'content_viewer/prompt_body',
+ :locals => {
+ :embeded => params[:embeded],
+ :source => params[:source],
+ :pairwise_content => pairwise_content,
+ :question => nil
+ }
+ end
+ end
+end
+
diff --git a/plugins/pairwise/lib/pairwise_plugin/pairwise_content.rb b/plugins/pairwise/lib/pairwise_plugin/pairwise_content.rb
new file mode 100644
index 0000000..c774c30
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin/pairwise_content.rb
@@ -0,0 +1,330 @@
+class PairwisePlugin::PairwiseContent < Article
+ include ActionView::Helpers::TagHelper
+ settings_items :pairwise_question_id
+ settings_items :allow_new_ideas, :type => :boolean, :default => true
+
+ before_save :send_question_to_service
+
+ validate_on_create :validate_choices
+
+ REASONS_ARRAY = [
+ {:text => _("I like both ideas"), :compare => false},
+ {:text => _("I think both ideas are the same"), :compare => false},
+ {:text => _("I don't know enough about either idea"),:compare => false},
+ {:text => _("I don't like either idea"), :compare => false},
+ {:text => _("I don't know enough about: "),:compare => true},
+ {:text => _("I just can't decide"),:compare => false}
+ ]
+
+ def initialize(*args)
+ super(*args)
+ self.published = false
+ self.accept_comments = false
+ self.notify_comments = false
+ @next_prompt = nil
+ end
+
+ def has_next_prompt?
+ @next_prompt.present?
+ end
+
+ alias_method :original_view_url, :view_url
+
+ def result_url
+ profile.url.merge(
+ :controller => :pairwise_plugin_profile,
+ :action => :result,
+ :id => id)
+ end
+
+ def prompt_url
+ profile.url.merge(
+ :controller => :pairwise_plugin_profile,
+ :action => :prompt_tab,
+ :id => id)
+ end
+
+ def self.short_description
+ 'Pairwise question'
+ end
+
+ def self.description
+ 'Question managed by pairwise'
+ end
+
+ def to_html(options = {})
+ source = options["source"]
+ embeded = options.has_key? "embeded"
+ prompt_id = options["prompt_id"]
+ pairwise_content = self
+ lambda do
+ locals = {:pairwise_content => pairwise_content, :source => source, :embeded => embeded, :prompt_id => prompt_id }
+ render :file => 'content_viewer/prompt.rhtml', :locals => locals
+ end
+ end
+
+ def pairwise_client
+ @pairwise_client ||= Pairwise::Client.build(profile.id, environment.settings[:pairwise_plugin])
+ @pairwise_client
+ end
+
+
+ def prepare_prompt(user_identifier, prompt_id=nil)
+ prepared_question = question
+ if has_next_prompt?
+ prepared_question.set_prompt @next_prompt
+ else
+ prepared_question = self.question_with_prompt_for_visitor(user_identifier, prompt_id)
+ end
+ prepared_question
+ end
+
+ def question
+ begin
+ @question ||= pairwise_client.find_question_by_id(pairwise_question_id)
+ rescue Exception => error
+ errors.add_to_base(error.message)
+ end
+ @question
+ end
+
+ def question_with_prompt_for_visitor(visitor='guest', prompt_id=nil)
+ pairwise_client.question_with_prompt(pairwise_question_id, visitor, prompt_id)
+ end
+
+ def description=(value)
+ @description=value
+ end
+
+ def description
+ begin
+ @description ||= question.name
+ rescue
+ @description = ""
+ end
+ @description
+ end
+
+ def pending_choices(filter, order)
+ if(question)
+ @inactive_choices ||= question.pending_choices(filter, order)
+ else
+ []
+ end
+ end
+
+ def reproved_choices(filter, order)
+ @reproved_choices ||= question ? question.reproved_choices(filter, order) : []
+ end
+
+ def inactive_choices(options={})
+ if(question)
+ @inactive_choices ||= (question.choices_include_inactive - question.get_choices)
+ else
+ []
+ end
+ end
+
+ def raw_choices(filter=nil, order=nil)
+ return [] if pairwise_question_id.nil?
+ @raw_choices ||= question ? question.get_choices(filter, order) : []
+ end
+
+ def choices
+ if raw_choices.nil?
+ @choices = []
+ else
+ begin
+ @choices ||= question.get_choices.map {|q| { q.id.to_s, q.data } }
+ rescue
+ @choices = []
+ end
+ end
+ @choices
+ end
+
+ def choices=(value)
+ @choices = value
+ end
+
+ def choices_saved
+ @choices_saved
+ end
+
+ def choices_saved=value
+ @choices_saved = value
+ end
+
+ def vote_to(prompt_id, direction, visitor, appearance_id)
+ raise _("Excepted question not found") if question.nil?
+ next_prompt = pairwise_client.vote(question.id, prompt_id, direction, visitor, appearance_id)
+ touch #invalidates cache
+ set_next_prompt(next_prompt)
+ next_prompt
+ end
+
+ def skip_prompt(prompt_id, visitor, appearance_id, reason=nil)
+ next_prompt = pairwise_client.skip_prompt(question.id, prompt_id, visitor, appearance_id, reason)
+ touch #invalidates cache
+ set_next_prompt(next_prompt)
+ next_prompt
+ end
+
+ def ask_skip_reasons(prompt)
+ reasons = REASONS_ARRAY.map do |item|
+ if item[:compare]
+ [ item[:text] + prompt.left_choice_text, item[:text] + prompt.right_choice_text]
+ else
+ item[:text]
+ end
+ end
+ reasons.flatten
+ end
+
+ def validate_choices
+ errors.add_to_base(_("Choices empty")) if choices.nil?
+ errors.add_to_base(_("Choices invalid format")) unless choices.is_a?(Array)
+ errors.add_to_base(_("Choices invalid")) if choices.size == 0
+ choices.each do | choice |
+ if choice.empty?
+ errors.add_to_base(_("Choice empty"))
+ break
+ end
+ end
+ end
+
+ def update_choice(choice_id, choice_text, active)
+ begin
+ return pairwise_client.update_choice(question, choice_id, choice_text, active)
+ rescue Exception => e
+ errors.add_to_base(N_("Choices:") + " " + N_(e.message))
+ return false
+ end
+ end
+
+ def approve_choice(choice_id)
+ begin
+ return pairwise_client.approve_choice(question, choice_id)
+ rescue Exception => e
+ errors.add_to_base(N_("Choices:") + " " + N_(e.message))
+ return false
+ end
+ end
+
+ def flag_choice(choice_id, explanation=nil)
+ pairwise_client.flag_choice(question, choice_id, explanation || 'reproved')
+ end
+
+ def find_choice id
+ return nil if question.nil?
+ question.find_choice id
+ end
+
+ def toggle_autoactivate_ideas(active_flag)
+ pairwise_client.toggle_autoactivate_ideas(question, active_flag)
+ end
+
+ def send_question_to_service
+ if new_record?
+ @question = create_pairwise_question
+ self.pairwise_question_id = @question.id
+ toggle_autoactivate_ideas(false)
+ else
+ #add new choices
+ unless @choices.nil?
+ @choices.each do |choice_text|
+ begin
+ unless choice_text.empty?
+ choice = pairwise_client.add_choice(pairwise_question_id, choice_text)
+ pairwise_client.approve_choice(question, choice.id)
+ end
+ rescue Exception => e
+ errors.add_to_base(N_("Choices: Error adding new choice to question") + N_(e.message))
+ return false
+ end
+ end
+ end
+ #change old choices
+ unless @choices_saved.nil?
+ @choices_saved.each do |id,data|
+ begin
+ pairwise_client.update_choice(question, id, data, true)
+ rescue Exception => e
+ errors.add_to_base(N_("Choices:") + " " + N_(e.message))
+ return false
+ end
+ end
+ end
+ begin
+ pairwise_client.update_question(pairwise_question_id, name)
+ rescue Exception => e
+ errors.add_to_base(N_("Question not saved: ") + N_(e.message))
+ return false
+ end
+ end
+ end
+
+ def create_pairwise_question
+ question = pairwise_client.create_question(name, choices)
+ question
+ end
+
+ def ideas_contributors(options=nil)
+ question.get_ideas_contributors(options)
+ end
+
+ def allow_new_ideas?
+ allow_new_ideas
+ end
+
+ def add_new_idea(text, visitor=nil)
+ return false unless allow_new_ideas?
+ pairwise_client.add_new_idea(pairwise_question_id, text, visitor)
+ end
+
+ def join_choices(ids_choices_to_join, id_choice_elected, user)
+ ids_choices_to_join.each do |id_choice|
+ unless id_choice.eql?(id_choice_elected)
+ choice = question.find_choice(id_choice)
+ choice_related = PairwisePlugin::ChoicesRelated.new do |cr|
+ cr.question = self
+ cr.choice_id = choice.id
+ cr.parent_choice_id = id_choice_elected
+ cr.user = user
+ cr.save!
+ end
+ end
+ end
+ end
+
+ def copy(options = {})
+ attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
+ attrs.merge!(options)
+ obj = self.class.new(attrs)
+ obj.pairwise_question_id = self.pairwise_question_id
+ obj.allow_new_ideas = self.allow_new_ideas
+ id = obj.send(:create_without_callbacks)
+ raise "Objeto não gravado" unless id
+ end
+
+ def copy!(options = {})
+ attrs = attributes.reject! { |key, value| ATTRIBUTES_NOT_COPIED.include?(key.to_sym) }
+ attrs.merge!(options)
+ #self.class.create!(attrs)
+ obj = self.class.new(attrs)
+ obj.pairwise_question_id = self.pairwise_question_id
+ obj.allow_new_ideas = self.allow_new_ideas
+ id = obj.send(:create_without_callbacks)
+ raise "Objeto não gravado" unless id
+ end
+
+ def page_size
+ 20
+ end
+
+private
+
+ def set_next_prompt(prompt)
+ @next_prompt = Pairwise::Prompt.new(prompt["prompt"])
+ end
+end
diff --git a/plugins/pairwise/lib/pairwise_plugin/pairwise_question_block.rb b/plugins/pairwise/lib/pairwise_plugin/pairwise_question_block.rb
new file mode 100644
index 0000000..9ea0916
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin/pairwise_question_block.rb
@@ -0,0 +1,32 @@
+class PairwisePlugin::PairwiseQuestionBlock < Block
+
+ settings_items :pairwise_question_id, :type => :integer
+
+ alias :profile :owner
+
+ def self.description
+ _('Display active pairwise question')
+ end
+
+ def help
+ _('This block displays a pairwise question.')
+ end
+
+ def content(args={})
+ block = self
+ lambda do
+ pairwise_client = new PairwiseClient(owner.id)
+ question = pairwise_client.get_question(pairwise_question_id)
+ if !question.blank?
+ block_title(question.name) + content_tag('div',
+ render(:file => 'blocks/pairwise_question', :locals => {:question => question}), :class => 'contents', :id => "pairwise_question_#{block.id}")
+ else
+ ''
+ end
+ end
+ end
+
+ def cacheable?
+ false
+ end
+end
\ No newline at end of file
diff --git a/plugins/pairwise/lib/pairwise_plugin/questions_group_block.rb b/plugins/pairwise/lib/pairwise_plugin/questions_group_block.rb
new file mode 100644
index 0000000..d7bd4e0
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin/questions_group_block.rb
@@ -0,0 +1,70 @@
+class PairwisePlugin::QuestionsGroupBlock < Block
+
+ def self.description
+ _('Display question of a group of questions')
+ end
+
+ def help
+ _('This block displays one of your pairwise questions in a predefined group. You can edit the block to select which one of your questions is going to be displayed in the block.')
+ end
+
+
+ def content(args={})
+ block = self
+ question = pick_question
+ lambda do
+ content = block_title(block.title)
+ content += ( question ? article_to_html(question,:gallery_view => false, :format => 'full').html_safe : _('No Question selected yet.') )
+ end
+ end
+
+ def questions_ids
+ self.settings[:questions_ids]
+ end
+
+ def questions_ids= value
+ if value.is_a?(Array)
+ self.settings[:questions_ids] = value
+ else
+ self.settings[:questions_ids] = value.nil? ? [] : [value]
+ end
+ self.settings[:questions_ids].delete('')
+ end
+
+ def pick_question
+ (questions && questions.length > 0) ? questions[Kernel.rand(questions.size)] : nil
+ end
+
+ def questions(reload = false)
+ @questions = nil if reload
+ if @questions || questions_ids
+ begin
+ @questions = Article.find(:all, :conditions => {'id' => questions_ids})
+ rescue ActiveRecord::RecordNotFound
+ # dangling reference, clear it
+ @questions = []
+ self.questions_ids = nil
+ self.save!
+ end
+ end
+ @questions
+ end
+
+ def questions=(arr)
+ self.questions_ids = arr.select {|x| x.attribute[:id] }
+ @questions = arr
+ end
+
+ def available_questions
+ return [] if self.owner.nil?
+ self.owner.kind_of?(Environment) ? self.owner.portal_community.questions : self.owner.questions
+ end
+
+ def self.expire_on
+ { :profile => [:article], :environment => [:article] }
+ end
+
+ def cacheable?
+ false
+ end
+end
diff --git a/plugins/pairwise/lib/pairwise_plugin/questions_group_list_block.rb b/plugins/pairwise/lib/pairwise_plugin/questions_group_list_block.rb
new file mode 100644
index 0000000..a36fc65
--- /dev/null
+++ b/plugins/pairwise/lib/pairwise_plugin/questions_group_list_block.rb
@@ -0,0 +1,124 @@
+class PairwisePlugin::QuestionsGroupListBlock < Block
+
+ def self.description
+ _('Display question of a group of questions')
+ end
+
+ def help
+ _('This block displays one of your pairwise questions in a predefined group. You can edit the block to select which one of your questions is going to be displayed in the block.')
+ end
+
+ settings_items :group_description, :type => String
+
+ def content(args={})
+ block = self
+ questions = questions.shuffle if(questions)
+ #lambda do
+ # content = block_title(block.title)
+ # content += ( question ? article_to_html(question,:gallery_view => false, :format => 'full').html_safe : _('No Question selected yet.') )
+ #end
+ lambda do
+ render :file => 'blocks/questions_group_list.rhtml', :locals => {:block => block}
+ end
+ end
+
+ def random_sort= value
+ self.settings[:random_sort] = value
+ end
+
+ def random_sort
+ self.settings[:random_sort]
+ end
+
+ def is_random?
+ random_sort && !'0'.eql?(random_sort)
+ end
+
+ def contains_question?(id)
+ if self.settings[:questions_ids]
+ self.settings[:questions_ids].include?(id.to_s)
+ else
+ return false
+ end
+ end
+
+ def questions_ids
+ self.settings[:questions_ids]
+ end
+
+ def questions_ids= value
+ if value.is_a?(Array)
+ self.settings[:questions_ids] = value
+ else
+ self.settings[:questions_ids] = value.nil? ? [] : value.split(",")
+ end
+ self.settings[:questions_ids].delete('')
+ end
+
+ def questions_for_view
+ result = nil
+ if questions && questions.length > 0
+ result = is_random? ? questions.shuffle : questions
+ end
+ result
+ end
+
+ def questions(reload = false)
+ @questions = nil if reload
+ if @questions || questions_ids
+ begin
+ @questions = []
+ questions_ids.each do |id|
+ @questions << Article.find(id)
+ end
+ rescue ActiveRecord::RecordNotFound
+ # dangling reference, clear it
+ @questions = []
+ self.questions_ids = nil
+ self.save!
+ end
+ end
+ @questions
+ end
+
+ def questions=(arr)
+ self.questions_ids = arr.select {|x| x.attribute[:id] }
+ @questions = arr
+ end
+
+ def available_questions
+ return [] if self.owner.nil?
+ result = []
+ conditions = {}
+ if questions_ids && !questions_ids.empty?
+ questions_ids.each do |id|
+ if self.owner.kind_of?(Environment)
+ question = self.owner.portal_community.questions.find(id)
+ else
+ question = self.owner.questions.find(id)
+ end
+ result << question
+ end
+ conditions = { :conditions => ['id not in (?)', questions_ids] }
+ end
+
+ if self.owner.kind_of?(Environment)
+ result += self.owner.portal_community.questions.find(:all, conditions)
+ else
+ result += self.owner.questions.find(:all, conditions)
+ end
+ result
+ end
+
+ def self.expire_on
+ { :profile => [:article], :environment => [:article] }
+ end
+
+ def timeout
+ 1.hours
+ end
+
+ def embedable?
+ true
+ end
+end
diff --git a/plugins/pairwise/public/ajax-loader.gif b/plugins/pairwise/public/ajax-loader.gif
new file mode 100644
index 0000000..5f78ce7
Binary files /dev/null and b/plugins/pairwise/public/ajax-loader.gif differ
diff --git a/plugins/pairwise/public/javascripts/pairwise.js b/plugins/pairwise/public/javascripts/pairwise.js
new file mode 100644
index 0000000..b3b8768
--- /dev/null
+++ b/plugins/pairwise/public/javascripts/pairwise.js
@@ -0,0 +1,117 @@
+/* jQuery jqEasyCharCounter plugin
+ * Examples and documentation at: http://www.jqeasy.com/
+ * Version: 1.0 (05/07/2010)
+ * No license. Use it however you want. Just keep this notice included.
+ * Requires: jQuery v1.3+
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+(function($) {
+
+$.fn.extend({
+ jqEasyCounter: function(givenOptions) {
+ return this.each(function() {
+ var $this = $(this),
+ options = $.extend({
+ maxChars: 160,
+ maxCharsWarning: 150,
+ msgFontSize: '100%',
+ msgFontColor: '#000',
+ msgFontFamily: 'inherit',
+ msgTextAlign: 'right',
+ msgWarningColor: '#F00',
+ msgAppendMethod: 'insertAfter'
+ }, givenOptions);
+
+ if(options.maxChars <= 0) return;
+ // create counter element
+ var jqEasyCounterMsg = $("
");
+ var jqEasyCounterMsgStyle = {
+ 'font-size' : options.msgFontSize,
+ 'font-family' : options.msgFontFamily,
+ 'color' : options.msgFontColor,
+ 'text-align' : options.msgTextAlign,
+ 'width' : '100%',
+ 'opacity' : 0
+ };
+ jqEasyCounterMsg.css(jqEasyCounterMsgStyle);
+ // append counter element to DOM
+ if (options.target) {
+ jqEasyCounterMsg.appendTo($(options.target));
+ $(options.target).show();
+ }
+ else {
+ jqEasyCounterMsg[options.msgAppendMethod]($this);
+ }
+
+ // bind events to this element
+ $this
+ .bind('keydown keyup keypress focus',function() {
+ // allow chance for other events to modify value first
+ // e.g., hint plugins that clear the value on focus
+ setTimeout(doCount, 1);
+ });
+ function doCount(){
+ var val = $this.val(),
+ length = val.length;
+
+ if(length >= options.maxChars) {
+ val = val.substring(0, options.maxChars);
+ }
+
+ if(length > options.maxChars){
+ // keep scroll bar position
+ var originalScrollTopPosition = $this.scrollTop();
+ $this.val(val.substring(0, options.maxChars));
+ $this.scrollTop(originalScrollTopPosition);
+ }
+
+ if(length >= options.maxCharsWarning){
+ jqEasyCounterMsg.css({"color" : options.msgWarningColor});
+ }else {
+ jqEasyCounterMsg.css({"color" : options.msgFontColor});
+ }
+
+ jqEasyCounterMsg.html(options.maxChars - $this.val().length);
+ jqEasyCounterMsg.stop().fadeTo( 'fast', 1);
+ }
+ });
+ }
+});
+
+})(jQuery);
+
+ jQuery(document).ready(function($){
+/* $('#suggestions_box span.close_button').live('click', function(){
+ $('#suggestions_box').fadeOut();
+ $('#pairwise_main div.show_new_idea_box').show();
+ });
+
+ $('#suggestions_box_show_link').live('click', function(){
+ $('#suggestions_box').fadeIn();
+ $('#pairwise_main div.show_new_idea_box').hide();
+ }); */
+
+ $('#pairwise_main ul.pairwise_menu li a').mouseenter(function(){
+ if($(this).attr('id') != 'pairwise_voting_tab') {
+ $('#pairwise_voting_tab').attr("class", "");
+ }
+ });
+
+ $('#pairwise_main ul.pairwise_menu li a').mouseout(function(){
+ if($(this).attr('id') != 'pairwise_voting_tab') {
+ $('#pairwise_voting_tab').attr("class", "active");
+ }
+ });
+ $('span.embeded_code_link a').live('click', function(){
+ $(this).parents('.embeded_code').find('#pairwise_embeded_box').slideToggle();
+ });
+
+ });
diff --git a/plugins/pairwise/public/style.css b/plugins/pairwise/public/style.css
new file mode 100644
index 0000000..e0705dc
--- /dev/null
+++ b/plugins/pairwise/public/style.css
@@ -0,0 +1,344 @@
+div#pairwise_form_fields textarea {
+ width: 100%;
+ margin-top: 5px;
+ height:30px;
+
+}
+
+#pairwise_main {
+ width: 100%;
+ padding: 10px;
+}
+
+.vote_question {
+
+}
+
+#pairwise_main div.footer {
+ text-align:right;
+ padding: 20px;
+}
+
+#pairwise_main div.prompt {
+ width: 45%;
+ float:none;
+ color:white;
+ min-height: 30px;
+ height:auto;
+ word-wrap: break-word;
+ font-size: 12pt;
+ text-align: center;
+ display: inline-block;
+ vertical-align: top;
+
+}
+
+#pairwise_main div.prompt a {
+ width:100%;
+ color:white;
+ display: block;
+ text-decoration: none;
+}
+
+
+#pairwise_main div#suggestions_box {
+ /*border: 1px solid;
+ border-radius: 7px;
+ -webkit-border-radius: 7px;
+ -moz-border-radius: 7px;
+ border-color: #ccc;
+ border-width: 1px;
+ border-style: solid;*/
+ padding: 10px;
+ margin-top: 15px;
+}
+
+#pairwise_main div#suggestion_box_loading {
+ color: black;
+ border: 1px solid;
+ border-radius: 7px;
+ -webkit-border-radius: 7px;
+ -moz-border-radius: 7px;
+ border-color: #ccc;
+ border-width: 1px;
+ border-style: solid;
+ padding: 10px;
+ margin-top: 15px;
+ text-align: center;
+}
+
+
+#pairwise_main div#suggestions_box textarea{
+ width: 100%;
+ border: 1px solid #99999;
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+}
+
+#pairwise_main div#suggestions_box #new_idea_button{
+ background-color: #01bb00;
+ padding: 5px 10px 5px 10px;
+ cursor: pointer;
+ border-radius: 5px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+}
+
+#pairwise_main div#suggestions_box div.suggestion_header {
+ text-align: right;
+ color: blue;
+}
+
+#pairwise_main div#suggestions_box #new_idea_button:hover{
+ boder-color: gray;
+}
+
+#pairwise_main #suggestions_box span.close_button {
+ cursor: pointer;
+}
+
+#pairwise_main #suggestions_box span.close_button:hover {
+ cursor: pointer;
+ text-decoration: underline;
+}
+
+
+#pairwise_main div.show_new_idea_box {
+ width: 150px;
+ float:none;
+ color:white;
+ min-height: 18px;
+ height:auto;
+ padding: 0.5em;
+ word-wrap: break-word;
+ font-size: 12pt;
+ background-color: #01bb00;
+ text-align: center;
+ border-radius: 7px;
+ -webkit-border-radius: 7px;
+ -moz-border-radius: 7px;
+ border-color:#CCCCCC;
+ border-width: 1px;
+ border-style: solid;
+ vertical-align: top;
+ margin-top: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+ clear: both;
+}
+
+#pairwise_main div.show_new_idea_box a{
+ color: white;
+ text-decoration: none;
+}
+
+#pairwise_main div.show_new_idea_box a:hover{
+ text-decoration: underline;
+}
+
+#pairwise_main div.skip_vote {
+ width: 150px;
+ float:none;
+ color:white;
+ min-height: 18px;
+ height:auto;
+ padding: 0.5em;
+ word-wrap: break-word;
+ font-size: 12pt;
+ text-align: center;
+ vertical-align: top;
+ margin-top: 12px;
+ margin-left: auto;
+ margin-right: auto;
+ text-align: center;
+}
+
+
+#pairwise_main div.skip_vote_reasons.show {
+ display:block;
+}
+
+#pairwise_main div.skip_vote_reasons {
+ display:none;
+ padding:20px;
+ margin-bottom: 10px;
+}
+
+#pairwise_main div.skip_vote_item {
+ width:100%;
+ margin-bottom: 15px;
+ padding-left: 5px;
+ padding-right: 5px;
+ /*float:left;*/
+ float:left;
+ background-color:#ccc;
+ height: 3em;
+ text-align: center;
+ vertical-align: center;
+ min-height: 2em;
+ padding-top: 10px;
+ border-width: 1px;
+ border-style: solid;
+ border-radius: 7px;
+ -webkit-border-radius: 7px;
+ -moz-border-radius: 7px;
+ border-color:#CCCCCC;
+}
+
+#pairwise_main div.skip_vote_reasons div:nth-child(even) {
+ /*margin-left: 10px;*/
+}
+
+#pairwise_main div.skip_vote a{
+ color: white;
+ text-decoration: none;
+ width: 100%;
+}
+
+#pairwise_main div.skip_vote a:hover{
+ text-decoration: underline;
+ width: 100%;
+}
+
+.result_label {
+ padding: 15px 0px;
+}
+
+div.choices_filter {
+ width: 100%;
+ text-align: right;
+}
+
+table.pairwise_choices_table {
+ border: 1px #fcfcfc solid;
+ border-radius: 7px;
+ -webkit-border-radius: 7px;
+ -moz-border-radius: 7px;
+}
+
+table.pairwise_choices_table th{
+ font-weight: bolder;
+ text-align: left;
+}
+
+
+
+div.pairwise_group_list_container {
+ font-family: 'Open Sans';
+}
+
+div.pairwise_group_list_container .row {
+ font-size: 14px;
+ height: 40px;
+ width:100%;
+ background-color: #F8C300;
+ vertical-align: middle;
+ margin-top:10px;
+ margin-bottom:auto;
+ padding:0px;
+ cursor: auto;
+}
+
+div.pairwise_group_list_container .row p {
+ line-height: 30px;
+ margin: auto;
+ padding-bottom: 5px;
+ padding-top: 5px;
+}
+
+
+div.pairwise_group_list_container .title{
+ display: inline-block;
+ color: #2F5707;
+ Height: 40px;
+ padding-left: 20px;
+}
+
+div.pairwise_group_list_container .number{
+ display: inline-block;
+ left: 0px;
+ background-color: #2F5707;
+ width: 40px;
+ text-align: center;
+ color: #F8C300;
+ }
+
+div.pairwise_group_list_container .row.secondary {
+ cursor: pointer;
+ background-color: #497B16;
+}
+
+div.pairwise_group_list_container .row.secondary .title {
+ color: white;
+}
+
+
+div.pairwise_group_list_container .row.secondary .number {
+ color: white;
+}
+
+div.pairwise_group_list_container .arrow{
+ display: inline-block;
+ position: absolute;
+ right: 20px;
+ margin-top: 10px;
+}
+/*
+div.pairwise_group_list_container .arrow{
+ display: inline-block;
+ position: absolute;
+ right: 20px;
+ margin-top: 10px;
+ height: 22px;
+ width:23px;
+ color: #2F5707;
+ background: url('/designs/themes/participa-theme/images/arrow_right.jpg') no-repeat center;
+}
+
+div.pairwise_group_list_container .arrow.active{
+ height: 18px;
+ margin-top: 10px;
+ right: 20px;
+ width: 22px;
+ background: url('/designs/themes/participa-theme/images/arrow_down.jpg') no-repeat center;
+}*/
+
+div.pairwise_group_list_container .row.secondary .arrow span {
+ background: url('/designs/themes/participa-theme/images/arrow_right.jpg') no-repeat center;
+ border: 0px;
+ width: 25px;
+ height: 25px;
+ display: inline-block;
+ cursor: pointer;
+}
+
+div.pairwise_group_list_container .row .arrow span {
+ cursor: auto;
+ border: 0px;
+ width: 25px;
+ height: 25px;
+ display: inline-block;
+ background: url('/designs/themes/participa-theme/images/arrow_down.jpg') no-repeat center;
+
+}
+
+div.pairwise_main .spinner {
+ position: absolute;
+ text-align: center;
+ width: 95%;
+ height: 190px;
+ display: none;
+ z-index: 999;
+ background-color: #ECF2E7;
+}
+
+div.pairwise_main .spinner h5{
+ padding-top: 30px;
+}
+
+#pairwise_main .pairwise_content .total_votes {
+ float: right;
+ color: #999;
+}
diff --git a/plugins/pairwise/test/fixtures/http_stub_fixtures.rb b/plugins/pairwise/test/fixtures/http_stub_fixtures.rb
new file mode 100644
index 0000000..a1c5183
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/http_stub_fixtures.rb
@@ -0,0 +1,22 @@
+require 'vcr'
+
+VCR.configure do |c|
+ c.cassette_library_dir = "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/vcr_cassettes"
+ c.hook_into :webmock
+end
+
+class HttpStubFixtures
+ attr_accessor :client
+
+ def initialize(pairwise_env_settings)
+ @client = Pairwise::Client.build('1', pairwise_env_settings)
+ end
+
+ def create_question(id_question, name, choices)
+ VCR.use_cassette('pairwise_create_question_dynamic',
+ :erb => { :id_question => id_question, :question_name => name, :choices => choices }
+ ) do
+ @client.create_question(name, choices)
+ end
+ end
+end
\ No newline at end of file
diff --git a/plugins/pairwise/test/fixtures/pairwise_content_fixtures.rb b/plugins/pairwise/test/fixtures/pairwise_content_fixtures.rb
new file mode 100644
index 0000000..e5b0ba6
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/pairwise_content_fixtures.rb
@@ -0,0 +1,80 @@
+class PairwiseContentFixtures
+
+ def self.pairwise_content
+ content = PairwisePlugin::PairwiseContent.new
+ content.pairwise_question_id = 1
+ content.name = "Question 1"
+ content.choices = ["choice1,choice2"]
+ content
+ end
+
+ def self.content_stub_with_3_choices
+ content = PairwisePlugin::PairwiseContent.new
+ content.pairwise_question_id = 1
+ content.name = "Question 1"
+ content.choices = ["choice1,choice2,choice3"]
+ content
+
+ question = Pairwise::Question.new(:id =>1, :name => "Question 1")
+ choices = []
+ choices << Pairwise::Choice.new(:id => 1, :data => "Choice1")
+ choices << Pairwise::Choice.new(:id => 2, :data => "Choice2")
+ choices << Pairwise::Choice.new(:id => 3, :data => "Choice3")
+
+ question.stubs(:find_choice).with(1).returns(choices[0])
+ question.stubs(:find_choice).with(2).returns(choices[1])
+ question.stubs(:find_choice).with(3).returns(choices[2])
+
+ question.stubs(:choices => choices)
+ content.stubs(:question => question)
+ content
+ end
+
+ def self.new_pairwise_content
+ PairwisePlugin::PairwiseContent.new do |content|
+ content.name = "New question content"
+ content.published = true
+ end
+ end
+
+ def self.pairwise_content_inactive
+ content = self.pairwise_content
+ content.published = false
+ content
+ end
+
+ def self.pairwise_question(votes_count = 0)
+ question = Pairwise::Question.new({
+ :id => 1,
+ :name => 'Question 1',
+ :active => true,
+ :description => 'Some description',
+ :appearance_id => 'abcdef',
+ :votes_count => votes_count
+ })
+ end
+
+ def self.pairwise_prompt
+ prompt = Pairwise::Prompt.new({
+ :id => 1,
+ :question_id => 1,
+ :left_choice_text => 'Option 1',
+ :left_choice_id => 1,
+ :right_choice_text => 'Option 2',
+ :right_choice_id => 2
+ })
+ end
+
+ def self.pairwise_question_with_prompt
+ question = self.pairwise_question
+ question.set_prompt self.pairwise_prompt
+ question
+ end
+
+ def self.choices_with_stats
+ choices = []
+ choices << Pairwise::Choice.new(:id => 1, :data => "Choice1", :wins => 0, :losses => 0, :score => 0.0)
+ choices << Pairwise::Choice.new(:id => 2, :data => "Choice2", :wins => 0, :losses => 0, :score => 0.0)
+ choices << Pairwise::Choice.new(:id => 3, :data => "Choice3", :wins => 0, :losses => 0, :score => 0.0)
+ end
+end
\ No newline at end of file
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/flag_choice_as_reproved.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/flag_choice_as_reproved.yml
new file mode 100644
index 0000000..86de357
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/flag_choice_as_reproved.yml
@@ -0,0 +1,269 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/6.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Content-Length:
+ - "955"
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzYueG1sOg9zZXNzaW9uX2lkIiVmNTI4NDk5MWE4MWY4Y2JjZDcyOTFlYmFhMDM0MWZlYg%3D%3D--451165241c218ffe9a88776f330bd9224b3251e7; path=/; HttpOnly
+ Date:
+ - Thu, 20 Mar 2014 15:20:18 GMT
+ Content-Type:
+ - application/xml; charset=utf-8
+ X-Runtime:
+ - "37"
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"890ce780d1a33e8e4dfd9e742c6f54f7\""
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-19T18:38:15Z
+ 4
+ 6
+ 1
+
+ true
+ 1
+ Q1
+ 0
+ true
+ 1
+
+ 2014-03-20T15:19:04Z
+ true
+ 7
+ 0
+ 3
+
+
+ http_version:
+ recorded_at: Thu, 20 Mar 2014 15:20:18 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/6/choices.xml?inactive_ignore_flagged=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Content-Length:
+ - "471"
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjovcXVlc3Rpb25zLzYvY2hvaWNlcy54bWw%2FaW5hY3RpdmVfaWdub3JlX2ZsYWdnZWQ9dHJ1ZToPc2Vzc2lvbl9pZCIlMDMwMmIxYjA4NjZiNjE2NTAxM2EwYjM0NjdiMzI1N2Y%3D--f0e1fbb7ab8c04b8001b421abbf0680b20b14ab9; path=/; HttpOnly
+ Date:
+ - Thu, 20 Mar 2014 15:20:19 GMT
+ Content-Type:
+ - application/xml; charset=utf-8
+ X-Runtime:
+ - "57"
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"404952a7933bc1080179d9b9ba1f2e18\""
+ body:
+ string: |
+
+
+
+ false
+ 2014-03-19T18:38:15Z
+ Choice 2
+ 38
+ 0
+ 50.0
+ 0
+ false
+ 1
+
+
+
+ http_version:
+ recorded_at: Thu, 20 Mar 2014 15:20:19 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/6/choices/38.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Content-Length:
+ - "1048"
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzYvY2hvaWNlcy8zOC54bWw6D3Nlc3Npb25faWQiJWE5ZjA3MjM3NGE3ODdmMzc2MzI1YjkyNGU3ZDRjMTM0--c7700e91fd411a2aa89ceb1ed8629d279038b7d5; path=/; HttpOnly
+ Date:
+ - Thu, 20 Mar 2014 15:20:19 GMT
+ Content-Type:
+ - application/xml; charset=utf-8
+ X-Runtime:
+ - "74"
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"484f2a633216bd272aeb60e35c4dd7e4\""
+ body:
+ string: |
+
+
+ false
+ 2014-03-19T18:38:15Z
+ 4
+ Choice 2
+ 38
+
+
+ 0
+
+
+ 0
+ 0
+ 0
+ 6
+
+
+ 50.0
+
+ 2014-03-20T15:19:04Z
+ 4
+ 0
+
+
+ http_version:
+ recorded_at: Thu, 20 Mar 2014 15:20:19 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/6/choices/38/flag.xml?explanation=reproved&visitor_identifier=1
+ body:
+ string: ""
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 201
+ message: "Created "
+ headers:
+ Content-Length:
+ - "1048"
+ Cache-Control:
+ - no-cache
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlMGIxZmU1MGYzZDFhNDNmNzhlMTY1ZmZhYWQ5ZDY4ZDI%3D--7d921de6d0fc3eeb5ef6f37ff00159a427455892; path=/; HttpOnly
+ Date:
+ - Thu, 20 Mar 2014 15:20:19 GMT
+ Content-Type:
+ - application/xml; charset=utf-8
+ X-Runtime:
+ - "75"
+ Connection:
+ - Keep-Alive
+ body:
+ string: |
+
+
+ false
+ 2014-03-19T18:38:15Z
+ 4
+ Choice 2
+ 38
+
+
+ 0
+
+
+ 0
+ 0
+ 0
+ 6
+
+
+ 50.0
+
+ 2014-03-20T15:19:04Z
+ 4
+ 0
+
+
+ http_version:
+ recorded_at: Thu, 20 Mar 2014 15:20:19 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/6/choices.xml?inactive_ignore_flagged=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Content-Length:
+ - "67"
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjovcXVlc3Rpb25zLzYvY2hvaWNlcy54bWw%2FaW5hY3RpdmVfaWdub3JlX2ZsYWdnZWQ9dHJ1ZToPc2Vzc2lvbl9pZCIlMmU3ZTM1MWYwZWE1NzJiZDlmODVhYWY3ZmIzNmFmZjA%3D--242ddcf0222a1c1d36ca7f34e77ccf541b9cea1c; path=/; HttpOnly
+ Date:
+ - Thu, 20 Mar 2014 15:20:19 GMT
+ Content-Type:
+ - application/xml; charset=utf-8
+ X-Runtime:
+ - "28"
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"4f31ca96db448bb738a3923db737871d\""
+ body:
+ string: |
+
+
+
+ http_version:
+ recorded_at: Thu, 20 Mar 2014 15:20:19 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_add_new_choice.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_add_new_choice.yml
new file mode 100644
index 0000000..442cbb8
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_add_new_choice.yml
@@ -0,0 +1,62 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "773"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTcwNTViODljNzY0YWYyNTdiOTlmMDJmMTVkMzU3ZDQy--e1ef0b40ed34d06aab2f0770d9f7b2103758934f; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "34"
+ Etag:
+ - "\"0813255a93cff945e3f3ce1f6f128460\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:23 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:23 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_approve_choice.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_approve_choice.yml
new file mode 100644
index 0000000..6f4b8d0
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_approve_choice.yml
@@ -0,0 +1,644 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:23Z
+ true
+ 0
+ 1
+ false
+
+ 3
+ true
+ 4
+
+ 0
+ 1
+ Q1
+ true
+ 0
+ 1
+ 1
+ 2014-03-18T13:53:23Z
+ Choice 1
+ Choice 2
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlMTZhMGI4N2M2NjI3ZjBkMTEwYjMxMjkxZmQwMGU5NTk%3D--918486552d2ddd85974c072ed27052e6361cf5bf; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "42"
+ Date:
+ - Tue, 18 Mar 2014 13:53:23 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:23 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "956"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiU0NTZjNDRjZjM0MmFjNjNkOThhYzg2NWMyMTNmM2UzMg%3D%3D--09bee603168fd563081f55c581dab952dc5a935b; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "87"
+ Etag:
+ - "\"a4aedcf5bbd98d62bb423366ffd4b670\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:23 GMT
+ body:
+ string: |
+
+
+ true
+ 2
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ false
+ 1
+ Q1
+ 0
+ true
+ 1
+
+ 2014-03-18T13:53:23Z
+ true
+ 3
+ 0
+ 2
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:23 GMT
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: |
+
+
+ New inactive choice
+ 1
+ 1
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 201
+ message: "Created "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1049"
+ Location:
+ - http://localhost:3030/questions/3/choices/13
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlNGUzMzg0MmZhNGRjOWU2MmUzNzRmZTgyMWNiMjRlMzI%3D--a743d79d192e7d00d3e6c6eb5569b3f8851fc47c; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "155"
+ Date:
+ - Tue, 18 Mar 2014 13:53:24 GMT
+ body:
+ string: |
+
+
+ false
+ 2014-03-18T13:53:24Z
+ 4
+ New inactive choice
+ 13
+
+ 1
+ 0
+
+
+ 0
+ 0
+ 0
+ 3
+
+
+ 50.0
+
+ 2014-03-18T13:53:24Z
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:24 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml?include_inactive=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1135"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjMvcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw%2FaW5jbHVkZV9pbmFjdGl2ZT10cnVlOg9zZXNzaW9uX2lkIiVmYTJiN2JlNTk4OTg1ZGQzYzA2ZmNmMTdjZmRhY2EyYg%3D%3D--105dc6ae0881fbbd34864a93aff4adfe4e885b3c; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "39"
+ Etag:
+ - "\"d84f7f32e1b78fb781400017b6c29802\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:24 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ false
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:24 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "773"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJWY0OTQ2OWIwZTBkNGFmNDNjNDA5NzE1MWM2NWNmYTFm--c6c11e071bf7549ee9f28eb084c57a545a4c7b6f; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "33"
+ Etag:
+ - "\"0813255a93cff945e3f3ce1f6f128460\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:24 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:24 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/13.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1049"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvY2hvaWNlcy8xMy54bWw6D3Nlc3Npb25faWQiJTA1YjZkOTRkMzUyNjQwMmFlYzFhNjRjNjU4MDg2YWE2--114aca8aa089105631e0d908f3d12ad06132588d; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "24"
+ Etag:
+ - "\"323b6fd72f7ceb8579523f15601a8fd8\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:24 GMT
+ body:
+ string: |
+
+
+ false
+ 2014-03-18T13:53:24Z
+ 4
+ New inactive choice
+ 13
+
+ 1
+ 0
+
+
+ 0
+ 0
+ 0
+ 3
+
+
+ 50.0
+
+ 2014-03-18T13:53:24Z
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:24 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/13.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:24Z
+ true
+ 0
+
+ 1
+
+
+ 0
+ 13
+ New inactive choice
+ 0
+ 4
+ 50.0
+
+
+ 1
+
+ 2014-03-18T13:53:24Z
+ 0
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlZDk5ZGE3ZWE2NmJiNTJmYWMzMmI5YzY5YmQxM2IyYjg%3D--3358d7c14ea6e9bfc5c2c1b1c0462ebe4e4c4d8b; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "140"
+ Date:
+ - Tue, 18 Mar 2014 13:53:25 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:25 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml?include_inactive=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1134"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjMvcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw%2FaW5jbHVkZV9pbmFjdGl2ZT10cnVlOg9zZXNzaW9uX2lkIiU0ZTEwOGMwNDljYWQwZTc2MmU1NTM5OWI3NzM4M2FkZg%3D%3D--fbc1753c1d7065794142c62c81041089e63b306f; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "38"
+ Etag:
+ - "\"3d3cc6bfd093918ac1b1b8c8e465efa7\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:25 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:25 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1134"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJWMzMmI0ODZiY2FiOGQ5ZTRiOTFlMThkMGIwNWEwZDU1--c17c6f4b6f52d774507c14c7869114329cc4a822; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "41"
+ Etag:
+ - "\"3d3cc6bfd093918ac1b1b8c8e465efa7\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:25 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:25 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1134"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTUwNGEzNDgxMTI4NThmZTUzM2JlY2ZjZjZlNDQxYzVl--10cef7014de7c9b7a84b3226a696b7ff62f9631a; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "45"
+ Etag:
+ - "\"3d3cc6bfd093918ac1b1b8c8e465efa7\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:25 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:25 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_blank_value.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_blank_value.yml
new file mode 100644
index 0000000..dfddcd3
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_blank_value.yml
@@ -0,0 +1,132 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1134"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTcxMmUwYTYyOTE3NGE0OWU3MzhiMjA4MDFmOGJiNDM4--8d93999812fc4be458135b01a42d53e8ff9b58de; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "100"
+ Etag:
+ - "\"3d3cc6bfd093918ac1b1b8c8e465efa7\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:26 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:26 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/11.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1047"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvY2hvaWNlcy8xMS54bWw6D3Nlc3Npb25faWQiJTM1NmM3MmJmNTczYzIwYzcyODBjMWFlNDBkNTAxNzlm--2dc46b515e26ca772b36dab15b0359c7317e28ca; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "25"
+ Etag:
+ - "\"05b426e3208a00fc0be6d435b75cc361\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:26 GMT
+ body:
+ string: |
+
+
+ true
+ 2014-03-18T13:53:23Z
+ 4
+ Choice 1
+ 11
+
+
+ 0
+
+
+ 0
+ 0
+ 0
+ 3
+
+
+ 50.0
+
+ 2014-03-18T13:53:23Z
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:26 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_create_question.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_create_question.yml
new file mode 100644
index 0000000..e314778
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_create_question.yml
@@ -0,0 +1,131 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions.xml
+ body:
+ string: |
+
+
+ Q1
+ 1
+ 1
+ Choice 1
+ Choice 2
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "913"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlY2RiMDVkZWU4YjMyZDgzYWY0MzMxMDM3ODFkNzdkMzk%3D--b37e44bec446d3860dc1bf888a36e36e940cb2e0; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "175"
+ Etag:
+ - "\"59680dc7fa311f91dd47e51a799904d8\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:23 GMT
+ body:
+ string: |
+
+
+ false
+ 0
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ false
+ 1
+ Q1
+ 0
+ true
+ 1
+
+ 2014-03-18T13:53:23Z
+ true
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:23 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:23Z
+ true
+ 0
+ 1
+ true
+
+ 3
+ true
+ 4
+
+ 0
+ 1
+ Q1
+ true
+ 0
+ 1
+ 1
+ 2014-03-18T13:53:23Z
+ Choice 1
+ Choice 2
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlNzQ0Mjc3YzFhNzdlOTI2MDMyNzdiMTMxYjc5MzdiM2M%3D--84b0fbf2d2803c8fbe89ac4571d99fca0a2293ab; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "43"
+ Date:
+ - Tue, 18 Mar 2014 13:53:23 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:23 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_create_question_dynamic.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_create_question_dynamic.yml
new file mode 100644
index 0000000..c9c7582
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_create_question_dynamic.yml
@@ -0,0 +1,129 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions.xml
+ body:
+ string: |
+
+
+ 1
+ <%= question_name %>
+ 1
+ <%= choices %>
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Connection:
+ - Keep-Alive
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "915"
+ Content-Type:
+ - application/xml; charset=utf-8
+ X-Runtime:
+ - "173"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlNDMxNTYxNzdlODhiMjk2ZjI1YTMyNjNhMTIxOTMwOGE%3D--0bbc7b694ddc26c1c225eb50ac18b2232d294100; path=/; HttpOnly
+ Etag:
+ - "\"78556b001eadd8e658d5219148956316\""
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Date:
+ - Tue, 25 Feb 2014 14:16:26 GMT
+ body:
+ string: |
+
+
+ false
+ 0
+ 2014-02-25T14:16:26Z
+ 8
+ <%= id_question %>
+ 0
+
+ false
+ 1
+ <%= question_name %>
+ 0
+ true
+ 1
+
+ 2014-02-25T14:16:26Z
+ true
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 25 Feb 2014 14:16:26 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/<%=id_question%>.xml
+ body:
+ string: |
+
+
+ true
+ 0
+ 1
+ 1
+ true
+ true
+
+ 0
+ 8
+
+ 0
+ 0
+ <%= id_question %>
+ 1
+ <%= question_name %>
+ 1
+ 2014-02-25T14:16:26Z
+ true
+ <%= choices %>
+ 2014-02-25T14:16:26Z
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Connection:
+ - Keep-Alive
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Content-Type:
+ - application/xml; charset=utf-8
+ X-Runtime:
+ - "57"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlMjk3YzEwMDk0MzIwZmRiYWQwNDc3OTk4OTRkYWU1MTY%3D--f33badfd5f25126de46a042621203f8a3fb8df5b; path=/; HttpOnly
+ Cache-Control:
+ - no-cache
+ Date:
+ - Tue, 25 Feb 2014 14:16:26 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 25 Feb 2014 14:16:26 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_not_register_votes.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_not_register_votes.yml
new file mode 100644
index 0000000..cf8f1a4
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_not_register_votes.yml
@@ -0,0 +1,221 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml?creator_id=1&visitor_identifier=guest&with_appearance=true&with_prompt=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1064"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvImEvcXVlc3Rpb25zLzMueG1sP2NyZWF0b3JfaWQ9MSZ2aXNpdG9yX2lkZW50aWZpZXI9Z3Vlc3Qmd2l0aF9hcHBlYXJhbmNlPXRydWUmd2l0aF9wcm9tcHQ9dHJ1ZToPc2Vzc2lvbl9pZCIlY2ZjMmU2MmRlMjkyNDQyMDlmMGNmYzU4NDJkZmU5MDQ%3D--428dd8b3e0c6690f28d07b312de8fbf335eea099; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "156"
+ Etag:
+ - "\"317ba026722fb4381c030bcc1fa7f953\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:26 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ false
+ 1
+ Q1
+ 0
+ true
+ 1
+
+ 2014-03-18T13:53:25Z
+ true
+ 5
+ 0
+ 3
+ 7fb7e9aefb38b3ead7e75c87cbbc2e46
+ 11
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:26 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/prompts/11.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "559"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvcHJvbXB0cy8xMS54bWw6D3Nlc3Npb25faWQiJTk2ODk5Njg4MjRhNjNlNzYzMGQwNGFiNDUwZjFmNTE1--25da5da7ea058b396e345f68c3e58dbed76622f5; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "39"
+ Etag:
+ - "\"a3c909043cb826bc0f39faabc7471bcd\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:26 GMT
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:26Z
+ 11
+ 13
+ 3
+ 11
+
+ 2014-03-18T13:53:26Z
+ 0
+ New inactive choice
+ Choice 1
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:26 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/prompts/11.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "559"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvcHJvbXB0cy8xMS54bWw6D3Nlc3Npb25faWQiJThhYWM1YTQzMTczNzRjOGM2MmM2OTZmODZmNjE4ZjVj--93243b55accf34cc2f2f9917e08954e5e601a8d2; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "39"
+ Etag:
+ - "\"a3c909043cb826bc0f39faabc7471bcd\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:26 GMT
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:26Z
+ 11
+ 13
+ 3
+ 11
+
+ 2014-03-18T13:53:26Z
+ 0
+ New inactive choice
+ Choice 1
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:26 GMT
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/prompts/11/vote.xml?next_prompt%5Bvisitor_identifier%5D=guest-tester&next_prompt%5Bwith_appearance%5D=true&next_prompt%5Bwith_visitor_stats%5D=true&question_id=3&vote%5Bappearance_lookup%5D=&vote%5Bdirection%5D=left&vote%5Bvisitor_identifier%5D=guest-tester
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:26Z
+ 0
+ 11
+ 11
+ 13
+
+ New inactive choice
+ Choice 1
+ 2014-03-18T13:53:26Z
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 422
+ message: ""
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "450"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlYjIxZjkwY2Q5MDcxMjI2ZThhYmQ2MDljMDIzODViYWY%3D--bc3c89b56744d9adb9f647e3c233c8cbd5ca8cac; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "149"
+ Date:
+ - Tue, 18 Mar 2014 13:53:27 GMT
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:26Z
+ 11
+ 13
+ 3
+ 11
+
+ 2014-03-18T13:53:26Z
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:27 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_register_votes.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_register_votes.yml
new file mode 100644
index 0000000..3878319
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_register_votes.yml
@@ -0,0 +1,228 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml?creator_id=1&visitor_identifier=guest&with_appearance=true&with_prompt=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1064"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvImEvcXVlc3Rpb25zLzMueG1sP2NyZWF0b3JfaWQ9MSZ2aXNpdG9yX2lkZW50aWZpZXI9Z3Vlc3Qmd2l0aF9hcHBlYXJhbmNlPXRydWUmd2l0aF9wcm9tcHQ9dHJ1ZToPc2Vzc2lvbl9pZCIlYWMzZmU3ZDNhYmVkODZmZGYyNTYxYzRjN2RlNjY0YjM%3D--3a4f27f429286fc546a6e938019fa32fdb91b70f; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "82"
+ Etag:
+ - "\"7f078ba830c502f3e05c5572f949f4f4\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:27 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ false
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:25Z
+ true
+ 5
+ 0
+ 3
+ 7fb7e9aefb38b3ead7e75c87cbbc2e46
+ 11
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:27 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/prompts/11.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "559"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvcHJvbXB0cy8xMS54bWw6D3Nlc3Npb25faWQiJTc2NWY2ZmE2ZDZkZWZiZmI0YmM4NTI3ZDY2MWY5OTIx--8355c5afeb8191f3d3c86ebe80a4dccfdc44ae59; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "50"
+ Etag:
+ - "\"a3c909043cb826bc0f39faabc7471bcd\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:28 GMT
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:26Z
+ 11
+ 13
+ 3
+ 11
+
+ 2014-03-18T13:53:26Z
+ 0
+ New inactive choice
+ Choice 1
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:28 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/prompts/11.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "559"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvcHJvbXB0cy8xMS54bWw6D3Nlc3Npb25faWQiJWEyMjY5N2ZiZTVhNWUxMDMyZTM2NmU1OTdhM2Y0YmQ2--75d6ab708fef2f4eff3a1e27617bcdc0053dab4b; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "108"
+ Etag:
+ - "\"a3c909043cb826bc0f39faabc7471bcd\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:28 GMT
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:26Z
+ 11
+ 13
+ 3
+ 11
+
+ 2014-03-18T13:53:26Z
+ 0
+ New inactive choice
+ Choice 1
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:28 GMT
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/prompts/11/vote.xml?next_prompt%5Bvisitor_identifier%5D=guest-tester&next_prompt%5Bwith_appearance%5D=true&next_prompt%5Bwith_visitor_stats%5D=true&question_id=3&vote%5Bappearance_lookup%5D=7fb7e9aefb38b3ead7e75c87cbbc2e46&vote%5Bdirection%5D=left&vote%5Bvisitor_identifier%5D=guest-tester
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:26Z
+ 0
+ 11
+ 11
+ 13
+
+ New inactive choice
+ Choice 1
+ 2014-03-18T13:53:26Z
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "695"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlZjlhODY1NWQxMWE2ZTRlMGM0YzI0YTFmOGM4OGQ3M2Y%3D--51a238d54ad7d76107c9b3f27db3bbdd162edbb0; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "189"
+ Etag:
+ - "\"99bb2329ad4ffcb4a022ddcb352c151b\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:28 GMT
+ body:
+ string: |
+
+
+ 2014-03-18T13:53:27Z
+ 12
+ 11
+ 3
+ 13
+
+ 2014-03-18T13:53:27Z
+ 0
+ Choice 1
+ New inactive choice
+ 1
+ 37d36e84a28d6b9c2d7766e78b6c0128
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:28 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_correct_values.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_correct_values.yml
new file mode 100644
index 0000000..141b132
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_correct_values.yml
@@ -0,0 +1,61 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "956"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiVmNmNiMDRhYmE0NTJjMWUxY2QwZDU4ODJhMzA5ZDFmNA%3D%3D--5f5c2a5a6288a460a46ca282b0f0ab501c8b216f; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "38"
+ Etag:
+ - "\"136a4319c14522cafd554602fe195a14\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:29 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ false
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:25Z
+ true
+ 5
+ 1
+ 3
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:29 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_question.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_question.yml
new file mode 100644
index 0000000..cd807a3
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_question.yml
@@ -0,0 +1,61 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "956"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiViNDNhZjdhNzY0YTk5Yjg1YzMyOTcyYjM2YzExNGQwNg%3D%3D--43f1cfa66b564c94c154466e9076731ef1815293; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "101"
+ Etag:
+ - "\"136a4319c14522cafd554602fe195a14\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:29 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ false
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:25Z
+ true
+ 5
+ 1
+ 3
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:29 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_question_choices.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_question_choices.yml
new file mode 100644
index 0000000..c2c0cfc
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_retrieve_question_choices.yml
@@ -0,0 +1,199 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiVmZGM4OWFkYmRiMmFjYzg1MDJkZGNiNDMwNmQxM2JjOQ%3D%3D--bd186dd42dd0910a7b4a288ababa51e9fe89938c; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Content-Length:
+ - "955"
+ X-Runtime:
+ - "32"
+ Connection:
+ - Keep-Alive
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Etag:
+ - "\"02fabf29f70655795720421eaeb60eff\""
+ Date:
+ - Tue, 18 Mar 2014 14:03:30 GMT
+ body:
+ string: |
+
+
+ true
+ 4
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ true
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:30Z
+ true
+ 6
+ 1
+ 4
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:03:30 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJWM5ODM4YWI1YTY4MGM1NzkyYTA4NzZiMDRmZTdiNTNh--cbd780784d8f3de7a81dcf7c4c8006349f97dc21; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Content-Length:
+ - "1523"
+ X-Runtime:
+ - "105"
+ Connection:
+ - Keep-Alive
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Etag:
+ - "\"eeca0792e33b8baef6a91a806cbe6a37\""
+ Date:
+ - Tue, 18 Mar 2014 14:03:30 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice Changes
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T14:00:51Z
+ New Choice
+ 16
+ 0
+ 50.0
+ 0
+ true
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice Renamed
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:03:30 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTFkYTY1YTI4YzJhZGVhMjcwODM4YjBkYmE5MWM3MTU1--357b1dcc8c88cdcee7b6c6df9dd22113282f690b; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Content-Length:
+ - "1523"
+ X-Runtime:
+ - "35"
+ Connection:
+ - Keep-Alive
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Etag:
+ - "\"eeca0792e33b8baef6a91a806cbe6a37\""
+ Date:
+ - Tue, 18 Mar 2014 14:03:31 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ Choice 1
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:03:31 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_toggle_autactivate_ideas.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_toggle_autactivate_ideas.yml
new file mode 100644
index 0000000..f42b9ee
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_toggle_autactivate_ideas.yml
@@ -0,0 +1,121 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "956"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiVlMDU4ZjNiMWMyMjdhYjc3NzM1MDY3ZDA0Yjk5MjQwOA%3D%3D--b459f53957ba48ab323b64547a1388ccc21519ae; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "38"
+ Etag:
+ - "\"136a4319c14522cafd554602fe195a14\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:30 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ <%= autoactivateidea %>
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:25Z
+ true
+ 5
+ 1
+ 3
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:30 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:23Z
+ true
+ 0
+ 1
+ <%= autoactivateidea %>
+
+ 3
+ true
+ 4
+
+ 0
+ 1
+ Q1
+ true
+ 0
+ 1
+ 1
+ 2014-03-18T13:53:23Z
+ Choice 1
+ Choice 2
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlYTUxYWFkMjI3YmU5OTJkNzUzNmQyZTIyMWFmMjY1ODE%3D--5a099c1625bf09a2f0dbfccf7ac4ccf70ab7f15f; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "46"
+ Date:
+ - Tue, 18 Mar 2014 13:53:30 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:30 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_choice.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_choice.yml
new file mode 100644
index 0000000..6f1073d
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_choice.yml
@@ -0,0 +1,309 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1164"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJWQ2OGI0OGY2OTQxNTQyMDczODA0NWZlMjQ5Y2IzZThi--4aa8834cf7ce8aef4d9cba1b0865112eeb431fd2; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "36"
+ Etag:
+ - "\"69f5a8090e05f8f10004245d647cd2dc\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:33 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice Renamed
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:33 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/13.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1060"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvY2hvaWNlcy8xMy54bWw6D3Nlc3Npb25faWQiJTBiMzRmOGNmM2UwYmM2NDI1NmYwOTI5YjQxY2E5MGQ0--8c662ffceec610d8e1fa5cc84e326d54785349f1; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "29"
+ Etag:
+ - "\"3bfe38df8adc8b51f7668b6bd9b7fac8\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:33 GMT
+ body:
+ string: |
+
+
+ true
+ 2014-03-18T13:53:24Z
+ 4
+ New inactive choice
+ 13
+
+ 1
+ 0
+
+
+ 0
+ 1
+ 1
+ 3
+
+
+ 66.6666666666667
+
+ 2014-03-18T13:53:28Z
+ 2
+ 1
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:33 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/13.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:28Z
+ true
+ 1
+
+ 2
+
+
+ 1
+ 13
+ New inactive choice Changes
+ 0
+ 4
+ 66.6666666666667
+
+
+ 1
+
+ 2014-03-18T13:53:24Z
+ 1
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlYWY5MTQ0ODk4ZjFiZTQyMGQ1YjA4OWYzZGQ4ZGM0Nzg%3D--6e7bebf904ab8d762617352a3d8f4714b992a6d6; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "71"
+ Date:
+ - Tue, 18 Mar 2014 13:53:33 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:33 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "955"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiU2ZTMzYzY4NDQwNGVkY2MzZmM4ZmE3YjlkODJjYjE5ZA%3D%3D--e9058c1f1929399cd13aa89dc7ccfbb9dcacfa71; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "35"
+ Etag:
+ - "\"6cf98e7e9708e9d7badfffd9accdc061\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:33 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ true
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:30Z
+ true
+ 6
+ 1
+ 3
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:33 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/13.xml?include_inactive=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1068"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjYvcXVlc3Rpb25zLzMvY2hvaWNlcy8xMy54bWw%2FaW5jbHVkZV9pbmFjdGl2ZT10cnVlOg9zZXNzaW9uX2lkIiUwMzFkMGRiYzIzZmFkZmVlYWRjMTJmYWI1ZjQ2Y2QwMg%3D%3D--737cab737a413d46b798135bc710f5f3aa4dadbe; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "92"
+ Etag:
+ - "\"fa59c6db820376f577981a0439ec0544\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:33 GMT
+ body:
+ string: |
+
+
+ true
+ 2014-03-18T13:53:24Z
+ 4
+ New inactive choice Changes
+ 13
+
+ 1
+ 0
+
+
+ 0
+ 1
+ 1
+ 3
+
+
+ 66.6666666666667
+
+ 2014-03-18T13:53:33Z
+ 3
+ 1
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:33 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_choice_text.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_choice_text.yml
new file mode 100644
index 0000000..0fdaa7f
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_choice_text.yml
@@ -0,0 +1,387 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1158"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTA2MzFlYTI5MjNhYzVkNDdjMWE0NDAxMDdhYTkyM2M2--e6dda2b61067b8850f33c271d3b5053f3ef24b35; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "94"
+ Etag:
+ - "\"36c2be193a2606eea188bd73a67bf117\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:30 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 1
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:30 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/11.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1059"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIiAvcXVlc3Rpb25zLzMvY2hvaWNlcy8xMS54bWw6D3Nlc3Npb25faWQiJTAwM2U5NmEzYjI2ZTg5ODdkOTA1ZjBhNzJjZDgyZjZj--dbb3296e74f765aff28204bf6156ecd076dc52d1; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "26"
+ Etag:
+ - "\"8a0260eef9947c322ecf01a42b14b856\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:30 GMT
+ body:
+ string: |
+
+
+ true
+ 2014-03-18T13:53:23Z
+ 4
+ Choice 1
+ 11
+
+
+ 1
+
+
+ 0
+ 1
+ 1
+ 3
+
+
+ 33.3333333333333
+
+ 2014-03-18T13:53:28Z
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:30 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices/11.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:28Z
+ true
+ 0
+
+ 1
+
+
+ 1
+ 11
+ Choice Renamed
+ 1
+ 4
+ 33.3333333333333
+
+
+
+
+ 2014-03-18T13:53:23Z
+ 1
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlYjA2MDMzOGI1NjMzZjc3ODVjM2E1MWM3OTJhNDVjOWM%3D--530dcfc4c8732f518002a28d1c38e0ef350e8e37; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "80"
+ Date:
+ - Tue, 18 Mar 2014 13:53:31 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:31 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "955"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiU4NjQyMGVhYWI5MTliYWJhZWM5ZGNkY2EyZTVjYjk1Nw%3D%3D--7268c2bbdf6f9d714be4207b2a6fd346525d7756; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "102"
+ Etag:
+ - "\"6cf98e7e9708e9d7badfffd9accdc061\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:31 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ true
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:30Z
+ true
+ 6
+ 1
+ 3
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:31 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1164"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTE2Mzk3ZDE2ZTA3ZDI1ZjhmNDAwNDFjMGY4ZDliYTM0--8d386baca8871c626d42619ec7315b5e17ff11b0; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "32"
+ Etag:
+ - "\"69f5a8090e05f8f10004245d647cd2dc\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:31 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice Renamed
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:31 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1164"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTQ2MjBiZDg0NjRkZjU3MjZjYWFlOTIxNzA2MGYxYzUx--96772cc727d52444b69fad3eef54958acd9e3537; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "36"
+ Etag:
+ - "\"69f5a8090e05f8f10004245d647cd2dc\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:31 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice Renamed
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:31 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_question.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_question.yml
new file mode 100644
index 0000000..39d0ae4
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/pairwise_update_question.yml
@@ -0,0 +1,305 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions.xml
+ body:
+ string: |
+
+
+ Question 1
+ 1
+ 1
+ Choice 1
+ Choice 2
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "921"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlNDU1ZTU4YjczNTAwZThkNzE1ODdkZTU2N2FlODg2OWE%3D--dccbf4094db2e7726c7a7bd6d723687c0f94c550; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "142"
+ Etag:
+ - "\"e10a4ecad2ee796de647436a5d754335\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:32 GMT
+ body:
+ string: |
+
+
+ false
+ 0
+ 2014-03-18T13:53:31Z
+ 4
+ 4
+ 0
+
+ false
+ 1
+ Question 1
+ 0
+ true
+ 1
+
+ 2014-03-18T13:53:31Z
+ true
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:32 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/4.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:31Z
+ true
+ 0
+ 1
+ true
+
+ 4
+ true
+ 4
+
+ 0
+ 1
+ Question 1
+ true
+ 0
+ 1
+ 1
+ 2014-03-18T13:53:31Z
+ Choice 1
+ Choice 2
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlMDQ0YmY1ZGZlMmY1OWUxYTZlM2RkNTM2OTI1MTUwOGM%3D--1038ef2e280bcada953209be557c671d4ac8f9bc; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "53"
+ Date:
+ - Tue, 18 Mar 2014 13:53:32 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:32 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/4.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "963"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzQueG1sOg9zZXNzaW9uX2lkIiVmMTE3MzE0MjZkZWIzMTA0ZDc2OWUyMmUwY2I1ZmJkMw%3D%3D--931b245e8287eeedaf868537dd26d15dac62d12a; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "99"
+ Etag:
+ - "\"47502300372faf4e6c7b5e523025c7a6\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:32 GMT
+ body:
+ string: |
+
+
+ true
+ 2
+ 2014-03-18T13:53:31Z
+ 4
+ 4
+ 0
+
+ true
+ 1
+ Question 1
+ 0
+ true
+ 1
+
+ 2014-03-18T13:53:32Z
+ true
+ 2
+ 0
+ 2
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:32 GMT
+- request:
+ method: put
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/4.xml
+ body:
+ string: |
+
+
+ 0
+ 2014-03-18T13:53:32Z
+ true
+ 0
+ 2
+ true
+ 4
+
+ true
+ 4
+ 2
+
+ New name
+ 2
+ 1
+ true
+ 1
+ 0
+ 2014-03-18T13:53:31Z
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlOWQ0MmMyMDU2ZTg2ZmMxNWJiMWJjOGFmZjU0YzEzMGQ%3D--65e0d4ebabdef5ab35424b49d7d3ba053043bec4; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - no-cache
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "45"
+ Date:
+ - Tue, 18 Mar 2014 13:53:32 GMT
+ body:
+ string: " "
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:32 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/4.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "961"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzQueG1sOg9zZXNzaW9uX2lkIiVmY2M2YmRkYzIyN2Y4NjdjODlkMzIyMGZjZDEwZWFiZA%3D%3D--69aae7ad54982192c7c145ab10d9d31f2f76e85a; path=/; HttpOnly
+ Content-Type:
+ - application/xml; charset=utf-8
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Connection:
+ - Keep-Alive
+ X-Runtime:
+ - "36"
+ Etag:
+ - "\"0fee6a1f73a2c0d5bceb2e041fcb913d\""
+ Date:
+ - Tue, 18 Mar 2014 13:53:32 GMT
+ body:
+ string: |
+
+
+ true
+ 2
+ 2014-03-18T13:53:31Z
+ 4
+ 4
+ 0
+
+ true
+ 1
+ New name
+ 0
+ true
+ 1
+
+ 2014-03-18T13:53:32Z
+ true
+ 3
+ 0
+ 2
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 13:53:32 GMT
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/question_contributors.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/question_contributors.yml
new file mode 100644
index 0000000..cc9c8ef
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/question_contributors.yml
@@ -0,0 +1,180 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ X-Runtime:
+ - "34"
+ Etag:
+ - "\"39313ba95b65cb4e2d34f30b0a5bd2f8\""
+ Content-Type:
+ - application/xml; charset=utf-8
+ Content-Length:
+ - "955"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiVjNDJlNjkyMGMxOWVkYWYxNTMzMTI2YTZmNjIyODA1NQ%3D%3D--94c39b83716120a25177673b0a21d788dd4af36c; path=/; HttpOnly
+ Date:
+ - Wed, 19 Mar 2014 18:46:05 GMT
+ Connection:
+ - Keep-Alive
+ body:
+ string: |
+
+
+ true
+ 9
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ true
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:30Z
+ true
+ 6
+ 1
+ 9
+
+
+ http_version:
+ recorded_at: Wed, 19 Mar 2014 18:46:05 GMT
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: |
+
+
+ 1
+ New Choice
+ John Travolta
+
+
+ headers:
+ Content-Type:
+ - application/xml
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 201
+ message: "Created "
+ headers:
+ Cache-Control:
+ - no-cache
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ X-Runtime:
+ - "157"
+ Content-Type:
+ - application/xml; charset=utf-8
+ Content-Length:
+ - "1039"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlM2FhODAxMDFkZmUwZDJmMTgyYjNkNGZjMzEzOTQ0ZTM%3D--0cde22913ec32bc420cafc0e60a84bfd45878c00; path=/; HttpOnly
+ Date:
+ - Wed, 19 Mar 2014 18:46:05 GMT
+ Location:
+ - http://localhost:3030/questions/3/choices/40
+ Connection:
+ - Keep-Alive
+ body:
+ string: |
+
+
+ true
+ 2014-03-19T18:46:05Z
+ 5
+ New Choice
+ 40
+
+ 1
+ 0
+
+
+ 0
+ 0
+ 0
+ 3
+
+
+ 50.0
+
+ 2014-03-19T18:46:05Z
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Wed, 19 Mar 2014 18:46:05 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/visitors.xml?ideas_count=1&page=1&question_id=3
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ X-Runtime:
+ - "107"
+ Etag:
+ - "\"5252e9c48a1957fab7084271c0aed768\""
+ Content-Type:
+ - application/xml; charset=utf-8
+ Content-Length:
+ - "527"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjUvdmlzaXRvcnMueG1sP2lkZWFzX2NvdW50PTEmcGFnZT0xJnF1ZXN0aW9uX2lkPTM6D3Nlc3Npb25faWQiJTNhMzQyOTUyMzY0ZWE4MjA0MzlhNmZjOTY4M2Y5MGRk--215ec52c7edd5d155e2c6cb59c37aadea69c0d65; path=/; HttpOnly
+ Date:
+ - Wed, 19 Mar 2014 18:46:06 GMT
+ Connection:
+ - Keep-Alive
+ body:
+ string: |
+
+
+
+
+ 2014-03-18T13:48:45Z
+ 5
+ 7
+ John Travolta
+ 1
+
+ 2014-03-18T13:48:45Z
+
+
+
+
+ http_version:
+ recorded_at: Wed, 19 Mar 2014 18:46:06 GMT
+recorded_with: VCR 2.8.0
diff --git a/plugins/pairwise/test/fixtures/vcr_cassettes/record_choice_creator.yml b/plugins/pairwise/test/fixtures/vcr_cassettes/record_choice_creator.yml
new file mode 100644
index 0000000..aa1040c
--- /dev/null
+++ b/plugins/pairwise/test/fixtures/vcr_cassettes/record_choice_creator.yml
@@ -0,0 +1,357 @@
+---
+recorded_with: VCR 2.8.0
+http_interactions:
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ X-Runtime:
+ - "35"
+ Content-Type:
+ - application/xml; charset=utf-8
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"4b2d620734a664b36d31db9fcd8e4297\""
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1172"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIh0vcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw6D3Nlc3Npb25faWQiJTM4N2YwYTliMDFhODJhY2ZjOGRjM2E0ZmQ2ZjQwMWIy--fae08f96d043b11de376a04f238f7b8c1f0f3c3f; path=/; HttpOnly
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Date:
+ - Tue, 18 Mar 2014 14:00:50 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice Changes
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice Renamed
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:00:50 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3.xml
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ X-Runtime:
+ - "32"
+ Content-Type:
+ - application/xml; charset=utf-8
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"6cf98e7e9708e9d7badfffd9accdc061\""
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "955"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIhUvcXVlc3Rpb25zLzMueG1sOg9zZXNzaW9uX2lkIiVjMmMyNjI3ZDEwYTVkZWY2YTM2ZWMxM2U5YmFiMmIzNg%3D%3D--eb2d4a800975312d07663ff97eff315d887e65b6; path=/; HttpOnly
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Date:
+ - Tue, 18 Mar 2014 14:00:51 GMT
+ body:
+ string: |
+
+
+ true
+ 3
+ 2014-03-18T13:53:23Z
+ 4
+ 3
+ 0
+
+ true
+ 1
+ Q1
+ 2
+ true
+ 1
+
+ 2014-03-18T13:53:30Z
+ true
+ 6
+ 1
+ 3
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:00:51 GMT
+- request:
+ method: post
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml
+ body:
+ string: |
+
+
+ 1
+ New Choice
+ John Travolta
+
+
+ headers:
+ Accept:
+ - "*/*"
+ Content-Type:
+ - application/xml
+ response:
+ status:
+ code: 201
+ message: "Created "
+ headers:
+ X-Runtime:
+ - "159"
+ Content-Type:
+ - application/xml; charset=utf-8
+ Connection:
+ - Keep-Alive
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1039"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BjoPc2Vzc2lvbl9pZCIlMGQzMGVkYWY2NjFmYmQ3YWE4Mzg1NGU5NzNkNzhkYmU%3D--5d712da68957bb74bf36d1b58e7b298953114fbe; path=/; HttpOnly
+ Cache-Control:
+ - no-cache
+ Date:
+ - Tue, 18 Mar 2014 14:00:51 GMT
+ Location:
+ - http://localhost:3030/questions/3/choices/16
+ body:
+ string: |
+
+
+ true
+ 2014-03-18T14:00:51Z
+ 5
+ New Choice
+ 16
+
+ 1
+ 0
+
+
+ 0
+ 0
+ 0
+ 3
+
+
+ 50.0
+
+ 2014-03-18T14:00:51Z
+ 1
+ 0
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:00:51 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml?include_inactive=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ X-Runtime:
+ - "43"
+ Content-Type:
+ - application/xml; charset=utf-8
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"eeca0792e33b8baef6a91a806cbe6a37\""
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1523"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjMvcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw%2FaW5jbHVkZV9pbmFjdGl2ZT10cnVlOg9zZXNzaW9uX2lkIiUwZDZjOWVhZWRjN2I0ZDRmZThjYTVhMmU4M2NmNWM3ZQ%3D%3D--5e669c225a5fe59e510aa3fab3271452f3339e98; path=/; HttpOnly
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Date:
+ - Tue, 18 Mar 2014 14:00:51 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice Changes
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T14:00:51Z
+ New Choice
+ 16
+ 0
+ 50.0
+ 0
+ true
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice Renamed
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:00:51 GMT
+- request:
+ method: get
+ uri: http://abner.oliveira%40serpro.gov.br:serpro@localhost:3030/questions/3/choices.xml?include_inactive=true
+ body:
+ string: ""
+ headers:
+ Accept:
+ - application/xml
+ response:
+ status:
+ code: 200
+ message: "OK "
+ headers:
+ X-Runtime:
+ - "40"
+ Content-Type:
+ - application/xml; charset=utf-8
+ Connection:
+ - Keep-Alive
+ Etag:
+ - "\"eeca0792e33b8baef6a91a806cbe6a37\""
+ Server:
+ - WEBrick/1.3.1 (Ruby/1.8.7/2013-06-27)
+ Content-Length:
+ - "1523"
+ Set-Cookie:
+ - _rebirth_session_key=BAh7BzoOcmV0dXJuX3RvIjMvcXVlc3Rpb25zLzMvY2hvaWNlcy54bWw%2FaW5jbHVkZV9pbmFjdGl2ZT10cnVlOg9zZXNzaW9uX2lkIiVlMmNkNjUwNGUyMTA0Y2JhODQwMGQ4Yzc1NmYwNGI1Ng%3D%3D--0f22b4c9da5493e370bbcfaa2d5510b050652705; path=/; HttpOnly
+ Cache-Control:
+ - private, max-age=0, must-revalidate
+ Date:
+ - Tue, 18 Mar 2014 14:00:51 GMT
+ body:
+ string: |
+
+
+
+ true
+ 2014-03-18T13:53:24Z
+ New inactive choice Changes
+ 13
+ 0
+ 66.6666666666667
+ 1
+ false
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice 2
+ 12
+ 0
+ 50.0
+ 0
+ false
+
+
+ true
+ 2014-03-18T14:00:51Z
+ New Choice
+ 16
+ 0
+ 50.0
+ 0
+ true
+
+
+ true
+ 2014-03-18T13:53:23Z
+ Choice Renamed
+ 11
+ 1
+ 33.3333333333333
+ 0
+ false
+
+
+
+ http_version:
+ recorded_at: Tue, 18 Mar 2014 14:00:51 GMT
diff --git a/plugins/pairwise/test/functional/profile/pairwise_plugin_profile_controller_test.rb b/plugins/pairwise/test/functional/profile/pairwise_plugin_profile_controller_test.rb
new file mode 100644
index 0000000..d5741d5
--- /dev/null
+++ b/plugins/pairwise/test/functional/profile/pairwise_plugin_profile_controller_test.rb
@@ -0,0 +1,238 @@
+require 'test_helper'
+
+require "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/pairwise_content_fixtures"
+
+class PairwisePluginProfileControllerTest < ActionController::TestCase
+
+ def pairwise_env_settings
+ { :api_host => "http://localhost:3030/",
+ :username => "abner.oliveira@serpro.gov.br",
+ :password => "serpro"
+ }
+ end
+
+ def setup
+ @environment = Environment.default
+
+ @pairwise_client = Pairwise::Client.build(1, pairwise_env_settings)
+ @controller = PairwisePluginProfileController.new
+ @request = ActionController::TestRequest.new
+ @response = ActionController::TestResponse.new
+
+ @profile = fast_create(Community, :environment_id => @environment.id)
+ @question = PairwiseContentFixtures.pairwise_question_with_prompt
+ @user = create_user('testinguser').person
+ @profile.add_admin(@user)
+ @content = PairwiseContentFixtures.pairwise_content
+
+ @content.expects(:new_record?).returns(true).at_least_once
+ @content.expects(:valid?).returns(true).at_least_once
+ @content.expects(:send_question_to_service).returns(true).at_least_once
+ @profile.articles << @content
+ end
+
+ should 'get a first prompt' do
+ login_as(@user.user.login)
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content)
+ @content.expects(:question_with_prompt_for_visitor).with(@user.identifier, nil).returns(@question)
+ get :prompt,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id
+ assert_not_nil assigns(:pairwise_content)
+ assert_match /#{@question.name}/, @response.body
+ assert_match /#{@question.prompt.left_choice_text}/, @response.body
+ assert_match /#{@question.prompt.right_choice_text}/, @response.body
+ end
+
+ should 'get a prompt by a prompt id' do
+ login_as(@user.user.login)
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content)
+ @content.expects(:question_with_prompt_for_visitor).with(@user.identifier, @question.prompt.id.to_s).returns(@question)
+ get :prompt,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id,
+ :prompt_id => @question.prompt.id
+
+ assert_not_nil assigns(:pairwise_content)
+
+ assert_match /#{@question.name}/, @response.body
+ assert_match /#{@question.prompt.left_choice_text}/, @response.body
+ assert_match /#{@question.prompt.right_choice_text}/, @response.body
+ end
+
+ should 'register a vote' do
+ login_as(@user.user.login)
+ #next prompt will have id = 33
+ next_prompt_id = 33
+ vote = {
+ 'prompt' => {
+ "id" => next_prompt_id,
+ "left_choice_id" => 3,
+ "left_choice_test" => "Option 3",
+ "right_choice_id" => 4,
+ "right_choice_text" => "Option 4"
+ }
+ }
+ @content.expects(:vote_to).with(@question.prompt.id.to_s, 'left', @user.identifier, @question.appearance_id).returns(vote).at_least_once
+ #@content.expects(:question_with_prompt_for_visitor).with(@user.identifier, nil).returns(@question).at_least_once
+
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content).at_least_once
+
+ get :choose,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id,
+ :prompt_id => @question.prompt.id,
+ :appearance_id => @question.appearance_id,
+ :direction => 'left'
+ assert_response :redirect
+ assert_redirected_to @content.url
+ end
+
+ should 'show new ideas elements when new ideas were allowed' do
+ login_as(@user.user.login)
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content)
+ get :prompt,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id,
+ :prompt_id => @question.prompt.id
+ assert_not_nil assigns(:pairwise_content)
+
+ assert_select "div[class='suggestion_form']", 1
+ assert_select "div#suggestions_box", 1
+ end
+
+ should 'not show new ideas elements when new ideas were not allowed' do
+ login_as(@user.user.login)
+ @content.allow_new_ideas = false
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content)
+ get :prompt,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id,
+ :prompt_id => @question.prompt.id
+ assert_not_nil assigns(:pairwise_content)
+
+ assert_select "div[class='suggestion_form']", 0
+ assert_select "div#suggestions_box", 0
+ end
+
+ should 'skip prompt' do
+ login_as @user.user.login
+ next_prompt_id = 33
+ next_prompt = {
+ 'prompt' => {
+ "id" => next_prompt_id,
+ "left_choice_id" => 3,
+ "left_choice_test" => "Option 3",
+ "right_choice_id" => 4,
+ "right_choice_text" => "Option 4"
+ }
+ }
+ @content.expects(:skip_prompt).with(@question.prompt.id.to_s, @user.identifier, @question.appearance_id, 'some reason').returns(next_prompt).at_least_once
+ #@content.expects(:question_with_prompt_for_visitor).with(@user.identifier, nil).returns(@question).at_least_once
+
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content).at_least_once
+ get :skip_prompt,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id,
+ :prompt_id => @question.prompt.id,
+ :appearance_id => @question.appearance_id,
+ :reason => 'some reason'
+ assert_not_nil assigns(:pairwise_content)
+
+ assert_response :redirect
+ assert_redirected_to @content.url
+ end
+
+ should 'fail to skip prompt if prompt_id param is missing' do
+ login_as @user.user.login
+ next_prompt_id = 33
+ next_prompt = {
+ 'prompt' => {
+ "id" => next_prompt_id,
+ "left_choice_id" => 3,
+ "left_choice_test" => "Option 3",
+ "right_choice_id" => 4,
+ "right_choice_text" => "Option 4"
+ }
+ }
+ exception = assert_raises RuntimeError do
+ get :skip_prompt,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id,
+ :appearance_id => @question.appearance_id,
+ :reason => 'some reason'
+ end
+ assert_equal _("Invalid request"), exception.message
+ end
+
+ should 'fail to skip appearance_id param is missing' do
+ login_as @user.user.login
+ next_prompt_id = 33
+ next_prompt = {
+ 'prompt' => {
+ "id" => next_prompt_id,
+ "left_choice_id" => 3,
+ "left_choice_test" => "Option 3",
+ "right_choice_id" => 4,
+ "right_choice_text" => "Option 4"
+ }
+ }
+ exception = assert_raises RuntimeError do
+ get :skip_prompt,
+ :profile => @profile.identifier,
+ :id => @content.id,
+ :question_id => @question.id,
+ :prompt_id => @question.prompt.id,
+ :reason => 'some reason'
+ end
+ assert_equal _("Invalid request"), exception.message
+ end
+
+ should 'show result to non logged user' do
+ @question.expects(:get_choices).returns(PairwiseContentFixtures.choices_with_stats).at_least_once
+ PairwisePlugin::PairwiseContent.any_instance.expects(:question).returns(@question).at_least_once
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content).at_least_once
+
+ get :result, :profile => @profile.identifier,
+ :id => @content.id, :question_id => @question.id
+
+ assert_select "div[class='total_votes']", 1
+ end
+
+ should 'show result to logged user' do
+ login_as(@user.user.login)
+ @question.expects(:get_choices).returns(PairwiseContentFixtures.choices_with_stats).at_least_once
+ PairwisePlugin::PairwiseContent.any_instance.expects(:question).returns(@question).at_least_once
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content).at_least_once
+
+ get :result, :profile => @profile.identifier,
+ :id => @content.id, :question_id => @question.id
+
+ assert_select "div[class='total_votes']", 1
+ end
+
+ should 'suggest new idea' do
+ login_as(@user.user.login)
+
+ PairwisePluginProfileController.any_instance.expects(:find_content).returns(@content).at_least_once
+ @content.expects(:add_new_idea).returns(true).at_least_once
+
+ post :suggest_idea, :id => @content.id, :profile => @profile.identifier, :idea => {:text => "NEW IDEA"}
+
+ assert_redirected_to @content.url
+ assert_equal "Thanks for your contributtion!", flash[:notice]
+ end
+
+ should 'not accept ideas from not logged users' do
+ post :suggest_idea, :id => @content.id, :profile => @profile.identifier, :idea => {:text => "NEW IDEA"}
+ assert_redirected_to @content.url
+ assert_equal "Only logged user could suggest new ideas", flash[:error]
+ end
+end
diff --git a/plugins/pairwise/test/unit/pairwise/client_test.rb b/plugins/pairwise/test/unit/pairwise/client_test.rb
new file mode 100644
index 0000000..016ebd7
--- /dev/null
+++ b/plugins/pairwise/test/unit/pairwise/client_test.rb
@@ -0,0 +1,176 @@
+require "test_helper"
+
+require 'vcr'
+
+VCR.configure do |c|
+ c.cassette_library_dir = "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/vcr_cassettes"
+ c.hook_into :webmock
+end
+
+class Pairwise::ClientTest < ActiveSupport::TestCase
+ def setup
+ pairwise_env_settings = { :api_host => "http://localhost:3030/",
+ :username => "abner.oliveira@serpro.gov.br",
+ :password => "serpro"
+ }
+ @client = Pairwise::Client.build('1', pairwise_env_settings)
+ @choices = "Choice 1\nChoice 2"
+
+ VCR.use_cassette('pairwise_create_question') do
+ @question = @client.create_question('Q1', @choices)
+ end
+
+ end
+
+ should 'create an new question in pairwise service' do
+ assert_not_nil @question.id
+ end
+
+ should 'update a question' do
+ VCR.use_cassette('pairwise_update_question') do
+ @question_to_be_changed = @client.create_question('Question 1', @choices)
+ @client.update_question(@question_to_be_changed.id, "New name")
+ assert_equal "New name", @client.find_question_by_id(@question_to_be_changed.id).name
+ end
+ end
+
+ should "add new choice to a question" do
+ VCR.use_cassette('pairwise_add_new_choice') do
+ assert_equal 2, @question.get_choices.size
+ end
+ end
+ should 'record that an user created the choice' do
+ VCR.use_cassette('record_choice_creator') do
+ assert_equal 3, @question.get_choices.size
+ @client.add_choice(@question.id, 'New Choice', 'John Travolta')
+ assert_equal 4, @question.choices_include_inactive.size
+ created_choice = @question.choices_include_inactive[2]
+ assert_equal true, created_choice.user_created
+ end
+ end
+
+ should 'update a choice text' do
+ VCR.use_cassette('pairwise_update_choice_text') do
+ choice = @question.get_choice_with_text("Choice 1")
+ assert_not_nil choice
+ @client.update_choice(@question, choice.id, 'Choice Renamed', true)
+ @question_after_change = @client.find_question_by_id(@question.id)
+ assert @question_after_change.has_choice_with_text?("Choice Renamed"), "Choice not found"
+ assert ! @question_after_change.has_choice_with_text?("Choice 1"), "Choice 1 should not exist"
+ end
+ end
+
+ should 'not allow change choice to a blank value' do
+ VCR.use_cassette('pairwise_blank_value') do
+ choice = @question.get_choice_with_text("Choice 1")
+ assert_not_nil choice
+ exception = assert_raises Pairwise::Error do
+ @client.update_choice(@question, choice.id, '', true)
+ end
+ assert_equal "Empty choice text", exception.message
+ end
+ end
+
+
+ should 'retrieve question from service' do
+ VCR.use_cassette('pairwise_retrieve_question') do
+ @question_retrieved = @client.find_question_by_id(@question.id)
+ assert_not_nil @question_retrieved
+ assert_equal @question.id, @question_retrieved.id
+ end
+ end
+
+ should 'retrieve question with values correct attributes values' do
+ VCR.use_cassette('pairwise_retrieve_correct_values') do
+ @question_retrieved = @client.find_question_by_id(@question.id)
+ assert_equal "Q1", @question_retrieved.name
+ end
+ end
+
+ should 'retrieve question choices' do
+ VCR.use_cassette('pairwise_retrieve_question_choices') do
+ @question_retrieved = @client.find_question_by_id(@question.id)
+ assert_not_nil @question_retrieved.choices
+ @question_retrieved.choices.each do | choice |
+ assert @choices.include?(choice.data), "Choice #{choice} not found in question retrieved"
+ end
+ end
+ end
+
+ should 'register votes' do
+ VCR.use_cassette('pairwise_register_votes') do
+ @question = @client.question_with_prompt(@question.id)
+ assert_not_nil @question.prompt
+ vote = @client.vote(@question.id, @question.prompt.id, 'left', 'guest-tester', @question.appearance_id)
+
+ assert vote.is_a?(Hash)
+ assert_not_nil vote["prompt"], "Next prompt hash expected"
+ assert_not_nil vote["prompt"]["id"], "Next prompt id expected"
+ assert_not_nil vote["prompt"]["question_id"], "question_id expected"
+ assert_not_nil vote["prompt"]["appearance_id"], "appearance_id expected"
+ assert_not_nil vote["prompt"]["left_choice_text"], "left_choice_text expected"
+ assert_not_nil vote["prompt"]["right_choice_text"], "right_choice_text expected"
+ end
+ end
+
+ should 'not register votes when appearance_id is missing' do
+ VCR.use_cassette('pairwise_not_register_votes') do
+ @question = @client.question_with_prompt(@question.id)
+ assert_not_nil @question.prompt
+ exception = assert_raises Pairwise::Error do
+ @client.vote(@question.id, @question.prompt.id, 'left', 'guest-tester')
+ end
+ assert_equal "Vote not registered. Please check if all the necessary parameters were passed.", exception.message
+ end
+ end
+
+ should 'approve choice' do
+ VCR.use_cassette('pairwise_approve_choice') do
+ @client.toggle_autoactivate_ideas(@question, false)
+ choice = @client.add_choice(@question.id, 'New inactive choice')
+ assert_equal 1, (@question.choices_include_inactive - @question.choices).size
+ @client.approve_choice(@question, choice.id)
+ assert_equal 0, (@question.choices_include_inactive - @question.choices).size
+ assert_equal 3, @question.choices.size
+ end
+ end
+
+ should 'update choice' do
+ VCR.use_cassette('pairwise_update_choice') do
+ choice = @question.get_choices.first
+ new_choice_text = choice.data + " Changes"
+ assert_equal true, @client.update_choice(@question, choice.id, choice.data + " Changes", true)
+ assert_equal new_choice_text, @client.find_question_by_id(@question.id).find_choice(choice.id).data
+ end
+ end
+
+ should 'return users whom suggested ideas' do
+ #Rails.logger.level = :debug # at any time
+ #ActiveResource::Base.logger = Logger.new(STDERR)
+ VCR.use_cassette('question_contributors') do
+ @client.add_choice(@question.id, 'New Choice', 'John Travolta')
+ assert_equal 1, @question.get_ideas_contributors().size
+ end
+ end
+
+ should 'toggle autoactivate ideas' do
+ VCR.use_cassette('pairwise_toggle_autactivate_ideas', :erb => {:autoactivateidea => false}) do
+ assert_equal false, @client.find_question_by_id(@question.id).it_should_autoactivate_ideas
+ @client.toggle_autoactivate_ideas(@question, true)
+ end
+
+ VCR.use_cassette('pairwise_toggle_autactivate_ideas', :erb => {:autoactivateidea => true}) do
+ assert_equal true, @client.find_question_by_id(@question.id).it_should_autoactivate_ideas
+ end
+ end
+
+ should 'flag a choice as reproved' do
+ VCR.use_cassette('flag_choice_as_reproved') do
+ question = @client.find_question_by_id 6
+ choices_waiting_approval = question.pending_choices
+ assert choices_waiting_approval.count > 0, "Expected to find a inactive choice here"
+ @client.flag_choice(question, choices_waiting_approval.first.id, 'reproved')
+ assert_equal 0, question.pending_choices.count
+ end
+ end
+end
\ No newline at end of file
diff --git a/plugins/pairwise/test/unit/pairwise_plugin/choices_related_test.rb b/plugins/pairwise/test/unit/pairwise_plugin/choices_related_test.rb
new file mode 100644
index 0000000..83f3c33
--- /dev/null
+++ b/plugins/pairwise/test/unit/pairwise_plugin/choices_related_test.rb
@@ -0,0 +1,53 @@
+require "test_helper"
+require "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/pairwise_content_fixtures"
+
+class PairwisePlugin::ChoicesRelatedTest < ActiveSupport::TestCase
+
+ def setup
+ @pairwise_content = PairwiseContentFixtures.pairwise_content
+ end
+
+ should 'have choice id' do
+ choices_related = PairwisePlugin::ChoicesRelated.new
+ choices_related.valid?
+ assert choices_related.errors.invalid?(:choice_id)
+
+ choices_related.choice_id = 1
+ choices_related.valid?
+ assert !choices_related.errors.invalid?(:choice_id)
+ end
+
+ should 'have parent choice id' do
+ choices_related = PairwisePlugin::ChoicesRelated.new
+ choices_related.valid?
+ assert choices_related.errors.invalid?(:parent_choice_id)
+
+ choices_related.parent_choice_id = 1
+ choices_related.valid?
+ assert !choices_related.errors.invalid?(:parent_choice_id)
+ end
+
+ should 'belongs to a question' do
+ choices_related = PairwisePlugin::ChoicesRelated.new
+ choices_related.valid?
+ assert choices_related.errors.invalid?(:question)
+
+ choices_related.question = @pairwise_content
+ choices_related.valid?
+ assert !choices_related.errors.invalid?(:question)
+ end
+
+ should 'optionally have an user' do
+ @user = create_user('testinguser')
+ choices_related = PairwisePlugin::ChoicesRelated.new
+ assert choices_related.user_id.nil?
+ choices_related.user = @user
+ assert_equal @user.id, choices_related.user_id
+ end
+
+ should 'search for related choices' do
+ PairwisePlugin::ChoicesRelated.create!(:question => @pairwise_content, :choice_id => 1, :parent_choice_id =>2)
+ assert_equal 1, PairwisePlugin::ChoicesRelated.related_choices_for(1).size
+ assert_equal 1, PairwisePlugin::ChoicesRelated.related_choices_for(2).size
+ end
+end
\ No newline at end of file
diff --git a/plugins/pairwise/test/unit/pairwise_plugin/pairwise_content_test.rb b/plugins/pairwise/test/unit/pairwise_plugin/pairwise_content_test.rb
new file mode 100644
index 0000000..35be4ab
--- /dev/null
+++ b/plugins/pairwise/test/unit/pairwise_plugin/pairwise_content_test.rb
@@ -0,0 +1,198 @@
+require "test_helper"
+require "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/pairwise_content_fixtures"
+require "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/http_stub_fixtures"
+
+# require 'vcr'
+
+# VCR.configure do |c|
+# c.cassette_library_dir = "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/vcr_cassettes"
+# c.hook_into :webmock
+# c.before_playback do |i|
+# puts "I in PLAYBACK: #{i.inspect}"
+# end
+# end
+
+class PairwisePlugin::PairwiseContentTest < ActiveSupport::TestCase
+
+ fixtures :environments
+
+ def setup
+ pairwise_env_settings = { :api_host => "http://localhost:3030/",
+ :username => "abner.oliveira@serpro.gov.br",
+ :password => "serpro"
+ }
+ @profile = create_user('testing').person
+ @profile.environment = environments(:colivre_net)
+ @pairwise_client = Pairwise::Client.build(1, pairwise_env_settings)
+ @pairwise_content = PairwiseContentFixtures.pairwise_content
+ @pairwise_content.profile = @profile
+ #PairwisePlugin::PairwiseContent.any_instance.stubs(:send_question_to_service).returns(true)
+ #PairwisePlugin::PairwiseContent.any_instance.stubs(:pairwise_client).returns(@pairwise_client)
+ @http_stub_fixtures = HttpStubFixtures.new(pairwise_env_settings)
+ end
+
+ should 'be inactive when created' do
+ assert_equal false, @pairwise_content.published?
+ end
+
+ should 'get question from stubed api call' do
+ question = @http_stub_fixtures.create_question(2, 'Question 2', 'Choice X\nChoice Y')
+ assert_not_nil question
+ assert_equal 2, question.id
+ assert_equal 'Question 2', question.name
+ end
+
+ should 'provide proper short description' do
+ assert_equal 'Pairwise question', PairwisePlugin::PairwiseContent.short_description
+ end
+
+ should 'provide proper description' do
+ assert_equal 'Question managed by pairwise', PairwisePlugin::PairwiseContent.description
+ end
+
+ should 'have an html view' do
+ assert_not_nil @pairwise_content.to_html
+ end
+
+ should 'have result_url' do
+ assert_not_nil @pairwise_content.result_url
+ assert_equal @pairwise_content.profile.identifier, @pairwise_content.result_url[:profile]
+ assert_equal :pairwise_plugin_profile, @pairwise_content.result_url[:controller]
+ assert_equal :result, @pairwise_content.result_url[:action]
+ end
+
+ should 'get question from pairwise service' do
+ @question = Pairwise::Question.new(:id => @pairwise_content.pairwise_question_id, :name => 'Question 1')
+ @pairwise_content.expects(:pairwise_client).returns(@pairwise_client)
+ @pairwise_client.expects(:find_question_by_id).with(@question.id).returns(@question)
+ assert_equal @question, @pairwise_content.question
+ end
+
+ should 'prepare prompt' do
+ @question = Pairwise::Question.new(:id => @pairwise_content.pairwise_question_id, :name => 'Question 1')
+ @pairwise_content.expects(:pairwise_client).returns(@pairwise_client)
+ @pairwise_client.expects(:question_with_prompt).with(@question.id,'any_user', nil).returns(@question)
+ prompt = @pairwise_content.prepare_prompt('any_user')
+ assert_not_nil prompt
+ end
+
+ should 'add error to base when the question does not exist' do
+ Response = Struct.new(:code, :message)
+
+ @response = Response.new(422, "Any error")
+
+ @pairwise_client.expects(:find_question_by_id).with(@pairwise_content.pairwise_question_id).raises(ActiveResource::ResourceNotFound.new(@response))
+
+ @pairwise_content.expects(:pairwise_client).returns(@pairwise_client)
+ assert_nil @pairwise_content.errors[:base]
+ @pairwise_content.question
+
+ assert_not_nil @pairwise_content.errors[:base]
+ assert_equal 'Failed with 422 Any error', @pairwise_content.errors[:base]
+ end
+
+ should 'send question to pairwise service' do
+ question = Pairwise::Question.new(:id => 3, :name => 'Question 1')
+ #expectations
+ pairwise_content = PairwiseContentFixtures.new_pairwise_content
+ pairwise_content.profile = @profile
+ pairwise_content.expects(:valid?).returns(true)
+ pairwise_content.expects(:create_pairwise_question).returns(question)
+ pairwise_content.expects(:toggle_autoactivate_ideas).at_least_once
+ #save should call before_save which sends the question to pairwise
+ pairwise_content.save!
+
+ #after save pairwise_question_id should store question id generated by pairwise
+ assert_equal question.id, pairwise_content.pairwise_question_id
+ end
+
+ should 'send changes in choices to pairwise service' do
+ @question = Pairwise::Question.new(:id => @pairwise_content.pairwise_question_id, :name => 'Question 1', :active => false)
+ @pairwise_content.expects(:question).returns(@question).at_least_once
+ @pairwise_content.expects(:pairwise_client).returns(@pairwise_client).at_least_once
+ @pairwise_content.expects('new_record?').returns(false).at_least_once
+ @pairwise_content.expects('valid?').returns(true).at_least_once
+ @pairwise_content.choices = []
+ @pairwise_content.choices_saved = {'1' => 'Choice 1', '2' => 'Choice 2'}
+ #save should call update_choice in pairwise_client for each choice already saved
+ @pairwise_client.expects(:update_choice).returns(true).times(2)
+ @pairwise_content.save
+ end
+
+ should 'send new choices to pairwise_service' do
+ @question = Pairwise::Question.new(:id => @pairwise_content.pairwise_question_id, :name => 'Question 1', :active => false)
+ @pairwise_content.expects('new_record?').returns(false).at_least_once
+ @pairwise_content.expects('valid?').returns(true).at_least_once
+
+ @pairwise_content.expects(:pairwise_client).returns(@pairwise_client).at_least_once
+ @pairwise_content.expects(:question).returns(@question).at_least_once
+ @pairwise_content.choices = ['New Choice 1', 'New Choice 2']
+ @pairwise_content.choices_saved = []
+
+ @pairwise_client.expects(:approve_choice).returns(true).at_least_once
+ choice_stub = Pairwise::Choice.new(:id=> 1, :data => 'txt')
+ @pairwise_client.expects(:add_choice).with(@pairwise_content.pairwise_question_id, "New Choice 1").returns(choice_stub)
+ @pairwise_client.expects(:add_choice).with(@pairwise_content.pairwise_question_id, "New Choice 2").returns(choice_stub)
+ @pairwise_client.expects(:update_question).with(@question.id, @question.name).returns(true)
+ @pairwise_content.save
+ puts @pairwise_content.errors.full_messages
+ end
+
+ should 'allow new ideas by default when created' do
+ assert_equal true, @pairwise_content.allow_new_ideas?
+ end
+
+ should 'add new ideas suggestions when new ideas are allowed' do
+ assert_equal true, @pairwise_content.allow_new_ideas?
+ @question = Pairwise::Question.new(:id => @pairwise_content.pairwise_question_id, :name => 'Question 1', :active => false)
+ @pairwise_content.expects(:pairwise_client).returns(@pairwise_client).at_least_once
+ @pairwise_client.expects(:add_new_idea).with(@question.id, "New idea").returns(true)
+ assert_equal true, @pairwise_content.add_new_idea("New idea")
+ end
+
+ should 'not add new ideas suggestions when new ideas are not allowed' do
+ assert_equal true, @pairwise_content.allow_new_ideas?
+ @question = Pairwise::Question.new(:id => @pairwise_content.pairwise_question_id, :name => 'Question 1', :active => false)
+ @pairwise_content.allow_new_ideas = false
+ assert_equal false, @pairwise_content.add_new_idea("New idea")
+ end
+
+ should 'join similar choices' do
+ pairwise_content = PairwiseContentFixtures.content_stub_with_3_choices
+
+ assert_equal 3, pairwise_content.question.choices.size
+
+ choices_to_join = pairwise_content.question.choices[1..2].map { |choice| choice.id }
+ parent_choice = pairwise_content.question.choices[0].id
+
+ pairwise_content.profile = @profile
+ pairwise_content.stubs(:valid? => true)
+ pairwise_content.stubs(:send_question_to_service => true)
+ pairwise_content.join_choices(choices_to_join, parent_choice, user=nil)
+
+ choices_related = PairwisePlugin::ChoicesRelated.related_choices_for(parent_choice)
+ assert_equal 2, choices_related.size
+ assert_equal 1, choices_related.select { |c| c.choice_id == 2}.size
+ assert_equal 1, choices_related.select { |c| c.choice_id == 3 }.size
+ end
+
+ # should 'skip prompt' do
+
+ # end
+
+ should 'ask skip prompt reasons' do
+ prompt = Pairwise::Prompt.new({"left_choice_text"=>"Choice 1", "right_choice_text"=>"New inactive choice", "left_choice_id"=>1300, "right_choice_id"=>1302, "id"=>194, "tracking"=>nil, "votes_count"=>0})
+ reasons = @pairwise_content.ask_skip_reasons(prompt)
+
+ assert_not_nil reasons
+ assert_equal 7, reasons.size
+
+ assert reasons[0].include? PairwisePlugin::PairwiseContent::REASONS_ARRAY[0][:text]
+ assert reasons[1].include? PairwisePlugin::PairwiseContent::REASONS_ARRAY[1][:text]
+ assert reasons[2].include? PairwisePlugin::PairwiseContent::REASONS_ARRAY[2][:text]
+ assert reasons[3].include? PairwisePlugin::PairwiseContent::REASONS_ARRAY[3][:text]
+ assert reasons[4].include? PairwisePlugin::PairwiseContent::REASONS_ARRAY[4][:text]
+ assert reasons[5].include? PairwisePlugin::PairwiseContent::REASONS_ARRAY[4][:text]
+ assert reasons[6].include? PairwisePlugin::PairwiseContent::REASONS_ARRAY[5][:text]
+ end
+end
diff --git a/plugins/pairwise/test/unit/pairwise_plugin/questions_group_block_test.rb b/plugins/pairwise/test/unit/pairwise_plugin/questions_group_block_test.rb
new file mode 100644
index 0000000..7229561
--- /dev/null
+++ b/plugins/pairwise/test/unit/pairwise_plugin/questions_group_block_test.rb
@@ -0,0 +1,46 @@
+require 'test_helper'
+require "#{RAILS_ROOT}/plugins/pairwise/test/fixtures/pairwise_content_fixtures"
+
+class PairwisePlugin::QuestionsGroupBlockTest < ActiveSupport::TestCase
+
+ fixtures :environments
+
+ def setup
+ @profile = create_user('testing').person
+ @profile.environment = environments(:colivre_net)
+
+ PairwisePlugin::PairwiseContent.any_instance.stubs(:send_question_to_service).returns(true)
+
+ @question1 = PairwisePlugin::PairwiseContent.new(:name => 'Question 1', :profile => @profile, :pairwise_question_id => 1, :body => 'Body 1')
+ @question1.stubs(:valid?).returns(true)
+ @question1.save
+
+ @question2 = PairwisePlugin::PairwiseContent.new(:name => 'Question 2', :profile => @profile, :pairwise_question_id => 2, :body => 'Body 2')
+ @question2.stubs(:valid?).returns(true)
+ @question2.save
+
+ @block = PairwisePlugin::QuestionsGroupBlock.create(:title => "Pairwise Question Block")
+ @profile.boxes.first.blocks << @block
+ @block.save!
+ end
+
+ should 'have available question' do
+ assert_equal [@question1, @question2], @block.available_questions
+ end
+
+ should 'add multiple questions to block' do
+ @block.questions_ids = [@question1.id, @question2.id ]
+ @block.save
+ @block.reload
+ assert_equal 2, @block.questions.length
+ end
+
+ should 'pick a question to show' do
+ @block.questions_ids = [ @question1.id, @question2.id ]
+ @block.save
+ @block.reload
+ assert_not_nil @block.pick_question
+ assert_equal true, @block.pick_question.is_a?(PairwisePlugin::PairwiseContent)
+ end
+
+end
diff --git a/plugins/pairwise/views/blocks/questions_group_list.rhtml b/plugins/pairwise/views/blocks/questions_group_list.rhtml
new file mode 100644
index 0000000..359a356
--- /dev/null
+++ b/plugins/pairwise/views/blocks/questions_group_list.rhtml
@@ -0,0 +1,46 @@
+<% extend PairwisePlugin::Helpers::ViewerHelper %>
+
+<%= block_title(block.title) %>
+
+
+
+ <%= block.group_description %>
+
+
+ <% if block.questions.nil? || block.questions.empty? %>
+
<%= _("Empty") %>
+ <% else
+ block.questions_for_view.each_with_index do |pairwise_content, index|
+ %>
+
+
+
<%= pairwise_content.title %>
+
<%= pairwise_span_arrow(index) %>
+
+ <%= pairwise_group_content_body(index, pairwise_content) %>
+ <% end %>
+ <% end %>
+
+
+
+
diff --git a/plugins/pairwise/views/box_organizer/pairwise_plugin/_questions_group_block.rhtml b/plugins/pairwise/views/box_organizer/pairwise_plugin/_questions_group_block.rhtml
new file mode 100644
index 0000000..41b9fea
--- /dev/null
+++ b/plugins/pairwise/views/box_organizer/pairwise_plugin/_questions_group_block.rhtml
@@ -0,0 +1,19 @@
+
+<% if @block.owner.kind_of?(Environment) and @block.owner.portal_community.nil? %>
+
+<% else %>
+ <%
+ questions = @block.available_questions
+ %>
+
+
+ <% questions.each do |question| %>
+ -
+ <%= labelled_check_box(question.name, "block[questions_ids][]", question.id, @block.settings[:questions_ids] !=null && @block.settings[:questions_ids].include?(question.id.to_s) ) %>
+
+ <% end %>
+
+
+<% end %>
\ No newline at end of file
diff --git a/plugins/pairwise/views/box_organizer/pairwise_plugin/_questions_group_list_block.rhtml b/plugins/pairwise/views/box_organizer/pairwise_plugin/_questions_group_list_block.rhtml
new file mode 100644
index 0000000..b5e8975
--- /dev/null
+++ b/plugins/pairwise/views/box_organizer/pairwise_plugin/_questions_group_list_block.rhtml
@@ -0,0 +1,34 @@
+
+<% if @block.owner.kind_of?(Environment) and @block.owner.portal_community.nil? %>
+
+<% else %>
+ <%
+ questions = @block.available_questions
+ %>
+
+
<%= _('Description:') %>
+ <%= text_area(:block, :group_description, :rows => 6, :cols => 50) %>
+
+
+
<%= _('Choose which attributes should be displayed and drag to reorder them:') %>
+
+ <% questions.each do |question| %>
+ -
+ <%=
+ check_box_tag( "block[questions_ids][]", question.id, @block.settings[:questions_ids] && @block.settings[:questions_ids].include?(question.id.to_s), :id => "pairwise_question_#{question.id}" ) +
+ content_tag( 'label', question.name, :for => "pairwise_question_#{question.id}" )
+ %>
+
+ <% end %>
+
+
+ <%= labelled_form_field check_box(:block, :random_sort) + _('Show items in a random order'), '' %>
+
+
+<% end %>
+
+
diff --git a/plugins/pairwise/views/cms/pairwise_plugin/_pairwise_content.html.erb b/plugins/pairwise/views/cms/pairwise_plugin/_pairwise_content.html.erb
new file mode 100644
index 0000000..1da6013
--- /dev/null
+++ b/plugins/pairwise/views/cms/pairwise_plugin/_pairwise_content.html.erb
@@ -0,0 +1,19 @@
+
+
<%= _(PairwisePlugin::PairwiseContent.short_description) %>
+
+<%
+ @question = @article.title.nil? ? nil : @article.question
+%>
+
+<%= error_messages_for 'question_content' %>
+
+<%= hidden_field_tag 'question_content[profile_id]', profile.id %>
+<%= hidden_field_tag 'pairwise_question_id', @article.pairwise_question_id %>
+<%= render :partial => "cms/pairwise_plugin/pairwise_content_form", :locals => {:f => f} %>
diff --git a/plugins/pairwise/views/cms/pairwise_plugin/_pairwise_content_form.html.erb b/plugins/pairwise/views/cms/pairwise_plugin/_pairwise_content_form.html.erb
new file mode 100644
index 0000000..8dc99b9
--- /dev/null
+++ b/plugins/pairwise/views/cms/pairwise_plugin/_pairwise_content_form.html.erb
@@ -0,0 +1,47 @@
+
\ No newline at end of file
diff --git a/plugins/pairwise/views/content_viewer/_menu.rhtml b/plugins/pairwise/views/content_viewer/_menu.rhtml
new file mode 100644
index 0000000..d1c979d
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/_menu.rhtml
@@ -0,0 +1,12 @@
+<% extend PairwisePlugin::Helpers::ViewerHelper %>
+
+
diff --git a/plugins/pairwise/views/content_viewer/_pairwise_prompts.rhtml b/plugins/pairwise/views/content_viewer/_pairwise_prompts.rhtml
new file mode 100644
index 0000000..91ec8f2
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/_pairwise_prompts.rhtml
@@ -0,0 +1,17 @@
+
+ <%= pairwise_spinner(pairwise_content) %>
+ <% unless question %>
+
+
+ <% else %>
+
<%= choose_left_link(pairwise_content, question, question.prompt, embeded, source, question.appearance_id) %>
+
+
<%= choose_right_link(pairwise_content, question, question.prompt, embeded, source, question.appearance_id ) %>
+ <% end %>
+
diff --git a/plugins/pairwise/views/content_viewer/_pairwise_skips.rhtml b/plugins/pairwise/views/content_viewer/_pairwise_skips.rhtml
new file mode 100644
index 0000000..38d6c0a
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/_pairwise_skips.rhtml
@@ -0,0 +1,5 @@
+
+ <% pairwise_content.ask_skip_reasons(question.prompt).each do |reason| %>
+ <%= skip_vote_link(pairwise_content, question, question.prompt, embeded, source, question.appearance_id, reason ) %>
+ <% end %>
+
\ No newline at end of file
diff --git a/plugins/pairwise/views/content_viewer/_prompt_body.rhtml b/plugins/pairwise/views/content_viewer/_prompt_body.rhtml
new file mode 100644
index 0000000..23aaaf9
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/_prompt_body.rhtml
@@ -0,0 +1,37 @@
+
+
+ <%= render :partial => 'content_viewer/menu', :locals => {:embeded => embeded, :pairwise_content => pairwise_content, :active_tab => :prompt} %>
+
+
<%= pairwise_content.title %>
+
<%= pairwise_content.body %>
+ <%= render :partial => 'content_viewer/pairwise_prompts', :locals => {:embeded => embeded, :pairwise_content => pairwise_content, :question => question, :source => (defined?(source) ? source : '') } %>
+ <% if embeded %>
+
+ <% end %>
+
+
+ <%= skip_vote_open_function(pairwise_content) %>
+
+
+ <% if question %>
+ <%= render :partial => 'content_viewer/pairwise_skips', :locals => {:embeded => embeded, :pairwise_content => pairwise_content, :question => question, :source => (defined?(source) ? source : '') } %>
+ <% end %>
+
+
+ <% if pairwise_content.allow_new_ideas? %>
+ <% if user %>
+
+
Gostaria de sugerir uma ideia?
+
+ <%= render :partial => "pairwise_plugin_profile/suggestion_form",
+ :locals => {:pairwise_content => pairwise_content, :embeded => embeded, :source => source} %>
+
+
+ <% else %>
+
+ <%= link_to(_("Add new idea"), '#', :id => 'new_idea_button_not_logged', :class => 'require-login-popup') %>
+
+ <% end %>
+ <% end %>
+
+
diff --git a/plugins/pairwise/views/content_viewer/_result.rhtml b/plugins/pairwise/views/content_viewer/_result.rhtml
new file mode 100644
index 0000000..f3133bb
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/_result.rhtml
@@ -0,0 +1,63 @@
+
+
+
+<%
+ @question = @page.question
+ %>
+
+<% extend PairwisePlugin::Helpers::ViewerHelper %>
+
+<% unless @page.errors[:base].nil? %>
+
<%= _('Pairwise Integration Error') %>
+
<%= _('Please contact the administrator') %>
+
+ <%= @page.errors[:base] %>
+
+<% else %>
+
+ <%= render :partial => 'content_viewer/menu', :locals => {:embeded => embeded, :pairwise_content => pairwise_content, :active_tab => :results} %>
+
+ <% cache_timeout("pairwise-result-#{pairwise_content.id}", 1.hours) do %>
+
+<%= pairwise_spinner(pairwise_content) %>
+
+
+ <%= _('Total votes:') %>
+ <%= @page.question.votes_count %>
+
+
+
+
+ | <%= _('Choice Text') %> |
+ <%= _('Choice Wins') %> |
+ <%= _('Choice Losses') %> |
+ <%= _('Choice Score') %> |
+
+
+
+ <% @page.question.get_choices.each do |choice| %>
+
+ | <%= choice.data %> |
+ <%= choice.wins %> |
+ <%= choice.losses %> |
+ <%= choice.score.round.to_s %> |
+
+ <% end %>
+
+
+
+ <% if @page.allow_edit?(user) %>
+
+ <% end %>
+ <%#= link_to _('Vote'), @page.url, :class=>"button with-text icon-edit" %>
+<% end %>
+<% end %>
+
+
+
+
diff --git a/plugins/pairwise/views/content_viewer/prompt.rhtml b/plugins/pairwise/views/content_viewer/prompt.rhtml
new file mode 100644
index 0000000..514ec6e
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/prompt.rhtml
@@ -0,0 +1,14 @@
+<% extend PairwisePlugin::Helpers::ViewerHelper %>
+
+<%= pairwise_plugin_stylesheet %>
+
+<% if embeded %>
+ <%= javascript_include_tag :defaults, 'jquery-latest.js',
+ 'jquery.noconflict.js', 'jquery.cycle.all.min.js', 'thickbox.js', 'lightbox', 'colorbox',
+ 'jquery-ui-1.8.2.custom.min', 'jquery.scrollTo', 'jquery.form.js', 'jquery-validation/jquery.validate',
+ 'jquery.cookie', 'jquery.ba-bbq.min.js', 'reflection', 'jquery.tokeninput',
+ 'add-and-join', 'report-abuse', 'catalog', 'manage-products',
+ 'jquery-ui-timepicker-addon', :cache => 'cache-general' %>
+<% end %>
+
+<%= render :partial => 'content_viewer/prompt_body', :locals => {:embeded => embeded, :pairwise_content => pairwise_content, :question => nil, :source => (defined?(source) ? source : '') }%>
diff --git a/plugins/pairwise/views/content_viewer/prompt.rjs b/plugins/pairwise/views/content_viewer/prompt.rjs
new file mode 100644
index 0000000..f22e80e
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/prompt.rjs
@@ -0,0 +1,25 @@
+extend PairwisePlugin::Helpers::ViewerHelper
+
+question = @pairwise_content.prepare_prompt(pairwise_user_identifier(user), nil)
+
+spinner = "pairwise_spinner#{@pairwise_content.id}"
+
+div_id = "pairwise_prompts_#{@pairwise_content.id}"
+
+skip_div_id = "skip_vote_reasons_#{@pairwise_content.id}"
+
+page.replace div_id, :partial => 'content_viewer/pairwise_prompts', :locals => {
+ :embeded => params[:embeded],
+ :source => params[:source],
+ :pairwise_content => @pairwise_content,
+ :question => question
+ }
+
+page.replace_html skip_div_id, :partial => 'content_viewer/pairwise_skips', :locals => {
+ :embeded => params[:embeded],
+ :source => params[:source],
+ :pairwise_content => @pairwise_content,
+ :question => question
+ }
+
+page.call pairwise_spinner_hide_function_name(@pairwise_content)
diff --git a/plugins/pairwise/views/content_viewer/prompt_tab.rjs b/plugins/pairwise/views/content_viewer/prompt_tab.rjs
new file mode 100644
index 0000000..c455920
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/prompt_tab.rjs
@@ -0,0 +1,14 @@
+extend PairwisePlugin::Helpers::ViewerHelper
+
+div_id = "pairwise_#{@pairwise_content.id}"
+
+question = @pairwise_content.prepare_prompt(pairwise_user_identifier(user), nil)
+
+page.replace div_id, :partial => 'content_viewer/prompt_body', :locals => {
+ :embeded => params[:embeded],
+ :source => params[:source],
+ :pairwise_content => @pairwise_content,
+ :question => question
+ }
+
+page.call pairwise_spinner_hide_function_name(@pairwise_content)
diff --git a/plugins/pairwise/views/content_viewer/result.rjs b/plugins/pairwise/views/content_viewer/result.rjs
new file mode 100644
index 0000000..e595239
--- /dev/null
+++ b/plugins/pairwise/views/content_viewer/result.rjs
@@ -0,0 +1,10 @@
+extend PairwisePlugin::Helpers::ViewerHelper
+
+div_id = "pairwise_#{@pairwise_content.id}"
+
+page.replace div_id, :partial => 'content_viewer/result', :locals => {
+ :embeded => params[:embeded],
+ :pairwise_content => @pairwise_content,
+ }
+
+page.call pairwise_spinner_hide_function_name(@pairwise_content)
diff --git a/plugins/pairwise/views/environment_design/pairwise_plugin b/plugins/pairwise/views/environment_design/pairwise_plugin
new file mode 120000
index 0000000..e3d6ee8
--- /dev/null
+++ b/plugins/pairwise/views/environment_design/pairwise_plugin
@@ -0,0 +1 @@
+../box_organizer/pairwise_plugin
\ No newline at end of file
diff --git a/plugins/pairwise/views/layouts/embeded.erb b/plugins/pairwise/views/layouts/embeded.erb
new file mode 100644
index 0000000..3b52f21
--- /dev/null
+++ b/plugins/pairwise/views/layouts/embeded.erb
@@ -0,0 +1,34 @@
+
+
+
+
Pairwise embed
+
+
+ <%= noosfero_stylesheets %>
+ <%= noosfero_javascript %>
+
+
+
+
+
+
+
+ <%=
+ @plugins.dispatch(:body_beginning).collect do |content|
+ content.respond_to?(:call) ? content.call : content
+ end.join("\n")
+ %>
+
+
+ <%= yield %>
+
+
+
+
diff --git a/plugins/pairwise/views/pairwise_plugin_admin/index.rhtml b/plugins/pairwise/views/pairwise_plugin_admin/index.rhtml
new file mode 100644
index 0000000..8070e67
--- /dev/null
+++ b/plugins/pairwise/views/pairwise_plugin_admin/index.rhtml
@@ -0,0 +1,17 @@
+
<%= _('Pairwise settings')%>
+
+<% form_for(:settings) do |f| %>
+
+
+ <%= labelled_form_field _('Pairwise api host'), f.text_field(:api_host) %>
+ <%= labelled_form_field _('Pairwise username'), f.text_field(:username) %>
+ <%= labelled_form_field _('Pairwise password'), f.text_field(:password) %>
+
+
+
+ <% button_bar do %>
+ <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %>
+ <% end %>
+
+<% end %>
+
diff --git a/plugins/pairwise/views/pairwise_plugin_profile/_suggestion_form.rhtml b/plugins/pairwise/views/pairwise_plugin_profile/_suggestion_form.rhtml
new file mode 100644
index 0000000..9a99087
--- /dev/null
+++ b/plugins/pairwise/views/pairwise_plugin_profile/_suggestion_form.rhtml
@@ -0,0 +1,28 @@
+ <% remote_form_for('idea', :url => pairwise_suggestion_url(pairwise_content, embeded, source),
+ :html => {:id => "pairwise_suggestion_form_#{pairwise_content.id}"}, :loading => "jQuery('#pairwise_suggestion_form_#{pairwise_content.id} .suggestion_box_fields').hide();jQuery('#pairwise_suggestion_form_#{pairwise_content.id} .suggestion_box_loading').show();", :loaded => "jQuery('#pairwise_suggestion_form_#{pairwise_content.id} .suggestion_box_fields').show();jQuery('#pairwise_suggestion_form_#{pairwise_content.id} .suggestion_box_loading').hide();") do |f| %>
+
+
+ <%= flash[:error] %>
+
+
+ <%= flash[:notice] %>
+
+
+
+ <%= f.text_area 'text', :maxlenght => 160, :rows => 4, :placeholder => _('Type your idea here') %>
+
+
+ <%= submit_button('', '', :id => 'new_idea_button', :class => user ? '':'require-login-popup') %>
+
+
+
+
+ Processando...
+
+
+ <% end %>
diff --git a/plugins/pairwise/views/pairwise_plugin_profile/result.rhtml b/plugins/pairwise/views/pairwise_plugin_profile/result.rhtml
new file mode 100644
index 0000000..25b14f2
--- /dev/null
+++ b/plugins/pairwise/views/pairwise_plugin_profile/result.rhtml
@@ -0,0 +1,10 @@
+<% extend PairwisePlugin::Helpers::ViewerHelper %>
+
+<%= pairwise_plugin_stylesheet %>
+
+
<%= @page.name %>
+
+<%= render :partial => "content_viewer/result", :locals => {
+ :embeded => @embeded,
+ :pairwise_content => @pairwise_content,
+ } %>
diff --git a/plugins/pairwise/views/pairwise_plugin_profile/suggestion_form.rjs b/plugins/pairwise/views/pairwise_plugin_profile/suggestion_form.rjs
new file mode 100644
index 0000000..f3683f4
--- /dev/null
+++ b/plugins/pairwise/views/pairwise_plugin_profile/suggestion_form.rjs
@@ -0,0 +1,5 @@
+extend PairwisePlugin::Helpers::ViewerHelper
+
+page.replace_html "pairwise_suggestion_form_#{@pairwise_content.id}", :partial => "suggestion_form",
+ :locals=> {:pairwise_content => @pairwise_content, :page => @pairwise_content, :embeded => @embeded, :source => @source }
+#page.visual_effect :slide_down, "suggestions_box"
\ No newline at end of file
diff --git a/plugins/pairwise/views/pairwise_plugin_suggestions/edit.rhtml b/plugins/pairwise/views/pairwise_plugin_suggestions/edit.rhtml
new file mode 100644
index 0000000..015a294
--- /dev/null
+++ b/plugins/pairwise/views/pairwise_plugin_suggestions/edit.rhtml
@@ -0,0 +1,16 @@
+
<%= _("Edit Pairwise Question Choice") %>
+
+
<%= @pairwise_content.name %>
+
+<% form_for 'choice',
+ :url => {
+ :controller => 'pairwise_plugin_suggestions',
+ :action => 'update',
+ :id => @pairwise_content.id
+ } do |f| %>
+ <%= f.hidden_field 'id' %>
+ <%= f.text_area 'data', :rows => 4, :style => "width:100%" %>
+ <%= f.check_box 'active' %> <%= f.label _('Active') %>
+
+ <%= submit_button('save', _('Update'), :id => 'update_choice_button') %>
+<% end %>
diff --git a/plugins/pairwise/views/pairwise_plugin_suggestions/index.rhtml b/plugins/pairwise/views/pairwise_plugin_suggestions/index.rhtml
new file mode 100644
index 0000000..21538ed
--- /dev/null
+++ b/plugins/pairwise/views/pairwise_plugin_suggestions/index.rhtml
@@ -0,0 +1,154 @@
+<% extend PairwisePlugin::Helpers::ViewerHelper %>
+<% extend PairwisePlugin::Helpers::SuggestionsHelper %>
+
+<%= pairwise_plugin_stylesheet %>
+
+
<%= _("Pairwise Question") %>
+
<%= _("Question text" ) %>:
<%= @pairwise_content.name %>
+
+ <%= pairwise_result_link _("Results"), @pairwise_content %>
+
+<% if flash[:error] %>
+
+ <%= flash[:error] %>
+
+<% end %>
+<% if flash[:notice] %>
+
+ <%= flash[:notice] %>
+
+<% end %>
+
+
+
+
+
+
+
+ ">
+ <%= link_to_if has_param_pending_choices?, _('Ideas'), :pending => '' %>
+ |
+ ">
+ <%= link_to_if ! has_param_pending_choices?, _('Suggestions'), :pending => '1', :reproved => '' %>
+ |
+
+ <% if params[:pending] == '1' %>
+
+ | |
+ ">
+ <%= link_to_if has_param_reproved_choices?, _('Pending'), :pending => '1', :reproved => '' %>
+ |
+ ">
+ <%= link_to_if ! has_param_reproved_choices?, _('Reproved'), :pending => '1', :reproved => '1' %>
+ |
+
+ <% end %>
+
+
+
+
+<% form_for(
+ :filter, {
+ :action => :index,
+ :controller => 'pairwise_plugin_suggestions',
+ :profile => profile.identifier
+ }) do %>
+
+
+ |
+ <%= hidden_field_tag 'pending', params[:pending] %>
+ <%= hidden_field_tag 'reproved', params[:reproved] %>
+ <%= text_field_tag(
+ 'filter[data]',
+ params[:filter] ? params[:filter][:data]:'',
+ :placeholder => _('Type words about ideas/suggestions you\'re looking for'),
+ :class => "pairwise_search_field"
+ ) %>
+ |
+ <%= submit_button :search, _('Search') %> |
+
+
+<% end %>
+
+
+
+
+
+ | ">
+ <%= link_to_sort_choices(@pairwise_content, _("Text"), "data") %>
+ |
+ ">
+ <%= link_to_sort_choices(@pairwise_content, _("Date"), "created_date") %>
+ |
+ ">
+ <%= link_to_sort_choices(@pairwise_content, _("Author"), "visitor_identifier") %>
+ |
+ |
+
+
+ <% @choices.each do |choice| %>
+
+ | <%= choice.data %> |
+ <%= show_date choice.created_at %> |
+ <%= choice.user_created ? choice.creator_identifier : profile.identifier %> |
+
+ <%= link_to_edit_choice(@pairwise_content, choice) unless choice.reproved %>
+ <% unless choice.active || choice.reproved %>
+ |
+ <%= link_to_approve_choice(@pairwise_content, choice, params)%>
+ | <%= link_to_reprove_idea @pairwise_content, choice, 'reprove', params %>
+ <% end %>
+ |
+
+ <% end %>
+
+<%= pagination_for_choices(@choices) %>
diff --git a/plugins/pairwise/views/profile_design/pairwise_plugin b/plugins/pairwise/views/profile_design/pairwise_plugin
new file mode 120000
index 0000000..e3d6ee8
--- /dev/null
+++ b/plugins/pairwise/views/profile_design/pairwise_plugin
@@ -0,0 +1 @@
+../box_organizer/pairwise_plugin
\ No newline at end of file
--
libgit2 0.21.2