Add more tests for ActivityPub controllers (#13585)
This commit is contained in:
		
							parent
							
								
									a1062df1e1
								
							
						
					
					
						commit
						988b0493fe
					
				
					 19 changed files with 1320 additions and 147 deletions
				
			
		| 
						 | 
					@ -27,7 +27,7 @@ class AccountsController < ApplicationController
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
 | 
					        @pinned_statuses = cache_collection(@account.pinned_statuses, Status) if show_pinned_statuses?
 | 
				
			||||||
        @statuses        = filtered_status_page(params)
 | 
					        @statuses        = filtered_status_page
 | 
				
			||||||
        @statuses        = cache_collection(@statuses, Status)
 | 
					        @statuses        = cache_collection(@statuses, Status)
 | 
				
			||||||
        @rss_url         = rss_url
 | 
					        @rss_url         = rss_url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -140,12 +140,12 @@ class AccountsController < ApplicationController
 | 
				
			||||||
    request.path.split('.').first.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
 | 
					    request.path.split('.').first.ends_with?(Addressable::URI.parse("/tagged/#{params[:tag]}").normalize)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def filtered_status_page(params)
 | 
					  def filtered_status_page
 | 
				
			||||||
    if params[:min_id].present?
 | 
					    filtered_statuses.paginate_by_id(PAGE_SIZE, params_slice(:max_id, :min_id, :since_id))
 | 
				
			||||||
      filtered_statuses.paginate_by_min_id(PAGE_SIZE, params[:min_id]).reverse
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      filtered_statuses.paginate_by_max_id(PAGE_SIZE, params[:max_id], params[:since_id]).to_a
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def params_slice(*keys)
 | 
				
			||||||
 | 
					    params.slice(*keys).permit(*keys)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def restrict_fields_to
 | 
					  def restrict_fields_to
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,20 +24,23 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
 | 
				
			||||||
  def set_size
 | 
					  def set_size
 | 
				
			||||||
    case params[:id]
 | 
					    case params[:id]
 | 
				
			||||||
    when 'featured'
 | 
					    when 'featured'
 | 
				
			||||||
      @account.pinned_statuses.count
 | 
					      @size = @account.pinned_statuses.count
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
      raise ActiveRecord::RecordNotFound
 | 
					      not_found
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def scope_for_collection
 | 
					  def scope_for_collection
 | 
				
			||||||
    case params[:id]
 | 
					    case params[:id]
 | 
				
			||||||
    when 'featured'
 | 
					    when 'featured'
 | 
				
			||||||
      return Status.none if @account.blocking?(signed_request_account)
 | 
					      # Because in public fetch mode we cache the response, there would be no
 | 
				
			||||||
 | 
					      # benefit from performing the check below, since a blocked account or domain
 | 
				
			||||||
      @account.pinned_statuses
 | 
					      # would likely be served the cache from the reverse proxy anyway
 | 
				
			||||||
 | 
					      if authorized_fetch_mode? && !signed_request_account.nil? && (@account.blocking?(signed_request_account) || (!signed_request_account.domain.nil? && @account.domain_blocking?(signed_request_account.domain)))
 | 
				
			||||||
 | 
					        Status.none
 | 
				
			||||||
      else
 | 
					      else
 | 
				
			||||||
      raise ActiveRecord::RecordNotFound
 | 
					        @account.pinned_statuses
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
 | 
				
			||||||
  before_action :set_cache_headers
 | 
					  before_action :set_cache_headers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode?)
 | 
					    expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode? && !(signed_request_account.present? && page_requested?))
 | 
				
			||||||
    render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
 | 
					    render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,12 +50,12 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
 | 
				
			||||||
    return unless page_requested?
 | 
					    return unless page_requested?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @statuses = @account.statuses.permitted_for(@account, signed_request_account)
 | 
					    @statuses = @account.statuses.permitted_for(@account, signed_request_account)
 | 
				
			||||||
    @statuses = params[:min_id].present? ? @statuses.paginate_by_min_id(LIMIT, params[:min_id]).reverse : @statuses.paginate_by_max_id(LIMIT, params[:max_id])
 | 
					    @statuses = @statuses.paginate_by_id(LIMIT, params_slice(:max_id, :min_id, :since_id))
 | 
				
			||||||
    @statuses = cache_collection(@statuses, Status)
 | 
					    @statuses = cache_collection(@statuses, Status)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def page_requested?
 | 
					  def page_requested?
 | 
				
			||||||
    params[:page] == 'true'
 | 
					    truthy_param?(:page)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def page_params
 | 
					  def page_params
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
# frozen_string_literal: true
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ActivityPub::RepliesController < ActivityPub::BaseController
 | 
					class ActivityPub::RepliesController < ActivityPub::BaseController
 | 
				
			||||||
  include SignatureAuthentication
 | 
					  include SignatureVerification
 | 
				
			||||||
  include Authorization
 | 
					  include Authorization
 | 
				
			||||||
  include AccountOwnedConcern
 | 
					  include AccountOwnedConcern
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,15 +19,19 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private
 | 
					  private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def pundit_user
 | 
				
			||||||
 | 
					    signed_request_account
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_status
 | 
					  def set_status
 | 
				
			||||||
    @status = @account.statuses.find(params[:status_id])
 | 
					    @status = @account.statuses.find(params[:status_id])
 | 
				
			||||||
    authorize @status, :show?
 | 
					    authorize @status, :show?
 | 
				
			||||||
  rescue Mastodon::NotPermittedError
 | 
					  rescue Mastodon::NotPermittedError
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound
 | 
					    not_found
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_replies
 | 
					  def set_replies
 | 
				
			||||||
    @replies = page_params[:only_other_accounts] ? Status.where.not(account_id: @account.id) : @account.statuses
 | 
					    @replies = only_other_accounts? ? Status.where.not(account_id: @account.id) : @account.statuses
 | 
				
			||||||
    @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
 | 
					    @replies = @replies.where(in_reply_to_id: @status.id, visibility: [:public, :unlisted])
 | 
				
			||||||
    @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
 | 
					    @replies = @replies.paginate_by_min_id(DESCENDANTS_LIMIT, params[:min_id])
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					@ -38,7 +42,7 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
 | 
				
			||||||
      type: :unordered,
 | 
					      type: :unordered,
 | 
				
			||||||
      part_of: account_status_replies_url(@account, @status),
 | 
					      part_of: account_status_replies_url(@account, @status),
 | 
				
			||||||
      next: next_page,
 | 
					      next: next_page,
 | 
				
			||||||
      items: @replies.map { |status| status.local ? status : status.uri }
 | 
					      items: @replies.map { |status| status.local? ? status : status.uri }
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return page if page_requested?
 | 
					    return page if page_requested?
 | 
				
			||||||
