+
+
+
<%= t("welcome.featured_debates") %>
+
+
+
<%= render partial: "featured_debate", collection: @featured_debates %>
-
\ No newline at end of file
+
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index 5e6eb2899..d2eef0c1d 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -93,14 +93,13 @@ ignore_missing:
## Consider these keys used:
ignore_unused:
- - 'activerecord.*'
+ - 'unauthorized.*'
+ - 'simple_captcha.*'
+ - 'admin.officials.level_*'
# - '{devise,kaminari,will_paginate}.*'
# - 'simple_form.{yes,no}'
# - 'simple_form.{placeholders,hints,labels}.*'
# - 'simple_form.{error_notification,required}.:'
-ignore_unused:
- - 'unauthorized.*'
- - 'simple_captcha.*'
## Exclude these keys from the `i18n-tasks eq-base' report:
# ignore_eq_base:
diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb
new file mode 100644
index 000000000..b1d87b01b
--- /dev/null
+++ b/config/initializers/kaminari_config.rb
@@ -0,0 +1,10 @@
+Kaminari.configure do |config|
+ # config.default_per_page = 25
+ # config.max_per_page = nil
+ # config.window = 4
+ # config.outer_window = 0
+ # config.left = 0
+ # config.right = 0
+ # config.page_method_name = :page
+ # config.param_name = :page
+end
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 2bdab2317..dcf924632 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -21,3 +21,5 @@ en:
last_name: "Last name"
nickname: Nickname
password: Password
+ official_position: Official position
+ official_level: Official level
diff --git a/config/locales/activerecord.es.yml b/config/locales/activerecord.es.yml
index 6a3d0b28c..dccc9cee2 100644
--- a/config/locales/activerecord.es.yml
+++ b/config/locales/activerecord.es.yml
@@ -21,3 +21,5 @@ es:
last_name: Apellidos
nickname: Pseudónimo
password: Contraseña
+ official_position: Cargo público
+ official_level: Nivel del cargo
\ No newline at end of file
diff --git a/config/locales/admin.en.yml b/config/locales/admin.en.yml
index 3f922f5eb..76bd55598 100644
--- a/config/locales/admin.en.yml
+++ b/config/locales/admin.en.yml
@@ -1,12 +1,19 @@
en:
admin:
+ settings:
+ index:
+ title: Global settings
+ flash:
+ updated: 'Setting updated!'
dashboard:
index:
title: Administration
menu:
+ settings: Global settings
debate_topics: Debate topics
hidden_debates: Hidden debates
hidden_comments: Hidden comments
+ officials: Officials
actions:
hide: Hide
restore: Restore
@@ -31,3 +38,26 @@ en:
back: Back
restore:
success: The debate has been restored
+ officials:
+ level_0: Level 0
+ level_1: Level 1
+ level_2: Level 2
+ level_3: Level 3
+ level_4: Level 4
+ level_5: Level 5
+ index:
+ title: Officials
+ search_email_placeholder: 'Search user by email'
+ search: Search
+ search:
+ title: 'Officials: Search users'
+ edit_official: Edit official
+ make_official: Make this user an official
+ search: Search
+ edit:
+ title: 'Officials: edit user'
+ destroy: "Remove 'Official' condition"
+ cancel: "Cancel"
+ flash:
+ official_updated: 'Official position saved!'
+ official_destroyed: 'User is not an official anymore'
diff --git a/config/locales/admin.es.yml b/config/locales/admin.es.yml
index 58a23bcde..4889f4813 100644
--- a/config/locales/admin.es.yml
+++ b/config/locales/admin.es.yml
@@ -1,12 +1,19 @@
es:
admin:
+ settings:
+ index:
+ title: Configuración global
+ flash:
+ updated: 'Valor actualizado'
dashboard:
index:
title: Administración
menu:
+ settings: Configuración global
debate_topics: Temas de debate
hidden_debates: Debates ocultos
hidden_comments: Comentarios ocultos
+ officials: Cargos públicos
actions:
hide: Ocultar
restore: Permitir
@@ -31,3 +38,26 @@ es:
back: Volver
restore:
success: El debate ha sido permitido
+ officials:
+ level_0: Nivel 0
+ level_1: Nivel 1
+ level_2: Nivel 2
+ level_3: Nivel 3
+ level_4: Nivel 4
+ level_5: Nivel 5
+ index:
+ title: Cargos Públicos
+ search_email_placeholder: 'Buscar usuario por email'
+ search: Buscar
+ search:
+ title: 'Cargos Públicos: Búsqueda de usuarios'
+ edit_official: Editar cargo público
+ make_official: Convertir en cargo público
+ search: Buscar
+ edit:
+ title: 'Cargos Públicos: Editar usuario'
+ destroy: "Eliminar condición de 'Cargo Público'"
+ cancel: "Cancelar"
+ flash:
+ official_updated: 'Datos del cargo público guardados'
+ official_destroyed: 'Datos guardados: el usuario ya no es cargo público'
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 0866dfa7d..9b60136d6 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -31,6 +31,14 @@ en:
debates:
index:
create_debate: Create a debate
+ showing: You are seeing
+ tag: with the topic
+ filter_debates: debates
+ filter_initiatives: initiatives
+ filter_debates_and_initiatives: debates and initiatives
+ filter_news: the newest
+ filter_votes: the most voted
+ filter_rated: the best rated
debate:
debate: Debate
comments:
@@ -129,3 +137,5 @@ en:
default: "You are not authorized to access this page."
manage:
all: "You are not authorized to %{action} %{subject}."
+ welcome:
+ featured_debates: Features debates
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 1091a30e9..41dc92104 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -31,6 +31,14 @@ es:
debates:
index:
create_debate: Crea un debate
+ showing: "Estás viendo"
+ tag: "con el tema"
+ filter_debates: debates
+ filter_initiatives: iniciativas
+ filter_debates_and_initiatives: debates e iniciativas
+ filter_news: "más nuevos"
+ filter_votes: "más votados"
+ filter_rated: mejor valorados
debate:
debate: Debate
comments:
@@ -127,17 +135,7 @@ es:
subject: Alguien ha respondido a tu comentario
unauthorized:
default: "No tienes permiso para acceder a esta página."
- index:
- all: "No tienes permiso para listar %{subject}"
- show:
- all: "No tienes permiso para ver %{subject}"
- edit:
- all: "No tienes permiso para editar %{subject}"
- update:
- all: "No tienes permiso para modificar %{subject}"
- create:
- all: "No tienes permiso para crear %{subject}"
- delete:
- all: "No tienes permiso para borrar %{subject}"
manage:
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."
+ welcome:
+ featured_debates: Debates destacados
diff --git a/config/locales/kaminari.en.yml b/config/locales/kaminari.en.yml
new file mode 100644
index 000000000..e73c82637
--- /dev/null
+++ b/config/locales/kaminari.en.yml
@@ -0,0 +1,17 @@
+en:
+ views:
+ pagination:
+ first: "« First"
+ last: "Last »"
+ previous: "‹ Prev"
+ next: "Next ›"
+ truncate: "…"
+ helpers:
+ page_entries_info:
+ one_page:
+ display_entries:
+ zero: "No %{entry_name} found"
+ one: "Displaying
1 %{entry_name}"
+ other: "Displaying
all %{count} %{entry_name}"
+ more_pages:
+ display_entries: "Displaying %{entry_name}
%{first} - %{last} of
%{total} in total"
\ No newline at end of file
diff --git a/config/locales/kaminari.es.yml b/config/locales/kaminari.es.yml
new file mode 100644
index 000000000..50a2fe90c
--- /dev/null
+++ b/config/locales/kaminari.es.yml
@@ -0,0 +1,17 @@
+es:
+ views:
+ pagination:
+ first: "« Primera"
+ last: "Última »"
+ previous: "‹ Anterior"
+ next: "Siguiente ›"
+ truncate: "…"
+ helpers:
+ page_entries_info:
+ one_page:
+ display_entries:
+ zero: "No se han encontrado %{entry_name}"
+ one: "Encontrado
1 %{entry_name}"
+ other: "Encontrados
%{count} %{entry_name}"
+ more_pages:
+ display_entries: "Se muestran
del %{first} al %{last} de un total de
%{total} %{entry_name}"
\ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 27f558e69..ea8e71b52 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -29,6 +29,11 @@ Rails.application.routes.draw do
end
resources :tags, only: [:index, :create, :update, :destroy]
+ resources :officials, only: [:index, :edit, :update, :destroy] do
+ collection { get :search}
+ end
+
+ resources :settings, only: [:index, :update]
end
namespace :moderation do
diff --git a/db/migrate/20150814074250_add_official_position_to_user.rb b/db/migrate/20150814074250_add_official_position_to_user.rb
new file mode 100644
index 000000000..49719f510
--- /dev/null
+++ b/db/migrate/20150814074250_add_official_position_to_user.rb
@@ -0,0 +1,6 @@
+class AddOfficialPositionToUser < ActiveRecord::Migration
+ def change
+ add_column :users, :official_position, :string
+ add_column :users, :official_level, :integer, default: 0
+ end
+end
diff --git a/db/migrate/20150817150457_add_settings.rb b/db/migrate/20150817150457_add_settings.rb
new file mode 100644
index 000000000..1ba7fe9c6
--- /dev/null
+++ b/db/migrate/20150817150457_add_settings.rb
@@ -0,0 +1,8 @@
+class AddSettings < ActiveRecord::Migration
+ def change
+ create_table :settings do |t|
+ t.string :key
+ t.string :value
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index f35d265f6..a7c0bbd44 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,8 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150815154430) do
+ActiveRecord::Schema.define(version: 20150817150457) do
+
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -58,6 +59,11 @@ ActiveRecord::Schema.define(version: 20150815154430) do
add_index "moderators", ["user_id"], name: "index_moderators_on_user_id", using: :btree
+ create_table "settings", force: :cascade do |t|
+ t.string "key"
+ t.string "value"
+ end
+
create_table "simple_captcha_data", force: :cascade do |t|
t.string "key", limit: 40
t.string "value", limit: 6
@@ -111,6 +117,8 @@ ActiveRecord::Schema.define(version: 20150815154430) do
t.boolean "use_nickname", default: false, null: false
t.boolean "email_on_debate_comment", default: false
t.boolean "email_on_comment_reply", default: false
+ t.string "official_position"
+ t.integer "official_level", default: 0
end
add_index "users", ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true, using: :btree
diff --git a/db/seeds.rb b/db/seeds.rb
index 4edb1e857..7a5bbdc8d 100644
--- a/db/seeds.rb
+++ b/db/seeds.rb
@@ -1,7 +1,8 @@
-# This file should contain all the record creation needed to seed the database with its default values.
-# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
-#
-# Examples:
-#
-# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
-# Mayor.create(name: 'Emanuel', city: cities.first)
+# Names for the moderation console, as a hint for moderators
+# to know better how to assign users with official positions
+Setting.create(key: 'official_level_0_name', value: 'No cargo público')
+Setting.create(key: 'official_level_1_name', value: 'Organización Municipal')
+Setting.create(key: 'official_level_2_name', value: 'Funcionariado')
+Setting.create(key: 'official_level_3_name', value: 'Directores generales')
+Setting.create(key: 'official_level_4_name', value: 'Concejales')
+Setting.create(key: 'official_level_5_name', value: 'Alcaldes')
\ No newline at end of file
diff --git a/spec/factories.rb b/spec/factories.rb
index 3a06c4701..72c5d5522 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -55,4 +55,9 @@ FactoryGirl.define do
end
end
+ factory :setting do
+ sequence(:key) { |n| "setting key number #{n}" }
+ sequence(:value) { |n| "setting number #{n} value" }
+ end
+
end
diff --git a/spec/features/admin/officials_spec.rb b/spec/features/admin/officials_spec.rb
new file mode 100644
index 000000000..6824ccf62
--- /dev/null
+++ b/spec/features/admin/officials_spec.rb
@@ -0,0 +1,78 @@
+require 'rails_helper'
+
+feature 'Admin officials' do
+
+ background do
+ @citizen = create(:user, first_name: "Citizen", last_name: "Kane")
+ @official = create(:user, official_position: "Mayor", official_level: 5)
+ @admin = create(:administrator)
+ login_as(@admin.user)
+ end
+
+ scenario 'Index' do
+ visit admin_officials_path
+
+ expect(page).to have_content @official.name
+ expect(page).to_not have_content @citizen.name
+ expect(page).to have_content @official.official_position
+ expect(page).to have_content @official.official_level
+ end
+
+ scenario 'Edit an official' do
+ visit admin_officials_path
+ click_link @official.name
+
+ expect(current_path).to eq(edit_admin_official_path(@official))
+
+ expect(page).to_not have_content @citizen.name
+ expect(page).to have_content @official.name
+ expect(page).to have_content @official.email
+
+ fill_in 'user_official_position', with: 'School Teacher'
+ select '3', from: 'user_official_level'
+ click_button 'Update User'
+
+ expect(page).to have_content 'Official position saved!'
+
+ visit admin_officials_path
+
+ expect(page).to have_content @official.name
+ expect(page).to have_content 'School Teacher'
+ expect(page).to have_content '3'
+ end
+
+ scenario 'Create an official' do
+ visit admin_officials_path
+ fill_in 'email', with: @citizen.email
+ click_button 'Search'
+
+ expect(current_path).to eq(search_admin_officials_path)
+ expect(page).to_not have_content @official.name
+
+ click_link @citizen.name
+
+ fill_in 'user_official_position', with: 'Hospital manager'
+ select '4', from: 'user_official_level'
+ click_button 'Update User'
+
+ expect(page).to have_content 'Official position saved!'
+
+ visit admin_officials_path
+
+ expect(page).to have_content @official.name
+ expect(page).to have_content @citizen.name
+ expect(page).to have_content 'Hospital manager'
+ expect(page).to have_content '4'
+ end
+
+ scenario 'Destroy' do
+ visit edit_admin_official_path(@official)
+
+ click_link "Remove 'Official' condition"
+
+ expect(page).to have_content 'User is not an official anymore'
+ expect(current_path).to eq(admin_officials_path)
+ expect(page).to_not have_content @citizen.name
+ expect(page).to_not have_content @official.name
+ end
+end
\ No newline at end of file
diff --git a/spec/features/admin/settings_spec.rb b/spec/features/admin/settings_spec.rb
new file mode 100644
index 000000000..a64e48a6a
--- /dev/null
+++ b/spec/features/admin/settings_spec.rb
@@ -0,0 +1,30 @@
+require 'rails_helper'
+
+feature 'Admin settings' do
+
+ background do
+ @setting1 = create(:setting)
+ @setting2 = create(:setting)
+ @setting3 = create(:setting)
+ login_as(create(:administrator).user)
+ end
+
+ scenario 'Index' do
+ visit admin_settings_path
+
+ expect(page).to have_content @setting1.key.classify
+ expect(page).to have_content @setting2.key.classify
+ expect(page).to have_content @setting3.key.classify
+ end
+
+ scenario 'Update' do
+ visit admin_settings_path
+
+ within("#edit_setting_#{@setting2.id}") do
+ fill_in "setting_#{@setting2.id}", with: 'Super Users of level 2'
+ click_button 'Update Setting'
+ end
+
+ expect(page).to have_content 'Setting updated!'
+ end
+end
\ No newline at end of file
diff --git a/spec/features/moderation/debates_spec.rb b/spec/features/moderation/debates_spec.rb
index 388044a72..5692a8b5b 100644
--- a/spec/features/moderation/debates_spec.rb
+++ b/spec/features/moderation/debates_spec.rb
@@ -15,6 +15,8 @@ feature 'Moderate debates' do
click_link 'Hide'
end
+ expect(page).to have_css("#debate_#{debate.id}.faded")
+
login_as(citizen)
visit debates_path
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 10191576b..2d8d83562 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -107,4 +107,80 @@ describe User do
end
end
+ describe "official?" do
+ it "is false when the user is not an official" do
+ expect(subject.official_level).to eq(0)
+ expect(subject.official?).to be false
+ end
+
+ it "is true when the user is an official" do
+ subject.official_level = 3
+ subject.save
+ expect(subject.official?).to be true
+ end
+ end
+
+ describe "add_official_position!" do
+ it "is false when level not valid" do
+ expect(subject.add_official_position!("Boss", 89)).to be false
+ end
+
+ it "updates official position fields" do
+ expect(subject).not_to be_official
+ subject.add_official_position!("Veterinarian", 2)
+
+ expect(subject).to be_official
+ expect(subject.official_position).to eq("Veterinarian")
+ expect(subject.official_level).to eq(2)
+
+ subject.add_official_position!("Brain surgeon", 3)
+ expect(subject.official_position).to eq("Brain surgeon")
+ expect(subject.official_level).to eq(3)
+ end
+ end
+
+ describe "remove_official_position!" do
+ it "updates official position fields" do
+ subject.add_official_position!("Brain surgeon", 3)
+ expect(subject).to be_official
+
+ subject.remove_official_position!
+
+ expect(subject).not_to be_official
+ expect(subject.official_position).to be_nil
+ expect(subject.official_level).to eq(0)
+ end
+ end
+
+ describe "officials scope" do
+ it "returns only users with official positions" do
+ create(:user, official_position: "Mayor", official_level: 1)
+ create(:user, official_position: "Director", official_level: 3)
+ create(:user, official_position: "Math Teacher", official_level: 4)
+ create(:user, official_position: "Manager", official_level: 5)
+ 2.times { create(:user) }
+
+ officials = User.officials
+ expect(officials.size).to eq(4)
+ officials.each do |user|
+ expect(user.official_level).to be > 0
+ expect(user.official_position).to be_present
+ end
+ end
+ end
+
+ describe "self.with_email" do
+ it "find users by email" do
+ user1 = create(:user, email: "larry@madrid.es")
+ user2 = create(:user, email: "bird@madrid.es")
+ search = User.with_email("larry@madrid.es")
+ expect(search.size).to eq(1)
+ expect(search.first).to eq(user1)
+ end
+
+ it "returns no results if no email provided" do
+ expect(User.with_email(" ").size).to eq(0)
+ end
+ end
+
end