Adding unified streamable notifications
This commit is contained in:
		
							parent
							
								
									3838e6836d
								
							
						
					
					
						commit
						da2ef4d676
					
				
					 20 changed files with 205 additions and 44 deletions
				
			
		|  | @ -10,7 +10,7 @@ module ApplicationCable | ||||||
|       return [nil, message] if message['type'] == 'delete' |       return [nil, message] if message['type'] == 'delete' | ||||||
| 
 | 
 | ||||||
|       status             = Status.find_by(id: message['id']) |       status             = Status.find_by(id: message['id']) | ||||||
|       message['message'] = FeedManager.instance.inline_render(current_user.account, status) |       message['message'] = FeedManager.instance.inline_render(current_user.account, 'api/v1/statuses/show', status) | ||||||
| 
 | 
 | ||||||
|       [status, message] |       [status, message] | ||||||
|     end |     end | ||||||
|  |  | ||||||
							
								
								
									
										17
									
								
								app/controllers/api/v1/notifications_controller.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/controllers/api/v1/notifications_controller.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,17 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class Api::V1::NotificationsController < ApiController | ||||||
|  |   before_action -> { doorkeeper_authorize! :read } | ||||||
|  |   before_action :require_user! | ||||||
|  | 
 | ||||||
|  |   respond_to :json | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  |     @notifications = Notification.where(account: current_account).with_includes.paginate_by_max_id(20, params[:max_id], params[:since_id]) | ||||||
|  | 
 | ||||||
|  |     next_path = api_v1_notifications_url(max_id: @notifications.last.id)    if @notifications.size == 20 | ||||||
|  |     prev_path = api_v1_notifications_url(since_id: @notifications.first.id) unless @notifications.empty? | ||||||
|  | 
 | ||||||
