From db134de31549961bf8f1deeeaa26ca813357bad9 Mon Sep 17 00:00:00 2001 From: Carlos Purificacao Date: Tue, 29 Sep 2015 12:18:23 -0300 Subject: [PATCH] Implemented votes with captcha --- lib/noosfero/api/captcha_session_store.rb | 30 ------------------------------ lib/noosfero/api/helpers.rb | 3 ++- lib/noosfero/api/session.rb | 6 +++++- lib/noosfero/api/v1/articles.rb | 17 +++++++++++++++-- test/unit/api/articles_test.rb | 32 ++++++++++++++++++++++++++++++++ test/unit/api/login_captcha_test.rb | 20 ++++++++++++++++++++ 6 files changed, 74 insertions(+), 34 deletions(-) delete mode 100644 lib/noosfero/api/captcha_session_store.rb diff --git a/lib/noosfero/api/captcha_session_store.rb b/lib/noosfero/api/captcha_session_store.rb deleted file mode 100644 index 2617129..0000000 --- a/lib/noosfero/api/captcha_session_store.rb +++ /dev/null @@ -1,30 +0,0 @@ -class Noosfero::API::CaptchaSessionStore - - attr_accessor :data - attr_reader :private_token - - def self.create - key = SecureRandom.hex - store = Noosfero::API::CaptchaSessionStore.new(key) - Rails.cache.write(store.private_token, store, expires_in: 300) - return store - end - - def initialize(key) - @private_token = key - end - - def self.get(key) - Rails.cache.fetch(key) - end - - def store - Rails.cache.write(@private_token, self) - end - - def destroy - Rails.cache.delete(@private_token) - end - - -end diff --git a/lib/noosfero/api/helpers.rb b/lib/noosfero/api/helpers.rb index e3cea4f..3544bb5 100644 --- a/lib/noosfero/api/helpers.rb +++ b/lib/noosfero/api/helpers.rb @@ -23,7 +23,8 @@ require 'grape' def current_tmp_user private_token = (params[PRIVATE_TOKEN_PARAM] || headers['Private-Token']).to_s - @current_tmp_user = Noosfero::API::CaptchaSessionStore.get(private_token) + ## Get the "captcha" session store + @current_tmp_user = Noosfero::API::SessionStore.get("captcha##{private_token}") @current_tmp_user end diff --git a/lib/noosfero/api/session.rb b/lib/noosfero/api/session.rb index fa5824a..7ffaa16 100644 --- a/lib/noosfero/api/session.rb +++ b/lib/noosfero/api/session.rb @@ -16,7 +16,11 @@ module Noosfero # this return is just to improve the clarity of the execution path return unless test_captcha(remote_ip, params, environment) ## Creates and caches a captcha session store - store = Noosfero::API::CaptchaSessionStore.create + store = Noosfero::API::SessionStore.create("captcha") + ## Initialize the data for the session store + store.data = [] + ## Put it back in cache + store.store { "private_token" => "#{store.private_token}" } end diff --git a/lib/noosfero/api/v1/articles.rb b/lib/noosfero/api/v1/articles.rb index 518b5cf..17c1318 100644 --- a/lib/noosfero/api/v1/articles.rb +++ b/lib/noosfero/api/v1/articles.rb @@ -139,8 +139,21 @@ module Noosfero # FIXME verify allowed values render_api_error!('Vote value not allowed', 400) unless [-1, 1].include?(value) article = find_article(environment.articles, params[:id]) - vote = Vote.new(:voteable => article, :voter => current_person, :vote => value) - {:vote => vote.save} + ## If login with captcha + if @current_tmp_user + vote = (@current_tmp_user.data.include? article.id) ? false : true + if vote + @current_tmp_user.data << article.id + @current_tmp_user.store + vote = Vote.new(:voteable => article, :voter => current_person, :vote => value) + {:vote => vote.save} + else + {:vote => false} + end + else + vote = Vote.new(:voteable => article, :voter => current_person, :vote => value) + {:vote => vote.save} + end end desc 'Return the children of a article identified by id' do diff --git a/test/unit/api/articles_test.rb b/test/unit/api/articles_test.rb index abdf5d2..2f99f07 100644 --- a/test/unit/api/articles_test.rb +++ b/test/unit/api/articles_test.rb @@ -127,6 +127,37 @@ class ArticlesTest < ActiveSupport::TestCase assert_equal 1, json['total_followers'] end + should 'not perform a vote twice in same article' do + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing") + @params[:value] = 1 + ## Perform a vote twice in API should compute only one vote + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}" + json = JSON.parse(last_response.body) + + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}" + json = JSON.parse(last_response.body) + + total = article.votes_total + + assert_equal 1, total + end + + should 'not perform a vote in favor and against a proposal' do + article = fast_create(Article, :profile_id => @person.id, :name => "Some thing") + @params[:value] = 1 + ## Perform a vote in favor a proposal + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}" + json = JSON.parse(last_response.body) + assert_equal 201, last_response.status + ## Perform a vote against a proposal + @params[:value] = -1 + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}" + json = JSON.parse(last_response.body) + ## The api should not allow to save this vote + assert_equal false, json['vote'] + end + + should 'perform a vote in a article identified by id' do article = fast_create(Article, :profile_id => @person.id, :name => "Some thing") @params[:value] = 1 @@ -136,6 +167,7 @@ class ArticlesTest < ActiveSupport::TestCase assert_not_equal 401, last_response.status assert_equal true, json['vote'] + end expose_attributes = %w(id body abstract created_at title author profile categories image votes_for votes_against setting position hits start_date end_date tag_list parent children children_count) diff --git a/test/unit/api/login_captcha_test.rb b/test/unit/api/login_captcha_test.rb index 8864e61..78de0c3 100644 --- a/test/unit/api/login_captcha_test.rb +++ b/test/unit/api/login_captcha_test.rb @@ -47,6 +47,26 @@ class LoginCaptchaTest < ActiveSupport::TestCase assert_equal true, json['vote'] end + should 'not perform a vote twice in same article' do + login_with_captcha + article = create_article('Article 1') + params[:value] = 1 + + ## Perform a vote twice in API should compute only one vote + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}" + json = JSON.parse(last_response.body) + assert_equal true, json['vote'] + + post "/api/v1/articles/#{article.id}/vote?#{params.to_query}" + json = JSON.parse(last_response.body) + ## Should not allow vote again + assert_equal false, json['vote'] + + total = article.votes_total + + assert_equal 1, total + end + should 'not follow any article' do login_with_captcha article = create_article('Article 1') -- libgit2 0.21.2