Add limited_scope support
This commit is contained in:
parent
ec16074def
commit
c1f6d22ad2
17 changed files with 107 additions and 10 deletions
|
@ -24,6 +24,7 @@ module ContextHelper
|
||||||
emoji_reactions: { 'fedibird' => 'http://fedibird.com/ns#', 'emojiReactions' => { '@id' => 'fedibird:emojiReactions', '@type' => '@id' } },
|
emoji_reactions: { 'fedibird' => 'http://fedibird.com/ns#', 'emojiReactions' => { '@id' => 'fedibird:emojiReactions', '@type' => '@id' } },
|
||||||
searchable_by: { 'fedibird' => 'http://fedibird.com/ns#', 'searchableBy' => { '@id' => 'fedibird:searchableBy', '@type' => '@id' } },
|
searchable_by: { 'fedibird' => 'http://fedibird.com/ns#', 'searchableBy' => { '@id' => 'fedibird:searchableBy', '@type' => '@id' } },
|
||||||
subscribable_by: { 'kmyblue' => 'http://kmy.blue/ns#', 'subscribableBy' => { '@id' => 'kmyblue:subscribableBy', '@type' => '@id' } },
|
subscribable_by: { 'kmyblue' => 'http://kmy.blue/ns#', 'subscribableBy' => { '@id' => 'kmyblue:subscribableBy', '@type' => '@id' } },
|
||||||
|
limited_scope: { 'kmyblue' => 'http://kmy.blue/ns#', 'limitedScope' => { '@id' => 'kmyblue:limitedScope', '@type' => '@id' } },
|
||||||
other_setting: { 'fedibird' => 'http://fedibird.com/ns#', 'otherSetting' => 'fedibird:otherSetting' },
|
other_setting: { 'fedibird' => 'http://fedibird.com/ns#', 'otherSetting' => 'fedibird:otherSetting' },
|
||||||
references: { 'fedibird' => 'http://fedibird.com/ns#', 'references' => { '@id' => 'fedibird:references', '@type' => '@id' } },
|
references: { 'fedibird' => 'http://fedibird.com/ns#', 'references' => { '@id' => 'fedibird:references', '@type' => '@id' } },
|
||||||
olm: {
|
olm: {
|
||||||
|
|
|
@ -70,6 +70,7 @@ const messages = defineMessages({
|
||||||
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
||||||
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
||||||
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
||||||
|
mutual_short: { id: 'privacy.mutual.short', defaultMessage: 'Mutual followers only' },
|
||||||
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
||||||
edited: { id: 'status.edited', defaultMessage: 'Edited {date}' },
|
edited: { id: 'status.edited', defaultMessage: 'Edited {date}' },
|
||||||
});
|
});
|
||||||
|
@ -400,10 +401,11 @@ class Status extends ImmutablePureComponent {
|
||||||
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
||||||
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
||||||
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
||||||
|
'mutual': { icon: 'exchange', text: intl.formatMessage(messages.mutual_short) },
|
||||||
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
||||||
};
|
};
|
||||||
|
|
||||||
let visibilityIcon = visibilityIconInfo[status.get('visibility_ex')] || visibilityIconInfo[status.get('visibility')];
|
let visibilityIcon = visibilityIconInfo[status.get('limited_scope') || status.get('visibility_ex')] || visibilityIconInfo[status.get('visibility')];
|
||||||
|
|
||||||
if (this.state.forceFilter === undefined ? matchedFilters : this.state.forceFilter) {
|
if (this.state.forceFilter === undefined ? matchedFilters : this.state.forceFilter) {
|
||||||
const minHandlers = this.props.muted ? {} : {
|
const minHandlers = this.props.muted ? {} : {
|
||||||
|
@ -564,7 +566,7 @@ class Status extends ImmutablePureComponent {
|
||||||
statusAvatar = <AvatarOverlay account={status.get('account')} friend={account} />;
|
statusAvatar = <AvatarOverlay account={status.get('account')} friend={account} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
visibilityIcon = visibilityIconInfo[status.get('visibility_ex')] || visibilityIconInfo[status.get('visibility')];
|
visibilityIcon = visibilityIconInfo[status.get('limited_scope') || status.get('visibility_ex')] || visibilityIconInfo[status.get('visibility')];
|
||||||
|
|
||||||
let emojiReactionsBar = null;
|
let emojiReactionsBar = null;
|
||||||
if (!this.props.withoutEmojiReactions && status.get('emoji_reactions')) {
|
if (!this.props.withoutEmojiReactions && status.get('emoji_reactions')) {
|
||||||
|
|
|
@ -21,6 +21,7 @@ const messages = defineMessages({
|
||||||
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
||||||
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
||||||
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
||||||
|
mutual_short: { id: 'privacy.mutual.short', defaultMessage: 'Mutual followers only' },
|
||||||
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,10 +54,11 @@ class StatusCheckBox extends PureComponent {
|
||||||
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
||||||
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
||||||
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
||||||
|
'mutual': { icon: 'exchange', text: intl.formatMessage(messages.mutual_short) },
|
||||||
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
||||||
};
|
};
|
||||||
|
|
||||||
const visibilityIcon = visibilityIconInfo[status.get('visibility_ex')];
|
const visibilityIcon = visibilityIconInfo[status.get('limited_scope') || status.get('visibility_ex')];
|
||||||
|
|
||||||
const labelComponent = (
|
const labelComponent = (
|
||||||
<div className='status-check-box__status poll__option__text'>
|
<div className='status-check-box__status poll__option__text'>
|
||||||
|
|
|
@ -31,6 +31,7 @@ const messages = defineMessages({
|
||||||
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
||||||
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
||||||
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
||||||
|
mutual_short: { id: 'privacy.mutual.short', defaultMessage: 'Mutual followers only' },
|
||||||
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
||||||
searchability_public_short: { id: 'searchability.public.short', defaultMessage: 'Public' },
|
searchability_public_short: { id: 'searchability.public.short', defaultMessage: 'Public' },
|
||||||
searchability_private_short: { id: 'searchability.unlisted.short', defaultMessage: 'Followers' },
|
searchability_private_short: { id: 'searchability.unlisted.short', defaultMessage: 'Followers' },
|
||||||
|
@ -251,10 +252,11 @@ class DetailedStatus extends ImmutablePureComponent {
|
||||||
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
||||||
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
||||||
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
||||||
|
'mutual': { icon: 'exchange', text: intl.formatMessage(messages.mutual_short) },
|
||||||
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
||||||
};
|
};
|
||||||
|
|
||||||
const visibilityIcon = visibilityIconInfo[status.get('visibility_ex')];
|
const visibilityIcon = visibilityIconInfo[status.get('limited_scope') || status.get('visibility_ex')];
|
||||||
const visibilityLink = <> · <Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></>;
|
const visibilityLink = <> · <Icon id={visibilityIcon.icon} title={visibilityIcon.text} /></>;
|
||||||
|
|
||||||
const searchabilityIconInfo = {
|
const searchabilityIconInfo = {
|
||||||
|
|
|
@ -28,6 +28,7 @@ const messages = defineMessages({
|
||||||
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
login_short: { id: 'privacy.login.short', defaultMessage: 'Login only' },
|
||||||
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
private_short: { id: 'privacy.private.short', defaultMessage: 'Followers only' },
|
||||||
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
limited_short: { id: 'privacy.limited.short', defaultMessage: 'Limited menbers only' },
|
||||||
|
mutual_short: { id: 'privacy.mutual.short', defaultMessage: 'Mutual followers only' },
|
||||||
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Mentioned people only' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -96,10 +97,11 @@ class BoostModal extends ImmutablePureComponent {
|
||||||
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
'login': { icon: 'key', text: intl.formatMessage(messages.login_short) },
|
||||||
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
'private': { icon: 'lock', text: intl.formatMessage(messages.private_short) },
|
||||||
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
'limited': { icon: 'get-pocket', text: intl.formatMessage(messages.limited_short) },
|
||||||
|
'mutual': { icon: 'exchange', text: intl.formatMessage(messages.mutual_short) },
|
||||||
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
'direct': { icon: 'at', text: intl.formatMessage(messages.direct_short) },
|
||||||
};
|
};
|
||||||
|
|
||||||
const visibilityIcon = visibilityIconInfo[status.get('visibility_ex')];
|
const visibilityIcon = visibilityIconInfo[status.get('limited_scope') || status.get('visibility_ex')];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='modal-root__modal boost-modal'>
|
<div className='modal-root__modal boost-modal'>
|
||||||
|
|
|
@ -133,6 +133,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
||||||
reply: @status_parser.reply,
|
reply: @status_parser.reply,
|
||||||
sensitive: @account.sensitized? || @status_parser.sensitive || false,
|
sensitive: @account.sensitized? || @status_parser.sensitive || false,
|
||||||
visibility: @status_parser.visibility,
|
visibility: @status_parser.visibility,
|
||||||
|
limited_scope: @status_parser.limited_scope,
|
||||||
searchability: searchability,
|
searchability: searchability,
|
||||||
thread: replied_to_status,
|
thread: replied_to_status,
|
||||||
conversation: conversation_from_uri(@object['conversation']),
|
conversation: conversation_from_uri(@object['conversation']),
|
||||||
|
|
|
@ -86,6 +86,14 @@ class ActivityPub::Parser::StatusParser
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def limited_scope
|
||||||
|
if @object['limitedScope'] == 'Mutual'
|
||||||
|
:mutual
|
||||||
|
else
|
||||||
|
:none
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def language
|
def language
|
||||||
if content_language_map?
|
if content_language_map?
|
||||||
@object['contentMap'].keys.first
|
@object['contentMap'].keys.first
|
||||||
|
|
|
@ -221,6 +221,10 @@ class ActivityPub::TagManager
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def limited_scope(status)
|
||||||
|
status.mutual_limited? ? 'Mutual' : ''
|
||||||
|
end
|
||||||
|
|
||||||
def subscribable_by(account)
|
def subscribable_by(account)
|
||||||
account.dissubscribable ? [] : [COLLECTIONS[:public]]
|
account.dissubscribable ? [] : [COLLECTIONS[:public]]
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
# ordered_media_attachment_ids :bigint(8) is an Array
|
# ordered_media_attachment_ids :bigint(8) is an Array
|
||||||
# searchability :integer
|
# searchability :integer
|
||||||
# markdown :boolean default(FALSE)
|
# markdown :boolean default(FALSE)
|
||||||
|
# limited_scope :integer
|
||||||
#
|
#
|
||||||
|
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
@ -54,6 +55,7 @@ class Status < ApplicationRecord
|
||||||
|
|
||||||
enum visibility: { public: 0, unlisted: 1, private: 2, direct: 3, limited: 4, public_unlisted: 10, login: 11 }, _suffix: :visibility
|
enum visibility: { public: 0, unlisted: 1, private: 2, direct: 3, limited: 4, public_unlisted: 10, login: 11 }, _suffix: :visibility
|
||||||
enum searchability: { public: 0, private: 1, direct: 2, limited: 3, unsupported: 4, public_unlisted: 10 }, _suffix: :searchability
|
enum searchability: { public: 0, private: 1, direct: 2, limited: 3, unsupported: 4, public_unlisted: 10 }, _suffix: :searchability
|
||||||
|
enum limited_scope: { none: 0, mutual: 1 }, _suffix: :limited
|
||||||
|
|
||||||
belongs_to :application, class_name: 'Doorkeeper::Application', optional: true
|
belongs_to :application, class_name: 'Doorkeeper::Application', optional: true
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
||||||
include FormattingHelper
|
include FormattingHelper
|
||||||
|
|
||||||
context_extensions :atom_uri, :conversation, :sensitive, :voters_count, :searchable_by, :references
|
context_extensions :atom_uri, :conversation, :sensitive, :voters_count, :searchable_by, :references, :limited_scope
|
||||||
|
|
||||||
attributes :id, :type, :summary,
|
attributes :id, :type, :summary,
|
||||||
:in_reply_to, :published, :url,
|
:in_reply_to, :published, :url,
|
||||||
:attributed_to, :to, :cc, :sensitive,
|
:attributed_to, :to, :cc, :sensitive,
|
||||||
:atom_uri, :in_reply_to_atom_uri,
|
:atom_uri, :in_reply_to_atom_uri,
|
||||||
:conversation, :searchable_by
|
:conversation, :searchable_by, :limited_scope
|
||||||
|
|
||||||
attribute :references, if: :not_private_post?
|
attribute :references, if: :not_private_post?
|
||||||
|
|
||||||
|
@ -148,6 +148,10 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
||||||
ActivityPub::TagManager.instance.searchable_by(object)
|
ActivityPub::TagManager.instance.searchable_by(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def limited_scope
|
||||||
|
ActivityPub::TagManager.instance.limited_scope(object)
|
||||||
|
end
|
||||||
|
|
||||||
def local?
|
def local?
|
||||||
object.account.local?
|
object.account.local?
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
include FormattingHelper
|
include FormattingHelper
|
||||||
|
|
||||||
attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id,
|
attributes :id, :created_at, :in_reply_to_id, :in_reply_to_account_id,
|
||||||
:sensitive, :spoiler_text, :visibility, :visibility_ex, :language,
|
:sensitive, :spoiler_text, :visibility, :visibility_ex, :limited_scope, :language,
|
||||||
:uri, :url, :replies_count, :reblogs_count, :searchability, :markdown,
|
:uri, :url, :replies_count, :reblogs_count, :searchability, :markdown,
|
||||||
:status_reference_ids, :status_references_count, :status_referred_by_count,
|
:status_reference_ids, :status_references_count, :status_referred_by_count,
|
||||||
:favourites_count, :emoji_reactions, :emoji_reactions_count, :reactions, :edited_at
|
:favourites_count, :emoji_reactions, :emoji_reactions_count, :reactions, :edited_at
|
||||||
|
@ -69,6 +69,10 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
object.visibility
|
object.visibility
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def limited_scope
|
||||||
|
!object.none_limited? && object.limited_visibility? ? object.limited_scope : nil
|
||||||
|
end
|
||||||
|
|
||||||
def searchability
|
def searchability
|
||||||
object.compute_searchability
|
object.compute_searchability
|
||||||
end
|
end
|
||||||
|
|
|
@ -128,6 +128,7 @@ class REST::V1::InstanceSerializer < ActiveModel::Serializer
|
||||||
:kmyblue_visibility_login,
|
:kmyblue_visibility_login,
|
||||||
:status_reference,
|
:status_reference,
|
||||||
:visibility_mutual,
|
:visibility_mutual,
|
||||||
|
:kmyblue_limited_scope,
|
||||||
]
|
]
|
||||||
|
|
||||||
capabilities << :profile_search unless Chewy.enabled?
|
capabilities << :profile_search unless Chewy.enabled?
|
||||||
|
|
|
@ -247,6 +247,7 @@ class PostStatusService < BaseService
|
||||||
spoiler_text: @options[:spoiler_text] || '',
|
spoiler_text: @options[:spoiler_text] || '',
|
||||||
markdown: @markdown,
|
markdown: @markdown,
|
||||||
visibility: @visibility,
|
visibility: @visibility,
|
||||||
|
limited_scope: @visibility == :limited ? :mutual : :none,
|
||||||
searchability: @searchability,
|
searchability: @searchability,
|
||||||
language: valid_locale_cascade(@options[:language], @account.user&.preferred_posting_language, I18n.default_locale),
|
language: valid_locale_cascade(@options[:language], @account.user&.preferred_posting_language, I18n.default_locale),
|
||||||
application: @options[:application],
|
application: @options[:application],
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddLimitedScopeToStatuses < ActiveRecord::Migration[7.0]
|
||||||
|
def change
|
||||||
|
add_column :statuses, :limited_scope, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -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[7.0].define(version: 2023_08_12_083752) do
|
ActiveRecord::Schema[7.0].define(version: 2023_08_12_130612) 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"
|
||||||
|
|
||||||
|
@ -1122,6 +1122,7 @@ ActiveRecord::Schema[7.0].define(version: 2023_08_12_083752) do
|
||||||
t.bigint "ordered_media_attachment_ids", array: true
|
t.bigint "ordered_media_attachment_ids", array: true
|
||||||
t.integer "searchability"
|
t.integer "searchability"
|
||||||
t.boolean "markdown", default: false
|
t.boolean "markdown", default: false
|
||||||
|
t.integer "limited_scope"
|
||||||
t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20190820", order: { id: :desc }, where: "(deleted_at IS NULL)"
|
t.index ["account_id", "id", "visibility", "updated_at"], name: "index_statuses_20190820", order: { id: :desc }, where: "(deleted_at IS NULL)"
|
||||||
t.index ["account_id"], name: "index_statuses_on_account_id"
|
t.index ["account_id"], name: "index_statuses_on_account_id"
|
||||||
t.index ["deleted_at"], name: "index_statuses_on_deleted_at", where: "(deleted_at IS NOT NULL)"
|
t.index ["deleted_at"], name: "index_statuses_on_deleted_at", where: "(deleted_at IS NOT NULL)"
|
||||||
|
|
|
@ -290,6 +290,7 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
|
|
||||||
expect(status).to_not be_nil
|
expect(status).to_not be_nil
|
||||||
expect(status.visibility).to eq 'limited'
|
expect(status.visibility).to eq 'limited'
|
||||||
|
expect(status.limited_scope).to eq 'none'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates silent mention' do
|
it 'creates silent mention' do
|
||||||
|
@ -298,6 +299,50 @@ RSpec.describe ActivityPub::Activity::Create do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when limited_scope' do
|
||||||
|
let(:recipient) { Fabricate(:account) }
|
||||||
|
|
||||||
|
let(:object_json) do
|
||||||
|
{
|
||||||
|
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||||
|
type: 'Note',
|
||||||
|
content: 'Lorem ipsum',
|
||||||
|
to: ActivityPub::TagManager.instance.uri_for(recipient),
|
||||||
|
limitedScope: 'Mutual',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates status' do
|
||||||
|
status = sender.statuses.first
|
||||||
|
|
||||||
|
expect(status).to_not be_nil
|
||||||
|
expect(status.visibility).to eq 'limited'
|
||||||
|
expect(status.limited_scope).to eq 'mutual'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when invalid limited_scope' do
|
||||||
|
let(:recipient) { Fabricate(:account) }
|
||||||
|
|
||||||
|
let(:object_json) do
|
||||||
|
{
|
||||||
|
id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
|
||||||
|
type: 'Note',
|
||||||
|
content: 'Lorem ipsum',
|
||||||
|
to: ActivityPub::TagManager.instance.uri_for(recipient),
|
||||||
|
limitedScope: 'IdosdsazsF',
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'creates status' do
|
||||||
|
status = sender.statuses.first
|
||||||
|
|
||||||
|
expect(status).to_not be_nil
|
||||||
|
expect(status.visibility).to eq 'limited'
|
||||||
|
expect(status.limited_scope).to eq 'none'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when direct' do
|
context 'when direct' do
|
||||||
let(:recipient) { Fabricate(:account) }
|
let(:recipient) { Fabricate(:account) }
|
||||||
|
|
||||||
|
|
|
@ -168,7 +168,17 @@ RSpec.describe PostStatusService, type: :service do
|
||||||
status = subject.call(account, text: 'test status update')
|
status = subject.call(account, text: 'test status update')
|
||||||
|
|
||||||
expect(ProcessMentionsService).to have_received(:new)
|
expect(ProcessMentionsService).to have_received(:new)
|
||||||
expect(mention_service).to have_received(:call).with(status, save_records: false)
|
expect(mention_service).to have_received(:call).with(status, limited_type: '', save_records: false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'mutual visibility' do
|
||||||
|
account = Fabricate(:account)
|
||||||
|
text = 'This is an English text.'
|
||||||
|
|
||||||
|
status = subject.call(account, text: text, visibility: 'mutual')
|
||||||
|
|
||||||
|
expect(status.visibility).to eq 'limited'
|
||||||
|
expect(status.limited_scope).to eq 'mutual'
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'safeguards mentions' do
|
it 'safeguards mentions' do
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue