diff --git a/.rspec b/.rspec index 4e1e0d2f7..f26ef5abe 100644 --- a/.rspec +++ b/.rspec @@ -1 +1,2 @@ --color + diff --git a/Gemfile b/Gemfile index aeca43f64..9d6ee2da2 100644 --- a/Gemfile +++ b/Gemfile @@ -46,6 +46,7 @@ group :development, :test do gem 'rspec-rails', '~> 3.0' gem 'capybara' gem 'factory_girl_rails' + gem 'fuubar' gem 'launchy' gem 'quiet_assets' gem 'letter_opener_web', '~> 1.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 92b372edc..c47ad1ed3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -132,6 +132,9 @@ GEM activesupport (~> 4.1, >= 4.1.1) railties (~> 4.1, >= 4.1.1) tzinfo (~> 1.2, >= 1.2.2) + fuubar (2.0.0) + rspec (~> 3.0) + ruby-progressbar (~> 1.4) globalid (0.3.6) activesupport (>= 4.1.0) highline (1.7.3) @@ -224,6 +227,10 @@ GEM http-cookie (>= 1.0.2, < 2.0) mime-types (>= 1.16, < 3.0) netrc (~> 0.7) + rspec (3.3.0) + rspec-core (~> 3.3.0) + rspec-expectations (~> 3.3.0) + rspec-mocks (~> 3.3.0) rspec-core (3.3.2) rspec-support (~> 3.3.0) rspec-expectations (3.3.1) @@ -241,6 +248,7 @@ GEM rspec-mocks (~> 3.3.0) rspec-support (~> 3.3.0) rspec-support (3.3.0) + ruby-progressbar (1.7.5) sass (3.4.16) sass-rails (5.0.3) railties (>= 4.0.0, < 5.0) @@ -327,6 +335,7 @@ DEPENDENCIES factory_girl_rails foundation-rails foundation_rails_helper + fuubar i18n-tasks initialjs-rails jquery-rails diff --git a/app/assets/stylesheets/debates.scss b/app/assets/stylesheets/debates.scss index afc99b75a..c8b40f0c3 100644 --- a/app/assets/stylesheets/debates.scss +++ b/app/assets/stylesheets/debates.scss @@ -138,10 +138,6 @@ // 02. Index // - - - - - - - - - - - - - - - - - - - - - - - - - -.featured-debates { - margin-top: rem-calc(23); -} - .debate-featured { .panel { @@ -244,7 +240,6 @@ .debates-list { margin-bottom: rem-calc(48); - margin-top: rem-calc(24); } .debate { diff --git a/app/assets/stylesheets/participacion.scss b/app/assets/stylesheets/participacion.scss index 710fb8c6d..d6490f4ae 100644 --- a/app/assets/stylesheets/participacion.scss +++ b/app/assets/stylesheets/participacion.scss @@ -10,6 +10,7 @@ // 08. Forms // 09. Alerts // 10. User account +// 11. Filters // // 01. Variables @@ -111,7 +112,6 @@ h1, h2, h3, h4, h5, h6 { } .sidebar { - margin-top: rem-calc(24); margin-bottom: rem-calc(48); } @@ -585,3 +585,36 @@ form { } } } + +// 11. Filters +// - - - - - - - - - - - - - - - - - - - - - - - - - + +.filters { + + h2 { + display: inline-block; + font-size: rem-calc(24); + margin: rem-calc(24) 0; + } + + select { + height: auto; + margin: rem-calc(24) rem-calc(6); + min-width: rem-calc(180); + outline: 0; + padding: rem-calc(12); + width: auto; + + optgroup { + font-size: rem-calc(14); + } + + option { + + &:after { + content: "a"; + font-family: "icons"; + } + } + } +} diff --git a/app/controllers/admin/officials_controller.rb b/app/controllers/admin/officials_controller.rb new file mode 100644 index 000000000..023f0f7fc --- /dev/null +++ b/app/controllers/admin/officials_controller.rb @@ -0,0 +1,32 @@ +class Admin::OfficialsController < Admin::BaseController + + def index + @officials = User.officials.page(params[:page]) + end + + def search + @users = User.with_email(params[:email]).page(params[:page]) + end + + def edit + @user = User.find(params[:id]) + end + + def update + @user = User.find(params[:id]) + @user.update(user_params) + redirect_to admin_officials_path, notice: t("admin.officials.flash.official_updated") + end + + def destroy + @official = User.officials.find(params[:id]) + @official.remove_official_position! + redirect_to admin_officials_path, notice: t("admin.officials.flash.official_destroyed") + end + + private + def user_params + params.require(:user).permit(:official_position, :official_level) + end + +end \ No newline at end of file diff --git a/app/controllers/admin/settings_controller.rb b/app/controllers/admin/settings_controller.rb new file mode 100644 index 000000000..b369d2cbc --- /dev/null +++ b/app/controllers/admin/settings_controller.rb @@ -0,0 +1,17 @@ +class Admin::SettingsController < Admin::BaseController + + def index + @settings = Setting.all + end + + def update + @setting = Setting.find(params[:id]) + @setting.update(settings_params) + redirect_to admin_settings_path, notice: t("admin.settings.flash.updated") + end + + private + def settings_params + params.require(:setting).permit(:value) + end +end \ No newline at end of file diff --git a/app/controllers/admin/tags_controller.rb b/app/controllers/admin/tags_controller.rb index ecacdbdb2..03cfeb64f 100644 --- a/app/controllers/admin/tags_controller.rb +++ b/app/controllers/admin/tags_controller.rb @@ -1,5 +1,4 @@ class Admin::TagsController < Admin::BaseController - layout 'admin' before_action :find_tag, only: [:update, :destroy] respond_to :html, :js diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index a7fef3aa2..09d325e08 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -4,6 +4,14 @@ module AdminHelper render "/#{namespace}/menu" end + def official_level_options + options = [] + (0..5).each do |i| + options << [[t("admin.officials.level_#{i}"), Setting.value_for("official_level_#{i}_name")].compact.join(': '), i] + end + options + end + private def namespace diff --git a/app/models/setting.rb b/app/models/setting.rb new file mode 100644 index 000000000..1a52ebe60 --- /dev/null +++ b/app/models/setting.rb @@ -0,0 +1,7 @@ +class Setting < ActiveRecord::Base + default_scope { order(key: :desc) } + + def self.value_for(key) + where(key: key).pluck(:value).first + end +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 205a6bf5f..16d1de154 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -8,6 +8,9 @@ class User < ActiveRecord::Base validates :first_name, presence: true, unless: :use_nickname? validates :last_name, presence: true, unless: :use_nickname? validates :nickname, presence: true, if: :use_nickname? + validates :official_level, inclusion: {in: 0..5} + + scope :officials, -> { where("official_level > 0") } def name use_nickname? ? nickname : "#{first_name} #{last_name}" @@ -25,4 +28,21 @@ class User < ActiveRecord::Base def moderator? @is_moderator ||= Moderator.where(user_id: id).exists? end + + def official? + official_level && official_level > 0 + end + + def add_official_position!(position, level) + return if position.blank? || level.blank? + update official_position: position, official_level: level.to_i + end + + def remove_official_position! + update official_position: nil, official_level: 0 + end + + def self.with_email(e) + e.present? ? where(email: e) : none + end end diff --git a/app/views/admin/officials/edit.html.erb b/app/views/admin/officials/edit.html.erb new file mode 100644 index 000000000..b986df2b5 --- /dev/null +++ b/app/views/admin/officials/edit.html.erb @@ -0,0 +1,14 @@ +

