Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions app/models/better_together/platform_invitation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ class PlatformInvitation < ApplicationRecord

has_rich_text :greeting, encrypted: true

validates :invitee_email, uniqueness: { scope: :invitable_id, allow_nil: true }
validates :invitee_email, uniqueness: { scope: :invitable_id, allow_nil: true, allow_blank: true }
validates :invitee_email,
uniqueness: { scope: :invitable_id, case_sensitive: false },
format: { with: URI::MailTo::EMAIL_REGEXP },
allow_blank: true
validates :locale, presence: true, inclusion: { in: I18n.available_locales.map(&:to_s) }
validates :status, presence: true, inclusion: { in: STATUS_VALUES.values }
validates :token, uniqueness: true
Expand All @@ -46,8 +48,9 @@ class PlatformInvitation < ApplicationRecord

scope :pending, -> { where(status: STATUS_VALUES[:pending]) }
scope :accepted, -> { where(status: STATUS_VALUES[:accepted]) }
scope :expired, -> { where('valid_until IS NOT NULL AND valid_until < ?', Time.current) }
scope :not_expired, -> { where('valid_until IS NULL OR valid_until >= ?', Time.current) }

scope :expired, -> { where('valid_until IS NULL OR valid_until < ?', Time.current) }
scope :not_expired, -> { where('valid_until >= ?', Time.current) }

def self.load_all_subclasses
Rails.application.eager_load! # Ensure all models are loaded
Expand Down
30 changes: 12 additions & 18 deletions spec/models/better_together/platform_invitation_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ module BetterTogether # rubocop:todo Metrics/ModuleLength

describe 'ActiveModel validations' do
it {
# rubocop:todo RSpec/NamedSubject
expect(subject).to validate_uniqueness_of(:invitee_email).scoped_to(:invitable_id)
# rubocop:enable RSpec/NamedSubject
.allow_nil.allow_blank.case_insensitive
is_expected.to validate_uniqueness_of(:invitee_email).scoped_to(:invitable_id)
.allow_blank.case_insensitive
}

it { is_expected.to allow_value('[email protected]').for(:invitee_email) }
it { is_expected.not_to allow_value('invalid_email').for(:invitee_email) }
it { is_expected.to validate_presence_of(:locale) }
it { is_expected.to validate_inclusion_of(:locale).in_array(I18n.available_locales.map(&:to_s)) }
it { is_expected.to validate_presence_of(:status) }
Expand Down Expand Up @@ -89,27 +88,22 @@ module BetterTogether # rubocop:todo Metrics/ModuleLength
end

describe '.expired' do
it 'returns only expired invitations' do # rubocop:todo RSpec/MultipleExpectations
expired_invitation = create(:better_together_platform_invitation, valid_until: 1.day.ago)
it 'includes invitations with nil or past valid_until' do
nil_invitation = create(:better_together_platform_invitation, valid_until: nil)
past_invitation = create(:better_together_platform_invitation, valid_until: 1.day.ago)
create(:better_together_platform_invitation, valid_until: 1.day.from_now)

expect(described_class.expired).to include(expired_invitation)
expect(described_class.expired.count).to eq(1)
expect(described_class.expired).to match_array([nil_invitation, past_invitation])
end
end

describe '.not_expired' do
# rubocop:todo RSpec/MultipleExpectations
it 'returns invitations that are not expired or have no expiration' do # rubocop:todo RSpec/ExampleLength, RSpec/MultipleExpectations
# rubocop:enable RSpec/MultipleExpectations
future_invitation = create(:better_together_platform_invitation, valid_until: 1.day.from_now)
nil_invitation = create(:better_together_platform_invitation, valid_until: nil)
it 'includes only invitations with future valid_until' do
create(:better_together_platform_invitation, valid_until: nil)
create(:better_together_platform_invitation, valid_until: 1.day.ago)
future_invitation = create(:better_together_platform_invitation, valid_until: 1.day.from_now)

result = described_class.not_expired

expect(result).to include(future_invitation, nil_invitation)
expect(result.count).to eq(2)
expect(described_class.not_expired).to match_array([future_invitation])
end
end
end
Expand Down
Loading