|  |     set_pagination_headers(next_path, prev_path) | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -26,7 +26,7 @@ class FeedManager | ||||||
|   def push(timeline_type, account, status) |   def push(timeline_type, account, status) | ||||||
|     redis.zadd(key(timeline_type, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id) |     redis.zadd(key(timeline_type, account.id), status.id, status.reblog? ? status.reblog_of_id : status.id) | ||||||
|     trim(timeline_type, account.id) |     trim(timeline_type, account.id) | ||||||
|     broadcast(account.id, type: 'update', timeline: timeline_type, message: inline_render(account, status)) |     broadcast(account.id, type: 'update', timeline: timeline_type, message: inline_render(account, 'api/v1/statuses/show', status)) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def broadcast(timeline_id, options = {}) |   def broadcast(timeline_id, options = {}) | ||||||
|  | @ -39,7 +39,7 @@ class FeedManager | ||||||
|     redis.zremrangebyscore(key(type, account_id), '-inf', "(#{last.last}") |     redis.zremrangebyscore(key(type, account_id), '-inf', "(#{last.last}") | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def inline_render(target_account, status) |   def inline_render(target_account, template, object) | ||||||
|     rabl_scope = Class.new do |     rabl_scope = Class.new do | ||||||
|       include RoutingHelper |       include RoutingHelper | ||||||
| 
 | 
 | ||||||
|  | @ -56,7 +56,7 @@ class FeedManager | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     Rabl::Renderer.new('api/v1/statuses/show', status, view_path: 'app/views', format: :json, scope: rabl_scope.new(target_account)).render |     Rabl::Renderer.new(template, object, view_path: 'app/views', format: :json, scope: rabl_scope.new(target_account)).render | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   private |   private | ||||||
|  |  | ||||||
|  | @ -3,46 +3,38 @@ | ||||||
| class NotificationMailer < ApplicationMailer | class NotificationMailer < ApplicationMailer | ||||||
|   helper StreamEntriesHelper |   helper StreamEntriesHelper | ||||||
| 
 | 
 | ||||||
|   def mention(mentioned_account, status) |   def mention(recipient, notification) | ||||||
|     @me     = mentioned_account |     @me     = recipient | ||||||
|     @status = status |     @status = notification.target_status | ||||||
| 
 |  | ||||||
|     return unless @me.user.settings(:notification_emails).mention |  | ||||||
| 
 | 
 | ||||||
|     I18n.with_locale(@me.user.locale || I18n.default_locale) do |     I18n.with_locale(@me.user.locale || I18n.default_locale) do | ||||||
|       mail to: @me.user.email, subject: I18n.t('notification_mailer.mention.subject', name: @status.account.acct) |       mail to: @me.user.email, subject: I18n.t('notification_mailer.mention.subject', name: @status.account.acct) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def follow(followed_account, follower) |   def follow(recipient, notification) | ||||||
|     @me      = followed_account |     @me      = recipient | ||||||
|     @account = follower |     @account = notification.from_account | ||||||
| 
 |  | ||||||
|     return unless @me.user.settings(:notification_emails).follow |  | ||||||
| 
 | 
 | ||||||
|     I18n.with_locale(@me.user.locale || I18n.default_locale) do |     I18n.with_locale(@me.user.locale || I18n.default_locale) do | ||||||
|       mail to: @me.user.email, subject: I18n.t('notification_mailer.follow.subject', name: @account.acct) |       mail to: @me.user.email, subject: I18n.t('notification_mailer.follow.subject', name: @account.acct) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def favourite(target_status, from_account) |   def favourite(recipient, notification) | ||||||
|     @me      = target_status.account |     @me      = recipient | ||||||
|     @account = from_account |     @account = notification.from_account | ||||||
|     @status  = target_status |     @status  = notification.target_status | ||||||
| 
 |  | ||||||
|     return unless @me.user.settings(:notification_emails).favourite |  | ||||||
| 
 | 
 | ||||||
|     I18n.with_locale(@me.user.locale || I18n.default_locale) do |     I18n.with_locale(@me.user.locale || I18n.default_locale) do | ||||||
|       mail to: @me.user.email, subject: I18n.t('notification_mailer.favourite.subject', name: @account.acct) |       mail to: @me.user.email, subject: I18n.t('notification_mailer.favourite.subject', name: @account.acct) | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def reblog(target_status, from_account) |   def reblog(recipient, notification) | ||||||
|     @me      = target_status.account |     @me      = recipient | ||||||
|     @account = from_account |     @account = notification.from_account | ||||||
|     @status  = target_status |     @status  = notification.target_status | ||||||
| 
 |  | ||||||
|     return unless @me.user.settings(:notification_emails).reblog |  | ||||||
| 
 | 
 | ||||||
|     I18n.with_locale(@me.user.locale || I18n.default_locale) do |     I18n.with_locale(@me.user.locale || I18n.default_locale) do | ||||||
|       mail to: @me.user.email, subject: I18n.t('notification_mailer.reblog.subject', name: @account.acct) |       mail to: @me.user.email, subject: I18n.t('notification_mailer.reblog.subject', name: @account.acct) | ||||||
|  |  | ||||||
							
								
								
									
										44
									
								
								app/models/notification.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								app/models/notification.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class Notification < ApplicationRecord | ||||||
|  |   include Paginable | ||||||
|  | 
 | ||||||
|  |   belongs_to :account | ||||||
|  |   belongs_to :activity, polymorphic: true | ||||||
|  | 
 | ||||||
|  |   belongs_to :mention,   foreign_type: 'Mention',   foreign_key: 'activity_id' | ||||||
|  |   belongs_to :status,    foreign_type: 'Status',    foreign_key: 'activity_id' | ||||||
|  |   belongs_to :follow,    foreign_type: 'Follow',    foreign_key: 'activity_id' | ||||||
|  |   belongs_to :favourite, foreign_type: 'Favourite', foreign_key: 'activity_id' | ||||||
|  | 
 | ||||||
|  |   STATUS_INCLUDES = [:account, :media_attachments, mentions: :account, reblog: [:account, mentions: :account]].freeze | ||||||
|  | 
 | ||||||
|  |   scope :with_includes, -> { includes(status: STATUS_INCLUDES, mention: [status: STATUS_INCLUDES], favourite: [:account, status: STATUS_INCLUDES], follow: :account) } | ||||||
|  | 
 | ||||||
|  |   def type | ||||||
|  |     case activity_type | ||||||
|  |     when 'Status' | ||||||
|  |       :reblog | ||||||
|  |     else | ||||||
|  |       activity_type.downcase.to_sym | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def from_account | ||||||
|  |     case type | ||||||
|  |     when :mention | ||||||
|  |       activity.status.account | ||||||
|  |     when :follow, :favourite, :reblog | ||||||
|  |       activity.account | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def target_status | ||||||
|  |     case type | ||||||
|  |     when :reblog | ||||||
|  |       activity.reblog | ||||||
|  |     when :favourite, :mention | ||||||
|  |       activity.status | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -10,7 +10,7 @@ class FavouriteService < BaseService | ||||||
|     HubPingWorker.perform_async(account.id) |     HubPingWorker.perform_async(account.id) | ||||||
| 
 | 
 | ||||||
|     if status.local? |     if status.local? | ||||||
|       NotificationMailer.favourite(status, account).deliver_later unless status.account.blocking?(account) |       NotifyService.new.call(status.account, favourite) | ||||||
|     else |     else | ||||||
|       NotificationWorker.perform_async(favourite.stream_entry.id, status.account_id) |       NotificationWorker.perform_async(favourite.stream_entry.id, status.account_id) | ||||||
|     end |     end | ||||||
|  |  | ||||||
|  | @ -12,7 +12,7 @@ class FollowService < BaseService | ||||||
|     follow = source_account.follow!(target_account) |     follow = source_account.follow!(target_account) | ||||||
| 
 | 
 | ||||||
|     if target_account.local? |     if target_account.local? | ||||||
|       NotificationMailer.follow(target_account, source_account).deliver_later unless target_account.blocking?(source_account) |       NotifyService.new.call(target_account, follow) | ||||||
|     else |     else | ||||||
|       subscribe_service.call(target_account) |       subscribe_service.call(target_account) | ||||||
|       NotificationWorker.perform_async(follow.stream_entry.id, target_account.id) |       NotificationWorker.perform_async(follow.stream_entry.id, target_account.id) | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								app/services/notify_service.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								app/services/notify_service.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | # frozen_string_literal: true | ||||||
|  | 
 | ||||||
|  | class NotifyService < BaseService | ||||||
|  |   def call(recipient, activity) | ||||||
|  |     @recipient    = recipient | ||||||
|  |     @activity     = activity | ||||||
|  |     @notification = Notification.new(account: @recipient, activity: @activity) | ||||||
|  | 
 | ||||||
|  |     return if blocked? | ||||||
|  | 
 | ||||||
|  |     create_notification | ||||||
|  |     send_email if email_enabled? | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def blocked? | ||||||
|  |     blocked = false | ||||||
|  |     blocked ||= @recipient.id == @notification.from_account.id | ||||||
|  |     blocked ||= @recipient.blocking?(@notification.from_account) | ||||||
|  |     blocked | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def create_notification | ||||||
|  |     @notification.save! | ||||||
|  |     FeedManager.instance.broadcast(@recipient.id, type: 'notification', message: FeedManager.instance.inline_render(@recipient, 'api/v1/notifications/show', @notification)) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def send_email | ||||||
|  |     NotificationMailer.send(@notification.type, @recipient, @notification).deliver_later | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def email_enabled? | ||||||
|  |     @recipient.user.settings(:notification_emails).send(@notification.type) | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | @ -150,12 +150,10 @@ class ProcessFeedService < BaseService | ||||||
| 
 | 
 | ||||||
|         next if mentioned_account.nil? || processed_account_ids.include?(mentioned_account.id) |         next if mentioned_account.nil? || processed_account_ids.include?(mentioned_account.id) | ||||||
| 
 | 
 | ||||||
|         if mentioned_account.local? |         mention = mentioned_account.mentions.where(status: parent).first_or_create(status: parent) | ||||||
|           # Send notifications |  | ||||||
|           NotificationMailer.mention(mentioned_account, parent).deliver_later unless mentioned_account.blocking?(parent.account) |  | ||||||
|         end |  | ||||||
| 
 | 
 | ||||||
|         mentioned_account.mentions.where(status: parent).first_or_create(status: parent) |         # Notify local user | ||||||
|  |         NotifyService.new.call(mentioned_account, mention) if mentioned_account.local? | ||||||
| 
 | 
 | ||||||
|         # So we can skip duplicate mentions |         # So we can skip duplicate mentions | ||||||
|         processed_account_ids << mentioned_account.id |         processed_account_ids << mentioned_account.id | ||||||
|  |  | ||||||
|  | @ -65,8 +65,8 @@ class ProcessInteractionService < BaseService | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def follow!(account, target_account) |   def follow!(account, target_account) | ||||||
|     account.follow!(target_account) |     follow = account.follow!(target_account) | ||||||
|     NotificationMailer.follow(target_account, account).deliver_later unless target_account.blocking?(account) |     NotifyService.new.call(target_account, follow) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def unfollow!(account, target_account) |   def unfollow!(account, target_account) | ||||||
|  | @ -83,8 +83,8 @@ class ProcessInteractionService < BaseService | ||||||
| 
 | 
 | ||||||
|   def favourite!(xml, from_account) |   def favourite!(xml, from_account) | ||||||
|     current_status = status(xml) |     current_status = status(xml) | ||||||
|     current_status.favourites.where(account: from_account).first_or_create!(account: from_account) |     favourite = current_status.favourites.where(account: from_account).first_or_create!(account: from_account) | ||||||
|     NotificationMailer.favourite(current_status, from_account).deliver_later unless current_status.account.blocking?(from_account) |     NotifyService.new.call(current_status.account, favourite) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def add_post!(body, account) |   def add_post!(body, account) | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ class ProcessMentionsService < BaseService | ||||||
|       mentioned_account = mention.account |       mentioned_account = mention.account | ||||||
| 
 | 
 | ||||||
|       if mentioned_account.local? |       if mentioned_account.local? | ||||||
|         NotificationMailer.mention(mentioned_account, status).deliver_later unless mentioned_account.blocking?(status.account) |         NotifyService.new.call(mentioned_account, mention) | ||||||
|       else |       else | ||||||
|         NotificationWorker.perform_async(status.stream_entry.id, mentioned_account.id) |         NotificationWorker.perform_async(status.stream_entry.id, mentioned_account.id) | ||||||
|       end |       end | ||||||
|  |  | ||||||
|  | @ -11,7 +11,7 @@ class ReblogService < BaseService | ||||||
|     HubPingWorker.perform_async(account.id) |     HubPingWorker.perform_async(account.id) | ||||||
| 
 | 
 | ||||||
|     if reblogged_status.local? |     if reblogged_status.local? | ||||||
|       NotificationMailer.reblog(reblogged_status, account).deliver_later unless reblogged_status.account.blocking?(account) |       NotifyService.new.call(reblogged_status.account, reblog) | ||||||
|     else |     else | ||||||
|       NotificationWorker.perform_async(reblog.stream_entry.id, reblogged_status.account_id) |       NotificationWorker.perform_async(reblog.stream_entry.id, reblogged_status.account_id) | ||||||
|     end |     end | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								app/views/api/v1/notifications/index.rabl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								app/views/api/v1/notifications/index.rabl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | collection @notifications | ||||||
|  | extends 'api/v1/notifications/show' | ||||||
							
								
								
									
										11
									
								
								app/views/api/v1/notifications/show.rabl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								app/views/api/v1/notifications/show.rabl
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | object @notification | ||||||
|  | 
 | ||||||
|  | attributes :id, :type | ||||||
|  | 
 | ||||||
|  | child from_account: :account do | ||||||
|  |   extends 'api/v1/accounts/show' | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | node(:status, if: lambda { |n| [:favourite, :reblog, :mention].include?(n.type) }) do |n| | ||||||
|  |   partial 'api/v1/statuses/show', object: n.target_status | ||||||
|  | end | ||||||
|  | @ -74,6 +74,8 @@ Rails.application.routes.draw do | ||||||
|       resources :media,    only: [:create] |       resources :media,    only: [:create] | ||||||
|       resources :apps,     only: [:create] |       resources :apps,     only: [:create] | ||||||
| 
 | 
 | ||||||
|  |       resources :notifications, only: [:index] | ||||||
|  | 
 | ||||||
|       resources :accounts, only: [:show] do |       resources :accounts, only: [:show] do | ||||||
|         collection do |         collection do | ||||||
|           get :relationships |           get :relationships | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								db/migrate/20161119211120_create_notifications.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								db/migrate/20161119211120_create_notifications.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | class CreateNotifications < ActiveRecord::Migration[5.0] | ||||||
|  |   def change | ||||||
|  |     create_table :notifications do |t| | ||||||
|  |       t.integer :account_id | ||||||
|  |       t.integer :activity_id | ||||||
|  |       t.string :activity_type | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     add_index :notifications, :account_id | ||||||
|  |   end | ||||||
|  | end | ||||||
							
								
								
									
										11
									
								
								db/schema.rb
									
										
									
									
									
								
							
							
						
						
									
										11
									
								
								db/schema.rb
									
										
									
									
									
								
							|  | @ -10,7 +10,7 @@ | ||||||
| # | # | ||||||
| # It's strongly recommended that you check this file into your version control system. | # It's strongly recommended that you check this file into your version control system. | ||||||
| 
 | 
 | ||||||
| ActiveRecord::Schema.define(version: 20161116162355) do | ActiveRecord::Schema.define(version: 20161119211120) do | ||||||
| 
 | 
 | ||||||
|   # These are extensions that must be enabled in order to support this database |   # These are extensions that must be enabled in order to support this database | ||||||
|   enable_extension "plpgsql" |   enable_extension "plpgsql" | ||||||
|  | @ -96,6 +96,15 @@ ActiveRecord::Schema.define(version: 20161116162355) do | ||||||
|     t.index ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree |     t.index ["account_id", "status_id"], name: "index_mentions_on_account_id_and_status_id", unique: true, using: :btree | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|  |   create_table "notifications", force: :cascade do |t| | ||||||
|  |     t.integer  "account_id" | ||||||
|  |     t.integer  "activity_id" | ||||||
|  |     t.string   "activity_type" | ||||||
|  |     t.datetime "created_at",    null: false | ||||||
|  |     t.datetime "updated_at",    null: false | ||||||
|  |     t.index ["account_id"], name: "index_notifications_on_account_id", using: :btree | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|   create_table "oauth_access_grants", force: :cascade do |t| |   create_table "oauth_access_grants", force: :cascade do |t| | ||||||
|     t.integer  "resource_owner_id", null: false |     t.integer  "resource_owner_id", null: false | ||||||
|     t.integer  "application_id",    null: false |     t.integer  "application_id",    null: false | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								spec/fabricators/notification_fabricator.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								spec/fabricators/notification_fabricator.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,4 @@ | ||||||
|  | Fabricator(:notification) do | ||||||
|  |   activity_id   1 | ||||||
|  |   activity_type "MyString" | ||||||
|  | end | ||||||
|  | @ -7,7 +7,8 @@ RSpec.describe NotificationMailer, type: :mailer do | ||||||
|   let(:own_status)     { Fabricate(:status, account: receiver.account) } |   let(:own_status)     { Fabricate(:status, account: receiver.account) } | ||||||
| 
 | 
 | ||||||
|   describe "mention" do |   describe "mention" do | ||||||
|     let(:mail) { NotificationMailer.mention(receiver.account, foreign_status) } |     let(:mention) { Mention.create!(account: receiver.account, status: foreign_status) } | ||||||
|  |     let(:mail) { NotificationMailer.mention(receiver.account, Notification.create!(account: receiver.account, activity: mention)) } | ||||||
| 
 | 
 | ||||||
|     it "renders the headers" do |     it "renders the headers" do | ||||||
|       expect(mail.subject).to eq("You were mentioned by bob") |       expect(mail.subject).to eq("You were mentioned by bob") | ||||||
|  | @ -20,7 +21,8 @@ RSpec.describe NotificationMailer, type: :mailer do | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   describe "follow" do |   describe "follow" do | ||||||
|     let(:mail) { NotificationMailer.follow(receiver.account, sender) } |     let(:follow) { sender.follow!(receiver.account) } | ||||||
|  |     let(:mail) { NotificationMailer.follow(receiver.account, Notification.create!(account: receiver.account, activity: follow)) } | ||||||
| 
 | 
 | ||||||
|     it "renders the headers" do |     it "renders the headers" do | ||||||
|       expect(mail.subject).to eq("bob is now following you") |       expect(mail.subject).to eq("bob is now following you") | ||||||
|  | @ -33,7 +35,8 @@ RSpec.describe NotificationMailer, type: :mailer do | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   describe "favourite" do |   describe "favourite" do | ||||||
|     let(:mail) { NotificationMailer.favourite(own_status, sender) } |     let(:favourite) { Favourite.create!(account: sender, status: own_status) } | ||||||
|  |     let(:mail) { NotificationMailer.favourite(own_status.account, Notification.create!(account: receiver.account, activity: favourite)) } | ||||||
| 
 | 
 | ||||||
|     it "renders the headers" do |     it "renders the headers" do | ||||||
|       expect(mail.subject).to eq("bob favourited your status") |       expect(mail.subject).to eq("bob favourited your status") | ||||||
|  | @ -46,7 +49,8 @@ RSpec.describe NotificationMailer, type: :mailer do | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   describe "reblog" do |   describe "reblog" do | ||||||
|     let(:mail) { NotificationMailer.reblog(own_status, sender) } |     let(:reblog) { Status.create!(account: sender, reblog: own_status) } | ||||||
|  |     let(:mail) { NotificationMailer.reblog(own_status.account, Notification.create!(account: receiver.account, activity: reblog)) } | ||||||
| 
 | 
 | ||||||
|     it "renders the headers" do |     it "renders the headers" do | ||||||
|       expect(mail.subject).to eq("bob reblogged your status") |       expect(mail.subject).to eq("bob reblogged your status") | ||||||
|  |  | ||||||
							
								
								
									
										29
									
								
								spec/models/notification_spec.rb
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								spec/models/notification_spec.rb
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | require 'rails_helper' | ||||||
|  | 
 | ||||||
|  | RSpec.describe Notification, type: :model do | ||||||
|  |   describe '#from_account' do | ||||||
|  |     pending | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   describe '#type' do | ||||||
|  |     it 'returns :reblog for a Status' do | ||||||
|  |       notification = Notification.new(activity: Status.new) | ||||||
|  |       expect(notification.type).to eq :reblog | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it 'returns :mention for a Mention' do | ||||||
|  |       notification = Notification.new(activity: Mention.new) | ||||||
|  |       expect(notification.type).to eq :mention | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it 'returns :favourite for a Favourite' do | ||||||
|  |       notification = Notification.new(activity: Favourite.new) | ||||||
|  |       expect(notification.type).to eq :favourite | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     it 'returns :follow for a Follow' do | ||||||
|  |       notification = Notification.new(activity: Follow.new) | ||||||
|  |       expect(notification.type).to eq :follow | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue