From ee9558f8a166a6ab6dad39be6427bcf9f94831ce Mon Sep 17 00:00:00 2001 From: Letiste Date: Thu, 5 Jan 2023 11:44:25 +0100 Subject: [PATCH 1/3] validate attribute of subscription --- app/models/subscription.rb | 20 +++++++ .../20230104090306_create_subscriptions.rb | 12 +++++ db/schema.rb | 9 +++- test/fixtures/subscriptions.yml | 4 ++ test/models/subscription_test.rb | 52 +++++++++++++++++++ 5 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 app/models/subscription.rb create mode 100644 db/migrate/20230104090306_create_subscriptions.rb create mode 100644 test/fixtures/subscriptions.yml create mode 100644 test/models/subscription_test.rb diff --git a/app/models/subscription.rb b/app/models/subscription.rb new file mode 100644 index 00000000..18300350 --- /dev/null +++ b/app/models/subscription.rb @@ -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 diff --git a/db/migrate/20230104090306_create_subscriptions.rb b/db/migrate/20230104090306_create_subscriptions.rb new file mode 100644 index 00000000..9e39c595 --- /dev/null +++ b/db/migrate/20230104090306_create_subscriptions.rb @@ -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 diff --git a/db/schema.rb b/db/schema.rb index f911de2b..9a45c70e 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.0].define(version: 2022_11_17_074056) do +ActiveRecord::Schema[7.0].define(version: 2023_01_04_090306) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -33,6 +33,13 @@ t.index ["user_id"], name: "index_machines_on_user_id" end + create_table "subscriptions", force: :cascade do |t| + t.integer "duration" + t.datetime "cancelled_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "users", force: :cascade do |t| t.string "firstname", null: false t.string "lastname", null: false diff --git a/test/fixtures/subscriptions.yml b/test/fixtures/subscriptions.yml new file mode 100644 index 00000000..711fc60d --- /dev/null +++ b/test/fixtures/subscriptions.yml @@ -0,0 +1,4 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + duration: 1 diff --git a/test/models/subscription_test.rb b/test/models/subscription_test.rb new file mode 100644 index 00000000..4e9e5d2b --- /dev/null +++ b/test/models/subscription_test.rb @@ -0,0 +1,52 @@ +# 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 "canceled_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? + 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 From dab7d72b4257d74158171a4450ead9f266e028f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Sal=C3=A9?= Date: Sun, 8 Jan 2023 17:24:54 +0100 Subject: [PATCH 2/3] Update test/models/subscription_test.rb Co-authored-by: Thomas Gaudin --- test/models/subscription_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/models/subscription_test.rb b/test/models/subscription_test.rb index 4e9e5d2b..4b568a69 100644 --- a/test/models/subscription_test.rb +++ b/test/models/subscription_test.rb @@ -34,7 +34,7 @@ def setup assert_not_predicate subscription, :valid? end - test "canceled_at can't be changed when not nil" do + test "cancelled_at can't be changed when not nil" do subscription = Subscription.new(duration: 2, cancelled_at: DateTime.now) subscription.save From 14d6a126d807113b6f02c88f50cb3ab922c0a00d Mon Sep 17 00:00:00 2001 From: Letiste Date: Sun, 8 Jan 2023 17:27:31 +0100 Subject: [PATCH 3/3] test for de cancelling subscription --- test/models/subscription_test.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/models/subscription_test.rb b/test/models/subscription_test.rb index 4b568a69..baeaed6a 100644 --- a/test/models/subscription_test.rb +++ b/test/models/subscription_test.rb @@ -40,6 +40,9 @@ def setup 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