mirror of
https://github.com/Evolix/chexpire.git
synced 2024-05-13 05:58:38 +02:00
Add & removal of notification from a check
This commit is contained in:
parent
1915a93848
commit
b952f600f1
3
Gemfile
3
Gemfile
|
@ -39,6 +39,9 @@ gem 'bcrypt', '~> 3.1.7'
|
||||||
gem 'open4'
|
gem 'open4'
|
||||||
gem 'naught'
|
gem 'naught'
|
||||||
|
|
||||||
|
|
||||||
|
gem 'octicons'
|
||||||
|
|
||||||
# Reduces boot times through caching; required in config/boot.rb
|
# Reduces boot times through caching; required in config/boot.rb
|
||||||
gem 'bootsnap', '>= 1.1.0', require: false
|
gem 'bootsnap', '>= 1.1.0', require: false
|
||||||
|
|
||||||
|
|
|
@ -175,6 +175,8 @@ GEM
|
||||||
notiffany (0.1.1)
|
notiffany (0.1.1)
|
||||||
nenv (~> 0.1)
|
nenv (~> 0.1)
|
||||||
shellany (~> 0.0)
|
shellany (~> 0.0)
|
||||||
|
octicons (7.3.0)
|
||||||
|
nokogiri (>= 1.6.3.1)
|
||||||
open4 (1.3.4)
|
open4 (1.3.4)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
parallel (1.12.1)
|
parallel (1.12.1)
|
||||||
|
@ -335,6 +337,7 @@ DEPENDENCIES
|
||||||
listen (>= 3.0.5, < 3.2)
|
listen (>= 3.0.5, < 3.2)
|
||||||
mysql2 (>= 0.4.4, < 0.6.0)
|
mysql2 (>= 0.4.4, < 0.6.0)
|
||||||
naught
|
naught
|
||||||
|
octicons
|
||||||
open4
|
open4
|
||||||
pry-byebug
|
pry-byebug
|
||||||
pry-rails
|
pry-rails
|
||||||
|
|
|
@ -10,6 +10,7 @@ class ChecksController < ApplicationController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@check = Check.new
|
@check = Check.new
|
||||||
|
build_empty_notification
|
||||||
authorize @check
|
authorize @check
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -27,7 +28,9 @@ class ChecksController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def edit; end
|
def edit
|
||||||
|
build_empty_notification
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @check.update(update_check_params)
|
if @check.update(update_check_params)
|
||||||
|
@ -35,6 +38,7 @@ class ChecksController < ApplicationController
|
||||||
redirect_to checks_path
|
redirect_to checks_path
|
||||||
else
|
else
|
||||||
flash.now[:alert] = "An error occured."
|
flash.now[:alert] = "An error occured."
|
||||||
|
build_empty_notification
|
||||||
render :edit
|
render :edit
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -62,6 +66,11 @@ class ChecksController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_params(*others)
|
def check_params(*others)
|
||||||
params.require(:check).permit(:domain, :domain_created_at, :comment, :vendor, *others)
|
params.require(:check).permit(:domain, :domain_created_at, :comment, :vendor, *others,
|
||||||
|
notifications_attributes: [:id, :channel, :recipient, :delay])
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_empty_notification
|
||||||
|
@check.notifications.build
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
44
app/controllers/notifications_controller.rb
Normal file
44
app/controllers/notifications_controller.rb
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
class NotificationsController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
before_action :set_notification, except: [:create]
|
||||||
|
|
||||||
|
def create
|
||||||
|
check = Check.find(params[:check_id])
|
||||||
|
@notification = check.notifications.build(notification_params)
|
||||||
|
authorize @notification
|
||||||
|
|
||||||
|
if @notification.save
|
||||||
|
flash[:notice] = "Your notification has been saved."
|
||||||
|
redirect_to check_path
|
||||||
|
else
|
||||||
|
flash.now[:alert] = "An error occured."
|
||||||
|
render "checks/edit"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
@notification.destroy!
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_notification
|
||||||
|
# joins the check because policy use the check relation
|
||||||
|
@notification = Notification
|
||||||
|
.joins(:check)
|
||||||
|
.find_by!(id: params[:id], check_id: params[:check_id])
|
||||||
|
authorize @notification
|
||||||
|
end
|
||||||
|
|
||||||
|
def notification_params
|
||||||
|
params.require(:notification).permit(:channel, :recipient, :delay)
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_path
|
||||||
|
edit_check_path(check_id: params[:check_id])
|
||||||
|
end
|
||||||
|
end
|
5
app/frontend/scss/icons.scss
Normal file
5
app/frontend/scss/icons.scss
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
.octicon {
|
||||||
|
fill: currentColor;
|
||||||
|
vertical-align: text-top;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
@import '~bootstrap/scss/bootstrap';
|
@import '~bootstrap/scss/bootstrap';
|
||||||
@import 'layout';
|
@import 'layout';
|
||||||
|
@import 'icons';
|
||||||
@import 'components/users';
|
@import 'components/users';
|
||||||
|
|
|
@ -1,2 +1,9 @@
|
||||||
module NotificationsHelper
|
module NotificationsHelper
|
||||||
|
def many_channels_available?
|
||||||
|
Notification.channels.many?
|
||||||
|
end
|
||||||
|
|
||||||
|
def recipient_col_class
|
||||||
|
many_channels_available? ? "col-md-7" : "col-md-9"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,7 +29,10 @@
|
||||||
class Check < ApplicationRecord
|
class Check < ApplicationRecord
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
has_many :logs, class_name: "CheckLog"
|
has_many :logs, class_name: "CheckLog"
|
||||||
has_many :notifications
|
has_many :notifications, validate: true, dependent: :destroy
|
||||||
|
accepts_nested_attributes_for :notifications,
|
||||||
|
allow_destroy: true,
|
||||||
|
reject_if: lambda { |at| at["recipient"].blank? && at["delay"].blank? }
|
||||||
|
|
||||||
enum kind: [:domain, :ssl]
|
enum kind: [:domain, :ssl]
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# Table name: notifications
|
# Table name: notifications
|
||||||
#
|
#
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
# channel :integer not null
|
# channel :integer default("email"), not null
|
||||||
# delay :integer not null
|
# delay :integer not null
|
||||||
# recipient :string(255) not null
|
# recipient :string(255) not null
|
||||||
# sent_at :datetime
|
# sent_at :datetime
|
||||||
|
@ -28,7 +28,7 @@ class Notification < ApplicationRecord
|
||||||
enum status: [:pending, :ongoing, :succeed, :failed]
|
enum status: [:pending, :ongoing, :succeed, :failed]
|
||||||
|
|
||||||
validates :channel, presence: true
|
validates :channel, presence: true
|
||||||
validates :delay, presence: true
|
validates :delay, numericality: { only_integer: true, greater_than_or_equal_to: 1 }
|
||||||
validates :recipient, presence: true
|
validates :recipient, presence: true
|
||||||
|
|
||||||
def pending!
|
def pending!
|
||||||
|
|
21
app/policies/notification_policy.rb
Normal file
21
app/policies/notification_policy.rb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
class NotificationPolicy < ApplicationPolicy
|
||||||
|
class Scope < Scope
|
||||||
|
def resolve
|
||||||
|
scope.joins(:check).where(checks: { user: user })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy?
|
||||||
|
check_owner?
|
||||||
|
end
|
||||||
|
|
||||||
|
def show?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_owner?
|
||||||
|
record.check.user == user
|
||||||
|
end
|
||||||
|
end
|
|
@ -12,5 +12,18 @@
|
||||||
<%= f.input :active %>
|
<%= f.input :active %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= f.button :submit, "Validate", class: "btn-primary" %>
|
<h2 class="mt-5"><%= t(".notifications") %></h2>
|
||||||
|
<p class="alert alert-light"><%= t(".notifications_hint") %></p>
|
||||||
|
|
||||||
|
<%- check.notifications.each_with_index do |notification, index| %>
|
||||||
|
<div data-notification-id="<%= notification.id %>">
|
||||||
|
<%= f.fields_for :notifications, notification do |nf| %>
|
||||||
|
<%= render "notifications/nested_form_headers", f: nf if index.zero? %>
|
||||||
|
<%= render "notifications/nested_form", f: nf, check: check %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
<%= f.button :submit, class: "btn-primary mt-5" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
29
app/views/notifications/_nested_form.html.erb
Normal file
29
app/views/notifications/_nested_form.html.erb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<fieldset class="form-group">
|
||||||
|
<div class="form-row">
|
||||||
|
<%- if many_channels_available? %>
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<%- if f.object.new_record? -%>
|
||||||
|
<%= f.input :channel, collection: Notification.channels.keys, label: false %>
|
||||||
|
<% else -%>
|
||||||
|
<%= f.input_field :channel, as: :string, readonly: true, class: "form-control-plaintext" %>
|
||||||
|
<%- end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="form-group <%= recipient_col_class %>">
|
||||||
|
<%= f.input :recipient, as: :email, label: false %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-md-2">
|
||||||
|
<%= f.input :delay, as: :integer, label: false %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group col-md-1">
|
||||||
|
<% if f.object.persisted? %>
|
||||||
|
<%= link_to check_notification_path(check, f.object), method: :delete, remote: true, class: "btn btn-danger" do %>
|
||||||
|
<%== Octicons::Octicon.new("x", width: 15, height: 20).to_svg %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
15
app/views/notifications/_nested_form_headers.html.erb
Normal file
15
app/views/notifications/_nested_form_headers.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<div class="form-row">
|
||||||
|
<%- if many_channels_available? %>
|
||||||
|
<div class="col-md-2">
|
||||||
|
<%= f.label :channel %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="<%= recipient_col_class %>">
|
||||||
|
<%= f.label :recipient %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-2">
|
||||||
|
<%= f.label :delay %>
|
||||||
|
</div>
|
||||||
|
</div>
|
1
app/views/notifications/destroy.js.erb
Normal file
1
app/views/notifications/destroy.js.erb
Normal file
|
@ -0,0 +1 @@
|
||||||
|
document.querySelector("[data-notification-id='<%= @notification.id %>']").remove();
|
|
@ -18,7 +18,7 @@ Rails.application.config.content_security_policy do |policy|
|
||||||
end
|
end
|
||||||
|
|
||||||
# If you are using UJS then enable automatic nonce generation
|
# If you are using UJS then enable automatic nonce generation
|
||||||
# Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
Rails.application.config.content_security_policy_nonce_generator = -> request { SecureRandom.base64(16) }
|
||||||
|
|
||||||
# Report CSP violations to a specified URI
|
# Report CSP violations to a specified URI
|
||||||
# For further information see the following documentation:
|
# For further information see the following documentation:
|
||||||
|
|
|
@ -17,6 +17,11 @@ en:
|
||||||
new:
|
new:
|
||||||
tos_acceptance_html: "You must accept our Terms of service"
|
tos_acceptance_html: "You must accept our Terms of service"
|
||||||
|
|
||||||
|
simple_form:
|
||||||
|
placeholders:
|
||||||
|
notifications:
|
||||||
|
recipient: john@example.org
|
||||||
|
|
||||||
flashes:
|
flashes:
|
||||||
user_not_authorized: "You are not authorized to access to this resource."
|
user_not_authorized: "You are not authorized to access to this resource."
|
||||||
|
|
||||||
|
@ -44,3 +49,7 @@ en:
|
||||||
You have not set up a check yet.
|
You have not set up a check yet.
|
||||||
Please add a <a href="%{new_domain_path}">domain</a>
|
Please add a <a href="%{new_domain_path}">domain</a>
|
||||||
or a <a href="%{new_ssl_path}">ssl</a> !
|
or a <a href="%{new_ssl_path}">ssl</a> !
|
||||||
|
form:
|
||||||
|
notifications_hint: |
|
||||||
|
Receive notifications to warn you when our system detects that the
|
||||||
|
expiration date is coming. The delay is set in number of days.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# == Route Map
|
# == Route Map
|
||||||
#
|
#
|
||||||
# Prefix Verb URI Pattern Controller#Action
|
# Prefix Verb URI Pattern Controller#Action
|
||||||
|
# check_notification DELETE /checks/:check_id/notifications/:id(.:format) notifications#destroy
|
||||||
# checks GET /checks(.:format) checks#index
|
# checks GET /checks(.:format) checks#index
|
||||||
# POST /checks(.:format) checks#create
|
# POST /checks(.:format) checks#create
|
||||||
# new_check GET /checks/new(.:format) checks#new
|
# new_check GET /checks/new(.:format) checks#new
|
||||||
|
@ -46,7 +47,9 @@
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
||||||
|
|
||||||
resources :checks, except: [:show]
|
resources :checks, except: [:show] do
|
||||||
|
resources :notifications, only: [:destroy]
|
||||||
|
end
|
||||||
|
|
||||||
devise_for :users
|
devise_for :users
|
||||||
root to: "pages#home"
|
root to: "pages#home"
|
||||||
|
|
|
@ -2,4 +2,9 @@ require "test_helper"
|
||||||
|
|
||||||
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
||||||
driven_by :headless_chrome
|
driven_by :headless_chrome
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
Capybara.reset_sessions!
|
||||||
|
Warden.test_reset!
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,4 +2,22 @@ module ChexpireAssertions
|
||||||
def assert_just_now(expected)
|
def assert_just_now(expected)
|
||||||
assert_in_delta expected.to_i, Time.now.to_i, 1.0
|
assert_in_delta expected.to_i, Time.now.to_i, 1.0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def assert_permit(user, record, action)
|
||||||
|
msg = "User #{user.inspect} should be permitted to #{action} #{record}, but isn't permitted"
|
||||||
|
assert policy_permit(user, record, action), msg
|
||||||
|
end
|
||||||
|
|
||||||
|
def refute_permit(user, record, action)
|
||||||
|
msg = "User #{user.inspect} should NOT be permitted to #{action} #{record}, but is permitted"
|
||||||
|
refute policy_permit(user, record, action), msg
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def policy_permit(user, record, action)
|
||||||
|
test_name = self.class.ancestors.select { |a| a.to_s.match(/PolicyTest/) }.first
|
||||||
|
klass = test_name.to_s.gsub(/Test/, "")
|
||||||
|
klass.constantize.new(user, record).public_send("#{action}?")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -67,5 +67,11 @@ FactoryBot.define do
|
||||||
trait :inactive do
|
trait :inactive do
|
||||||
active false
|
active false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
trait :with_notifications do
|
||||||
|
after :create do |check|
|
||||||
|
create_list :notification, 2, check: check
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# Table name: notifications
|
# Table name: notifications
|
||||||
#
|
#
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
# channel :integer not null
|
# channel :integer default("email"), not null
|
||||||
# delay :integer not null
|
# delay :integer not null
|
||||||
# recipient :string(255) not null
|
# recipient :string(255) not null
|
||||||
# sent_at :datetime
|
# sent_at :datetime
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
# Table name: notifications
|
# Table name: notifications
|
||||||
#
|
#
|
||||||
# id :bigint(8) not null, primary key
|
# id :bigint(8) not null, primary key
|
||||||
# channel :integer not null
|
# channel :integer default("email"), not null
|
||||||
# delay :integer not null
|
# delay :integer not null
|
||||||
# recipient :string(255) not null
|
# recipient :string(255) not null
|
||||||
# sent_at :datetime
|
# sent_at :datetime
|
||||||
|
|
|
@ -1,13 +1,40 @@
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
||||||
class CheckPolicyTest < ActiveSupport::TestCase
|
class CheckPolicyTest < ActiveSupport::TestCase
|
||||||
def test_scope; end
|
setup do
|
||||||
|
@owner, @other = create_list(:user, 2)
|
||||||
|
@check = create(:check, user: @owner)
|
||||||
|
end
|
||||||
|
|
||||||
def test_show; end
|
test "create" do
|
||||||
|
assert_permit @other, Check, :create
|
||||||
|
assert_permit @other, Check, :new
|
||||||
|
end
|
||||||
|
|
||||||
def test_create; end
|
test "check owner" do
|
||||||
|
assert_permit @owner, @check, :update
|
||||||
|
assert_permit @owner, @check, :edit
|
||||||
|
assert_permit @owner, @check, :destroy
|
||||||
|
assert_permit @owner, @check, :show
|
||||||
|
end
|
||||||
|
|
||||||
def test_update; end
|
test "anonymous and other user" do
|
||||||
|
refute_permit @other, @check, :update
|
||||||
|
refute_permit @other, @check, :edit
|
||||||
|
refute_permit @other, @check, :destroy
|
||||||
|
refute_permit @other, @check, :show
|
||||||
|
|
||||||
def test_destroy; end
|
refute_permit nil, @check, :update
|
||||||
|
refute_permit nil, @check, :edit
|
||||||
|
refute_permit nil, @check, :destroy
|
||||||
|
refute_permit nil, @check, :show
|
||||||
|
end
|
||||||
|
|
||||||
|
test "scope only to owner" do
|
||||||
|
others = create_list(:check, 2, user: @other)
|
||||||
|
|
||||||
|
assert_empty Pundit.policy_scope!(nil, Check)
|
||||||
|
assert_equal [@check], Pundit.policy_scope!(@owner, Check)
|
||||||
|
assert_equal others, Pundit.policy_scope!(@other, Check)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
32
test/policies/notification_policy_test.rb
Normal file
32
test/policies/notification_policy_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require "test_helper"
|
||||||
|
|
||||||
|
class NotificationPolicyTest < ActiveSupport::TestCase
|
||||||
|
setup do
|
||||||
|
@owner, @other = create_list(:user, 2)
|
||||||
|
@notification = create(:notification, check: build(:check, user: @owner))
|
||||||
|
end
|
||||||
|
|
||||||
|
test "permit to check user" do
|
||||||
|
assert_permit @owner, @notification, :destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
test "disallow to anonymous and other user" do
|
||||||
|
refute_permit @other, @notification, :destroy
|
||||||
|
refute_permit nil, @notification, :destroy
|
||||||
|
end
|
||||||
|
|
||||||
|
test "scope only to user checks" do
|
||||||
|
other_notifications = create_list(:notification, 2, check: build(:check, user: @other))
|
||||||
|
|
||||||
|
assert_empty Pundit.policy_scope!(nil, Notification)
|
||||||
|
assert_equal [@notification], Pundit.policy_scope!(@owner, Notification)
|
||||||
|
assert_equal other_notifications, Pundit.policy_scope!(@other, Notification)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "disabled actions" do
|
||||||
|
refute_permit @owner, @notification, :update
|
||||||
|
refute_permit @owner, @notification, :edit
|
||||||
|
refute_permit @owner, @notification, :create
|
||||||
|
refute_permit @owner, @notification, :index
|
||||||
|
end
|
||||||
|
end
|
85
test/system/checks_test.rb
Normal file
85
test/system/checks_test.rb
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
require "application_system_test_case"
|
||||||
|
|
||||||
|
class ChecksTest < ApplicationSystemTestCase
|
||||||
|
setup do
|
||||||
|
@user = create(:user)
|
||||||
|
login_as(@user)
|
||||||
|
|
||||||
|
@check = create(:check, :with_notifications, user: @user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "create a check and a notification" do
|
||||||
|
visit new_check_path
|
||||||
|
|
||||||
|
domain = "domain-test.fr"
|
||||||
|
fill_in("check[domain]", with: domain)
|
||||||
|
choose "domain"
|
||||||
|
|
||||||
|
recipient = "recipient@example.org"
|
||||||
|
fill_in("check[notifications_attributes][0][recipient]", with: recipient)
|
||||||
|
fill_in("check[notifications_attributes][0][delay]", with: 30)
|
||||||
|
|
||||||
|
click_button
|
||||||
|
|
||||||
|
assert_equal checks_path, page.current_path
|
||||||
|
|
||||||
|
assert page.has_css?(".alert-success")
|
||||||
|
assert page.has_content?(domain)
|
||||||
|
|
||||||
|
notification = Notification.last
|
||||||
|
assert_equal recipient, notification.recipient
|
||||||
|
assert_equal 30, notification.delay
|
||||||
|
assert notification.email?
|
||||||
|
assert notification.pending?
|
||||||
|
end
|
||||||
|
|
||||||
|
test "remove a notification" do
|
||||||
|
visit edit_check_path(@check)
|
||||||
|
notification = @check.notifications.first
|
||||||
|
|
||||||
|
selector = "[data-notification-id=\"#{notification.id}\"]"
|
||||||
|
|
||||||
|
assert_difference "Notification.where(check_id: #{@check.id}).count", -1 do
|
||||||
|
within selector do
|
||||||
|
find(".btn-danger").click
|
||||||
|
end
|
||||||
|
|
||||||
|
page.has_no_content?(selector)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "update a check" do
|
||||||
|
visit edit_check_path(@check)
|
||||||
|
|
||||||
|
fill_in "check[comment]", with: "My comment"
|
||||||
|
|
||||||
|
click_button "Update Check"
|
||||||
|
|
||||||
|
assert_equal checks_path, page.current_path
|
||||||
|
|
||||||
|
assert page.has_css?(".alert-success")
|
||||||
|
assert page.has_content?("My comment")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "add a notification" do
|
||||||
|
visit edit_check_path(@check)
|
||||||
|
|
||||||
|
recipient = "recipient2@example.org"
|
||||||
|
fill_in("check[notifications_attributes][2][recipient]", with: recipient)
|
||||||
|
fill_in("check[notifications_attributes][2][delay]", with: 55)
|
||||||
|
|
||||||
|
assert_difference "Notification.where(check_id: #{@check.id}).count", +1 do
|
||||||
|
click_button "Update Check"
|
||||||
|
|
||||||
|
assert_equal checks_path, page.current_path
|
||||||
|
end
|
||||||
|
|
||||||
|
assert page.has_css?(".alert-success")
|
||||||
|
|
||||||
|
notification = Notification.last
|
||||||
|
assert_equal recipient, notification.recipient
|
||||||
|
assert_equal 55, notification.delay
|
||||||
|
assert notification.email?
|
||||||
|
assert notification.pending?
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue