require 'test_helper' class UsersCreditsManagerTest < ActiveSupport::TestCase setup do @machine = Machine.find(6) @training = Training.find(2) @plan = Plan.find(3) @user = User.joins(statistic_profile: [:subscriptions]).find_by(subscriptions: { plan_id: @plan.id }) @user.users_credits.destroy_all @availability = @machine.availabilities.first @reservation_machine = Reservation.new(statistic_profile: @user.statistic_profile, reservable: @machine) @reservation_training = Reservation.new(statistic_profile: @user.statistic_profile, reservable: @training) end ## context machine reservation test "machine reservation from user without subscribed plan" do @user.subscriptions.destroy_all @reservation_machine.assign_attributes(slots_attributes: [{ start_at: @availability.start_at, end_at: @availability.start_at + 1.hour, availability_id: @availability.id }]) manager = UsersCredits::Manager.new(reservation: @reservation_machine) assert_equal false, manager.will_use_credits? assert_equal 0, manager.free_hours_count assert_no_difference 'UsersCredit.count' do manager.update_credits end end test "machine reservation without credit associated" do Credit.where(creditable: @machine).destroy_all @reservation_machine.assign_attributes(slots_attributes: [{ start_at: @availability.start_at, end_at: @availability.start_at + 1.hour, availability_id: @availability.id }]) manager = UsersCredits::Manager.new(reservation: @reservation_machine) assert_equal false, manager.will_use_credits? assert_equal 0, manager.free_hours_count assert_no_difference 'UsersCredit.count' do manager.update_credits end assert_raise UsersCredits::AlreadyUpdatedError do manager.update_credits end end test "machine reservation with credit associated and user never used his credit" do credit = Credit.find_by!(creditable: @machine, plan: @plan) credit.update!(hours: 2) @user.users_credits.destroy_all @reservation_machine.assign_attributes(slots_attributes: [{ start_at: @availability.start_at, end_at: @availability.start_at + 1.hour, availability_id: @availability.id }]) manager = UsersCredits::Manager.new(reservation: @reservation_machine) assert_equal true, manager.will_use_credits? assert_equal 1, manager.free_hours_count assert_difference 'UsersCredit.count' do manager.update_credits end assert_raise UsersCredits::AlreadyUpdatedError do manager.update_credits end end test "machine reservation with credit associated and user already used partially his credit" do credit = Credit.find_by!(creditable: @machine, plan: @plan) credit.update!(hours: 2) users_credit = @user.users_credits.create!(credit: credit, hours_used: 1) @reservation_machine.assign_attributes(slots_attributes: [ { start_at: @availability.start_at, end_at: @availability.start_at + 1.hour, availability_id: @availability.id }, { start_at: @availability.start_at + 1.hour, end_at: @availability.start_at + 2.hour, availability_id: @availability.id } ]) manager = UsersCredits::Manager.new(reservation: @reservation_machine) assert_equal true, manager.will_use_credits? assert_equal 1, manager.free_hours_count assert_no_difference 'UsersCredit.count' do manager.update_credits end users_credit.reload assert_equal 2, users_credit.hours_used end test "machine reservation with credit associated and user already used all credit" do credit = Credit.find_by!(creditable: @machine, plan: @plan) users_credit = @user.users_credits.create!(credit: credit, hours_used: 1) @reservation_machine.assign_attributes(slots_attributes: [ { start_at: @availability.start_at, end_at: @availability.start_at + 1.hour, availability_id: @availability.id }, { start_at: @availability.start_at + 1.hour, end_at: @availability.start_at + 2.hour, availability_id: @availability.id } ]) manager = UsersCredits::Manager.new(reservation: @reservation_machine) assert_equal false, manager.will_use_credits? assert_equal 0, manager.free_hours_count assert_no_difference 'UsersCredit.count' do manager.update_credits end users_credit.reload assert_equal 1, users_credit.hours_used end # context training reservation test "training reservation from user without subscribed plan" do @user.subscriptions.destroy_all manager = UsersCredits::Manager.new(reservation: @reservation_training) assert_equal false, manager.will_use_credits? assert_no_difference 'UsersCredit.count' do manager.update_credits end end test "training reservation without credit associated" do Credit.where(creditable: @training).destroy_all manager = UsersCredits::Manager.new(reservation: @reservation_training) assert_equal false, manager.will_use_credits? assert_no_difference 'UsersCredit.count' do manager.update_credits end assert_raise UsersCredits::AlreadyUpdatedError do manager.update_credits end end test "training reservation with credit associated and user didnt use his credit yet" do credit = Credit.find_or_create_by!(creditable: @training, plan: @plan) @user.users_credits.destroy_all manager = UsersCredits::Manager.new(reservation: @reservation_training) assert_equal true, manager.will_use_credits? assert_difference 'UsersCredit.count' do manager.update_credits end end test "training reservation with credit associated but user already used all his credits" do @user.users_credits.destroy_all another_training = Training.where.not(id: @training.id).first credit = Credit.find_or_create_by!(creditable: another_training, plan: @plan) @user.users_credits.find_or_create_by!(credit: credit) @plan.update(training_credit_nb: 1) manager = UsersCredits::Manager.new(reservation: @reservation_training) assert_equal false, manager.will_use_credits? assert_no_difference 'UsersCredit.count' do manager.update_credits end end # context reset user credits test "use UsersCredit::Manager to reset users_credits" do credit = Credit.find_by!(creditable: @machine, plan: @plan) users_credit = @user.users_credits.create!(credit: credit, hours_used: 1) assert_not_empty @user.users_credits manager = UsersCredits::Manager.new(user: @user) manager.reset_credits assert_empty @user.users_credits.reload end end