From a1cf67a6d137d4b42b82d5d8c44b8198bdeecb57 Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Wed, 10 Sep 2025 18:28:20 -0500 Subject: [PATCH 01/11] Add timezone field to events --- db/migrate/20250910231648_add_timezone_to_events.rb | 7 +++++++ db/schema.rb | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20250910231648_add_timezone_to_events.rb diff --git a/db/migrate/20250910231648_add_timezone_to_events.rb b/db/migrate/20250910231648_add_timezone_to_events.rb new file mode 100644 index 000000000..499751c0f --- /dev/null +++ b/db/migrate/20250910231648_add_timezone_to_events.rb @@ -0,0 +1,7 @@ +class AddTimezoneToEvents < ActiveRecord::Migration[7.1] + def change + change_table :events do |t| + t.string :timezone + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 523e24ad5..31e49cf99 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2025_08_26_154514) do +ActiveRecord::Schema[7.1].define(version: 2025_09_10_231648) do # These are extensions that must be enabled in order to support this database enable_extension "pg_stat_statements" enable_extension "plpgsql" @@ -383,6 +383,7 @@ t.datetime "start_datetime", precision: nil t.datetime "end_datetime", precision: nil t.string "in_person_or_virtual", default: "in_person", comment: "whether or not this is a virtual event" + t.string "timezone" t.index ["in_person_or_virtual"], name: "index_events_on_in_person_or_virtual" t.index ["nonprofit_id", "deleted", "published", "end_datetime"], name: "events_nonprofit_id_not_deleted_and_published_endtime" t.index ["nonprofit_id", "deleted", "published"], name: "index_events_on_nonprofit_id_and_deleted_and_published" From c26a3fde883bc2f54b67abe25cf88a5b347d9f21 Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Thu, 11 Sep 2025 11:34:21 -0500 Subject: [PATCH 02/11] Add timezone field to event forms --- app/views/events/_edit_form.html.erb | 15 ++++++++++++++- app/views/events/_new_modal.html.erb | 13 ++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/app/views/events/_edit_form.html.erb b/app/views/events/_edit_form.html.erb index b76baadf1..45f812acb 100644 --- a/app/views/events/_edit_form.html.erb +++ b/app/views/events/_edit_form.html.erb @@ -17,11 +17,12 @@
-
+
'>
+
@@ -37,6 +38,18 @@ Set
+ +
+ +
+ + +
+

