Merge pull request #2580 from consul/admin_notifications
Admin notifications
This commit is contained in:
@@ -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}" }
|
||||
|
||||
236
spec/features/admin/admin_notifications_spec.rb
Normal file
236
spec/features/admin/admin_notifications_spec.rb
Normal file
@@ -0,0 +1,236 @@
|
||||
require 'rails_helper'
|
||||
|
||||
feature "Admin Notifications" do
|
||||
|
||||
background do
|
||||
admin = create(:administrator)
|
||||
login_as(admin.user)
|
||||
create(:budget)
|
||||
end
|
||||
|
||||
context "Show" do
|
||||
scenario "Valid Admin Notification" do
|
||||
notification = create(:admin_notification, title: 'Notification title',
|
||||
body: 'Notification body',
|
||||
link: 'https://www.decide.madrid.es/vota',
|
||||
segment_recipient: :all_users)
|
||||
|
||||
visit admin_admin_notification_path(notification)
|
||||
|
||||
expect(page).to have_content('Notification title')
|
||||
expect(page).to have_content('Notification body')
|
||||
expect(page).to have_content('https://www.decide.madrid.es/vota')
|
||||
expect(page).to have_content('All users')
|
||||
end
|
||||
|
||||
scenario "Notification with invalid segment recipient" do
|
||||
invalid_notification = create(:admin_notification)
|
||||
invalid_notification.update_attribute(:segment_recipient, 'invalid_segment')
|
||||
|
||||
visit admin_admin_notification_path(invalid_notification)
|
||||
|
||||
expect(page).to have_content("Recipients user segment is invalid")
|
||||
end
|
||||
end
|
||||
|
||||
context "Index" do
|
||||
scenario "Valid Admin Notifications" do
|
||||
draft = create(:admin_notification, segment_recipient: :all_users, title: 'Not yet sent')
|
||||
sent = create(:admin_notification, :sent, segment_recipient: :administrators,
|
||||
title: 'Sent one')
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
|
||||
expect(page).to have_css(".admin_notification", count: 2)
|
||||
|
||||
within("#admin_notification_#{draft.id}") do
|
||||
expect(page).to have_content('Not yet sent')
|
||||
expect(page).to have_content('All users')
|
||||
expect(page).to have_content('Draft')
|
||||
end
|
||||
|
||||
within("#admin_notification_#{sent.id}") do
|
||||
expect(page).to have_content('Sent one')
|
||||
expect(page).to have_content('Administrators')
|
||||
expect(page).to have_content(I18n.l(Date.current))
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Notifications with invalid segment recipient" do
|
||||
invalid_notification = create(:admin_notification)
|
||||
invalid_notification.update_attribute(:segment_recipient, 'invalid_segment')
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
|
||||
expect(page).to have_content("Recipients user segment is invalid")
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Create" do
|
||||
visit admin_admin_notifications_path
|
||||
click_link "New notification"
|
||||
|
||||
fill_in_admin_notification_form(segment_recipient: 'Proposal authors',
|
||||
title: 'This is a title',
|
||||
body: 'This is a body',
|
||||
link: 'http://www.dummylink.dev')
|
||||
|
||||
click_button "Create Admin notification"
|
||||
|
||||
expect(page).to have_content "Notification created successfully"
|
||||
expect(page).to have_content "Proposal authors"
|
||||
expect(page).to have_content "This is a title"
|
||||
expect(page).to have_content "This is a body"
|
||||
expect(page).to have_content "http://www.dummylink.dev"
|
||||
end
|
||||
|
||||
context "Update" do
|
||||
scenario "A draft notification can be updated" do
|
||||
notification = create(:admin_notification)
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
within("#admin_notification_#{notification.id}") do
|
||||
click_link "Edit"
|
||||
end
|
||||
|
||||
|
||||
fill_in_admin_notification_form(segment_recipient: 'All users',
|
||||
title: 'Other title',
|
||||
body: 'Other body',
|
||||
link: '')
|
||||
|
||||
click_button "Update Admin notification"
|
||||
|
||||
expect(page).to have_content "Notification updated successfully"
|
||||
expect(page).to have_content "All users"
|
||||
expect(page).to have_content "Other title"
|
||||
expect(page).to have_content "Other body"
|
||||
expect(page).not_to have_content "http://www.dummylink.dev"
|
||||
end
|
||||
|
||||
scenario "Sent notification can not be updated" do
|
||||
notification = create(:admin_notification, :sent)
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
within("#admin_notification_#{notification.id}") do
|
||||
expect(page).not_to have_link("Edit")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "Destroy" do
|
||||
scenario "A draft notification can be destroyed" do
|
||||
notification = create(:admin_notification)
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
within("#admin_notification_#{notification.id}") do
|
||||
click_link "Delete"
|
||||
end
|
||||
|
||||
expect(page).to have_content "Notification deleted successfully"
|
||||
expect(page).to have_css(".notification", count: 0)
|
||||
end
|
||||
|
||||
scenario "Sent notification can not be destroyed" do
|
||||
notification = create(:admin_notification, :sent)
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
within("#admin_notification_#{notification.id}") do
|
||||
expect(page).not_to have_link("Delete")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "Visualize" do
|
||||
scenario "A draft notification can be previewed" do
|
||||
notification = create(:admin_notification, segment_recipient: :administrators)
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
within("#admin_notification_#{notification.id}") do
|
||||
click_link "Preview"
|
||||
end
|
||||
|
||||
expect(page).to have_content "This is how the users will see the notification:"
|
||||
expect(page).to have_content "Administrators (1 users will be notified)"
|
||||
end
|
||||
|
||||
scenario "A sent notification can be viewed" do
|
||||
notification = create(:admin_notification, :sent, recipients_count: 7,
|
||||
segment_recipient: :administrators)
|
||||
|
||||
visit admin_admin_notifications_path
|
||||
within("#admin_notification_#{notification.id}") do
|
||||
click_link "View"
|
||||
end
|
||||
|
||||
expect(page).to have_content "This is how the users see the notification:"
|
||||
expect(page).to have_content "Administrators (7 users got notified)"
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Errors on create' do
|
||||
visit new_admin_admin_notification_path
|
||||
|
||||
click_button "Create Admin notification"
|
||||
|
||||
expect(page).to have_content error_message
|
||||
end
|
||||
|
||||
scenario "Errors on update" do
|
||||
notification = create(:admin_notification)
|
||||
visit edit_admin_admin_notification_path(notification)
|
||||
|
||||
fill_in :admin_notification_title, with: ''
|
||||
click_button "Update Admin notification"
|
||||
|
||||
expect(page).to have_content error_message
|
||||
end
|
||||
|
||||
context "Send notification", :js do
|
||||
scenario "A draft Admin notification can be sent", :js do
|
||||
2.times { create(:user) }
|
||||
notification = create(:admin_notification, segment_recipient: :all_users)
|
||||
total_users = notification.list_of_recipients.count
|
||||
confirm_message = "Are you sure you want to send this notification to #{total_users} users?"
|
||||
|
||||
visit admin_admin_notification_path(notification)
|
||||
|
||||
accept_confirm { click_link "Send" }
|
||||
|
||||
expect(page).to have_content "Notification sent successfully"
|
||||
|
||||
User.all.each do |user|
|
||||
expect(user.notifications.count).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
scenario "A sent Admin notification can not be sent", :js do
|
||||
notification = create(:admin_notification, :sent)
|
||||
|
||||
visit admin_admin_notification_path(notification)
|
||||
|
||||
expect(page).not_to have_link("Send")
|
||||
end
|
||||
|
||||
scenario "Admin notification with invalid segment recipient cannot be sent", :js do
|
||||
invalid_notification = create(:admin_notification)
|
||||
invalid_notification.update_attribute(:segment_recipient, 'invalid_segment')
|
||||
visit admin_admin_notification_path(invalid_notification)
|
||||
|
||||
expect(page).not_to have_link("Send")
|
||||
end
|
||||
end
|
||||
|
||||
scenario "Select list of users to send notification" do
|
||||
UserSegments::SEGMENTS.each do |user_segment|
|
||||
segment_recipient = I18n.t("admin.segment_recipient.#{user_segment}")
|
||||
|
||||
visit new_admin_admin_notification_path
|
||||
|
||||
fill_in_admin_notification_form(segment_recipient: segment_recipient)
|
||||
click_button "Create Admin notification"
|
||||
|
||||
expect(page).to have_content(I18n.t("admin.segment_recipient.#{user_segment}"))
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -128,4 +128,50 @@ feature "Notifications" do
|
||||
expect(page).to_not have_css("#notifications")
|
||||
end
|
||||
|
||||
context "Admin Notifications" do
|
||||
let(:admin_notification) do
|
||||
create(:admin_notification, title: 'Notification title',
|
||||
body: 'Notification body',
|
||||
link: 'https://www.external.link.dev/',
|
||||
segment_recipient: 'all_users')
|
||||
end
|
||||
|
||||
let!(:notification) do
|
||||
create(:notification, user: user, notifiable: admin_notification)
|
||||
end
|
||||
|
||||
before do
|
||||
login_as user
|
||||
end
|
||||
|
||||
scenario "With external link" do
|
||||
visit notifications_path
|
||||
expect(page).to have_content('Notification title')
|
||||
expect(page).to have_content('Notification body')
|
||||
|
||||
first("#notification_#{notification.id} a").click
|
||||
expect(page.current_url).to eq('https://www.external.link.dev/')
|
||||
end
|
||||
|
||||
scenario "With internal link" do
|
||||
admin_notification.update_attributes(link: '/stats')
|
||||
|
||||
visit notifications_path
|
||||
expect(page).to have_content('Notification title')
|
||||
expect(page).to have_content('Notification body')
|
||||
|
||||
first("#notification_#{notification.id} a").click
|
||||
expect(page).to have_current_path('/stats')
|
||||
end
|
||||
|
||||
scenario "Without a link" do
|
||||
admin_notification.update_attributes(link: '/stats')
|
||||
|
||||
visit notifications_path
|
||||
expect(page).to have_content('Notification title')
|
||||
expect(page).to have_content('Notification body')
|
||||
expect(page).not_to have_link(notification_path(notification), visible: false)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
91
spec/models/admin_notification_spec.rb
Normal file
91
spec/models/admin_notification_spec.rb
Normal file
@@ -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
|
||||
@@ -53,4 +53,11 @@ module Notifications
|
||||
field_check_message = 'Please check the marked fields to know how to correct them:'
|
||||
/\d errors? prevented this #{resource_model} from being saved. #{field_check_message}/
|
||||
end
|
||||
|
||||
def fill_in_admin_notification_form(options = {})
|
||||
select (options[:segment_recipient] || 'All users'), from: :admin_notification_segment_recipient
|
||||
fill_in :admin_notification_title, with: (options[:title] || 'This is the notification title')
|
||||
fill_in :admin_notification_body, with: (options[:body] || 'This is the notification body')
|
||||
fill_in :admin_notification_link, with: (options[:link] || 'https://www.decide.madrid.es/vota')
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user