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