<%= t("admin.officials.edit.title") %>

+ +<%= @user.name %> (<%= @user.email %>) +<%= form_for @user, url: admin_official_path(@user) do |f| %> + <%= f.text_field :official_position %> + <%= f.select :official_level, official_level_options %> + <%= f.submit %> + + <% if @user.official? %> + <%= link_to t("admin.officials.edit.destroy"), admin_official_path(@user), method: :delete, class: 'button tiny alert' %> + <% else %> + <%= link_to t("admin.officials.edit.cancel"), admin_officials_path, class: 'button tiny alert' %> + <% end %> +<% end %> \ No newline at end of file diff --git a/app/views/admin/officials/index.html.erb b/app/views/admin/officials/index.html.erb new file mode 100644 index 000000000..d0a98a963 --- /dev/null +++ b/app/views/admin/officials/index.html.erb @@ -0,0 +1,25 @@ +

<%= t("admin.officials.index.title") %>

+ +
+<%= form_for(User.new, url: search_admin_officials_path, as: :user, method: :get) do |f| %> + <%= text_field_tag :email, "", label: false, placeholder: t("admin.officials.index.search_email_placeholder") %> + <%= f.submit t("admin.officials.index.search") %> +<% end %> +
+ +
+<%= page_entries_info @officials %> +
+ +
+<% @officials.each do |official| %> + <%= link_to official.name, edit_admin_official_path(official) %> + <%= official.official_position %> + <%= t("admin.officials.level_#{official.official_level}") %> +

+<% end %> +
+ +
+<%= paginate @officials %> +
\ No newline at end of file diff --git a/app/views/admin/officials/search.html.erb b/app/views/admin/officials/search.html.erb new file mode 100644 index 000000000..9549c7ad0 --- /dev/null +++ b/app/views/admin/officials/search.html.erb @@ -0,0 +1,21 @@ +

<%= t("admin.officials.search.title") %>

+ +
+<%= form_for(User.new, url: search_admin_officials_path, as: :user, method: :get) do |f| %> + <%= text_field_tag :email, "", label: false, placeholder: t("admin.officials.index.search_email_placeholder") %> + <%= f.submit t("admin.officials.search.search") %> +<% end %> +
+ +
+<%= page_entries_info @users %> +
+ +
+<% @users.each do |user| %> + <%= link_to user.name, edit_admin_official_path(user) %> + <%= user.official_position %> + <%= t("admin.officials.level_#{user.official_level}") %> + <%= link_to user.official? ? t("admin.officials.search.edit_official") : t("admin.officials.search.make_official"), edit_admin_official_path(user) %> +<% end %> +
\ No newline at end of file diff --git a/app/views/admin/settings/index.html.erb b/app/views/admin/settings/index.html.erb new file mode 100644 index 000000000..321b307d0 --- /dev/null +++ b/app/views/admin/settings/index.html.erb @@ -0,0 +1,15 @@ +

<%= t("admin.settings.index.title") %>

+ + \ No newline at end of file diff --git a/app/views/debates/index.html.erb b/app/views/debates/index.html.erb index 3a3881b76..0e3e41d1d 100644 --- a/app/views/debates/index.html.erb +++ b/app/views/debates/index.html.erb @@ -1,6 +1,79 @@
+ + +
+
+

<%= t("debates.index.showing") %>

+ + + + +
+
+ + + +
+
+

<%= t("debates.index.showing") %>

+ + + + + +

<%= t("debates.index.tag") %>

+ + + +

(43)

+
+
+ +
-
+
<%= render @debates %>
@@ -10,4 +83,4 @@
-
\ No newline at end of file + diff --git a/app/views/welcome/index.html.erb b/app/views/welcome/index.html.erb index 434499859..ada595c02 100644 --- a/app/views/welcome/index.html.erb +++ b/app/views/welcome/index.html.erb @@ -1,5 +1,10 @@
-
\ 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