diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss
index 2a78d3cc7..0be3d4eea 100644
--- a/app/assets/stylesheets/layout.scss
+++ b/app/assets/stylesheets/layout.scss
@@ -20,6 +20,7 @@
// 18. Comments
// 19. Flags
// 20. Accesibility
+// 21. Activity
//
// 01. Variables
@@ -2015,3 +2016,58 @@ table {
clip: rect(0, 0, 0, 0);
border: 0;
}
+
+// 21. Activity
+// - - - - - - - - - - - - - - - - - - - - - - - - -
+
+.activity {
+ margin-bottom: rem-calc(48);
+ margin-top: rem-calc(24);
+
+ .sub-nav {
+ background: none;
+ border-bottom: 1px solid $border;
+ border-radius: 0;
+ padding-bottom: 0;
+
+ dd.active {
+ background: none;
+ border-bottom: 2px solid $brand;
+ border-radius: 0;
+ color: $brand;
+ }
+ }
+
+ table {
+ border: 0;
+
+ td {
+ padding-left: rem-calc(36);
+ position: relative;
+
+ &:before {
+ color: $brand;
+ font-family: "icons" !important;
+ font-size: rem-calc(24);
+ left: 4px;
+ position: absolute;
+
+ }
+ }
+
+ &.activity-comments td:before {
+ content: "e";
+ top: 18px;
+ }
+
+ &.activity-debates td:before {
+ content: "i";
+ top: 14px;
+ }
+
+ &.activity-proposals td:before {
+ content: "h";
+ top: 18px;
+ }
+ }
+}
diff --git a/app/assets/stylesheets/participation.scss b/app/assets/stylesheets/participation.scss
index 583b614b3..1415ef33d 100644
--- a/app/assets/stylesheets/participation.scss
+++ b/app/assets/stylesheets/participation.scss
@@ -416,8 +416,15 @@
}
.author {
- color: $text;
font-weight: bold;
+
+ a {
+ color: $link !important;
+
+ &:hover {
+ color: $link-hover !important;
+ }
+ }
}
aside {
diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb
index 38bd4bfe5..f2a553c38 100644
--- a/app/controllers/account_controller.rb
+++ b/app/controllers/account_controller.rb
@@ -25,7 +25,7 @@ class AccountController < ApplicationController
if @account.organization?
params.require(:account).permit(:phone_number, :email_on_comment, :email_on_comment_reply, organization_attributes: [:name, :responsible_name])
else
- params.require(:account).permit(:username, :email_on_comment, :email_on_comment_reply)
+ params.require(:account).permit(:username, :public_activity, :email_on_comment, :email_on_comment_reply)
end
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
new file mode 100644
index 000000000..a978cd1ce
--- /dev/null
+++ b/app/controllers/users_controller.rb
@@ -0,0 +1,60 @@
+class UsersController < ApplicationController
+ has_filters %w{proposals debates comments}, only: :show
+
+ load_and_authorize_resource
+
+ def show
+ load_filtered_activity if valid_access?
+ end
+
+ private
+ def set_activity_counts
+ @activity_counts = HashWithIndifferentAccess.new(
+ proposals: Proposal.where(author_id: @user.id).count,
+ debates: Debate.where(author_id: @user.id).count,
+ comments: Comment.where(user_id: @user.id).count)
+ end
+
+ def load_filtered_activity
+ set_activity_counts
+ case params[:filter]
+ when "proposals" then load_proposals
+ when "debates" then load_debates
+ when "comments" then load_comments
+ else load_available_activity
+ end
+ end
+
+ def load_available_activity
+ if @activity_counts[:proposals] > 0
+ load_proposals
+ @current_filter = "proposals"
+ elsif @activity_counts[:debates] > 0
+ load_debates
+ @current_filter = "debates"
+ elsif @activity_counts[:comments] > 0
+ load_comments
+ @current_filter = "comments"
+ end
+ end
+
+ def load_proposals
+ @proposals = Proposal.where(author_id: @user.id).order(created_at: :desc).page(params[:page])
+ end
+
+ def load_debates
+ @debates = Debate.where(author_id: @user.id).order(created_at: :desc).page(params[:page])
+ end
+
+ def load_comments
+ @comments = Comment.where(user_id: @user.id).includes(:commentable).order(created_at: :desc).page(params[:page])
+ end
+
+ def valid_access?
+ @user.public_activity || authorized_current_user?
+ end
+
+ def authorized_current_user?
+ @authorized_current_user ||= current_user && (current_user == @user || current_user.moderator? || current_user.administrator?)
+ end
+end
diff --git a/app/models/abilities/everyone.rb b/app/models/abilities/everyone.rb
index 5f5de51b7..691735b10 100644
--- a/app/models/abilities/everyone.rb
+++ b/app/models/abilities/everyone.rb
@@ -5,6 +5,7 @@ module Abilities
def initialize(user)
can :read, Debate
can :read, Proposal
+ can :read, User
end
end
end
diff --git a/app/views/account/show.html.erb b/app/views/account/show.html.erb
index 40cf43a59..5acf6eb62 100644
--- a/app/views/account/show.html.erb
+++ b/app/views/account/show.html.erb
@@ -31,6 +31,13 @@
<% end %>
+
+ <%= f.label :public_activity do %>
+ <%= f.check_box :public_activity, label: false %>
+ <%= t("account.show.public_activity_label") %>
+ <% end %>
+
+
diff --git a/app/views/comments/_comment.html.erb b/app/views/comments/_comment.html.erb
index 1ec571633..dcf02d084 100644
--- a/app/views/comments/_comment.html.erb
+++ b/app/views/comments/_comment.html.erb
@@ -36,7 +36,7 @@
<% if comment.user.hidden? || comment.user.erased? %>
<%= t("comments.comment.user_deleted") %>
<% else %>
-
<%= comment.user.name %>
+
<%= link_to comment.user.name, user_path(comment.user) %>
<% if comment.user.official? %>
•
<% else %>
- <%= resource.author.name %>
+ <%= link_to resource.author.name, user_path(resource.author) %>
<% if resource.author.official? %>
•
diff --git a/app/views/users/_activity_page.html.erb b/app/views/users/_activity_page.html.erb
new file mode 100644
index 000000000..296f7e5c2
--- /dev/null
+++ b/app/views/users/_activity_page.html.erb
@@ -0,0 +1,3 @@
+<%= render "proposals" if @proposals.present? %>
+<%= render "debates" if @debates.present? %>
+<%= render "comments" if @comments.present? %>
diff --git a/app/views/users/_comments.html.erb b/app/views/users/_comments.html.erb
new file mode 100644
index 000000000..2a8c9d66b
--- /dev/null
+++ b/app/views/users/_comments.html.erb
@@ -0,0 +1,13 @@
+
+
+<%= paginate @comments %>
diff --git a/app/views/users/_debates.html.erb b/app/views/users/_debates.html.erb
new file mode 100644
index 000000000..53fc0d58e
--- /dev/null
+++ b/app/views/users/_debates.html.erb
@@ -0,0 +1,11 @@
+
+ <% @debates.each do |debate| %>
+
+ |
+ <%= link_to debate.title, debate %>
+ |
+
+ <% end %>
+
+
+<%= paginate @debates %>
\ No newline at end of file
diff --git a/app/views/users/_proposals.html.erb b/app/views/users/_proposals.html.erb
new file mode 100644
index 000000000..a8ec5061e
--- /dev/null
+++ b/app/views/users/_proposals.html.erb
@@ -0,0 +1,13 @@
+
+ <% @proposals.each do |proposal| %>
+
+
+ <%= link_to proposal.title, proposal %>
+
+ <%= proposal.summary %>
+ |
+
+ <% end %>
+
+
+<%= paginate @proposals %>
\ No newline at end of file
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
new file mode 100644
index 000000000..2be31b272
--- /dev/null
+++ b/app/views/users/show.html.erb
@@ -0,0 +1,29 @@
+
+
+
+
+
<%= avatar_image(@user, seed: @user.id, size: 60) %> <%= @user.name %>
+
+ <% if @user.public_activity || @authorized_current_user %>
+
+ <% @valid_filters.each do |filter| %>
+ <% if @activity_counts[filter] > 0 %>
+ <% if @current_filter == filter %>
+ - <%= t("users.show.filters.#{filter}", count: @activity_counts[filter]) %>
+ <% else %>
+ - <%= link_to t("users.show.filters.#{filter}", count: @activity_counts[filter]),
+ current_path_with_query_params(filter: filter, page: 1) %>
+ <% end %>
+ <% end %>
+ <% end %>
+ <%= t("users.show.no_activity") if @activity_counts.values.inject(&:+) == 0 %>
+
+
+ <%= render "activity_page" %>
+ <% else %>
+
<%= t('users.show.private_activity') %>
+ <% end %>
+
+
+
+
\ No newline at end of file
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index d725a77d8..c6393c23a 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -120,6 +120,7 @@ ignore_unused:
- 'moderation.proposals.index.order*'
- 'moderation.debates.index.filter*'
- 'moderation.debates.index.order*'
+ - 'users.show.filters.*'
- 'debates.index.orders.*'
- 'debates.index.search_form.*'
- 'proposals.index.orders.*'
diff --git a/config/locales/en.yml b/config/locales/en.yml
index b69f61197..55ab1ae33 100755
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -22,6 +22,7 @@ en:
"There are cities that are governed directly by their inhabitants, who
discuss the topics they are concerned about,
propose ideas to improve
their lives and
decide among themselves which ones will be carried out. Madrid is already one of these cities."
see_all: "See proposals"
+ my_activity_link: "My activity"
my_account_link: "My account"
locale: "Language:"
administration: "Administration"
@@ -283,6 +284,7 @@ en:
title: "My account"
save_changes_submit: "Save changes"
change_credentials_link: "Change my credentials"
+ public_activity_label: "Keep my list of activities public"
email_on_comment_label: "Notify me by email when someone comments on my proposals or debates"
email_on_comment_reply_label: "Notify me by email when someone replies to my comments"
erase_account_link: "Erase my account"
@@ -324,6 +326,20 @@ en:
check: "Select"
check_all: "All"
check_none: "None"
+ users:
+ show:
+ filters:
+ proposals:
+ one: "1 Proposal"
+ other: "%{count} Proposals"
+ debates:
+ one: "1 Debate"
+ other: "%{count} Debates"
+ comments:
+ one: "1 Comment"
+ other: "%{count} Comments"
+ no_activity: "User has no public activity"
+ private_activity: "This user decided to keep the activity list private"
unauthorized:
default: "You do not have permission to access this page."
manage:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 9a8b6b1a3..8d9f4da3b 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -22,6 +22,7 @@ es:
"Existen ciudades gobernadas directamente por sus habitantes, que
debaten sobre temas que les preocupan,
proponen ideas para mejorar
sus vidas y
deciden entre todas y todos las que se llevan a cabo. Madrid ya es una de ellas."
see_all: "Ver propuestas"
+ my_activity_link: "Mi actividad"
my_account_link: "Mi cuenta"
locale: "Idioma:"
administration: "Administrar"
@@ -283,6 +284,7 @@ es:
title: "Mi cuenta"
save_changes_submit: "Guardar cambios"
change_credentials_link: "Cambiar mis datos de acceso"
+ public_activity_label: "Mostrar públicamente mi lista de actividades"
email_on_comment_label: "Recibir un email cuando alguien comenta en mis propuestas o debates"
email_on_comment_reply_label: "Recibir un email cuando alguien contesta a mis comentarios"
erase_account_link: "Darme de baja"
@@ -324,6 +326,20 @@ es:
check: "Seleccionar"
check_all: "Todos"
check_none: "Ninguno"
+ users:
+ show:
+ filters:
+ proposals:
+ one: "1 Propuesta"
+ other: "%{count} Propuestas"
+ debates:
+ one: "1 Debate"
+ other: "%{count} Debates"
+ comments:
+ one: "1 Comentario"
+ other: "%{count} Comentarios"
+ no_activity: "Usuario sin actividad pública"
+ private_activity: "Este usuario ha decidido mantener en privado su lista de actividades"
unauthorized:
default: "No tienes permiso para acceder a esta página."
manage:
diff --git a/config/routes.rb b/config/routes.rb
index 3a63fa3b1..cb42ef6da 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -61,6 +61,8 @@ Rails.application.routes.draw do
end
end
+ resources :users, only: [:show]
+
resource :account, controller: "account", only: [:show, :update, :delete] do
collection { get :erase }
end
diff --git a/db/migrate/20151103194329_add_public_activity_to_users.rb b/db/migrate/20151103194329_add_public_activity_to_users.rb
new file mode 100644
index 000000000..8feebdff7
--- /dev/null
+++ b/db/migrate/20151103194329_add_public_activity_to_users.rb
@@ -0,0 +1,5 @@
+class AddPublicActivityToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :public_activity, :boolean, default: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 320bfffc1..95bd4a36d 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20151103175139) do
+ActiveRecord::Schema.define(version: 20151103194329) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -95,10 +95,10 @@ ActiveRecord::Schema.define(version: 20151103175139) do
t.string "visit_id"
t.datetime "hidden_at"
t.integer "flags_count", default: 0
- t.datetime "ignored_flag_at"
t.integer "cached_votes_total", default: 0
t.integer "cached_votes_up", default: 0
t.integer "cached_votes_down", default: 0
+ t.datetime "ignored_flag_at"
t.integer "comments_count", default: 0
t.datetime "confirmed_hide_at"
t.integer "cached_anonymous_votes_total", default: 0
@@ -114,6 +114,7 @@ ActiveRecord::Schema.define(version: 20151103175139) do
add_index "debates", ["cached_votes_total"], name: "index_debates_on_cached_votes_total", using: :btree
add_index "debates", ["cached_votes_up"], name: "index_debates_on_cached_votes_up", using: :btree
add_index "debates", ["confidence_score"], name: "index_debates_on_confidence_score", using: :btree
+ add_index "debates", ["description"], name: "index_debates_on_description", using: :btree
add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree
add_index "debates", ["hot_score"], name: "index_debates_on_hot_score", using: :btree
add_index "debates", ["title"], name: "index_debates_on_title", using: :btree
@@ -220,6 +221,7 @@ ActiveRecord::Schema.define(version: 20151103175139) do
add_index "proposals", ["author_id"], name: "index_proposals_on_author_id", using: :btree
add_index "proposals", ["cached_votes_up"], name: "index_proposals_on_cached_votes_up", using: :btree
add_index "proposals", ["confidence_score"], name: "index_proposals_on_confidence_score", using: :btree
+ add_index "proposals", ["description"], name: "index_proposals_on_description", using: :btree
add_index "proposals", ["hidden_at"], name: "index_proposals_on_hidden_at", using: :btree
add_index "proposals", ["hot_score"], name: "index_proposals_on_hot_score", using: :btree
add_index "proposals", ["question"], name: "index_proposals_on_question", using: :btree
@@ -306,6 +308,7 @@ ActiveRecord::Schema.define(version: 20151103175139) do
t.datetime "level_two_verified_at"
t.string "erase_reason"
t.datetime "erased_at"
+ t.boolean "public_activity", default: true
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
diff --git a/spec/features/users_auth_spec.rb b/spec/features/users_auth_spec.rb
new file mode 100644
index 000000000..b23d956ac
--- /dev/null
+++ b/spec/features/users_auth_spec.rb
@@ -0,0 +1,192 @@
+require 'rails_helper'
+
+feature 'Users' do
+
+ context 'Regular authentication' do
+ scenario 'Sign up' do
+ visit '/'
+ click_link 'Register'
+
+ fill_in 'user_username', with: 'Manuela Carmena'
+ fill_in 'user_email', with: 'manuela@madrid.es'
+ fill_in 'user_password', with: 'judgementday'
+ fill_in 'user_password_confirmation', with: 'judgementday'
+ fill_in 'user_captcha', with: correct_captcha_text
+ check 'user_terms_of_service'
+
+ click_button 'Register'
+
+ expect(page).to have_content "You have been sent a message containing a verification link. Please click on this link to activate your account."
+
+ sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
+ visit user_confirmation_path(confirmation_token: sent_token)
+
+ expect(page).to have_content "Your account has been confirmed."
+ end
+
+ scenario 'Errors on sign up' do
+ visit '/'
+ click_link 'Register'
+ click_button 'Register'
+
+ expect(page).to have_content error_message
+ end
+
+ scenario 'Sign in' do
+ create(:user, email: 'manuela@madrid.es', password: 'judgementday')
+
+ visit '/'
+ click_link 'Sign in'
+ fill_in 'user_email', with: 'manuela@madrid.es'
+ fill_in 'user_password', with: 'judgementday'
+ click_button 'Enter'
+
+ expect(page).to have_content 'You have been signed in successfully.'
+ end
+ end
+
+ xcontext 'OAuth authentication' do
+ context 'Twitter' do
+ background do
+ #request.env["devise.mapping"] = Devise.mappings[:user]
+ end
+
+ scenario 'Sign up, when email was provided by OAuth provider' do
+ omniauth_twitter_hash = { 'provider' => 'twitter',
+ 'uid' => '12345',
+ 'info' => {
+ 'name' => 'manuela',
+ 'email' => 'manuelacarmena@example.com',
+ 'nickname' => 'ManuelaRocks',
+ 'verified' => '1'
+ },
+ 'extra' => { 'raw_info' =>
+ { 'location' => 'Madrid',
+ 'name' => 'Manuela de las Carmenas'
+ }
+ }
+ }
+
+ OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
+
+ visit '/'
+ click_link 'Register'
+
+ expect do
+ expect do
+ expect do
+ click_link 'Sign up with Twitter'
+ end.not_to change { ActionMailer::Base.deliveries.size }
+ end.to change { Identity.count }.by(1)
+ end.to change { User.count }.by(1)
+
+ expect(current_path).to eq(root_path)
+ expect_to_be_signed_in
+
+ user = User.last
+ expect(user.username).to eq('ManuelaRocks')
+ expect(user.email).to eq('manuelacarmena@example.com')
+ expect(user.confirmed?).to eq(true)
+ end
+
+ scenario 'Sign up, when neither email nor nickname were provided by OAuth provider' do
+ omniauth_twitter_hash = { 'provider' => 'twitter',
+ 'uid' => '12345',
+ 'info' => {
+ 'name' => 'manuela'
+ },
+ 'extra' => { 'raw_info' =>
+ { 'location' => 'Madrid',
+ 'name' => 'Manuela de las Carmenas'
+ }
+ }
+ }
+
+ OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
+
+ visit '/'
+ click_link 'Register'
+
+ expect do
+ expect do
+ expect do
+ click_link 'Sign up with Twitter'
+ end.not_to change { ActionMailer::Base.deliveries.size }
+ end.to change { Identity.count }.by(1)
+ end.to change { User.count }.by(1)
+
+ expect(current_path).to eq(finish_signup_path)
+
+ user = User.last
+ expect(user.username).to eq('manuela-de-las-carmenas')
+ expect(user.email).to eq("omniauth@participacion-12345-twitter.com")
+
+ fill_in 'user_email', with: 'manueladelascarmenas@example.com'
+ click_button 'Register'
+
+ sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
+ visit user_confirmation_path(confirmation_token: sent_token)
+
+ expect(page).to have_content "Your email address has been successfully confirmed"
+
+ expect(user.reload.email).to eq('manueladelascarmenas@example.com')
+ end
+
+ scenario 'Sign in, user was already signed up with OAuth' do
+ user = create(:user, email: 'manuela@madrid.es', password: 'judgementday')
+ identity = create(:identity, uid: '12345', provider: 'twitter', user: user)
+ omniauth_twitter_hash = { 'provider' => 'twitter',
+ 'uid' => '12345',
+ 'info' => {
+ 'name' => 'manuela'
+ }
+ }
+
+ OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
+
+ visit '/'
+ click_link 'Sign in'
+
+ expect do
+ expect do
+ click_link 'Sign in with Twitter'
+ end.not_to change { Identity.count }
+ end.not_to change { User.count }
+
+ expect_to_be_signed_in
+ end
+ end
+ end
+
+ scenario 'Sign out' do
+ user = create(:user)
+ login_as(user)
+
+ visit "/"
+ click_link 'Sign out'
+
+ expect(page).to have_content 'You have been signed out successfully.'
+ end
+
+ scenario 'Reset password' do
+ create(:user, email: 'manuela@madrid.es')
+
+ visit '/'
+ click_link 'Sign in'
+ click_link 'Forgotten your password?'
+
+ fill_in 'user_email', with: 'manuela@madrid.es'
+ click_button 'Send instructions'
+
+ expect(page).to have_content "In a few minutes, you will receive an email containing instructions on resetting your password."
+
+ sent_token = /.*reset_password_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
+ visit edit_user_password_path(reset_password_token: sent_token)
+
+ fill_in 'user_password', with: 'new password'
+ fill_in 'user_password_confirmation', with: 'new password'
+ click_button 'Change my password'
+
+ expect(page).to have_content "Your password has been changed successfully."
+ end
+end
diff --git a/spec/features/users_spec.rb b/spec/features/users_spec.rb
index b23d956ac..4b90e737b 100644
--- a/spec/features/users_spec.rb
+++ b/spec/features/users_spec.rb
@@ -2,191 +2,171 @@ require 'rails_helper'
feature 'Users' do
- context 'Regular authentication' do
- scenario 'Sign up' do
- visit '/'
- click_link 'Register'
+ feature 'Show (public page)' do
- fill_in 'user_username', with: 'Manuela Carmena'
- fill_in 'user_email', with: 'manuela@madrid.es'
- fill_in 'user_password', with: 'judgementday'
- fill_in 'user_password_confirmation', with: 'judgementday'
- fill_in 'user_captcha', with: correct_captcha_text
- check 'user_terms_of_service'
+ background do
+ @user = create(:user)
+ 1.times {create(:debate, author: @user)}
+ 2.times {create(:proposal, author: @user)}
+ 3.times {create(:comment, user: @user)}
- click_button 'Register'
-
- expect(page).to have_content "You have been sent a message containing a verification link. Please click on this link to activate your account."
-
- sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
- visit user_confirmation_path(confirmation_token: sent_token)
-
- expect(page).to have_content "Your account has been confirmed."
+ visit user_path(@user)
end
- scenario 'Errors on sign up' do
- visit '/'
- click_link 'Register'
- click_button 'Register'
-
- expect(page).to have_content error_message
+ scenario 'shows user public activity' do
+ expect(page).to have_content('1 Debate')
+ expect(page).to have_content('2 Proposals')
+ expect(page).to have_content('3 Comments')
end
- scenario 'Sign in' do
- create(:user, email: 'manuela@madrid.es', password: 'judgementday')
+ scenario 'shows only items where user has activity' do
+ @user.proposals.destroy_all
- visit '/'
- click_link 'Sign in'
- fill_in 'user_email', with: 'manuela@madrid.es'
- fill_in 'user_password', with: 'judgementday'
- click_button 'Enter'
+ expect(page).to_not have_content('0 Proposals')
+ expect(page).to have_content('1 Debate')
+ expect(page).to have_content('3 Comments')
+ end
- expect(page).to have_content 'You have been signed in successfully.'
+ scenario 'default filter is proposals' do
+ @user.proposals.each do |proposal|
+ expect(page).to have_content(proposal.title)
+ end
+
+ @user.debates.each do |debate|
+ expect(page).to_not have_content(debate.title)
+ end
+
+ @user.comments.each do |comment|
+ expect(page).to_not have_content(comment.body)
+ end
+ end
+
+ scenario 'shows debates by default if user has no proposals' do
+ @user.proposals.destroy_all
+ visit user_path(@user)
+
+ expect(page).to have_content(@user.debates.first.title)
+ end
+
+ scenario 'shows comments by default if user has no proposals nor debates' do
+ @user.proposals.destroy_all
+ @user.debates.destroy_all
+ visit user_path(@user)
+
+ @user.comments.each do |comment|
+ expect(page).to have_content(comment.body)
+ end
+ end
+
+ scenario 'filters' do
+ click_link '1 Debate'
+
+ @user.debates.each do |debate|
+ expect(page).to have_content(debate.title)
+ end
+
+ @user.proposals.each do |proposal|
+ expect(page).to_not have_content(proposal.title)
+ end
+
+ @user.comments.each do |comment|
+ expect(page).to_not have_content(comment.body)
+ end
+
+ click_link '3 Comments'
+
+ @user.comments.each do |comment|
+ expect(page).to have_content(comment.body)
+ end
+
+ @user.proposals.each do |proposal|
+ expect(page).to_not have_content(proposal.title)
+ end
+
+ @user.debates.each do |debate|
+ expect(page).to_not have_content(debate.title)
+ end
+
+ click_link '2 Proposals'
+
+ @user.proposals.each do |proposal|
+ expect(page).to have_content(proposal.title)
+ end
+
+ @user.comments.each do |comment|
+ expect(page).to_not have_content(comment.body)
+ end
+
+ @user.debates.each do |debate|
+ expect(page).to_not have_content(debate.title)
+ end
+ end
+
+ end
+
+ feature 'Public activity' do
+ background do
+ @user = create(:user)
+ end
+
+ scenario 'visible by default' do
+ visit user_path(@user)
+
+ expect(page).to have_content(@user.username)
+ expect(page).to_not have_content('activity list private')
+ end
+
+ scenario 'user can hide public page' do
+ login_as(@user)
+ visit account_path
+
+ uncheck 'account_public_activity'
+ click_button 'Save changes'
+
+ logout
+
+ visit user_path(@user)
+ expect(page).to have_content('activity list private')
+ end
+
+ scenario 'is always visible for the owner' do
+ login_as(@user)
+ visit account_path
+
+ uncheck 'account_public_activity'
+ click_button 'Save changes'
+
+ visit user_path(@user)
+ expect(page).to_not have_content('activity list private')
+ end
+
+ scenario 'is always visible for admins' do
+ login_as(@user)
+ visit account_path
+
+ uncheck 'account_public_activity'
+ click_button 'Save changes'
+
+ logout
+
+ login_as(create(:administrator).user)
+ visit user_path(@user)
+ expect(page).to_not have_content('activity list private')
+ end
+
+ scenario 'is always visible for moderators' do
+ login_as(@user)
+ visit account_path
+
+ uncheck 'account_public_activity'
+ click_button 'Save changes'
+
+ logout
+
+ login_as(create(:moderator).user)
+ visit user_path(@user)
+ expect(page).to_not have_content('activity list private')
end
end
- xcontext 'OAuth authentication' do
- context 'Twitter' do
- background do
- #request.env["devise.mapping"] = Devise.mappings[:user]
- end
-
- scenario 'Sign up, when email was provided by OAuth provider' do
- omniauth_twitter_hash = { 'provider' => 'twitter',
- 'uid' => '12345',
- 'info' => {
- 'name' => 'manuela',
- 'email' => 'manuelacarmena@example.com',
- 'nickname' => 'ManuelaRocks',
- 'verified' => '1'
- },
- 'extra' => { 'raw_info' =>
- { 'location' => 'Madrid',
- 'name' => 'Manuela de las Carmenas'
- }
- }
- }
-
- OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
-
- visit '/'
- click_link 'Register'
-
- expect do
- expect do
- expect do
- click_link 'Sign up with Twitter'
- end.not_to change { ActionMailer::Base.deliveries.size }
- end.to change { Identity.count }.by(1)
- end.to change { User.count }.by(1)
-
- expect(current_path).to eq(root_path)
- expect_to_be_signed_in
-
- user = User.last
- expect(user.username).to eq('ManuelaRocks')
- expect(user.email).to eq('manuelacarmena@example.com')
- expect(user.confirmed?).to eq(true)
- end
-
- scenario 'Sign up, when neither email nor nickname were provided by OAuth provider' do
- omniauth_twitter_hash = { 'provider' => 'twitter',
- 'uid' => '12345',
- 'info' => {
- 'name' => 'manuela'
- },
- 'extra' => { 'raw_info' =>
- { 'location' => 'Madrid',
- 'name' => 'Manuela de las Carmenas'
- }
- }
- }
-
- OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
-
- visit '/'
- click_link 'Register'
-
- expect do
- expect do
- expect do
- click_link 'Sign up with Twitter'
- end.not_to change { ActionMailer::Base.deliveries.size }
- end.to change { Identity.count }.by(1)
- end.to change { User.count }.by(1)
-
- expect(current_path).to eq(finish_signup_path)
-
- user = User.last
- expect(user.username).to eq('manuela-de-las-carmenas')
- expect(user.email).to eq("omniauth@participacion-12345-twitter.com")
-
- fill_in 'user_email', with: 'manueladelascarmenas@example.com'
- click_button 'Register'
-
- sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
- visit user_confirmation_path(confirmation_token: sent_token)
-
- expect(page).to have_content "Your email address has been successfully confirmed"
-
- expect(user.reload.email).to eq('manueladelascarmenas@example.com')
- end
-
- scenario 'Sign in, user was already signed up with OAuth' do
- user = create(:user, email: 'manuela@madrid.es', password: 'judgementday')
- identity = create(:identity, uid: '12345', provider: 'twitter', user: user)
- omniauth_twitter_hash = { 'provider' => 'twitter',
- 'uid' => '12345',
- 'info' => {
- 'name' => 'manuela'
- }
- }
-
- OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
-
- visit '/'
- click_link 'Sign in'
-
- expect do
- expect do
- click_link 'Sign in with Twitter'
- end.not_to change { Identity.count }
- end.not_to change { User.count }
-
- expect_to_be_signed_in
- end
- end
- end
-
- scenario 'Sign out' do
- user = create(:user)
- login_as(user)
-
- visit "/"
- click_link 'Sign out'
-
- expect(page).to have_content 'You have been signed out successfully.'
- end
-
- scenario 'Reset password' do
- create(:user, email: 'manuela@madrid.es')
-
- visit '/'
- click_link 'Sign in'
- click_link 'Forgotten your password?'
-
- fill_in 'user_email', with: 'manuela@madrid.es'
- click_button 'Send instructions'
-
- expect(page).to have_content "In a few minutes, you will receive an email containing instructions on resetting your password."
-
- sent_token = /.*reset_password_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
- visit edit_user_password_path(reset_password_token: sent_token)
-
- fill_in 'user_password', with: 'new password'
- fill_in 'user_password_confirmation', with: 'new password'
- click_button 'Change my password'
-
- expect(page).to have_content "Your password has been changed successfully."
- end
-end
+end
\ No newline at end of file
diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb
index 8e93f5bca..4775cd1ee 100644
--- a/spec/models/abilities/common_spec.rb
+++ b/spec/models/abilities/common_spec.rb
@@ -57,7 +57,7 @@ describe "Abilities::Common" do
describe "other users" do
let(:other_user) { create(:user) }
- it { should_not be_able_to(:show, other_user) }
+ it { should be_able_to(:show, other_user) }
it { should_not be_able_to(:edit, other_user) }
end