diff --git a/app/views/events/_new_modal.html.erb b/app/views/events/_new_modal.html.erb index bd81461b6..876fbb50c 100644 --- a/app/views/events/_new_modal.html.erb +++ b/app/views/events/_new_modal.html.erb @@ -55,7 +55,7 @@ -
+
@@ -63,6 +63,17 @@
+
+ +
+ +
+
+ <%= render 'components/forms/submit_button', button_text: 'Next', scope: 'new_event_wiz', branded: true %> From 2f0ad9959cf074059c8ebfe89cddc4c522dcda5b Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Fri, 12 Sep 2025 17:12:45 -0500 Subject: [PATCH 03/11] Allow timezone field to be set via mass assignment Allows end user to change value via form --- app/models/event.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/event.rb b/app/models/event.rb index 17e906acd..4f206d550 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -33,7 +33,8 @@ class Event < ApplicationRecord :organizer_email, # string :receipt_message, # text :nonprofit, - :in_person_or_virtual + :in_person_or_virtual, + :timezone # string (timezone): event time zone if different from nonprofit timezone enum :in_person_or_virtual, %w[in_person virtual].index_by(&:itself), validate: true From 2f119d11bddfc9f1ba8513fcb06d293fd966229d Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Tue, 30 Sep 2025 15:19:26 -0500 Subject: [PATCH 04/11] Use new select helper for timezones --- app/views/events/_edit_form.html.erb | 7 +------ app/views/events/_new_modal.html.erb | 6 +----- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/app/views/events/_edit_form.html.erb b/app/views/events/_edit_form.html.erb index 45f812acb..60f332cac 100644 --- a/app/views/events/_edit_form.html.erb +++ b/app/views/events/_edit_form.html.erb @@ -42,12 +42,7 @@
- - + <%= select(:event, :timezone, time_zone_options_with_iana(@event.timezone || @nonprofit.timezone || "UTC"), include_blank: 'Select Timezone') %>
diff --git a/app/views/events/_new_modal.html.erb b/app/views/events/_new_modal.html.erb index 876fbb50c..b91a6bec3 100644 --- a/app/views/events/_new_modal.html.erb +++ b/app/views/events/_new_modal.html.erb @@ -66,11 +66,7 @@
- + <%= select(:event, :timezone, time_zone_options_with_iana(@nonprofit.timezone || "UTC"), include_blank: 'Select Timezone', class: 'u-bold') %>
From d14bc19a6f088c50978fad92d40f5687f916a279 Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Tue, 30 Sep 2025 17:08:12 -0500 Subject: [PATCH 05/11] Default timezone field on events This refactoring also cuts out some duplicate calls to use UTC as default. --- app/controllers/events_controller.rb | 16 +++++++++------- app/models/event.rb | 2 ++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index cc9a13221..f2405707e 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -29,19 +29,21 @@ def show end def create + Time.use_zone(event.timezone) do + params[:event][:start_datetime] = Chronic.parse(params[:event][:start_datetime]) if params[:event][:start_datetime].present? + params[:event][:end_datetime] = Chronic.parse(params[:event][:end_datetime]) if params[:event][:end_datetime].present? + end + event = current_nonprofit.events.create(params[:event]) + render_json do - Time.use_zone(current_nonprofit.timezone || "UTC") do - params[:event][:start_datetime] = Chronic.parse(params[:event][:start_datetime]) if params[:event][:start_datetime].present? - params[:event][:end_datetime] = Chronic.parse(params[:event][:end_datetime]) if params[:event][:end_datetime].present? - end flash[:notice] = "Your draft event has been created! Well done." - ev = current_nonprofit.events.create(params[:event]) - {url: "/events/#{ev.slug}", event: ev} + + { url: "/events/#{event.slug}", event: } end end def update - Time.use_zone(current_nonprofit.timezone || "UTC") do + Time.use_zone(event.timezone) do params[:event][:start_datetime] = Chronic.parse(params[:event][:start_datetime]) if params[:event][:start_datetime].present? params[:event][:end_datetime] = Chronic.parse(params[:event][:end_datetime]) if params[:event][:end_datetime].present? end diff --git a/app/models/event.rb b/app/models/event.rb index 4f206d550..280817358 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -88,6 +88,8 @@ class Event < ApplicationRecord end self.published = false if published.nil? self.total_raised ||= 0 + self.timezone = nonprofit_timezone || "UTC" + self end From 681f0e147289917b1dbc7b2f33a70eee0ebcf1c8 Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Tue, 30 Sep 2025 17:13:39 -0500 Subject: [PATCH 06/11] Better style event timezone select * Use select helper and `time_zone_options_with_iana` helper to render options * Widen area that timezone appears in so it isn't cut off when showing selected timezone in new form --- app/assets/stylesheets/events/new/index.scss | 5 +++ app/views/events/_edit_form.html.erb | 4 +-- app/views/events/_new_modal.html.erb | 38 ++++++++++---------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/app/assets/stylesheets/events/new/index.scss b/app/assets/stylesheets/events/new/index.scss index 87ae7a364..f62a82b3c 100644 --- a/app/assets/stylesheets/events/new/index.scss +++ b/app/assets/stylesheets/events/new/index.scss @@ -8,4 +8,9 @@ max-width: 270px; } +.timezone-select { + margin: 0 auto; + max-width: 350px; +} + .location-step .fieldsLayout--two { margin: 0 30px; } diff --git a/app/views/events/_edit_form.html.erb b/app/views/events/_edit_form.html.erb index 60f332cac..ff43be68d 100644 --- a/app/views/events/_edit_form.html.erb +++ b/app/views/events/_edit_form.html.erb @@ -39,10 +39,10 @@ -
+
- <%= select(:event, :timezone, time_zone_options_with_iana(@event.timezone || @nonprofit.timezone || "UTC"), include_blank: 'Select Timezone') %> + <%= select(:event, :timezone, time_zone_options_with_iana(@event.timezone), include_blank: 'Select Timezone') %>
diff --git a/app/views/events/_new_modal.html.erb b/app/views/events/_new_modal.html.erb index b91a6bec3..4c5a41b93 100644 --- a/app/views/events/_new_modal.html.erb +++ b/app/views/events/_new_modal.html.erb @@ -44,29 +44,31 @@
-
+ -
- -
- - Set -
-
+
+
+ +
+ + Set +
+
-
- -
- - Set -
-
+
+ +
+ + Set +
+
+
-
+
- <%= select(:event, :timezone, time_zone_options_with_iana(@nonprofit.timezone || "UTC"), include_blank: 'Select Timezone', class: 'u-bold') %> + <%= select(:event, :timezone, time_zone_options_with_iana(@nonprofit.timezone), include_blank: 'Select Timezone', class: 'u-bold') %>
@@ -75,8 +77,6 @@
- -
From 3ad548c2ce719ab9dfa2093d2cd5fbfae557fefc Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Thu, 2 Oct 2025 15:00:30 -0500 Subject: [PATCH 07/11] Fix tests --- app/controllers/events_controller.rb | 2 +- spec/lib/insert/insert_duplicate_spec.rb | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index f2405707e..e03302520 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -43,7 +43,7 @@ def create end def update - Time.use_zone(event.timezone) do + Time.use_zone(current_event.timezone) do params[:event][:start_datetime] = Chronic.parse(params[:event][:start_datetime]) if params[:event][:start_datetime].present? params[:event][:end_datetime] = Chronic.parse(params[:event][:end_datetime]) if params[:event][:end_datetime].present? end diff --git a/spec/lib/insert/insert_duplicate_spec.rb b/spec/lib/insert/insert_duplicate_spec.rb index d0fe2e3d4..606ec56ca 100644 --- a/spec/lib/insert/insert_duplicate_spec.rb +++ b/spec/lib/insert/insert_duplicate_spec.rb @@ -281,7 +281,8 @@ def set_event_start_time(start_time, end_time) { id: result.id, start_datetime: DateTime.new(2020, 5, 12), - end_datetime: DateTime.new(2020, 5, 12, 4) + end_datetime: DateTime.new(2020, 5, 12, 4), + timezone: "UTC" } ).with_indifferent_access) validate_tls(result) @@ -301,9 +302,9 @@ def set_event_start_time(start_time, end_time) expect(result.attributes.with_indifferent_access).to eq(common_result_attributes.merge( { id: result.id, - start_datetime: Time.utc(2020, 5, 12), - end_datetime: Time.utc(2020, 5, 12, 4) + end_datetime: Time.utc(2020, 5, 12, 4), + timezone: "UTC" } ).with_indifferent_access) @@ -323,7 +324,8 @@ def set_event_start_time(start_time, end_time) { id: result.id, start_datetime: event.start_datetime.to_time, - end_datetime: event.end_datetime.to_time + end_datetime: event.end_datetime.to_time, + timezone: "UTC" } ).with_indifferent_access) validate_tls(result) From be15adb8a94002d3c39e8920c2f641adf4e554d6 Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Thu, 2 Oct 2025 15:10:42 -0500 Subject: [PATCH 08/11] Frontend display of event timezones --- app/legacy_lib/format/date.rb | 4 ++++ app/legacy_lib/query_event_metrics.rb | 3 ++- app/models/event.rb | 4 ++++ app/views/events/_date_time.html.erb | 2 +- app/views/events/_listing.html.erb | 7 ++++--- client/js/events/listing-item/index.js | 8 ++++---- 6 files changed, 19 insertions(+), 9 deletions(-) diff --git a/app/legacy_lib/format/date.rb b/app/legacy_lib/format/date.rb index 181b9444b..fa36b48d4 100644 --- a/app/legacy_lib/format/date.rb +++ b/app/legacy_lib/format/date.rb @@ -41,5 +41,9 @@ def self.time(datetime, timezone = nil) datetime = datetime.in_time_zone(timezone) if timezone datetime.strftime("%l:%M%P") end + + def self.timezone(timezone) + Time.now.in_time_zone(timezone).strftime('%Z') + end end end diff --git a/app/legacy_lib/query_event_metrics.rb b/app/legacy_lib/query_event_metrics.rb index 0a9450c5c..d74230242 100644 --- a/app/legacy_lib/query_event_metrics.rb +++ b/app/legacy_lib/query_event_metrics.rb @@ -55,7 +55,8 @@ def self.for_listings(id_type, id, params) "events.start_datetime", "events.end_datetime", "events.organizer_email", - "events.in_person_or_virtual" + "events.in_person_or_virtual", + "events.timezone" ] exp = QueryEventMetrics.expression(selects) diff --git a/app/models/event.rb b/app/models/event.rb index 280817358..40613d7cb 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -126,4 +126,8 @@ def fee_coverage_option def get_tickets_button_label misc_event_info&.custom_get_tickets_button_label || "Get Tickets" end + + def timezone_with_fallback + timezone.presence || nonprofit_timezone + end end diff --git a/app/views/events/_date_time.html.erb b/app/views/events/_date_time.html.erb index 0d621f16e..3c0be8439 100644 --- a/app/views/events/_date_time.html.erb +++ b/app/views/events/_date_time.html.erb @@ -3,7 +3,7 @@
Date & Time
- <%= Format::Date.full_range(@event.start_datetime, @event.end_datetime, @event.nonprofit_timezone) %> + <%= Format::Date.full_range(@event.start_datetime, @event.end_datetime, @event.timezone_with_fallback) %> <%= Format::Date.timezone(@event.timezone_with_fallback) %>
<% if Time.now > @event.end_datetime %> diff --git a/app/views/events/_listing.html.erb b/app/views/events/_listing.html.erb index deab5ec8f..b4aa5ca7d 100644 --- a/app/views/events/_listing.html.erb +++ b/app/views/events/_listing.html.erb @@ -1,8 +1,9 @@ <%- # License: AGPL-3.0-or-later WITH Web-Template-Output-Additional-Permission-3.0-or-later -%> -<% css = 'fundraiser--active' if css.nil? %> -
+
css.nil? ) %>'>
-

