Skip to content

Commit

Permalink
Merge pull request #390 from dgmstuart/dgms/validation-of-one-offs
Browse files Browse the repository at this point in the history
Validations: handle one-offs
  • Loading branch information
dgmstuart authored Nov 21, 2024
2 parents d2122fb + 364b305 commit fef320f
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 0 deletions.
22 changes: 22 additions & 0 deletions app/validators/valid_social_or_class.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ class ValidSocialOrClass < ActiveModel::Validator
def validate(event)
socials_must_have_titles(event)
classes_must_have_organisers(event)
one_off_socials_occasional(event)
no_one_off_workshops(event)
end

private
Expand All @@ -20,4 +22,24 @@ def classes_must_have_organisers(event)

event.errors.add(:class_organiser_id, "must be present for classes")
end

def one_off_socials_occasional(event)
return unless event.has_social? && event.weekly? && one_off(event)

event.errors.add(:frequency, 'must be "Monthly or occasionally" if a social is only happening once')
end

def no_one_off_workshops(event)
return unless event.has_class? && one_off(event) && !event.has_social?

message = <<~MESSAGE.chomp
It looks like you're trying to list a one-off workshop.
Please don't do this: we only list weekly classes on SOLDN.
MESSAGE
event.errors.add(:base, message)
end

def one_off(event)
event.first_date.present? && event.first_date == event.last_date
end
end
15 changes: 15 additions & 0 deletions spec/factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,21 @@
venue_id { rand(999) }
end

trait(:social_dance) do
# default
end

trait(:with_class) do
social_has_class { true }
class_organiser_id { rand(999) }
end

trait(:weekly_class) do
title { "" }
event_type { "weekly_class" }
class_organiser_id { rand(999) }
end

factory :create_event_form do
event_form
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# frozen_string_literal: true

RSpec.shared_examples "validates class and social (form)" do |model_name|
include ActiveSupport::Testing::TimeHelpers

before { travel_to Date.parse("2010-01-01") }

it "is valid if it's a class without a title" do
expect(build(model_name, event_type: "weekly_class", title: nil, class_organiser_id: 7)).to be_valid
end
Expand All @@ -22,4 +26,37 @@
model.valid?
expect(model.errors.messages).to eq(class_organiser_id: ["must be present for classes"])
end

it "is invalid for socials with classes which are weekly but only happening on just one date" do
model = build(model_name, :social_dance, :with_class, :weekly, first_date: "2011-11-01", last_date: "2011-11-01")

model.valid?
expect(model.errors.messages)
.to eq(frequency: ['must be "Monthly or occasionally" if a social is only happening once'])
end

it "is invalid for socials with no classes which are weekly but only happening on just one date" do
model = build(model_name, :social_dance, :with_class, :weekly, first_date: "2011-11-01", last_date: "2011-11-01")

model.valid?
expect(model.errors.messages)
.to eq(frequency: ['must be "Monthly or occasionally" if a social is only happening once'])
end

it "is invalid for classes happening on just one date" do
model = build(model_name, :weekly_class, first_date: "2011-11-01", last_date: "2011-11-01")

model.valid?
message = <<~MESSAGE.chomp
It looks like you're trying to list a one-off workshop.
Please don't do this: we only list weekly classes on SOLDN.
MESSAGE
expect(model.errors.messages).to eq(base: [message])
end

it "is valid for occasional socials with classes happening on just one date" do
model = build(model_name, :social_dance, :with_class, :occasional, first_date: "2011-11-01", last_date: "2011-11-01")

expect(model).to be_valid
end
end
69 changes: 69 additions & 0 deletions spec/support/shared_examples/events/validates_class_and_social.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,73 @@
model.valid?
expect(model.errors.messages).to eq(frequency: ["can't be blank"])
end

it "is invalid for socials with classes which are weekly but only happening on just one date" do
model = build(
model_name,
:weekly,
has_taster: false,
has_social: true,
has_class: true,
class_organiser_id: 7,
first_date: "2011-11-01",
last_date: "2011-11-01"
)

model.valid?
expect(model.errors.messages)
.to eq(frequency: ['must be "Monthly or occasionally" if a social is only happening once'])
end

it "is invalid for socials with no classes which are weekly but only happening on just one date" do
model = build(
model_name,
:weekly,
has_taster: false,
has_social: true,
has_class: false,
class_organiser_id: 7,
first_date: "2011-11-01",
last_date: "2011-11-01"
)

model.valid?
expect(model.errors.messages)
.to eq(frequency: ['must be "Monthly or occasionally" if a social is only happening once'])
end

it "is invalid for classes happening on just one date" do
model = build(
model_name,
:weekly,
has_taster: false,
has_social: false,
has_class: true,
class_organiser_id: 7,
first_date: "2011-11-01",
last_date: "2011-11-01"
)

model.valid?
message = <<~MESSAGE.chomp
It looks like you're trying to list a one-off workshop.
Please don't do this: we only list weekly classes on SOLDN.
MESSAGE
expect(model.errors.messages).to eq(base: [message])
end

it "is valid for occasional socials with classes happening on just one date" do
model = build(
model_name,
:occasional,
has_taster: false,
has_social: true,
has_class: true,
class_organiser_id: 7,
first_date: "2011-11-01",
last_date: "2011-11-01"
)

expect(model).to be_valid
end
end
26 changes: 26 additions & 0 deletions spec/support/shared_examples/validates_no_one_off_workshops.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

RSpec.shared_examples "validates no one off workshops" do |model_name|
include ActiveSupport::Testing::TimeHelpers

before { travel_to Date.parse("2010-01-01") }

it "is invalid for classes happening on just one date" do
model = build(model_name, event_type: "weekly_class", first_date: "2011-11-01", last_date: "2011-11-01")

model.valid?
expect(model.errors.messages).to eq(base: ["It looks like you're trying to list a one-off workshop"])
end

it "is valid with a valid http url" do
model = build(model_name, url: "http://foo.com")

expect(model).to be_valid
end

it "is invalid with url missing a scheme" do
model = build(model_name, url: "www.foo.com")
model.valid?
expect(model.errors.messages).to eq(url: ["is not a valid URI"])
end
end
1 change: 1 addition & 0 deletions spec/support/system/drivers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ module Drivers

config.before(:each, :js, type: :system) do
driven_by :selenium_chrome_headless
current_window.resize_to(750, 1900) # 750x1900 is enough to fit the whole event form
end
end
end
Expand Down

0 comments on commit fef320f

Please sign in to comment.