diff --git a/app/controllers/articles_controller.rb b/app/controllers/articles_controller.rb
index e8bdfa688fa..3cd53ef7d76 100644
--- a/app/controllers/articles_controller.rb
+++ b/app/controllers/articles_controller.rb
@@ -32,6 +32,7 @@ def create
@article.user = current_user if @article.user.nil?
set_wip
if @article.save
+ Newspaper.publish(:create_article, { article: @article })
redirect_to redirect_url(@article), notice: notice_message(@article)
else
render :new
@@ -41,6 +42,7 @@ def create
def update
set_wip
if @article.update(article_params)
+ Newspaper.publish(:create_article, { article: @article })
redirect_to redirect_url(@article), notice: notice_message(@article)
else
render :edit
@@ -49,6 +51,7 @@ def update
def destroy
@article.destroy
+ Newspaper.publish(:destroy_article, { article: @article })
redirect_to articles_url, notice: '記事を削除しました'
end
diff --git a/app/mailers/activity_mailer.rb b/app/mailers/activity_mailer.rb
index b98438fce92..2b55104da6e 100644
--- a/app/mailers/activity_mailer.rb
+++ b/app/mailers/activity_mailer.rb
@@ -415,4 +415,21 @@ def product_update(args = {})
message
end
+
+ # required params: article, receiver
+ def create_article(args = {})
+ @article = params&.key?(:article) ? params[:article] : args[:article]
+ @receiver ||= args[:receiver]
+
+ @user = @receiver
+ @link_url = notification_redirector_url(
+ link: "/articles/#{@article.id}",
+ kind: Notification.kinds[:create_article]
+ )
+ subject = "新しいブログ「#{@article.title}」を#{@article.user.login_name}さんが投稿しました!"
+ message = mail(to: @user.email, subject:)
+ message.perform_deliveries = @user.mail_notification? && !@user.retired?
+
+ message
+ end
end
diff --git a/app/models/article.rb b/app/models/article.rb
index 763b1cea859..f662c38dc45 100644
--- a/app/models/article.rb
+++ b/app/models/article.rb
@@ -18,6 +18,7 @@ class Article < ApplicationRecord
}
belongs_to :user
+ alias sender user
include ActionView::Helpers::AssetUrlHelper
THUMBNAIL_SIZE = [1200, 630].freeze
diff --git a/app/models/article_notification_destroyer.rb b/app/models/article_notification_destroyer.rb
new file mode 100644
index 00000000000..e8537d32aad
--- /dev/null
+++ b/app/models/article_notification_destroyer.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+class ArticleNotificationDestroyer
+ def call(payload)
+ article = payload[:article]
+ Notification.where(link: "/articles/#{article.id}").destroy_all
+ end
+end
diff --git a/app/models/article_notifier.rb b/app/models/article_notifier.rb
new file mode 100644
index 00000000000..f85ee675170
--- /dev/null
+++ b/app/models/article_notifier.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class ArticleNotifier
+ def call(payload)
+ article = payload[:article]
+ return if article.wip?
+
+ receivers = User.students_trainees_mentors_and_admins.reject { |receiver| receiver == article.user }
+ send_notification(article:, receivers:)
+ end
+
+ private
+
+ def send_notification(article:, receivers:)
+ receivers.each do |receiver|
+ ActivityDelivery.with(article:, receiver:).notify(:create_article)
+ end
+ end
+end
diff --git a/app/models/notification.rb b/app/models/notification.rb
index 3a6e2eaedbd..7e572826413 100644
--- a/app/models/notification.rb
+++ b/app/models/notification.rb
@@ -39,7 +39,8 @@ class Notification < ApplicationRecord
signed_up: 20,
regular_event_updated: 21,
no_correct_answer: 22,
- comebacked: 23
+ comebacked: 23,
+ create_article: 24
}
scope :unreads, -> { where(read: false) }
diff --git a/app/notifiers/activity_notifier.rb b/app/notifiers/activity_notifier.rb
index b4f679d6439..018683d5a55 100644
--- a/app/notifiers/activity_notifier.rb
+++ b/app/notifiers/activity_notifier.rb
@@ -352,4 +352,19 @@ def moved_up_event_waiting_user(params = {})
read: false
)
end
+
+ def create_article(params = {})
+ params.merge!(@params)
+ article = params[:article]
+ receiver = params[:receiver]
+
+ notification(
+ body: "#{article.user.login_name}さんがブログに「#{article.title}」を投稿しました。",
+ kind: :create_article,
+ receiver:,
+ sender: article.user,
+ link: Rails.application.routes.url_helpers.polymorphic_path(article),
+ read: false
+ )
+ end
end
diff --git a/app/views/activity_mailer/create_article.html.slim b/app/views/activity_mailer/create_article.html.slim
new file mode 100644
index 00000000000..855aa3d3e56
--- /dev/null
+++ b/app/views/activity_mailer/create_article.html.slim
@@ -0,0 +1,4 @@
+= render '/notification_mailer/notification_mailer_template',
+ title: "#{@article.user.login_name}さんがブログに「#{@article.title}」を投稿しました。",
+ link_url: @link_url, link_text: 'ブログへ' do
+ = md2html(@article.body)
diff --git a/config/initializers/newspaper.rb b/config/initializers/newspaper.rb
index 1dfe2d6590d..3fe9d9115c2 100644
--- a/config/initializers/newspaper.rb
+++ b/config/initializers/newspaper.rb
@@ -70,4 +70,7 @@
Newspaper.subscribe(:product_update, ProductUpdateNotifierForChecker.new)
Newspaper.subscribe(:came_comment, CommentNotifier.new)
Newspaper.subscribe(:came_comment_in_talk, CommentNotifierForAdmin.new)
+
+ Newspaper.subscribe(:create_article, ArticleNotifier.new)
+ Newspaper.subscribe(:destroy_article, ArticleNotificationDestroyer.new)
end
diff --git a/test/deliveries/activity_delivery_test.rb b/test/deliveries/activity_delivery_test.rb
index 8c634c6f100..d66f6e719b6 100644
--- a/test/deliveries/activity_delivery_test.rb
+++ b/test/deliveries/activity_delivery_test.rb
@@ -452,4 +452,27 @@ class ActivityDeliveryTest < ActiveSupport::TestCase
ActivityDelivery.with(**params).notify(:came_comment)
end
end
+
+ test '.notify(:create_article)' do
+ params = {
+ article: articles(:article1),
+ receiver: users(:kimura)
+ }
+
+ assert_difference -> { AbstractNotifier::Testing::Driver.deliveries.count }, 1 do
+ ActivityDelivery.notify!(:create_article, **params)
+ end
+
+ assert_difference -> { AbstractNotifier::Testing::Driver.enqueued_deliveries.count }, 1 do
+ ActivityDelivery.notify(:create_article, **params)
+ end
+
+ assert_difference -> { AbstractNotifier::Testing::Driver.deliveries.count }, 1 do
+ ActivityDelivery.with(**params).notify!(:create_article)
+ end
+
+ assert_difference -> { AbstractNotifier::Testing::Driver.enqueued_deliveries.count }, 1 do
+ ActivityDelivery.with(**params).notify(:create_article)
+ end
+ end
end
diff --git a/test/mailers/activity_mailer_test.rb b/test/mailers/activity_mailer_test.rb
index 5f15118bdd9..bc8720ce3c8 100644
--- a/test/mailers/activity_mailer_test.rb
+++ b/test/mailers/activity_mailer_test.rb
@@ -1135,4 +1135,66 @@ class ActivityMailerTest < ActionMailer::TestCase
assert_empty ActionMailer::Base.deliveries
end
+
+ test 'create_article notifies students, trainees, mentors, and admins' do
+ target_users = %i[hatsuno kensyu mentormentaro machida]
+
+ target_users.each do |target_user|
+ article = articles(:article1)
+ receiver = users(target_user)
+
+ ActivityMailer.create_article(
+ article:,
+ receiver:
+ ).deliver_now
+
+ assert_not ActionMailer::Base.deliveries.empty?
+ email = ActionMailer::Base.deliveries.last
+ query = CGI.escapeHTML({ kind: 24, link: "/articles/#{article.id}" }.to_param)
+ assert_equal ['noreply@bootcamp.fjord.jp'], email.from
+ assert_equal [receiver.email], email.to
+ assert_equal "新しいブログ「#{article.title}」を#{article.user.login_name}さんが投稿しました!", email.subject
+ assert_match(%r{ブログへ}, email.body.to_s)
+ end
+ end
+
+ test 'create_article notifies students, trainees, mentors, and admins with params' do
+ target_users = %i[hatsuno kensyu mentormentaro machida]
+
+ target_users.each do |target_user|
+ article = articles(:article1)
+ receiver = users(target_user)
+
+ mailer = ActivityMailer.with(
+ article:,
+ receiver:
+ ).create_article
+
+ perform_enqueued_jobs do
+ mailer.deliver_later
+ end
+
+ assert_not ActionMailer::Base.deliveries.empty?
+ email = ActionMailer::Base.deliveries.last
+ query = CGI.escapeHTML({ kind: 24, link: "/articles/#{article.id}" }.to_param)
+ assert_equal ['noreply@bootcamp.fjord.jp'], email.from
+ assert_equal [receiver.email], email.to
+ assert_equal "新しいブログ「#{article.title}」を#{article.user.login_name}さんが投稿しました!", email.subject
+ assert_match(%r{ブログへ}, email.body.to_s)
+ end
+ end
+
+ test 'create_article notifies students, trainees, mentors, and admins with mail_notification off' do
+ article = articles(:article1)
+ receiver = users(:mentormentaro)
+ receiver.update(mail_notification: false)
+
+ ActivityMailer.create_article(
+ sender: article.user,
+ receiver:,
+ article:
+ ).deliver_now
+
+ assert_empty ActionMailer::Base.deliveries
+ end
end
diff --git a/test/mailers/previews/activity_mailer_preview.rb b/test/mailers/previews/activity_mailer_preview.rb
index 98b4aa8ef9e..0d28d39bcf8 100644
--- a/test/mailers/previews/activity_mailer_preview.rb
+++ b/test/mailers/previews/activity_mailer_preview.rb
@@ -170,4 +170,12 @@ def no_correct_answer
ActivityMailer.with(question:, receiver:).no_correct_answer
end
+
+ def create_article
+ article = Article.find(ActiveRecord::FixtureSet.identify(:article1))
+ receiver = User.find(ActiveRecord::FixtureSet.identify(:kimura))
+ user = User.find(article.user_id)
+
+ ActivityMailer.with(article:, receiver:, sender: user).create_article
+ end
end