diff --git a/enterprise/app/models/captain/lifecycle.rb b/enterprise/app/models/captain/lifecycle.rb new file mode 100644 index 000000000..ba1ad06ba --- /dev/null +++ b/enterprise/app/models/captain/lifecycle.rb @@ -0,0 +1,4 @@ +# frozen_string_literal: true + +module Captain::Lifecycle +end diff --git a/enterprise/app/models/captain/lifecycle/config.rb b/enterprise/app/models/captain/lifecycle/config.rb new file mode 100644 index 000000000..6e2472e1f --- /dev/null +++ b/enterprise/app/models/captain/lifecycle/config.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class Captain::Lifecycle::Config < ApplicationRecord + self.table_name = 'captain_lifecycle_configs' + + belongs_to :account + belongs_to :opt_out_label, class_name: 'Label', optional: true + + validates :account_id, uniqueness: true + validates :min_interval_minutes, numericality: { greater_than_or_equal_to: 0 } + validates :pause_on_customer_reply_within_minutes, numericality: { greater_than_or_equal_to: 0 } + + def self.for_account(account) + find_or_create_by!(account_id: account.id) + end +end diff --git a/spec/enterprise/models/captain/lifecycle/config_spec.rb b/spec/enterprise/models/captain/lifecycle/config_spec.rb new file mode 100644 index 000000000..fc7f36924 --- /dev/null +++ b/spec/enterprise/models/captain/lifecycle/config_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Captain::Lifecycle::Config, type: :model do + describe 'associations' do + it { is_expected.to belong_to(:account) } + it { is_expected.to belong_to(:opt_out_label).class_name('Label').optional } + end + + describe 'validations' do + subject { build(:captain_lifecycle_config) } + + it { is_expected.to validate_uniqueness_of(:account_id) } + it { is_expected.to validate_numericality_of(:min_interval_minutes).is_greater_than_or_equal_to(0) } + it { is_expected.to validate_numericality_of(:pause_on_customer_reply_within_minutes).is_greater_than_or_equal_to(0) } + end + + describe '.for_account' do + let(:account) { create(:account) } + + it 'returns existing config when present' do + config = create(:captain_lifecycle_config, account: account) + expect(described_class.for_account(account)).to eq(config) + end + + it 'creates default config when missing' do + expect { described_class.for_account(account) } + .to change(described_class, :count).by(1) + end + + it 'defaults have quiet_hours disabled' do + config = described_class.for_account(account) + expect(config.quiet_hours_enabled).to be(false) + end + end +end diff --git a/spec/factories/captain_lifecycle_configs.rb b/spec/factories/captain_lifecycle_configs.rb new file mode 100644 index 000000000..68f555b6d --- /dev/null +++ b/spec/factories/captain_lifecycle_configs.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :captain_lifecycle_config, class: 'Captain::Lifecycle::Config' do + account + quiet_hours_enabled { false } + quiet_hours_from { '23:00' } + quiet_hours_to { '08:00' } + min_interval_minutes { 30 } + pause_on_customer_reply { false } + pause_on_customer_reply_within_minutes { 60 } + end +end