Skip to content

Commit

Permalink
validate attribute of subscription (#408)
Browse files Browse the repository at this point in the history
Co-authored-by: Thomas Gaudin <thomas.gaudin@centraliens-lille.org>
  • Loading branch information
Letiste and nymous authored Jan 8, 2023
1 parent 8783c80 commit b851cbb
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 1 deletion.
20 changes: 20 additions & 0 deletions app/models/subscription.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

class Subscription < ApplicationRecord
validates :duration, presence: true, numericality: { only_integer: true, greater_than: 0 }
validate :cannot_change_after_cancelled, :cannot_change_duration, on: :update

private

def cannot_change_after_cancelled
return if cancelled_at_was.nil?

errors.add(:cancelled_at, 'Subscription has already been cancelled')
end

def cannot_change_duration
return if changes[:duration].nil?

errors.add(:duration, 'Duration is immutable')
end
end
12 changes: 12 additions & 0 deletions db/migrate/20230104090306_create_subscriptions.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

class CreateSubscriptions < ActiveRecord::Migration[7.0]
def change
create_table :subscriptions do |t|
t.integer :duration
t.datetime :cancelled_at

t.timestamps
end
end
end
9 changes: 8 additions & 1 deletion db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions test/fixtures/subscriptions.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html

one:
duration: 1
55 changes: 55 additions & 0 deletions test/models/subscription_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# frozen_string_literal: true

require 'test_helper'

class SubscriptionTest < ActiveSupport::TestCase
def setup
@subscription = subscriptions(:one)
end

test 'subscription is valid' do
assert_predicate @subscription, :valid?
end

test "duration can't be changed" do
@subscription.duration = 8
assert_not_predicate @subscription, :valid?
end

test "duration can't be nil" do
subscription = Subscription.new(duration: nil)
assert_not_predicate subscription, :valid?
end

test 'duration must be integer' do
subscription = Subscription.new(duration: 1.1)
assert_not_predicate subscription, :valid?
end

test 'duration must be strictly positive' do
subscription = Subscription.new(duration: 0)
assert_not_predicate subscription, :valid?

subscription = Subscription.new(duration: -1)
assert_not_predicate subscription, :valid?
end

test "cancelled_at can't be changed when not nil" do
subscription = Subscription.new(duration: 2, cancelled_at: DateTime.now)
subscription.save

subscription.cancelled_at = subscription.cancelled_at + 1.day
assert_not_predicate subscription, :valid?

subscription.cancelled_at = nil
assert_not_predicate subscription, :valid?
end

test 'cancelled_at can be changed when nil' do
subscription = Subscription.new(duration: 2)
subscription.save

subscription.cancelled_at = DateTime.now
assert_predicate subscription, :valid?
end
end

0 comments on commit b851cbb

Please sign in to comment.