<%= Format::Date.full_range(event.start_datetime, event.end_datetime, event.nonprofit_timezone) %>

+

+ <%= Format::Date.full_range(event.start_datetime, event.end_datetime, event.timezone_with_fallback) %> <%= Format::Date.timezone(event.timezone_with_fallback) %> +

diff --git a/client/js/events/listing-item/index.js b/client/js/events/listing-item/index.js index ba0fae608..ae6521c8c 100644 --- a/client/js/events/listing-item/index.js +++ b/client/js/events/listing-item/index.js @@ -4,8 +4,8 @@ const h = require('snabbdom/h') const moment = require('moment-timezone') const {commaJoin} = require('./common'); -const dateTime = (startTime, endTime) => { - const tz = ENV.nonprofitTimezone || 'America/Los_Angeles' +const dateTime = (startTime, endTime, timeZone) => { + const tz = timeZone || ENV.nonprofitTimezone || 'America/Los_Angeles' startTime = moment(startTime).tz(tz) endTime = moment(endTime).tz(tz) const sameDate = startTime.format("YYYY-MM-DD") === endTime.format("YYYY-MM-DD") @@ -14,7 +14,7 @@ const dateTime = (startTime, endTime) => { const endTimeFormatted = sameDate ? endTime.format("h:mma") : endTime.format(format) return [ - h('strong', startTime.format(format) + ' - ' + endTimeFormatted) + h('strong', startTime.format(format) + ' - ' + endTimeFormatted + ' ' + moment.tz(tz).zoneAbbr()) , h('span.u-color--grey', ended) ] } @@ -67,7 +67,7 @@ module.exports = e => { return h('div.u-paddingTop--10.u-marginBottom--20', [ h('h5.u-paddingX--20', e.name) , h('table.table--striped.u-margin--0', [ - row('fa-clock-o', dateTime(e.start_datetime, e.end_datetime)) + row('fa-clock-o', dateTime(e.start_datetime, e.end_datetime, e.timezone)) , row('fa-map-marker', location) , row('fa-users', attendeesMetrics) , row('fa-dollar', moneyMetrics) From 33628cc1cc24374b1f055544115ddf4581f020f4 Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Fri, 3 Oct 2025 17:55:32 -0500 Subject: [PATCH 09/11] Spec coverage for timezone_with_fallback --- spec/models/event_spec.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 09ca19d0b..a4ff229cb 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -2,6 +2,7 @@ require "rails_helper" RSpec.describe Event, type: :model do + it { is_expected.to belong_to(:nonprofit) } it { is_expected.to have_many(:ticketholders).through(:tickets).source(:supporter) } it { is_expected.to define_enum_for(:in_person_or_virtual).with_values(%w[in_person virtual].index_by(&:itself)).backed_by_column_of_type(:string).validating } it { is_expected.to delegate_method(:timezone).to(:nonprofit).with_prefix.allow_nil } @@ -18,4 +19,18 @@ it { is_expected.to_not validate_presence_of(:state_code) } end end + + describe "#timezone_with_fallback" do + let(:nonprofit) { create(:nonprofit_base, timezone: 'America/Los_Angeles') } + let(:event) { create(:event_base, nonprofit:, timezone: 'America/Central') } + let(:event_without_timezone) { create(:event_base, nonprofit:) } + + it "returns the event timezone with priority" do + expect(event.timezone_with_fallback).to eq('America/Central') + end + + it "returns the nonprofit timezone if event timezone is not set" do + expect(event_without_timezone.timezone_with_fallback).to eq(nonprofit.timezone) + end + end end From 559607840193ef2e5293009cf343ab3e8cce3100 Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Fri, 3 Oct 2025 17:58:44 -0500 Subject: [PATCH 10/11] Refactor request spec to be more spec-like --- app/controllers/events_controller.rb | 2 +- spec/requests/events_request_spec.rb | 37 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index e03302520..6850fbc5e 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -77,6 +77,6 @@ def stats end def name_and_id - @events = current_nonprofit.events.not_deleted.order("events.name ASC") + @events = current_nonprofit.events.not_deleted.order("events.name ASC").select(:name, :id) end end diff --git a/spec/requests/events_request_spec.rb b/spec/requests/events_request_spec.rb index d4c712f21..f5a7bc75d 100644 --- a/spec/requests/events_request_spec.rb +++ b/spec/requests/events_request_spec.rb @@ -2,34 +2,35 @@ require "rails_helper" describe EventsController, type: :request do - def event_setup - nonprofit = create(:nonprofit_base) + let(:nonprofit) { create(:nonprofit_base) } + let(:user) { create(:user_base, roles: [build(:role_base, name: "nonprofit_associate", host: nonprofit)]) } + let(:profile) { create(:profile, user:) } + let!(:events) do OpenStruct.new( - deleted: create(:event_base, nonprofit: nonprofit, deleted: true), - last: create(:event_base, nonprofit: nonprofit, name: "Last event"), - first: create(:event_base, nonprofit: nonprofit, name: "First event"), - nonprofit: nonprofit + deleted: create(:event_base, nonprofit:, deleted: true), + last: create(:event_base, nonprofit:, name: "Last event"), + first: create(:event_base, nonprofit:, name: "First event") ) end - def login_as_associate(nonprofit) - user = create(:user_base, roles: [build(:role_base, name: "nonprofit_associate", host: nonprofit)]) + before do sign_in user end - it "contains the events in order from first, to last with no deleted events" do - Event.any_instance.stub(:geocode).and_return([1, 1]) # otherwise the geocode call fails - events = event_setup - login_as_associate(events.nonprofit) - get "/nonprofits/#{events.nonprofit.id}/events/name_and_id" - result = JSON.parse(response.body) - expect(result).to include_json([ - {name: events.first.name, id: events.first.id}, - {name: events.last.name, id: events.last.id} - ]) + describe "GET name_and_id" do + it "contains the events in order from first, to last with no deleted events" do + get name_and_id_nonprofit_events_path(nonprofit) + + result = JSON.parse(response.body) + + expect(result).to include_json([ + {name: events.first.name, id: events.first.id}, + {name: events.last.name, id: events.last.id} + ]) + end end end From cf6e85c1cd608a364fb331199d69eb70caad6ffa Mon Sep 17 00:00:00 2001 From: Jared Mehle Date: Fri, 3 Oct 2025 17:59:38 -0500 Subject: [PATCH 11/11] Spec coverage for event create --- app/controllers/events_controller.rb | 4 +-- spec/requests/events_request_spec.rb | 50 ++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/app/controllers/events_controller.rb b/app/controllers/events_controller.rb index 6850fbc5e..e78e0fd9b 100644 --- a/app/controllers/events_controller.rb +++ b/app/controllers/events_controller.rb @@ -29,14 +29,14 @@ def show end def create - Time.use_zone(event.timezone) do + Time.use_zone(params[:event][:timezone] || current_nonprofit.timezone) do params[:event][:start_datetime] = Chronic.parse(params[:event][:start_datetime]) if params[:event][:start_datetime].present? params[:event][:end_datetime] = Chronic.parse(params[:event][:end_datetime]) if params[:event][:end_datetime].present? end event = current_nonprofit.events.create(params[:event]) render_json do - flash[:notice] = "Your draft event has been created! Well done." + flash[:notice] = "Your draft event has been created! Well done." if event.persisted? { url: "/events/#{event.slug}", event: } end diff --git a/spec/requests/events_request_spec.rb b/spec/requests/events_request_spec.rb index f5a7bc75d..4e09953bc 100644 --- a/spec/requests/events_request_spec.rb +++ b/spec/requests/events_request_spec.rb @@ -17,6 +17,56 @@ sign_in user end + describe "POST /nonprofit/:nonprofit_id/events" do + before do + expect_any_instance_of(Event).to receive(:geocode).and_return([1, 1]) # otherwise the geocode call fails + end + + context "with valid params" do + let(:params) { { event: attributes_for(:event_base, nonprofit_id: nonprofit.id, profile_id: profile.id) } } + + it "creates a new event" do + expect { post(nonprofit_events_path(nonprofit), params:) }.to change(Event, :count).by(1) + end + + it "returns a success status" do + post(nonprofit_events_path(nonprofit), params:) + expect(response).to have_http_status(:success) + end + + it "sets the flash" do + post(nonprofit_events_path(nonprofit), params:) + expect(flash[:notice]).to eq("Your draft event has been created! Well done.") + end + + it "returns the response" do + post(nonprofit_events_path(nonprofit), params:) + json = JSON.parse(response.body) + expect(json.dig('event', 'name')).to eq(params[:event][:name]) + expect(json['url']).to eq("/events/#{params[:event][:slug]}") + end + end + + context "with invalid params" do + let(:params) { { event: attributes_for(:event_base).merge(name: nil) } } + + it "does not create a new event" do + expect { post(nonprofit_events_path(nonprofit), params:) }.not_to change(Event, :count) + end + + it "returns a success status" do + post(nonprofit_events_path(nonprofit), params:) + expect(response).to have_http_status(:success) + end + + it "returns the response" do + post(nonprofit_events_path(nonprofit), params:) + json = JSON.parse(response.body) + expect(json.dig('event', 'id')).to be_nil + expect(json.dig('event', 'name')).to be_nil + end + end + end