mirror of
https://github.com/mastodon/mastodon.git
synced 2025-10-05 00:22:42 +00:00
Remove the outgoing_quotes
feature flag, making the feature unconditional (#36130)
This commit is contained in:
parent
6cbc857ee0
commit
e1f7847b64
|
@ -4,7 +4,6 @@ class Api::V1::Statuses::InteractionPoliciesController < Api::V1::Statuses::Base
|
||||||
include Api::InteractionPoliciesConcern
|
include Api::InteractionPoliciesConcern
|
||||||
|
|
||||||
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
|
before_action -> { doorkeeper_authorize! :write, :'write:statuses' }
|
||||||
before_action -> { check_feature_enabled }
|
|
||||||
|
|
||||||
def update
|
def update
|
||||||
authorize @status, :update?
|
authorize @status, :update?
|
||||||
|
@ -22,10 +21,6 @@ class Api::V1::Statuses::InteractionPoliciesController < Api::V1::Statuses::Base
|
||||||
params.permit(:quote_approval_policy)
|
params.permit(:quote_approval_policy)
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_feature_enabled
|
|
||||||
raise ActionController::RoutingError unless Mastodon::Feature.outgoing_quotes_enabled?
|
|
||||||
end
|
|
||||||
|
|
||||||
def broadcast_updates!
|
def broadcast_updates!
|
||||||
DistributionWorker.perform_async(@status.id, { 'update' => true })
|
DistributionWorker.perform_async(@status.id, { 'update' => true })
|
||||||
ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id, { 'updated_at' => Time.now.utc.iso8601 })
|
ActivityPub::StatusUpdateDistributionWorker.perform_async(@status.id, { 'updated_at' => Time.now.utc.iso8601 })
|
||||||
|
|
|
@ -157,8 +157,6 @@ class Api::V1::StatusesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_quoted_status
|
def set_quoted_status
|
||||||
return unless Mastodon::Feature.outgoing_quotes_enabled?
|
|
||||||
|
|
||||||
@quoted_status = Status.find(status_params[:quoted_status_id]) if status_params[:quoted_status_id].present?
|
@quoted_status = Status.find(status_params[:quoted_status_id]) if status_params[:quoted_status_id].present?
|
||||||
authorize(@quoted_status, :quote?) if @quoted_status.present?
|
authorize(@quoted_status, :quote?) if @quoted_status.present?
|
||||||
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
|
rescue ActiveRecord::RecordNotFound, Mastodon::NotPermittedError
|
||||||
|
|
|
@ -4,8 +4,6 @@ module Api::InteractionPoliciesConcern
|
||||||
extend ActiveSupport::Concern
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
def quote_approval_policy
|
def quote_approval_policy
|
||||||
return nil unless Mastodon::Feature.outgoing_quotes_enabled?
|
|
||||||
|
|
||||||
case status_params[:quote_approval_policy].presence || current_user.setting_default_quote_policy
|
case status_params[:quote_approval_policy].presence || current_user.setting_default_quote_policy
|
||||||
when 'public'
|
when 'public'
|
||||||
Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16
|
Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16
|
||||||
|
|
|
@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
|
||||||
import type { StatusVisibility } from '@/mastodon/api_types/statuses';
|
import type { StatusVisibility } from '@/mastodon/api_types/statuses';
|
||||||
import { statusFactoryState } from '@/testing/factories';
|
import { statusFactoryState } from '@/testing/factories';
|
||||||
|
|
||||||
import { LegacyReblogButton, StatusBoostButton } from './boost_button';
|
import { BoostButton } from './boost_button';
|
||||||
|
|
||||||
interface StoryProps {
|
interface StoryProps {
|
||||||
visibility: StatusVisibility;
|
visibility: StatusVisibility;
|
||||||
|
@ -38,10 +38,7 @@ const meta = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
render: (args) => (
|
render: (args) => (
|
||||||
<StatusBoostButton
|
<BoostButton status={argsToStatus(args)} counters={args.reblogCount > 0} />
|
||||||
status={argsToStatus(args)}
|
|
||||||
counters={args.reblogCount > 0}
|
|
||||||
/>
|
|
||||||
),
|
),
|
||||||
} satisfies Meta<StoryProps>;
|
} satisfies Meta<StoryProps>;
|
||||||
|
|
||||||
|
@ -78,12 +75,3 @@ export const Mine: Story = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Legacy: Story = {
|
|
||||||
render: (args) => (
|
|
||||||
<LegacyReblogButton
|
|
||||||
status={argsToStatus(args)}
|
|
||||||
counters={args.reblogCount > 0}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import type { FC, KeyboardEvent, MouseEvent, MouseEventHandler } from 'react';
|
import type { FC, KeyboardEvent, MouseEvent } from 'react';
|
||||||
|
|
||||||
import { useIntl } from 'react-intl';
|
import { useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import { openModal } from '@/mastodon/actions/modal';
|
||||||
import type { ActionMenuItem } from '@/mastodon/models/dropdown_menu';
|
import type { ActionMenuItem } from '@/mastodon/models/dropdown_menu';
|
||||||
import type { Status } from '@/mastodon/models/status';
|
import type { Status } from '@/mastodon/models/status';
|
||||||
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
import { useAppDispatch, useAppSelector } from '@/mastodon/store';
|
||||||
import { isFeatureEnabled } from '@/mastodon/utils/environment';
|
|
||||||
import type { SomeRequired } from '@/mastodon/utils/types';
|
import type { SomeRequired } from '@/mastodon/utils/types';
|
||||||
|
|
||||||
import type { RenderItemFn, RenderItemFnHandlers } from '../dropdown_menu';
|
import type { RenderItemFn, RenderItemFnHandlers } from '../dropdown_menu';
|
||||||
|
@ -47,10 +46,7 @@ interface ReblogButtonProps {
|
||||||
|
|
||||||
type ActionMenuItemWithIcon = SomeRequired<ActionMenuItem, 'icon'>;
|
type ActionMenuItemWithIcon = SomeRequired<ActionMenuItem, 'icon'>;
|
||||||
|
|
||||||
export const StatusBoostButton: FC<ReblogButtonProps> = ({
|
export const BoostButton: FC<ReblogButtonProps> = ({ status, counters }) => {
|
||||||
status,
|
|
||||||
counters,
|
|
||||||
}) => {
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const statusState = useAppSelector((state) =>
|
const statusState = useAppSelector((state) =>
|
||||||
|
@ -192,65 +188,3 @@ const ReblogMenuItem: FC<ReblogMenuItemProps> = ({
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Legacy helpers
|
|
||||||
|
|
||||||
// Switch between the legacy and new reblog button based on feature flag.
|
|
||||||
export const BoostButton: FC<ReblogButtonProps> = (props) => {
|
|
||||||
if (isFeatureEnabled('outgoing_quotes')) {
|
|
||||||
return <StatusBoostButton {...props} />;
|
|
||||||
}
|
|
||||||
return <LegacyReblogButton {...props} />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const LegacyReblogButton: FC<ReblogButtonProps> = ({
|
|
||||||
status,
|
|
||||||
counters,
|
|
||||||
}) => {
|
|
||||||
const intl = useIntl();
|
|
||||||
const statusState = useAppSelector((state) =>
|
|
||||||
selectStatusState(state, status),
|
|
||||||
);
|
|
||||||
|
|
||||||
const { title, meta, iconComponent, disabled } = useMemo(
|
|
||||||
() => boostItemState(statusState),
|
|
||||||
[statusState],
|
|
||||||
);
|
|
||||||
|
|
||||||
const dispatch = useAppDispatch();
|
|
||||||
const handleClick: MouseEventHandler = useCallback(
|
|
||||||
(event) => {
|
|
||||||
if (statusState.isLoggedIn) {
|
|
||||||
dispatch(toggleReblog(status.get('id') as string, event.shiftKey));
|
|
||||||
} else {
|
|
||||||
dispatch(
|
|
||||||
openModal({
|
|
||||||
modalType: 'INTERACTION',
|
|
||||||
modalProps: {
|
|
||||||
accountId: status.getIn(['account', 'id']),
|
|
||||||
url: status.get('uri'),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[dispatch, status, statusState.isLoggedIn],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
disabled={disabled}
|
|
||||||
active={!!status.get('reblogged')}
|
|
||||||
title={intl.formatMessage(meta ?? title)}
|
|
||||||
icon='retweet'
|
|
||||||
iconComponent={iconComponent}
|
|
||||||
onClick={!disabled ? handleClick : undefined}
|
|
||||||
counter={
|
|
||||||
counters
|
|
||||||
? (status.get('reblogs_count') as number) +
|
|
||||||
(status.get('quotes_count') as number)
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ import { Dropdown } from 'mastodon/components/dropdown_menu';
|
||||||
import { me } from '../../initial_state';
|
import { me } from '../../initial_state';
|
||||||
|
|
||||||
import { IconButton } from '../icon_button';
|
import { IconButton } from '../icon_button';
|
||||||
import { isFeatureEnabled } from '../../utils/environment';
|
|
||||||
import { BoostButton } from '../status/boost_button';
|
import { BoostButton } from '../status/boost_button';
|
||||||
import { RemoveQuoteHint } from './remove_quote_hint';
|
import { RemoveQuoteHint } from './remove_quote_hint';
|
||||||
|
|
||||||
|
@ -281,7 +280,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
|
|
||||||
if (writtenByMe || withDismiss) {
|
if (writtenByMe || withDismiss) {
|
||||||
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||||
if (writtenByMe && isFeatureEnabled('outgoing_quotes') && !['private', 'direct'].includes(status.get('visibility'))) {
|
if (writtenByMe && !['private', 'direct'].includes(status.get('visibility'))) {
|
||||||
menu.push({ text: intl.formatMessage(messages.quotePolicyChange), action: this.handleQuotePolicyChange });
|
menu.push({ text: intl.formatMessage(messages.quotePolicyChange), action: this.handleQuotePolicyChange });
|
||||||
}
|
}
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
|
|
@ -47,8 +47,6 @@ import Status from '../components/status';
|
||||||
import { deleteModal } from '../initial_state';
|
import { deleteModal } from '../initial_state';
|
||||||
import { makeGetStatus, makeGetPictureInPicture } from '../selectors';
|
import { makeGetStatus, makeGetPictureInPicture } from '../selectors';
|
||||||
|
|
||||||
import { isFeatureEnabled } from 'mastodon/utils/environment';
|
|
||||||
|
|
||||||
const makeMapStateToProps = () => {
|
const makeMapStateToProps = () => {
|
||||||
const getStatus = makeGetStatus();
|
const getStatus = makeGetStatus();
|
||||||
const getPictureInPicture = makeGetPictureInPicture();
|
const getPictureInPicture = makeGetPictureInPicture();
|
||||||
|
@ -81,9 +79,7 @@ const mapDispatchToProps = (dispatch, { contextType }) => ({
|
||||||
},
|
},
|
||||||
|
|
||||||
onQuote (status) {
|
onQuote (status) {
|
||||||
if (isFeatureEnabled('outgoing_quotes')) {
|
dispatch(quoteComposeById(status.get('id')));
|
||||||
dispatch(quoteComposeById(status.get('id')));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onFavourite (status) {
|
onFavourite (status) {
|
||||||
|
|
|
@ -12,14 +12,12 @@ import type { ApiQuotePolicy } from '@/mastodon/api_types/quotes';
|
||||||
import type { StatusVisibility } from '@/mastodon/api_types/statuses';
|
import type { StatusVisibility } from '@/mastodon/api_types/statuses';
|
||||||
import { Icon } from '@/mastodon/components/icon';
|
import { Icon } from '@/mastodon/components/icon';
|
||||||
import { useAppSelector, useAppDispatch } from '@/mastodon/store';
|
import { useAppSelector, useAppDispatch } from '@/mastodon/store';
|
||||||
import { isFeatureEnabled } from '@/mastodon/utils/environment';
|
|
||||||
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
|
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
|
||||||
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
|
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
|
||||||
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
||||||
import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react';
|
import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react';
|
||||||
|
|
||||||
import type { VisibilityModalCallback } from '../../ui/components/visibility_modal';
|
import type { VisibilityModalCallback } from '../../ui/components/visibility_modal';
|
||||||
import PrivacyDropdownContainer from '../containers/privacy_dropdown_container';
|
|
||||||
|
|
||||||
import { messages as privacyMessages } from './privacy_dropdown';
|
import { messages as privacyMessages } from './privacy_dropdown';
|
||||||
|
|
||||||
|
@ -43,9 +41,6 @@ interface PrivacyDropdownProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const VisibilityButton: FC<PrivacyDropdownProps> = (props) => {
|
export const VisibilityButton: FC<PrivacyDropdownProps> = (props) => {
|
||||||
if (!isFeatureEnabled('outgoing_quotes')) {
|
|
||||||
return <PrivacyDropdownContainer {...props} />;
|
|
||||||
}
|
|
||||||
return <PrivacyModalButton {...props} />;
|
return <PrivacyModalButton {...props} />;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
|
import InfoIcon from '@/material-icons/400-24px/info.svg?react';
|
||||||
import Column from 'mastodon/components/column';
|
import Column from 'mastodon/components/column';
|
||||||
import ColumnHeader from 'mastodon/components/column_header';
|
import ColumnHeader from 'mastodon/components/column_header';
|
||||||
import { isFeatureEnabled } from 'mastodon/utils/environment';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'keyboard_shortcuts.heading', defaultMessage: 'Keyboard Shortcuts' },
|
heading: { id: 'keyboard_shortcuts.heading', defaultMessage: 'Keyboard Shortcuts' },
|
||||||
|
@ -63,12 +62,10 @@ class KeyboardShortcuts extends ImmutablePureComponent {
|
||||||
<td><kbd>b</kbd></td>
|
<td><kbd>b</kbd></td>
|
||||||
<td><FormattedMessage id='keyboard_shortcuts.boost' defaultMessage='to boost' /></td>
|
<td><FormattedMessage id='keyboard_shortcuts.boost' defaultMessage='to boost' /></td>
|
||||||
</tr>
|
</tr>
|
||||||
{isFeatureEnabled('outgoing_quotes') && (
|
<tr>
|
||||||
<tr>
|
<td><kbd>q</kbd></td>
|
||||||
<td><kbd>q</kbd></td>
|
<td><FormattedMessage id='keyboard_shortcuts.quote' defaultMessage='Quote post' /></td>
|
||||||
<td><FormattedMessage id='keyboard_shortcuts.quote' defaultMessage='Quote post' /></td>
|
</tr>
|
||||||
</tr>
|
|
||||||
)}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><kbd>enter</kbd>, <kbd>o</kbd></td>
|
<td><kbd>enter</kbd>, <kbd>o</kbd></td>
|
||||||
<td><FormattedMessage id='keyboard_shortcuts.enter' defaultMessage='to open status' /></td>
|
<td><FormattedMessage id='keyboard_shortcuts.enter' defaultMessage='to open status' /></td>
|
||||||
|
|
|
@ -19,7 +19,6 @@ import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/
|
||||||
import { IconButton } from '../../../components/icon_button';
|
import { IconButton } from '../../../components/icon_button';
|
||||||
import { Dropdown } from 'mastodon/components/dropdown_menu';
|
import { Dropdown } from 'mastodon/components/dropdown_menu';
|
||||||
import { me } from '../../../initial_state';
|
import { me } from '../../../initial_state';
|
||||||
import { isFeatureEnabled } from '@/mastodon/utils/environment';
|
|
||||||
import { BoostButton } from '@/mastodon/components/status/boost_button';
|
import { BoostButton } from '@/mastodon/components/status/boost_button';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
|
@ -237,7 +236,7 @@ class ActionBar extends PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||||
if (isFeatureEnabled('outgoing_quotes') && !['private', 'direct'].includes(status.get('visibility'))) {
|
if (!['private', 'direct'].includes(status.get('visibility'))) {
|
||||||
menu.push({ text: intl.formatMessage(messages.quotePolicyChange), action: this.handleQuotePolicyChange });
|
menu.push({ text: intl.formatMessage(messages.quotePolicyChange), action: this.handleQuotePolicyChange });
|
||||||
}
|
}
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
|
|
@ -12,11 +12,7 @@ export function isProduction() {
|
||||||
else return import.meta.env.PROD;
|
else return import.meta.env.PROD;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Features =
|
export type Features = 'modern_emojis' | 'fasp' | 'http_message_signatures';
|
||||||
| 'modern_emojis'
|
|
||||||
| 'outgoing_quotes'
|
|
||||||
| 'fasp'
|
|
||||||
| 'http_message_signatures';
|
|
||||||
|
|
||||||
export function isFeatureEnabled(feature: Features) {
|
export function isFeatureEnabled(feature: Features) {
|
||||||
return initialState?.features.includes(feature) ?? false;
|
return initialState?.features.includes(feature) ?? false;
|
||||||
|
|
|
@ -9,7 +9,7 @@ class ActivityPub::Activity::QuoteRequest < ActivityPub::Activity
|
||||||
quoted_status = status_from_uri(object_uri)
|
quoted_status = status_from_uri(object_uri)
|
||||||
return if quoted_status.nil? || !quoted_status.account.local? || !quoted_status.distributable?
|
return if quoted_status.nil? || !quoted_status.account.local? || !quoted_status.distributable?
|
||||||
|
|
||||||
if Mastodon::Feature.outgoing_quotes_enabled? && StatusPolicy.new(@account, quoted_status).quote?
|
if StatusPolicy.new(@account, quoted_status).quote?
|
||||||
accept_quote_request!(quoted_status)
|
accept_quote_request!(quoted_status)
|
||||||
else
|
else
|
||||||
reject_quote_request!(quoted_status)
|
reject_quote_request!(quoted_status)
|
||||||
|
|
|
@ -36,7 +36,7 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer
|
||||||
attribute :quote, key: :quote_uri, if: :quote?
|
attribute :quote, key: :quote_uri, if: :quote?
|
||||||
attribute :quote_authorization, if: :quote_authorization?
|
attribute :quote_authorization, if: :quote_authorization?
|
||||||
|
|
||||||
attribute :interaction_policy, if: -> { Mastodon::Feature.outgoing_quotes_enabled? }
|
attribute :interaction_policy
|
||||||
|
|
||||||
def id
|
def id
|
||||||
ActivityPub::TagManager.instance.uri_for(object)
|
ActivityPub::TagManager.instance.uri_for(object)
|
||||||
|
|
|
@ -6,5 +6,5 @@ class REST::ShallowStatusSerializer < REST::StatusSerializer
|
||||||
# It looks like redefining one `has_one` requires redefining all inherited ones
|
# It looks like redefining one `has_one` requires redefining all inherited ones
|
||||||
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
||||||
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
||||||
has_one :quote_approval, if: -> { Mastodon::Feature.outgoing_quotes_enabled? }
|
has_one :quote_approval
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,7 +34,7 @@ class REST::StatusSerializer < ActiveModel::Serializer
|
||||||
has_one :quote, key: :quote, serializer: REST::QuoteSerializer
|
has_one :quote, key: :quote, serializer: REST::QuoteSerializer
|
||||||
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
has_one :preview_card, key: :card, serializer: REST::PreviewCardSerializer
|
||||||
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
has_one :preloadable_poll, key: :poll, serializer: REST::PollSerializer
|
||||||
has_one :quote_approval, if: -> { Mastodon::Feature.outgoing_quotes_enabled? }
|
has_one :quote_approval
|
||||||
|
|
||||||
def quote
|
def quote
|
||||||
object.quote if object.quote&.acceptable?
|
object.quote if object.quote&.acceptable?
|
||||||
|
|
|
@ -45,7 +45,7 @@ module Mastodon
|
||||||
|
|
||||||
def api_versions
|
def api_versions
|
||||||
{
|
{
|
||||||
mastodon: Mastodon::Feature.outgoing_quotes_enabled? ? 7 : 6,
|
mastodon: 7,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe ActivityPub::Activity::QuoteRequest, feature: :outgoing_quotes do
|
RSpec.describe ActivityPub::Activity::QuoteRequest do
|
||||||
let(:sender) { Fabricate(:account, domain: 'example.com') }
|
let(:sender) { Fabricate(:account, domain: 'example.com') }
|
||||||
let(:recipient) { Fabricate(:account) }
|
let(:recipient) { Fabricate(:account) }
|
||||||
let(:quoted_post) { Fabricate(:status, account: recipient) }
|
let(:quoted_post) { Fabricate(:status, account: recipient) }
|
||||||
|
|
|
@ -28,7 +28,7 @@ RSpec.describe StatusCacheHydrator do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when handling a status with a quote policy', feature: :outgoing_quotes do
|
context 'when handling a status with a quote policy' do
|
||||||
let(:status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) }
|
let(:status) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'rails_helper'
|
require 'rails_helper'
|
||||||
|
|
||||||
RSpec.describe 'Interaction policies', feature: :outgoing_quotes do
|
RSpec.describe 'Interaction policies' do
|
||||||
let(:user) { Fabricate(:user) }
|
let(:user) { Fabricate(:user) }
|
||||||
let(:scopes) { 'write:statuses' }
|
let(:scopes) { 'write:statuses' }
|
||||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||||
|
|
|
@ -158,7 +158,7 @@ RSpec.describe '/api/v1/statuses' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'without a quote policy', feature: :outgoing_quotes do
|
context 'without a quote policy' do
|
||||||
let(:user) do
|
let(:user) do
|
||||||
Fabricate(:user, settings: { default_quote_policy: 'followers' })
|
Fabricate(:user, settings: { default_quote_policy: 'followers' })
|
||||||
end
|
end
|
||||||
|
@ -180,7 +180,7 @@ RSpec.describe '/api/v1/statuses' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'without a quote policy and the user defaults to nobody', feature: :outgoing_quotes do
|
context 'without a quote policy and the user defaults to nobody' do
|
||||||
let(:user) do
|
let(:user) do
|
||||||
Fabricate(:user, settings: { default_quote_policy: 'nobody' })
|
Fabricate(:user, settings: { default_quote_policy: 'nobody' })
|
||||||
end
|
end
|
||||||
|
@ -202,7 +202,7 @@ RSpec.describe '/api/v1/statuses' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a quote policy', feature: :outgoing_quotes do
|
context 'with a quote policy' do
|
||||||
let(:quoted_status) { Fabricate(:status, account: user.account) }
|
let(:quoted_status) { Fabricate(:status, account: user.account) }
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
|
@ -227,7 +227,7 @@ RSpec.describe '/api/v1/statuses' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a self-quote post', feature: :outgoing_quotes do
|
context 'with a self-quote post' do
|
||||||
let(:quoted_status) { Fabricate(:status, account: user.account) }
|
let(:quoted_status) { Fabricate(:status, account: user.account) }
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
|
@ -248,7 +248,7 @@ RSpec.describe '/api/v1/statuses' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a self-quote post and a CW but no text', feature: :outgoing_quotes do
|
context 'with a self-quote post and a CW but no text' do
|
||||||
let(:quoted_status) { Fabricate(:status, account: user.account) }
|
let(:quoted_status) { Fabricate(:status, account: user.account) }
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
|
@ -420,7 +420,7 @@ RSpec.describe '/api/v1/statuses' do
|
||||||
context 'when updating only the quote policy' do
|
context 'when updating only the quote policy' do
|
||||||
let(:params) { { status: status.text, quote_approval_policy: 'public' } }
|
let(:params) { { status: status.text, quote_approval_policy: 'public' } }
|
||||||
|
|
||||||
it 'updates the status', :aggregate_failures, feature: :outgoing_quotes do
|
it 'updates the status', :aggregate_failures do
|
||||||
expect { subject }
|
expect { subject }
|
||||||
.to change { status.reload.quote_approval_policy }.to(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16)
|
.to change { status.reload.quote_approval_policy }.to(Status::QUOTE_APPROVAL_POLICY_FLAGS[:public] << 16)
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ RSpec.describe ActivityPub::NoteSerializer do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a quote policy', feature: :outgoing_quotes do
|
context 'with a quote policy' do
|
||||||
let(:parent) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) }
|
let(:parent) { Fabricate(:status, quote_approval_policy: Status::QUOTE_APPROVAL_POLICY_FLAGS[:followers] << 16) }
|
||||||
|
|
||||||
it 'has the expected shape' do
|
it 'has the expected shape' do
|
||||||
|
|
Loading…
Reference in New Issue
Block a user