Introduce Glitch::AccountRelationships (#193)

Where possible, it is a good idea to add new backend code in ways that
will minimize conflict with upstream changes.  We can't do that
everywhere, but we can move our custom methods to a module that won't
be modified upstream, and that's a start.

This commit also gets the block/mute note maps into
REST::RelationshipSerializer under the "block_notes" and "mute_notes"
keys.
This commit is contained in:
David Yip 2018-01-27 01:23:14 -06:00
parent 8f476ee39e
commit c17c07158a
No known key found for this signature in database
GPG Key ID: 7DA0036508FCC0CC
5 changed files with 118 additions and 2 deletions

View File

@ -52,6 +52,7 @@ class Account < ApplicationRecord
include AccountFinderConcern include AccountFinderConcern
include AccountHeader include AccountHeader
include AccountInteractions include AccountInteractions
include Glitch::AccountInteractions
include Attachmentable include Attachmentable
include Remotable include Remotable
include Paginable include Paginable

View File

@ -0,0 +1,25 @@
# frozen_string_literals: true
module Glitch::AccountInteractions
extend ActiveSupport::Concern
class_methods do
def mute_note_map(target_account_ids, account_id)
notes_from_relationship(Mute, target_account_ids, account_id).each_with_object({}) do |mute, mapping|
mapping[mute.target_account_id] = mute.note&.text
end
end
def block_note_map(target_account_ids, account_id)
notes_from_relationship(Block, target_account_ids, account_id).each_with_object({}) do |block, mapping|
mapping[block.target_account_id] = block.note&.text
end
end
private
def notes_from_relationship(klass, target_account_ids, account_id)
klass.where(target_account_id: target_account_ids, account_id: account_id).includes(:note)
end
end
end

View File

@ -2,7 +2,8 @@
class AccountRelationshipsPresenter class AccountRelationshipsPresenter
attr_reader :following, :followed_by, :blocking, attr_reader :following, :followed_by, :blocking,
:muting, :requested, :domain_blocking :muting, :requested, :domain_blocking,
:mute_notes, :block_notes
def initialize(account_ids, current_account_id, **options) def initialize(account_ids, current_account_id, **options)
@following = Account.following_map(account_ids, current_account_id).merge(options[:following_map] || {}) @following = Account.following_map(account_ids, current_account_id).merge(options[:following_map] || {})
@ -11,5 +12,7 @@ class AccountRelationshipsPresenter
@muting = Account.muting_map(account_ids, current_account_id).merge(options[:muting_map] || {}) @muting = Account.muting_map(account_ids, current_account_id).merge(options[:muting_map] || {})
@requested = Account.requested_map(account_ids, current_account_id).merge(options[:requested_map] || {}) @requested = Account.requested_map(account_ids, current_account_id).merge(options[:requested_map] || {})
@domain_blocking = Account.domain_blocking_map(account_ids, current_account_id).merge(options[:domain_blocking_map] || {}) @domain_blocking = Account.domain_blocking_map(account_ids, current_account_id).merge(options[:domain_blocking_map] || {})
@mute_notes = Account.mute_note_map(account_ids, current_account_id).merge(options[:mute_note_map] || {})
@block_notes = Account.block_note_map(account_ids, current_account_id).merge(options[:block_note_map] || {})
end end
end end

View File

@ -2,7 +2,8 @@
class REST::RelationshipSerializer < ActiveModel::Serializer class REST::RelationshipSerializer < ActiveModel::Serializer
attributes :id, :following, :showing_reblogs, :followed_by, :blocking, attributes :id, :following, :showing_reblogs, :followed_by, :blocking,
:muting, :muting_notifications, :requested, :domain_blocking :muting, :muting_notifications, :requested, :domain_blocking,
:mute_notes, :block_notes
def id def id
object.id.to_s object.id.to_s
@ -34,6 +35,14 @@ class REST::RelationshipSerializer < ActiveModel::Serializer
(instance_options[:relationships].muting[object.id] || {})[:notifications] || false (instance_options[:relationships].muting[object.id] || {})[:notifications] || false
end end
def mute_notes
instance_options[:relationships].mute_notes[object.id] || ''
end
def block_notes
instance_options[:relationships].block_notes[object.id] || ''
end
def requested def requested
instance_options[:relationships].requested[object.id] ? true : false instance_options[:relationships].requested[object.id] ? true : false
end end

View File

@ -0,0 +1,78 @@
require 'rails_helper'
describe Glitch::AccountInteractions do
let(:account) { Fabricate(:account, username: 'account') }
let(:account_id) { account.id }
let(:account_ids) { [account_id] }
let(:target_account) { Fabricate(:account, username: 'target') }
let(:target_account_id) { target_account.id }
let(:target_account_ids) { [target_account_id] }
describe '.mute_note_map' do
subject { Account.mute_note_map(target_account_ids, account_id) }
context 'account with Mute' do
before do
Fabricate(:mute, target_account: target_account, account: account).tap do |m|
m.create_note!(note: note) if note
end
end
context 'with a note' do
let(:note) { 'Too many jorts' }
it 'returns { target_account_id => "(a note)" }' do
is_expected.to eq(target_account_id => 'Too many jorts')
end
end
context 'with no associated note' do
let(:note) { nil }
it 'returns { target_account_id => nil }' do
is_expected.to eq(target_account_id => nil)
end
end
end
context 'account without Mute' do
it 'returns {}' do
is_expected.to eq({})
end
end
end
describe '.block_note_map' do
subject { Account.block_note_map(target_account_ids, account_id) }
context 'account with Block' do
before do
Fabricate(:block, target_account: target_account, account: account).tap do |m|
m.create_note!(note: note) if note
end
end
context 'with a note' do
let(:note) { 'Too many oats' }
it 'returns { target_account_id => "(a note)" }' do
is_expected.to eq(target_account_id => 'Too many oats')
end
end
context 'with no associated note' do
let(:note) { nil }
it 'returns { target_account_id => nil }' do
is_expected.to eq(target_account_id => nil)
end
end
end
context 'account without Block' do
it 'returns {}' do
is_expected.to eq({})
end
end
end
end