| 
						 | 
					@ -51,16 +55,21 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def page_requested?
 | 
					  def page_requested?
 | 
				
			||||||
    params[:page] == 'true'
 | 
					    truthy_param?(:page)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def only_other_accounts?
 | 
				
			||||||
 | 
					    truthy_param?(:only_other_accounts)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def next_page
 | 
					  def next_page
 | 
				
			||||||
    only_other_accounts = !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
 | 
					    only_other_accounts = !(@replies&.last&.account_id == @account.id && @replies.size == DESCENDANTS_LIMIT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    account_status_replies_url(
 | 
					    account_status_replies_url(
 | 
				
			||||||
      @account,
 | 
					      @account,
 | 
				
			||||||
      @status,
 | 
					      @status,
 | 
				
			||||||
      page: true,
 | 
					      page: true,
 | 
				
			||||||
      min_id: only_other_accounts && !page_params[:only_other_accounts] ? nil : @replies&.last&.id,
 | 
					      min_id: only_other_accounts && !only_other_accounts? ? nil : @replies&.last&.id,
 | 
				
			||||||
      only_other_accounts: only_other_accounts
 | 
					      only_other_accounts: only_other_accounts
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ class Api::V1::Polls::VotesController < Api::BaseController
 | 
				
			||||||
    @poll = Poll.attached.find(params[:poll_id])
 | 
					    @poll = Poll.attached.find(params[:poll_id])
 | 
				
			||||||
    authorize @poll.status, :show?
 | 
					    authorize @poll.status, :show?
 | 
				
			||||||
  rescue Mastodon::NotPermittedError
 | 
					  rescue Mastodon::NotPermittedError
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound
 | 
					    not_found
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def vote_params
 | 
					  def vote_params
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,7 +17,7 @@ class Api::V1::PollsController < Api::BaseController
 | 
				
			||||||
    @poll = Poll.attached.find(params[:id])
 | 
					    @poll = Poll.attached.find(params[:id])
 | 
				
			||||||
    authorize @poll.status, :show?
 | 
					    authorize @poll.status, :show?
 | 
				
			||||||
  rescue Mastodon::NotPermittedError
 | 
					  rescue Mastodon::NotPermittedError
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound
 | 
					    not_found
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def refresh_poll
 | 
					  def refresh_poll
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
 | 
				
			||||||
  before_action -> { doorkeeper_authorize! :push }
 | 
					  before_action -> { doorkeeper_authorize! :push }
 | 
				
			||||||
  before_action :require_user!
 | 
					  before_action :require_user!
 | 
				
			||||||
  before_action :set_web_push_subscription
 | 
					  before_action :set_web_push_subscription
 | 
				
			||||||
 | 
					  before_action :check_web_push_subscription, only: [:show, :update]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def create
 | 
					  def create
 | 
				
			||||||
    @web_subscription&.destroy!
 | 
					    @web_subscription&.destroy!
 | 
				
			||||||
| 
						 | 
					@ -21,16 +22,11 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def show
 | 
					  def show
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound if @web_subscription.nil?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
 | 
					    render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def update
 | 
					  def update
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound if @web_subscription.nil?
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @web_subscription.update!(data: data_params)
 | 
					    @web_subscription.update!(data: data_params)
 | 
				
			||||||
 | 
					 | 
				
			||||||
    render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
 | 
					    render json: @web_subscription, serializer: REST::WebPushSubscriptionSerializer
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,12 +41,17 @@ class Api::V1::Push::SubscriptionsController < Api::BaseController
 | 
				
			||||||
    @web_subscription = ::Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id)
 | 
					    @web_subscription = ::Web::PushSubscription.find_by(access_token_id: doorkeeper_token.id)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def check_web_push_subscription
 | 
				
			||||||
 | 
					    not_found if @web_subscription.nil?
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def subscription_params
 | 
					  def subscription_params
 | 
				
			||||||
    params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
 | 
					    params.require(:subscription).permit(:endpoint, keys: [:auth, :p256dh])
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def data_params
 | 
					  def data_params
 | 
				
			||||||
    return {} if params[:data].blank?
 | 
					    return {} if params[:data].blank?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    params.require(:data).permit(alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll])
 | 
					    params.require(:data).permit(alerts: [:follow, :follow_request, :favourite, :reblog, :mention, :poll])
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,8 +28,7 @@ class Api::V1::Statuses::MutesController < Api::BaseController
 | 
				
			||||||
    @status = Status.find(params[:status_id])
 | 
					    @status = Status.find(params[:status_id])
 | 
				
			||||||
    authorize @status, :show?
 | 
					    authorize @status, :show?
 | 
				
			||||||
  rescue Mastodon::NotPermittedError
 | 
					  rescue Mastodon::NotPermittedError
 | 
				
			||||||
    # Reraise in order to get a 404 instead of a 403 error code
 | 
					    not_found
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_conversation
 | 
					  def set_conversation
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,7 @@ class Api::V1::StatusesController < Api::BaseController
 | 
				
			||||||
    @status = Status.find(params[:id])
 | 
					    @status = Status.find(params[:id])
 | 
				
			||||||
    authorize @status, :show?
 | 
					    authorize @status, :show?
 | 
				
			||||||
  rescue Mastodon::NotPermittedError
 | 
					  rescue Mastodon::NotPermittedError
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound
 | 
					    not_found
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_thread
 | 
					  def set_thread
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@ class MediaController < ApplicationController
 | 
				
			||||||
  def verify_permitted_status!
 | 
					  def verify_permitted_status!
 | 
				
			||||||
    authorize @media_attachment.status, :show?
 | 
					    authorize @media_attachment.status, :show?
 | 
				
			||||||
  rescue Mastodon::NotPermittedError
 | 
					  rescue Mastodon::NotPermittedError
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound
 | 
					    not_found
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def check_playable
 | 
					  def check_playable
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,7 +41,7 @@ class RemoteInteractionController < ApplicationController
 | 
				
			||||||
    @status = Status.find(params[:id])
 | 
					    @status = Status.find(params[:id])
 | 
				
			||||||
    authorize @status, :show?
 | 
					    authorize @status, :show?
 | 
				
			||||||
  rescue Mastodon::NotPermittedError
 | 
					  rescue Mastodon::NotPermittedError
 | 
				
			||||||
    raise ActiveRecord::RecordNotFound
 | 
					    not_found
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def set_body_classes
 | 
					  def set_body_classes
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,7 @@ class StatusesController < ApplicationController
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  def embed
 | 
					  def embed
 | 
				
			||||||
    return not_found if @status.hidden?
 | 
					    return not_found if @status.hidden? || @status.reblog?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    expires_in 180, public: true
 | 
					    expires_in 180, public: true
 | 
				
			||||||
    response.headers['X-Frame-Options'] = 'ALLOWALL'
 | 
					    response.headers['X-Frame-Options'] = 'ALLOWALL'
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,7 +354,7 @@ class Status < ApplicationRecord
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      if account.nil?
 | 
					      if account.nil?
 | 
				
			||||||
        where(visibility: visibility)
 | 
					        where(visibility: visibility)
 | 
				
			||||||
      elsif target_account.blocking?(account) # get rid of blocked peeps
 | 
					      elsif target_account.blocking?(account) || (account.domain.present? && target_account.domain_blocking?(account.domain)) # get rid of blocked peeps
 | 
				
			||||||
        none
 | 
					        none
 | 
				
			||||||
      elsif account.id == target_account.id # author can see own stuff
 | 
					      elsif account.id == target_account.id # author can see own stuff
 | 
				
			||||||
        all
 | 
					        all
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,21 +3,133 @@
 | 
				
			||||||
require 'rails_helper'
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RSpec.describe ActivityPub::CollectionsController, type: :controller do
 | 
					RSpec.describe ActivityPub::CollectionsController, type: :controller do
 | 
				
			||||||
  describe 'POST #show' do
 | 
					  let!(:account) { Fabricate(:account) }
 | 
				
			||||||
    let(:account) { Fabricate(:account) }
 | 
					  let(:remote_account) { nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'id is "featured"' do
 | 
					  before do
 | 
				
			||||||
      it 'returns 200 with "application/activity+json"' do
 | 
					    allow(controller).to receive(:signed_request_account).and_return(remote_account)
 | 
				
			||||||
        post :show, params: { id: 'featured', account_username: account.username }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Fabricate(:status_pin, account: account)
 | 
				
			||||||
 | 
					    Fabricate(:status_pin, account: account)
 | 
				
			||||||
 | 
					    Fabricate(:status, account: account, visibility: :private)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe 'GET #show' do
 | 
				
			||||||
 | 
					    context 'when id is "featured"' do
 | 
				
			||||||
 | 
					      context 'without signature' do
 | 
				
			||||||
 | 
					        let(:remote_account) { nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          get :show, params: { id: 'featured', account_username: account.username }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
          expect(response).to have_http_status(200)
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
          expect(response.content_type).to eq 'application/activity+json'
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'id is not "featured"' do
 | 
					        it 'returns orderedItems with pinned statuses' do
 | 
				
			||||||
      it 'returns 404' do
 | 
					          json = body_as_json
 | 
				
			||||||
        post :show, params: { id: 'hoge', account_username: account.username }
 | 
					          expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].size).to eq 2
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'with signature' do
 | 
				
			||||||
 | 
					        let(:remote_account) { Fabricate(:account, domain: 'example.com') }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            get :show, params: { id: 'featured', account_username: account.username }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http success' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					            expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns orderedItems with pinned statuses' do
 | 
				
			||||||
 | 
					            json = body_as_json
 | 
				
			||||||
 | 
					            expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					            expect(json[:orderedItems].size).to eq 2
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'in authorized fetch mode' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            allow(controller).to receive(:authorized_fetch_mode?).and_return(true)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'when signed request account is blocked' do
 | 
				
			||||||
 | 
					            before do
 | 
				
			||||||
 | 
					              account.block!(remote_account)
 | 
				
			||||||
 | 
					              get :show, params: { id: 'featured', account_username: account.username }
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					              expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Cache-Control']).to include 'private'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns empty orderedItems' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					              expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					              expect(json[:orderedItems].size).to eq 0
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'when signed request account is domain blocked' do
 | 
				
			||||||
 | 
					            before do
 | 
				
			||||||
 | 
					              account.block_domain!(remote_account.domain)
 | 
				
			||||||
 | 
					              get :show, params: { id: 'featured', account_username: account.username }
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					              expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Cache-Control']).to include 'private'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns empty orderedItems' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					              expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					              expect(json[:orderedItems].size).to eq 0
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when id is not "featured"' do
 | 
				
			||||||
 | 
					      it 'returns http not found' do
 | 
				
			||||||
 | 
					        get :show, params: { id: 'hoge', account_username: account.username }
 | 
				
			||||||
        expect(response).to have_http_status(404)
 | 
					        expect(response).to have_http_status(404)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,25 +3,31 @@
 | 
				
			||||||
require 'rails_helper'
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RSpec.describe ActivityPub::InboxesController, type: :controller do
 | 
					RSpec.describe ActivityPub::InboxesController, type: :controller do
 | 
				
			||||||
  describe 'POST #create' do
 | 
					  let(:remote_account) { nil }
 | 
				
			||||||
    context 'with signed_request_account' do
 | 
					
 | 
				
			||||||
      it 'returns 202' do
 | 
					  before do
 | 
				
			||||||
        allow(controller).to receive(:signed_request_account) do
 | 
					    allow(controller).to receive(:signed_request_account).and_return(remote_account)
 | 
				
			||||||
          Fabricate(:account)
 | 
					 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe 'POST #create' do
 | 
				
			||||||
 | 
					    context 'with signature' do
 | 
				
			||||||
 | 
					      let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
        post :create, body: '{}'
 | 
					        post :create, body: '{}'
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http accepted' do
 | 
				
			||||||
        expect(response).to have_http_status(202)
 | 
					        expect(response).to have_http_status(202)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'without signed_request_account' do
 | 
					    context 'without signature' do
 | 
				
			||||||
      it 'returns 401' do
 | 
					      before do
 | 
				
			||||||
        allow(controller).to receive(:signed_request_account) do
 | 
					        post :create, body: '{}'
 | 
				
			||||||
          false
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        post :create, body: '{}'
 | 
					      it 'returns http not authorized' do
 | 
				
			||||||
        expect(response).to have_http_status(401)
 | 
					        expect(response).to have_http_status(401)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,12 +4,77 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
 | 
				
			||||||
  let!(:account) { Fabricate(:account) }
 | 
					  let!(:account) { Fabricate(:account) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  before do
 | 
					  before do
 | 
				
			||||||
    Fabricate(:status, account: account)
 | 
					    Fabricate(:status, account: account, visibility: :public)
 | 
				
			||||||
 | 
					    Fabricate(:status, account: account, visibility: :unlisted)
 | 
				
			||||||
 | 
					    Fabricate(:status, account: account, visibility: :private)
 | 
				
			||||||
 | 
					    Fabricate(:status, account: account, visibility: :direct)
 | 
				
			||||||
 | 
					    Fabricate(:status, account: account, visibility: :limited)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  before do
 | 
				
			||||||
 | 
					    allow(controller).to receive(:signed_request_account).and_return(remote_account)
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe 'GET #show' do
 | 
					  describe 'GET #show' do
 | 
				
			||||||
 | 
					    context 'without signature' do
 | 
				
			||||||
 | 
					      let(:remote_account) { nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      before do
 | 
					      before do
 | 
				
			||||||
      get :show, params: { account_username: account.username }
 | 
					        get :show, params: { account_username: account.username, page: page }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'with page not requested' do
 | 
				
			||||||
 | 
					        let(:page) { nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns totalItems' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					          expect(json[:totalItems]).to eq 4
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'with page requested' do
 | 
				
			||||||
 | 
					        let(:page) { 'true' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns orderedItems with public or unlisted statuses' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					          expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].size).to eq 2
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'with signature' do
 | 
				
			||||||
 | 
					      let(:remote_account) { Fabricate(:account, domain: 'example.com') }
 | 
				
			||||||
 | 
					      let(:page) { 'true' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when signed request account does not follow account' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          get :show, params: { account_username: account.username, page: page }
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it 'returns http success' do
 | 
					        it 'returns http success' do
 | 
				
			||||||
| 
						 | 
					@ -19,5 +84,94 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
 | 
				
			||||||
        it 'returns application/activity+json' do
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
          expect(response.content_type).to eq 'application/activity+json'
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns orderedItems with public or unlisted statuses' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					          expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].size).to eq 2
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when signed request account follows account' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          remote_account.follow!(account)
 | 
				
			||||||
 | 
					          get :show, params: { account_username: account.username, page: page }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns orderedItems with private statuses' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					          expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].size).to eq 3
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:to].include?(account_followers_url(account, ActionMailer::Base.default_url_options)) }).to be true
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when signed request account is blocked' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          account.block!(remote_account)
 | 
				
			||||||
 | 
					          get :show, params: { account_username: account.username, page: page }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns empty orderedItems' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					          expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].size).to eq 0
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when signed request account is domain blocked' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          account.block_domain!(remote_account.domain)
 | 
				
			||||||
 | 
					          get :show, params: { account_username: account.username, page: page }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns empty orderedItems' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					          expect(json[:orderedItems]).to be_an Array
 | 
				
			||||||
 | 
					          expect(json[:orderedItems].size).to eq 0
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										196
									
								
								spec/controllers/activitypub/replies_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								spec/controllers/activitypub/replies_controller_spec.rb
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,196 @@
 | 
				
			||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					require 'rails_helper'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RSpec.describe ActivityPub::RepliesController, type: :controller do
 | 
				
			||||||
 | 
					  let(:status) { Fabricate(:status, visibility: parent_visibility) }
 | 
				
			||||||
 | 
					  let(:remote_account) { nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  before do
 | 
				
			||||||
 | 
					    allow(controller).to receive(:signed_request_account).and_return(remote_account)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Fabricate(:status, thread: status, visibility: :public)
 | 
				
			||||||
 | 
					    Fabricate(:status, thread: status, visibility: :public)
 | 
				
			||||||
 | 
					    Fabricate(:status, thread: status, visibility: :private)
 | 
				
			||||||
 | 
					    Fabricate(:status, account: status.account, thread: status, visibility: :public)
 | 
				
			||||||
 | 
					    Fabricate(:status, account: status.account, thread: status, visibility: :private)
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe 'GET #index' do
 | 
				
			||||||
 | 
					    context 'with no signature' do
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :index, params: { account_username: status.account.username, status_id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is public' do
 | 
				
			||||||
 | 
					        let(:parent_visibility) { :public }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					          expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns items with account\'s own replies' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          expect(json[:first]).to be_a Hash
 | 
				
			||||||
 | 
					          expect(json[:first][:items]).to be_an Array
 | 
				
			||||||
 | 
					          expect(json[:first][:items].size).to eq 1
 | 
				
			||||||
 | 
					          expect(json[:first][:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is private' do
 | 
				
			||||||
 | 
					        let(:parent_visibility) { :private }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is direct' do
 | 
				
			||||||
 | 
					        let(:parent_visibility) { :direct }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'with signature' do
 | 
				
			||||||
 | 
					      let(:remote_account) { Fabricate(:account, domain: 'example.com') }
 | 
				
			||||||
 | 
					      let(:only_other_accounts) { nil }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          get :index, params: { account_username: status.account.username, status_id: status.id, only_other_accounts: only_other_accounts }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is public' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :public }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http success' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns application/activity+json' do
 | 
				
			||||||
 | 
					            expect(response.content_type).to eq 'application/activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'without only_other_accounts' do
 | 
				
			||||||
 | 
					            it 'returns items with account\'s own replies' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              expect(json[:first]).to be_a Hash
 | 
				
			||||||
 | 
					              expect(json[:first][:items]).to be_an Array
 | 
				
			||||||
 | 
					              expect(json[:first][:items].size).to eq 1
 | 
				
			||||||
 | 
					              expect(json[:first][:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'with only_other_accounts' do
 | 
				
			||||||
 | 
					            let(:only_other_accounts) { 'true' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns items with other public or unlisted replies' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              expect(json[:first]).to be_a Hash
 | 
				
			||||||
 | 
					              expect(json[:first][:items]).to be_an Array
 | 
				
			||||||
 | 
					              expect(json[:first][:items].size).to eq 2
 | 
				
			||||||
 | 
					              expect(json[:first][:items].all? { |item| item[:to].include?(ActivityPub::TagManager::COLLECTIONS[:public]) || item[:cc].include?(ActivityPub::TagManager::COLLECTIONS[:public]) }).to be true
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is private' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :private }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is direct' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :direct }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when signed request account is blocked' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          status.account.block!(remote_account)
 | 
				
			||||||
 | 
					          get :index, params: { account_username: status.account.username, status_id: status.id }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is public' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :public }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is private' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :private }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is direct' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :direct }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when signed request account is domain blocked' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          status.account.block_domain!(remote_account.domain)
 | 
				
			||||||
 | 
					          get :index, params: { account_username: status.account.username, status_id: status.id }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is public' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :public }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is private' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :private }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when status is direct' do
 | 
				
			||||||
 | 
					          let(:parent_visibility) { :direct }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http not found' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
| 
						 | 
					@ -5,128 +5,821 @@ require 'rails_helper'
 | 
				
			||||||
describe StatusesController do
 | 
					describe StatusesController do
 | 
				
			||||||
  render_views
 | 
					  render_views
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe '#show' do
 | 
					  describe 'GET #show' do
 | 
				
			||||||
    context 'account is suspended' do
 | 
					    let(:account) { Fabricate(:account) }
 | 
				
			||||||
      it 'returns gone' do
 | 
					    let(:status)  { Fabricate(:status, account: account) }
 | 
				
			||||||
        account = Fabricate(:account, suspended: true)
 | 
					 | 
				
			||||||
        status = Fabricate(:status, account: account)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when account is suspended' do
 | 
				
			||||||
 | 
					      let(:account) { Fabricate(:account, suspended: true) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
        get :show, params: { account_username: account.username, id: status.id }
 | 
					        get :show, params: { account_username: account.username, id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http gone' do
 | 
				
			||||||
        expect(response).to have_http_status(410)
 | 
					        expect(response).to have_http_status(410)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'status is not permitted' do
 | 
					    context 'when status is a reblog' do
 | 
				
			||||||
      it 'raises ActiveRecord::RecordNotFound' do
 | 
					      let(:original_account) { Fabricate(:account, domain: 'example.com') }
 | 
				
			||||||
        user = Fabricate(:user)
 | 
					      let(:original_status) { Fabricate(:status, account: original_account, url: 'https://example.com/123') }
 | 
				
			||||||
        status = Fabricate(:status)
 | 
					      let(:status) { Fabricate(:status, account: account, reblog: original_status) }
 | 
				
			||||||
        status.account.block!(user.account)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        sign_in(user)
 | 
					      before do
 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					        get :show, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        expect(response).to have_http_status(404)
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'status is a reblog' do
 | 
					 | 
				
			||||||
      it 'redirects to the original status' do
 | 
					      it 'redirects to the original status' do
 | 
				
			||||||
        original_account = Fabricate(:account, domain: 'example.com')
 | 
					 | 
				
			||||||
        original_status = Fabricate(:status, account: original_account, uri: 'tag:example.com,2017:foo', url: 'https://example.com/123')
 | 
					 | 
				
			||||||
        status = Fabricate(:status, reblog: original_status)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        expect(response).to redirect_to(original_status.url)
 | 
					        expect(response).to redirect_to(original_status.url)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    context 'account is not suspended and status is permitted' do
 | 
					    context 'when status is public' do
 | 
				
			||||||
      it 'assigns @account' do
 | 
					      before do
 | 
				
			||||||
        status = Fabricate(:status)
 | 
					        get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
        expect(assigns(:account)).to eq status.account
 | 
					 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it 'assigns @status' do
 | 
					      context 'as HTML' do
 | 
				
			||||||
        status = Fabricate(:status)
 | 
					        let(:format) { 'html' }
 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
        expect(assigns(:status)).to eq status
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it 'assigns @ancestors for ancestors of the status if it is a reply' do
 | 
					        it 'returns http success' do
 | 
				
			||||||
        ancestor = Fabricate(:status)
 | 
					 | 
				
			||||||
        status = Fabricate(:status, in_reply_to_id: ancestor.id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        expect(assigns(:ancestors)).to eq [ancestor]
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it 'assigns @ancestors for [] if it is not a reply' do
 | 
					 | 
				
			||||||
        status = Fabricate(:status)
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
        expect(assigns(:ancestors)).to eq []
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it 'assigns @descendant_threads for a thread with several statuses' do
 | 
					 | 
				
			||||||
        status = Fabricate(:status)
 | 
					 | 
				
			||||||
        child = Fabricate(:status, in_reply_to_id: status.id)
 | 
					 | 
				
			||||||
        grandchild = Fabricate(:status, in_reply_to_id: child.id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)[0][:statuses].pluck(:id)).to eq [child.id, grandchild.id]
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it 'assigns @descendant_threads for several threads sharing the same descendant' do
 | 
					 | 
				
			||||||
        status = Fabricate(:status)
 | 
					 | 
				
			||||||
        child = Fabricate(:status, in_reply_to_id: status.id)
 | 
					 | 
				
			||||||
        grandchildren = 2.times.map { Fabricate(:status, in_reply_to_id: child.id) }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)[0][:statuses].pluck(:id)).to eq [child.id, grandchildren[0].id]
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)[1][:statuses].pluck(:id)).to eq [grandchildren[1].id]
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it 'assigns @max_descendant_thread_id for the last thread if it is hitting the status limit' do
 | 
					 | 
				
			||||||
        stub_const 'StatusControllerConcern::DESCENDANTS_LIMIT', 1
 | 
					 | 
				
			||||||
        status = Fabricate(:status)
 | 
					 | 
				
			||||||
        child = Fabricate(:status, in_reply_to_id: status.id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)).to eq []
 | 
					 | 
				
			||||||
        expect(assigns(:max_descendant_thread_id)).to eq child.id
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it 'assigns @descendant_threads for threads with :next_status key if they are hitting the depth limit' do
 | 
					 | 
				
			||||||
        stub_const 'StatusControllerConcern::DESCENDANTS_DEPTH_LIMIT', 2
 | 
					 | 
				
			||||||
        status = Fabricate(:status)
 | 
					 | 
				
			||||||
        child0 = Fabricate(:status, in_reply_to_id: status.id)
 | 
					 | 
				
			||||||
        child1 = Fabricate(:status, in_reply_to_id: child0.id)
 | 
					 | 
				
			||||||
        child2 = Fabricate(:status, in_reply_to_id: child0.id)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)[0][:statuses].pluck(:id)).not_to include child1.id
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)[1][:statuses].pluck(:id)).not_to include child2.id
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)[0][:next_status].id).to eq child1.id
 | 
					 | 
				
			||||||
        expect(assigns(:descendant_threads)[1][:next_status].id).to eq child2.id
 | 
					 | 
				
			||||||
      end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      it 'returns a success' do
 | 
					 | 
				
			||||||
        status = Fabricate(:status)
 | 
					 | 
				
			||||||
        get :show, params: { account_username: status.account.username, id: status.id }
 | 
					 | 
				
			||||||
          expect(response).to have_http_status(200)
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      it 'renders statuses/show' do
 | 
					        it 'returns Link header' do
 | 
				
			||||||
        status = Fabricate(:status)
 | 
					          expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns Vary header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'renders status' do
 | 
				
			||||||
 | 
					          expect(response).to render_template(:show)
 | 
				
			||||||
 | 
					          expect(response.body).to include status.text
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'as JSON' do
 | 
				
			||||||
 | 
					        let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http success' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns Link header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns Vary header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns Content-Type header' do
 | 
				
			||||||
 | 
					          expect(response.headers['Content-Type']).to include 'application/activity+json'
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'renders ActivityPub Note object' do
 | 
				
			||||||
 | 
					          json = body_as_json
 | 
				
			||||||
 | 
					          expect(json[:content]).to include status.text
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is private' do
 | 
				
			||||||
 | 
					      let(:status) { Fabricate(:status, account: account, visibility: :private) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'as JSON' do
 | 
				
			||||||
 | 
					        let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'as HTML' do
 | 
				
			||||||
 | 
					        let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is direct' do
 | 
				
			||||||
 | 
					      let(:status) { Fabricate(:status, account: account, visibility: :direct) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'as JSON' do
 | 
				
			||||||
 | 
					        let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'as HTML' do
 | 
				
			||||||
 | 
					        let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when signed-in' do
 | 
				
			||||||
 | 
					      let(:user) { Fabricate(:user) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        sign_in(user)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when account blocks user' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          account.block!(user.account)
 | 
				
			||||||
          get :show, params: { account_username: status.account.username, id: status.id }
 | 
					          get :show, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
        expect(response).to render_template 'statuses/show'
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is public' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'as HTML' do
 | 
				
			||||||
 | 
					          let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http success' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Link header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Vary header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns no Cache-Control header' do
 | 
				
			||||||
 | 
					            expect(response.headers).to_not include 'Cache-Control'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'renders status' do
 | 
				
			||||||
 | 
					            expect(response).to render_template(:show)
 | 
				
			||||||
 | 
					            expect(response.body).to include status.text
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'as JSON' do
 | 
				
			||||||
 | 
					          let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http success' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Link header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Vary header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Content-Type header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Content-Type']).to include 'application/activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'renders ActivityPub Note object' do
 | 
				
			||||||
 | 
					            json = body_as_json
 | 
				
			||||||
 | 
					            expect(json[:content]).to include status.text
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is private' do
 | 
				
			||||||
 | 
					        let(:status) { Fabricate(:status, account: account, visibility: :private) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            user.account.follow!(account)
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns no Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers).to_not include 'Cache-Control'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders status' do
 | 
				
			||||||
 | 
					              expect(response).to render_template(:show)
 | 
				
			||||||
 | 
					              expect(response.body).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Cache-Control']).to include 'private'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Content-Type header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Content-Type']).to include 'application/activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders ActivityPub Note object' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					              expect(json[:content]).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is direct' do
 | 
				
			||||||
 | 
					        let(:status) { Fabricate(:status, account: account, visibility: :direct) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            Fabricate(:mention, account: user.account, status: status)
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns no Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers).to_not include 'Cache-Control'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders status' do
 | 
				
			||||||
 | 
					              expect(response).to render_template(:show)
 | 
				
			||||||
 | 
					              expect(response.body).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Cache-Control']).to include 'private'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Content-Type header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Content-Type']).to include 'application/activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders ActivityPub Note object' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					              expect(json[:content]).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'with signature' do
 | 
				
			||||||
 | 
					      let(:remote_account) { Fabricate(:account, domain: 'example.com') }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        allow(controller).to receive(:signed_request_account).and_return(remote_account)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when account blocks account' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          account.block!(remote_account)
 | 
				
			||||||
 | 
					          get :show, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when account domain blocks account' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          account.block_domain!(remote_account.domain)
 | 
				
			||||||
 | 
					          get :show, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it 'returns http not found' do
 | 
				
			||||||
 | 
					          expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is public' do
 | 
				
			||||||
 | 
					        before do
 | 
				
			||||||
 | 
					          get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'as HTML' do
 | 
				
			||||||
 | 
					          let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http success' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Link header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Vary header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns no Cache-Control header' do
 | 
				
			||||||
 | 
					            expect(response.headers).to_not include 'Cache-Control'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'renders status' do
 | 
				
			||||||
 | 
					            expect(response).to render_template(:show)
 | 
				
			||||||
 | 
					            expect(response.body).to include status.text
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'as JSON' do
 | 
				
			||||||
 | 
					          let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns http success' do
 | 
				
			||||||
 | 
					            expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Link header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Vary header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'returns Content-Type header' do
 | 
				
			||||||
 | 
					            expect(response.headers['Content-Type']).to include 'application/activity+json'
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          it 'renders ActivityPub Note object' do
 | 
				
			||||||
 | 
					            json = body_as_json
 | 
				
			||||||
 | 
					            expect(json[:content]).to include status.text
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is private' do
 | 
				
			||||||
 | 
					        let(:status) { Fabricate(:status, account: account, visibility: :private) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            remote_account.follow!(account)
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns no Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers).to_not include 'Cache-Control'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders status' do
 | 
				
			||||||
 | 
					              expect(response).to render_template(:show)
 | 
				
			||||||
 | 
					              expect(response.body).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Cache-Control']).to include 'private'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Content-Type header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Content-Type']).to include 'application/activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders ActivityPub Note object' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					              expect(json[:content]).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is direct' do
 | 
				
			||||||
 | 
					        let(:status) { Fabricate(:status, account: account, visibility: :direct) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            Fabricate(:mention, account: remote_account, status: status)
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns no Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers).to_not include 'Cache-Control'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders status' do
 | 
				
			||||||
 | 
					              expect(response).to render_template(:show)
 | 
				
			||||||
 | 
					              expect(response.body).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http success' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Link header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Vary header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns private Cache-Control header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Cache-Control']).to include 'private'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns Content-Type header' do
 | 
				
			||||||
 | 
					              expect(response.headers['Content-Type']).to include 'application/activity+json'
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'renders ActivityPub Note object' do
 | 
				
			||||||
 | 
					              json = body_as_json
 | 
				
			||||||
 | 
					              expect(json[:content]).to include status.text
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          before do
 | 
				
			||||||
 | 
					            get :show, params: { account_username: status.account.username, id: status.id, format: format }
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as JSON' do
 | 
				
			||||||
 | 
					            let(:format) { 'json' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          context 'as HTML' do
 | 
				
			||||||
 | 
					            let(:format) { 'html' }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            it 'returns http not found' do
 | 
				
			||||||
 | 
					              expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					            end
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe 'GET #activity' do
 | 
				
			||||||
 | 
					    let(:account) { Fabricate(:account) }
 | 
				
			||||||
 | 
					    let(:status)  { Fabricate(:status, account: account) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when account is suspended' do
 | 
				
			||||||
 | 
					      let(:account) { Fabricate(:account, suspended: true) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :activity, params: { account_username: account.username, id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http gone' do
 | 
				
			||||||
 | 
					        expect(response).to have_http_status(410)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is public' do
 | 
				
			||||||
 | 
					      pending
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is private' do
 | 
				
			||||||
 | 
					      pending
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is direct' do
 | 
				
			||||||
 | 
					      pending
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when signed-in' do
 | 
				
			||||||
 | 
					      context 'when status is public' do
 | 
				
			||||||
 | 
					        pending
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is private' do
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is direct' do
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'with signature' do
 | 
				
			||||||
 | 
					      context 'when status is public' do
 | 
				
			||||||
 | 
					        pending
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is private' do
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      context 'when status is direct' do
 | 
				
			||||||
 | 
					        context 'when user is authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        context 'when user is not authorized to see it' do
 | 
				
			||||||
 | 
					          pending
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe 'GET #embed' do
 | 
				
			||||||
 | 
					    let(:account) { Fabricate(:account) }
 | 
				
			||||||
 | 
					    let(:status)  { Fabricate(:status, account: account) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when account is suspended' do
 | 
				
			||||||
 | 
					      let(:account) { Fabricate(:account, suspended: true) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :embed, params: { account_username: account.username, id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http gone' do
 | 
				
			||||||
 | 
					        expect(response).to have_http_status(410)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is a reblog' do
 | 
				
			||||||
 | 
					      let(:original_account) { Fabricate(:account, domain: 'example.com') }
 | 
				
			||||||
 | 
					      let(:original_status) { Fabricate(:status, account: original_account, url: 'https://example.com/123') }
 | 
				
			||||||
 | 
					      let(:status) { Fabricate(:status, account: account, reblog: original_status) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :embed, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http not found' do
 | 
				
			||||||
 | 
					        expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is public' do
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :embed, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http success' do
 | 
				
			||||||
 | 
					        expect(response).to have_http_status(200)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns Link header' do
 | 
				
			||||||
 | 
					        expect(response.headers['Link'].to_s).to include 'activity+json'
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns Vary header' do
 | 
				
			||||||
 | 
					        expect(response.headers['Vary']).to eq 'Accept'
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns public Cache-Control header' do
 | 
				
			||||||
 | 
					        expect(response.headers['Cache-Control']).to include 'public'
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'renders status' do
 | 
				
			||||||
 | 
					        expect(response).to render_template(:embed)
 | 
				
			||||||
 | 
					        expect(response.body).to include status.text
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is private' do
 | 
				
			||||||
 | 
					      let(:status) { Fabricate(:status, account: account, visibility: :private) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :embed, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http not found' do
 | 
				
			||||||
 | 
					        expect(response).to have_http_status(404)
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context 'when status is direct' do
 | 
				
			||||||
 | 
					      let(:status) { Fabricate(:status, account: account, visibility: :direct) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        get :embed, params: { account_username: status.account.username, id: status.id }
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      it 'returns http not found' do
 | 
				
			||||||
 | 
					        expect(response).to have_http_status(404)
 | 
				
			||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
Fabricator(:status_pin) do
 | 
					Fabricator(:status_pin) do
 | 
				
			||||||
  account
 | 
					  account
 | 
				
			||||||
  status
 | 
					  status { |attrs| Fabricate(:status, account: attrs[:account], visibility: :public) }
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue