From 4f853a7cdbd1ae1071248a3334010c5fc7232c13 Mon Sep 17 00:00:00 2001 From: Matt Powell Date: Mon, 5 Oct 2015 13:35:42 +1300 Subject: [PATCH] update event settings --- app/concepts/power.rb | 6 +++-- app/controllers/events_controller.rb | 23 +++++++++++----- app/helpers/forms_helper.rb | 5 ++++ app/models/event.rb | 4 +++ app/services/events/update_event.rb | 14 ++++++++++ app/views/events/_form.html.haml | 20 ++++++++++++++ app/views/events/edit.html.haml | 1 + app/views/events/new.html.haml | 21 +-------------- config/locales/en.yml | 3 ++- features/events/create_event.feature | 2 +- features/events/edit_event.feature | 14 ++++++++++ features/step_definitions/event_steps.rb | 33 +++++++++++++++++++++++ spec/services/events/update_event_spec.rb | 29 ++++++++++++++++++++ 13 files changed, 145 insertions(+), 30 deletions(-) create mode 100644 app/services/events/update_event.rb create mode 100644 app/views/events/_form.html.haml create mode 100644 app/views/events/edit.html.haml create mode 100644 features/events/edit_event.feature create mode 100644 spec/services/events/update_event_spec.rb diff --git a/app/concepts/power.rb b/app/concepts/power.rb index e88a777..a1865c8 100644 --- a/app/concepts/power.rb +++ b/app/concepts/power.rb @@ -21,8 +21,10 @@ def initialize(user) end power(:creatable_events) { @user.presence && events } - power(:updatable_events) { events } - power(:destroyable_events) { events } + power(:updatable_events) do + @user.admin? && events || events.administered_by(@user) + end + power(:destroyable_events) { updatable_events } power :assignable_event_fields do [:name, :slug, :starts_on, :ends_on] diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index 6c370bd..57a5cb5 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -16,12 +16,16 @@ def new end def create - create_event = CreateEvent.new(current_user, event_params) - create_event.call - respond_with_success(create_event) + create_or_update_event(CreateEvent.new(current_user, event_params)) + end - rescue ActiveRecord::RecordInvalid - respond_with_failure(create_event) + def edit + current_power.updatable_event!(@event) + end + + def update + current_power.updatable_event!(@event) + create_or_update_event(UpdateEvent.new(@event, event_params)) end private @@ -34,9 +38,16 @@ def load_event @event ||= events.find_by(slug: params[:id]) end + def create_or_update_event(service) + service.call + respond_with_success(service) + rescue ActiveRecord::RecordInvalid + respond_with_failure(service) + end + def respond_with_success(service) respond_to do |format| - format.html { redirect_to(service.event) } + format.html { redirect_to(edit_event_path(service.event)) } format.json { render(json: service.event) } end end diff --git a/app/helpers/forms_helper.rb b/app/helpers/forms_helper.rb index 001ac79..7666f99 100644 --- a/app/helpers/forms_helper.rb +++ b/app/helpers/forms_helper.rb @@ -3,6 +3,11 @@ def inline_errors_for(instance, field) error_messages_for(instance, field).join end + def save_button(form) + action = form.object.new_record? ? "create" : "save" + button_tag(t(".#{action}"), type: :submit) + end + private def error_messages_for(instance, field) diff --git a/app/models/event.rb b/app/models/event.rb index cebab19..50a0b94 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -14,6 +14,10 @@ def to_param slug end + def self.administered_by(user) + joins(:administrators).where(administrators: { user_id: user.id }) + end + private def generate_slug diff --git a/app/services/events/update_event.rb b/app/services/events/update_event.rb new file mode 100644 index 0000000..e39a650 --- /dev/null +++ b/app/services/events/update_event.rb @@ -0,0 +1,14 @@ +class UpdateEvent + attr_reader :event + + delegate :errors, to: :event + + def initialize(event, params) + @event = event + @params = params + end + + def call + @event.update!(@params) + end +end diff --git a/app/views/events/_form.html.haml b/app/views/events/_form.html.haml new file mode 100644 index 0000000..bdf938a --- /dev/null +++ b/app/views/events/_form.html.haml @@ -0,0 +1,20 @@ += form_for @event do |form| + = @event.errors.inspect + + = form.label(:name) + = form.text_field(:name) + = inline_errors_for(@event, :name) + + = form.label(:slug) + = form.text_field(:slug) + = inline_errors_for(@event, :slug) + + = form.label(:starts_on) + = form.date_field(:starts_on) + = inline_errors_for(@event, :starts_on) + + = form.label(:ends_on) + = form.date_field(:ends_on) + = inline_errors_for(@event, :ends_on) + + = save_button(form) diff --git a/app/views/events/edit.html.haml b/app/views/events/edit.html.haml new file mode 100644 index 0000000..b1bc3ba --- /dev/null +++ b/app/views/events/edit.html.haml @@ -0,0 +1 @@ += render "form" diff --git a/app/views/events/new.html.haml b/app/views/events/new.html.haml index 124d85c..b1bc3ba 100644 --- a/app/views/events/new.html.haml +++ b/app/views/events/new.html.haml @@ -1,20 +1 @@ -= form_for @event do |form| - = @event.errors.inspect - - = form.label(:name) - = form.text_field(:name) - = inline_errors_for(@event, :name) - - = form.label(:slug) - = form.text_field(:slug) - = inline_errors_for(@event, :slug) - - = form.label(:starts_on) - = form.date_field(:starts_on) - = inline_errors_for(@event, :starts_on) - - = form.label(:ends_on) - = form.date_field(:ends_on) - = inline_errors_for(@event, :ends_on) - - = button_tag t(".create"), type: :submit += render "form" diff --git a/config/locales/en.yml b/config/locales/en.yml index 023bed7..d65b2ba 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -10,5 +10,6 @@ en: updated: "Your profile was updated" events: - new: + form: create: "Create event" + save: "Save settings" diff --git a/features/events/create_event.feature b/features/events/create_event.feature index 59332fb..b4acd19 100644 --- a/features/events/create_event.feature +++ b/features/events/create_event.feature @@ -8,7 +8,7 @@ Feature: Create an event When I visit the new event page And I enter my event details And I click the "Create event" button - Then I should be on the event's page + Then I should be on the event settings page And I should see the event's name Scenario: Attempt to create an event when not logged in diff --git a/features/events/edit_event.feature b/features/events/edit_event.feature new file mode 100644 index 0000000..9a647be --- /dev/null +++ b/features/events/edit_event.feature @@ -0,0 +1,14 @@ +Feature: Edit event settings + In order to manage my event + As an event administrator + I want to edit my event's settings + + Scenario: Change event name + Given I am logged in as an event administrator + When I visit the event settings page + And I enter a new event name + And I click the "Save settings" button + Then I should be on the event settings page + And I should see "updated" + And I should see the new event name + And the event should have been updated diff --git a/features/step_definitions/event_steps.rb b/features/step_definitions/event_steps.rb index 0ba0c0c..8fd5b41 100644 --- a/features/step_definitions/event_steps.rb +++ b/features/step_definitions/event_steps.rb @@ -2,10 +2,25 @@ @event = FactoryGirl.create(:event) end +Given(/^I am an event administrator$/) do + step("I am an existing user") unless @user + step("an event exists") + Administrator.create(user: @user, event: @event) +end + +Given(/^I am logged in as an event administrator$/) do + step("I am logged in") + step("I am an event administrator") +end + When(/^I visit the new event page$/) do visit(new_event_path) end +When(/^I visit the event settings page$/) do + visit(edit_event_path(@event)) +end + When(/^I enter (?:my|the) event details$/) do @event ||= FactoryGirl.build(:event).tap(&:validate) fill_in("Name", with: @event.name) @@ -14,6 +29,11 @@ fill_in("End date", with: @event.ends_on) end +When(/^I enter a new event name$/) do + @new_event_name = "New event name" + fill_in("Name", with: @new_event_name) +end + Then(/^I should be on the event's page$/) do expect(page.current_path).to eq(event_path(@event)) end @@ -22,6 +42,19 @@ expect(page.current_path).to eq(new_event_path) end +Then(/^I should be on the event settings page$/) do + expect(page.current_path).to eq(edit_event_path(@event)) +end + Then(/^I should see the event's name$/) do expect(page).to have_content(@event.name) end + +Then(/^I should see the new event name$/) do + expect(page).to have_content(@new_event_name) +end + +Then(/^the event should have been updated$/) do + @event.reload + expect(@event.name).to eq(@new_event_name) +end diff --git a/spec/services/events/update_event_spec.rb b/spec/services/events/update_event_spec.rb new file mode 100644 index 0000000..a4afb90 --- /dev/null +++ b/spec/services/events/update_event_spec.rb @@ -0,0 +1,29 @@ +require "rails_helper" + +describe UpdateEvent do + subject { service.call } + let(:service) { UpdateEvent.new(event, params) } + let(:event) { FactoryGirl.create(:event) } + let(:params) { { name: new_name } } + let(:new_name) { "Updated name" } + + it { is_expected.to be true } + + it "does not raise an error" do + expect { subject }.not_to raise_error + end + + it "updates the name" do + service.call + event.reload + expect(event.name).to eq(new_name) + end + + context "without an event name" do + let(:new_name) { "" } + + it "raises an error" do + expect { subject }.to raise_error(ActiveRecord::RecordInvalid) + end + end +end