diff --git a/app/models/admin_notification.rb b/app/models/admin_notification.rb new file mode 100644 index 000000000..eccd90910 --- /dev/null +++ b/app/models/admin_notification.rb @@ -0,0 +1,44 @@ +class AdminNotification < ActiveRecord::Base + include Notifiable + + validates :title, presence: true + validates :body, presence: true + validates :segment_recipient, presence: true + validate :validate_segment_recipient + + before_validation :complete_link_url + + def list_of_recipients + UserSegments.send(segment_recipient) if valid_segment_recipient? + end + + def valid_segment_recipient? + segment_recipient && UserSegments.respond_to?(segment_recipient) + end + + def draft? + sent_at.nil? + end + + def list_of_recipients_count + list_of_recipients.try(:count) || 0 + end + + def deliver + list_of_recipients.each { |user| Notification.add(user, self) } + self.update(sent_at: Time.current, recipients_count: list_of_recipients.count) + end + + private + + def validate_segment_recipient + errors.add(:segment_recipient, :invalid) unless valid_segment_recipient? + end + + def complete_link_url + return unless link.present? + unless self.link[/\Ahttp:\/\//] || self.link[/\Ahttps:\/\//] + self.link = "http://#{self.link}" + end + end +end diff --git a/spec/factories.rb b/spec/factories.rb index 77deec79a..beb64aa2d 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1003,6 +1003,20 @@ LOREM_IPSUM sequence(:body) { |n| "Body #{n}" } end + factory :admin_notification do + title { |n| "Admin Notification title #{n}" } + body { |n| "Admin Notification body #{n}" } + link nil + segment_recipient UserSegments::SEGMENTS.sample + recipients_count nil + sent_at nil + + trait :sent do + recipients_count 1 + sent_at Time.current + end + end + factory :widget_card, class: 'Widget::Card' do sequence(:title) { |n| "Title #{n}" } sequence(:description) { |n| "Description #{n}" } diff --git a/spec/models/admin_notification_spec.rb b/spec/models/admin_notification_spec.rb new file mode 100644 index 000000000..eeb974e83 --- /dev/null +++ b/spec/models/admin_notification_spec.rb @@ -0,0 +1,91 @@ +require 'rails_helper' + +describe AdminNotification do + let(:admin_notification) { build(:admin_notification) } + + it "is valid" do + expect(admin_notification).to be_valid + end + + it 'is not valid without a title' do + admin_notification.title = nil + expect(admin_notification).not_to be_valid + end + + it 'is not valid without a body' do + admin_notification.body = nil + expect(admin_notification).not_to be_valid + end + + it 'is not valid without a segment_recipient' do + admin_notification.segment_recipient = nil + expect(admin_notification).not_to be_valid + end + + describe '#complete_link_url' do + it 'does not change link if there is no value' do + expect(admin_notification.link).to be_nil + end + + it 'fixes a link without http://' do + admin_notification.link = 'lol.consul.dev' + + expect(admin_notification).to be_valid + expect(admin_notification.link).to eq('http://lol.consul.dev') + end + + it 'fixes a link with wwww. but without http://' do + admin_notification.link = 'www.lol.consul.dev' + + expect(admin_notification).to be_valid + expect(admin_notification.link).to eq('http://www.lol.consul.dev') + end + + it 'does not modify a link with http://' do + admin_notification.link = 'http://lol.consul.dev' + + expect(admin_notification).to be_valid + expect(admin_notification.link).to eq('http://lol.consul.dev') + end + + it 'does not modify a link with https://' do + admin_notification.link = 'https://lol.consul.dev' + + expect(admin_notification).to be_valid + expect(admin_notification.link).to eq('https://lol.consul.dev') + end + + it 'does not modify a link with http://wwww.' do + admin_notification.link = 'http://www.lol.consul.dev' + + expect(admin_notification).to be_valid + expect(admin_notification.link).to eq('http://www.lol.consul.dev') + end + end + + describe '#valid_segment_recipient?' do + it 'is false when segment_recipient value is invalid' do + admin_notification.update(segment_recipient: 'invalid_segment_name') + error = 'The user recipients segment is invalid' + + expect(admin_notification).not_to be_valid + expect(admin_notification.errors.messages[:segment_recipient]).to include(error) + end + end + + describe '#list_of_recipients' do + let(:erased_user) { create(:user, username: 'erased_user') } + + before do + 2.times { create(:user) } + erased_user.erase + admin_notification.update(segment_recipient: 'all_users') + end + + it 'returns list of all active users' do + expect(admin_notification.list_of_recipients.count).to eq(2) + expect(admin_notification.list_of_recipients).not_to include(erased_user) + end + end + +end