diff --git a/Gemfile b/Gemfile index 44c872c67..45f16f7b4 100644 --- a/Gemfile +++ b/Gemfile @@ -32,6 +32,7 @@ gem 'devise' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development +gem "responders" gem 'foundation-rails' group :development, :test do @@ -45,5 +46,6 @@ group :development, :test do gem 'spring' gem 'rspec-rails', '~> 3.0' gem 'capybara' + gem 'factory_girl_rails' end diff --git a/Gemfile.lock b/Gemfile.lock index ae27d30d2..01408b9c2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -68,6 +68,11 @@ GEM diff-lcs (1.2.5) erubis (2.7.0) execjs (2.5.2) + factory_girl (4.5.0) + activesupport (>= 3.0.0) + factory_girl_rails (4.5.0) + factory_girl (~> 4.5.0) + railties (>= 3.0.0) foundation-rails (5.5.2.1) railties (>= 3.1.0) sass (>= 3.3.0, < 3.5) @@ -187,10 +192,12 @@ DEPENDENCIES capybara coffee-rails (~> 4.1.0) devise + factory_girl_rails foundation-rails jbuilder (~> 2.0) jquery-rails rails (= 4.2.3) + responders rspec-rails (~> 3.0) sass-rails (~> 5.0) sdoc (~> 0.4.0) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d83690e1b..b64f11bb4 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,9 @@ +require "application_responder" + class ApplicationController < ActionController::Base + self.responder = ApplicationResponder + respond_to :html + # Prevent CSRF attacks by raising an exception. # For APIs, you may want to use :null_session instead. protect_from_forgery with: :exception diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb new file mode 100644 index 000000000..53545887e --- /dev/null +++ b/app/controllers/debates_controller.rb @@ -0,0 +1,38 @@ +class DebatesController < ApplicationController + before_action :set_debate, only: [:show, :edit, :update] + + def index + @debates = Debate.all + end + + def show + end + + def new + @debate = Debate.new + end + + def edit + end + + def create + @debate = Debate.create(debate_params) + respond_with @debate + end + + def update + @debate.update(debate_params) + respond_with @debate + end + + + private + def set_debate + @debate = Debate.find(params[:id]) + end + + def debate_params + params.require(:debate).permit(:title, :description, :external_link, :terms_of_service) + end + +end diff --git a/app/models/debate.rb b/app/models/debate.rb index 4e0f1012e..c66913c59 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -1,2 +1,6 @@ class Debate < ActiveRecord::Base + validates :title, presence: true + validates :description, presence: true + + validates :terms_of_service, acceptance: { allow_nil: false }, on: :create end diff --git a/app/views/debates/_debate.html.erb b/app/views/debates/_debate.html.erb new file mode 100644 index 000000000..4f99c9df9 --- /dev/null +++ b/app/views/debates/_debate.html.erb @@ -0,0 +1,6 @@ +
<%= link_to debate.title, debate %>
+<%= debate.description %>
+Creado el: <%= l debate.created_at.to_date %>
+Título del debate
+Sé claro y conciso a la hora de poner un título, pero recuerda que debe explicar bien tu idea, ¡es tu carta de entrada!
+ <%= f.text_field :title %> + +Describe tu opinión
+Explica con todo el detalle que puedas y de una manera sencilla la idea y que crees que conseguiríamos con ella
+ <%= f.text_area :description %> + + <% if action_name == 'new' %> + <%= f.check_box :terms_of_service %> + Acepto la política de privacidad y el aviso legal + <% end %> + +<%= @debate.title %>
+<%= @debate.description %>
+Creado el: <%= l @debate.created_at.to_date %>
+<%= notice %>
<%= alert %>
<%= yield %> diff --git a/config/application.rb b/config/application.rb index b2304b6ea..b8b69cec4 100644 --- a/config/application.rb +++ b/config/application.rb @@ -18,7 +18,7 @@ module Participacion # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] - # config.i18n.default_locale = :de + config.i18n.default_locale = :es # Do not swallow errors in after_commit/after_rollback callbacks. config.active_record.raise_in_transactional_callbacks = true diff --git a/config/locales/es.yml b/config/locales/es.yml new file mode 100644 index 000000000..68f7b4a06 --- /dev/null +++ b/config/locales/es.yml @@ -0,0 +1,198 @@ +--- +es: + date: + abbr_day_names: + - dom + - lun + - mar + - mié + - jue + - vie + - sáb + abbr_month_names: + - + - ene + - feb + - mar + - abr + - may + - jun + - jul + - ago + - sep + - oct + - nov + - dic + day_names: + - domingo + - lunes + - martes + - miércoles + - jueves + - viernes + - sábado + formats: + default: "%d/%m/%Y" + long: "%d de %B de %Y" + short: "%d de %b" + month_names: + - + - enero + - febrero + - marzo + - abril + - mayo + - junio + - julio + - agosto + - septiembre + - octubre + - noviembre + - diciembre + order: + - :day + - :month + - :year + datetime: + distance_in_words: + about_x_hours: + one: alrededor de 1 hora + other: alrededor de %{count} horas + about_x_months: + one: alrededor de 1 mes + other: alrededor de %{count} meses + about_x_years: + one: alrededor de 1 año + other: alrededor de %{count} años + almost_x_years: + one: casi 1 año + other: casi %{count} años + half_a_minute: medio minuto + less_than_x_minutes: + one: menos de 1 minuto + other: menos de %{count} minutos + less_than_x_seconds: + one: menos de 1 segundo + other: menos de %{count} segundos + over_x_years: + one: más de 1 año + other: más de %{count} años + x_days: + one: 1 día + other: "%{count} días" + x_minutes: + one: 1 minuto + other: "%{count} minutos" + x_months: + one: 1 mes + other: "%{count} meses" + x_seconds: + one: 1 segundo + other: "%{count} segundos" + prompts: + day: Día + hour: Hora + minute: Minutos + month: Mes + second: Segundos + year: Año + errors: + format: "%{attribute} %{message}" + messages: + accepted: debe ser aceptado + blank: no puede estar en blanco + present: debe estar en blanco + confirmation: no coincide + empty: no puede estar vacío + equal_to: debe ser igual a %{count} + even: debe ser par + exclusion: está reservado + greater_than: debe ser mayor que %{count} + greater_than_or_equal_to: debe ser mayor que o igual a %{count} + inclusion: no está incluido en la lista + invalid: no es válido + less_than: debe ser menor que %{count} + less_than_or_equal_to: debe ser menor que o igual a %{count} + not_a_number: no es un número + not_an_integer: debe ser un entero + odd: debe ser impar + record_invalid: 'La validación falló: %{errors}' + restrict_dependent_destroy: + one: No se puede eliminar el registro porque existe un %{record} dependiente + many: No se puede eliminar el registro porque existen %{record} dependientes + taken: ya está en uso + too_long: es demasiado largo (%{count} caracteres máximo) + too_short: es demasiado corto (%{count} caracteres mínimo) + wrong_length: no tiene la longitud correcta (%{count} caracteres exactos) + other_than: debe ser distinto de %{count} + template: + body: 'Se encontraron problemas con los siguientes campos:' + header: + one: No se pudo guardar este/a %{model} porque se encontró 1 error + other: No se pudo guardar este/a %{model} porque se encontraron %{count} errores + helpers: + select: + prompt: Por favor seleccione + submit: + create: Crear %{model} + submit: Guardar %{model} + update: Actualizar %{model} + number: + currency: + format: + delimiter: "." + format: "%n %u" + precision: 2 + separator: "," + significant: false + strip_insignificant_zeros: false + unit: "€" + format: + delimiter: "." + precision: 3 + separator: "," + significant: false + strip_insignificant_zeros: false + human: + decimal_units: + format: "%n %u" + units: + billion: mil millones + million: millón + quadrillion: mil billones + thousand: mil + trillion: billón + unit: '' + format: + delimiter: '' + precision: 1 + significant: true + strip_insignificant_zeros: true + storage_units: + format: "%n %u" + units: + byte: + one: Byte + other: Bytes + gb: GB + kb: KB + mb: MB + tb: TB + percentage: + format: + delimiter: '' + precision: + format: + delimiter: '' + support: + array: + last_word_connector: " y " + two_words_connector: " y " + words_connector: ", " + time: + am: am + formats: + default: "%A, %d de %B de %Y %H:%M:%S %z" + long: "%d de %B de %Y %H:%M" + short: "%d de %b %H:%M" + pm: pm \ No newline at end of file diff --git a/config/locales/responders.en.yml b/config/locales/responders.en.yml new file mode 100644 index 000000000..c3e147abf --- /dev/null +++ b/config/locales/responders.en.yml @@ -0,0 +1,12 @@ +en: + flash: + actions: + create: + notice: '%{resource_name} was successfully created.' + # alert: '%{resource_name} could not be created.' + update: + notice: '%{resource_name} was successfully updated.' + # alert: '%{resource_name} could not be updated.' + destroy: + notice: '%{resource_name} was successfully destroyed.' + alert: '%{resource_name} could not be destroyed.' diff --git a/config/locales/responders.es.yml b/config/locales/responders.es.yml new file mode 100644 index 000000000..aa3a47f0d --- /dev/null +++ b/config/locales/responders.es.yml @@ -0,0 +1,10 @@ +es: + flash: + actions: + create: + notice: "%{resource_name} creado correctamente." + update: + notice: "%{resource_name} actualizado correctamente." + destroy: + notice: "%{resource_name} borrado correctamente." + alert: "%{resource_name} no ha podido ser borrado." \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 26123d917..eae8764ed 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,6 +5,7 @@ Rails.application.routes.draw do # You can have the root of your site routed with "root" root 'welcome#index' + resources :debates # Example of regular route: # get 'products/:id' => 'catalog#view' diff --git a/db/migrate/20150716154501_remove_external_link_from_debates.rb b/db/migrate/20150716154501_remove_external_link_from_debates.rb new file mode 100644 index 000000000..5991b363d --- /dev/null +++ b/db/migrate/20150716154501_remove_external_link_from_debates.rb @@ -0,0 +1,5 @@ +class RemoveExternalLinkFromDebates < ActiveRecord::Migration + def change + remove_column :debates, :external_link + end +end diff --git a/lib/application_responder.rb b/lib/application_responder.rb new file mode 100644 index 000000000..cc3e58885 --- /dev/null +++ b/lib/application_responder.rb @@ -0,0 +1,8 @@ +class ApplicationResponder < ActionController::Responder + include Responders::FlashResponder + include Responders::HttpCacheResponder + + # Redirects resources to the collection path (index action) instead + # of the resource path (show action) for POST/PUT/DELETE requests. + # include Responders::CollectionResponder +end diff --git a/spec/factories.rb b/spec/factories.rb new file mode 100644 index 000000000..58f320ea7 --- /dev/null +++ b/spec/factories.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :debate do + title 'Debate title' + description 'Debate description' + terms_of_service '1' + end +end \ No newline at end of file diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb new file mode 100644 index 000000000..48f7d3b62 --- /dev/null +++ b/spec/features/debates_spec.rb @@ -0,0 +1,55 @@ +require 'rails_helper' + +feature 'Debates' do + + scenario 'Index' do + 3.times { create(:debate) } + + visit debates_path + + expect(page).to have_selector('.debate', count: 3) + within first('.debate') do + expect(page).to have_content "Debate title" + expect(page).to have_content "Debate description" + expect(page).to have_content "Creado el: #{I18n.l Date.today}" + end + end + + scenario 'Show' do + debate = create(:debate) + + visit debate_path(debate) + + expect(page).to have_content "Debate title" + expect(page).to have_content "Debate description" + expect(page).to have_content "Creado el: #{I18n.l Date.today}" + end + + scenario 'Create' do + visit new_debate_path + fill_in 'debate_title', with: 'Acabar con los desahucios' + fill_in 'debate_description', with: 'Esto es un tema muy importante porque...' + check 'debate_terms_of_service' + + click_button 'Crear Debate' + + expect(page).to have_content 'Debate creado correctamente' + expect(page).to have_content 'Acabar con los desahucios' + expect(page).to have_content 'Esto es un tema muy importante porque...' + end + + scenario 'Update' do + debate = create(:debate) + + visit edit_debate_path(debate) + fill_in 'debate_title', with: 'Dimisión Rajoy' + fill_in 'debate_description', with: 'Podríamos...' + + click_button 'Actualizar Debate' + + expect(page).to have_content 'Debate actualizado correctamente' + expect(page).to have_content 'Dimisión Rajoy' + expect(page).to have_content 'Podríamos...' + end + +end diff --git a/spec/models/debate_spec.rb b/spec/models/debate_spec.rb index 768e6feec..490eea985 100644 --- a/spec/models/debate_spec.rb +++ b/spec/models/debate_spec.rb @@ -1,5 +1,28 @@ require 'rails_helper' -RSpec.describe Debate, type: :model do - pending "add some examples to (or delete) #{__FILE__}" +describe Debate do + + before(:each) do + @debate = build(:debate) + end + + it "should be valid" do + expect(@debate).to be_valid + end + + it "should not be valid without a title" do + @debate.title = nil + expect(@debate).to_not be_valid + end + + it "should not be valid without a description" do + @debate.description = nil + expect(@debate).to_not be_valid + end + + it "should not be valid without accepting terms of service" do + @debate.terms_of_service = nil + expect(@debate).to_not be_valid + end + end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d0b233102..7ad54cc81 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,8 @@ +require 'factory_girl_rails' RSpec.configure do |config| config.filter_run :focus config.run_all_when_everything_filtered = true + config.include FactoryGirl::Syntax::Methods # Allows RSpec to persist some state between runs in order to support # the `--only-failures` and `--next-failure` CLI options.