Merge commit 'c62604b5f6
' into kb_migration
This commit is contained in:
commit
a1f6ef00db
86 changed files with 929 additions and 221 deletions
|
@ -71,7 +71,7 @@ module.exports = {
|
|||
'comma-style': ['warn', 'last'],
|
||||
'consistent-return': 'error',
|
||||
'dot-notation': 'error',
|
||||
eqeqeq: 'error',
|
||||
eqeqeq: ['error', 'always', { 'null': 'ignore' }],
|
||||
indent: ['warn', 2],
|
||||
'jsx-quotes': ['error', 'prefer-single'],
|
||||
'no-case-declarations': 'off',
|
||||
|
|
53
.github/workflows/build-nightly.yml
vendored
Normal file
53
.github/workflows/build-nightly.yml
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
name: Build nightly container image
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 2 * * *' # run at 2 AM UTC
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build-nightly-image:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: hadolint/hadolint-action@v3.1.0
|
||||
- uses: docker/setup-qemu-action@v2
|
||||
- uses: docker/setup-buildx-action@v2
|
||||
|
||||
- name: Log in to the Github Container registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- uses: docker/metadata-action@v4
|
||||
id: meta
|
||||
with:
|
||||
images: |
|
||||
ghcr.io/mastodon/mastodon
|
||||
flavor: |
|
||||
latest=auto
|
||||
tags: |
|
||||
type=raw,value=nightly
|
||||
labels: |
|
||||
org.opencontainers.image.description=Nightly build image used for testing purposes
|
||||
|
||||
- uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
provenance: false
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
push: ${{ github.repository == 'mastodon/mastodon' && github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
|
@ -1224,9 +1224,6 @@ Rails/ActiveRecordCallbacksOrder:
|
|||
Rails/ApplicationController:
|
||||
Exclude:
|
||||
- 'app/controllers/health_controller.rb'
|
||||
- 'app/controllers/well_known/host_meta_controller.rb'
|
||||
- 'app/controllers/well_known/nodeinfo_controller.rb'
|
||||
- 'app/controllers/well_known/webfinger_controller.rb'
|
||||
|
||||
# Configuration parameters: Database, Include.
|
||||
# SupportedDatabases: mysql, postgresql
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -120,7 +120,7 @@ end
|
|||
group :test do
|
||||
gem 'capybara', '~> 3.39'
|
||||
gem 'climate_control'
|
||||
gem 'faker', '~> 3.1'
|
||||
gem 'faker', '~> 3.2'
|
||||
gem 'json-schema', '~> 3.0'
|
||||
gem 'rack-test', '~> 2.1'
|
||||
gem 'rails-controller-testing', '~> 1.0'
|
||||
|
|
18
Gemfile.lock
18
Gemfile.lock
|
@ -243,7 +243,7 @@ GEM
|
|||
tzinfo
|
||||
excon (0.95.0)
|
||||
fabrication (2.30.0)
|
||||
faker (3.1.1)
|
||||
faker (3.2.0)
|
||||
i18n (>= 1.8.11, < 2)
|
||||
faraday (1.10.3)
|
||||
faraday-em_http (~> 1.0)
|
||||
|
@ -346,19 +346,19 @@ GEM
|
|||
ipaddress (0.8.3)
|
||||
jmespath (1.6.2)
|
||||
json (2.6.3)
|
||||
json-canonicalization (0.3.0)
|
||||
json-canonicalization (0.3.1)
|
||||
json-jwt (1.15.3)
|
||||
activesupport (>= 4.2)
|
||||
aes_key_wrap
|
||||
bindata
|
||||
httpclient
|
||||
json-ld (3.2.3)
|
||||
json-ld (3.2.4)
|
||||
htmlentities (~> 4.3)
|
||||
json-canonicalization (~> 0.3)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
multi_json (~> 1.15)
|
||||
rack (~> 2.2)
|
||||
rdf (~> 3.2, >= 3.2.9)
|
||||
rack (>= 2.2, < 4)
|
||||
rdf (~> 3.2, >= 3.2.10)
|
||||
json-ld-preloaded (3.2.2)
|
||||
json-ld (~> 3.2)
|
||||
rdf (~> 3.2)
|
||||
|
@ -477,7 +477,7 @@ GEM
|
|||
openssl-signature_algorithm (1.3.0)
|
||||
openssl (> 2.0)
|
||||
orm_adapter (0.5.0)
|
||||
ox (2.14.14)
|
||||
ox (2.14.16)
|
||||
parallel (1.22.1)
|
||||
parser (3.2.2.0)
|
||||
ast (~> 2.4.1)
|
||||
|
@ -485,7 +485,7 @@ GEM
|
|||
pastel (0.8.0)
|
||||
tty-color (~> 0.5)
|
||||
pg (1.4.6)
|
||||
pghero (3.3.1)
|
||||
pghero (3.3.2)
|
||||
activerecord (>= 6)
|
||||
pkg-config (1.5.1)
|
||||
posix-spawn (0.3.15)
|
||||
|
@ -555,7 +555,7 @@ GEM
|
|||
thor (~> 1.0)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
rdf (3.2.9)
|
||||
rdf (3.2.10)
|
||||
link_header (~> 0.0, >= 0.0.8)
|
||||
rdf-normalize (0.5.1)
|
||||
rdf (~> 3.2)
|
||||
|
@ -797,7 +797,7 @@ DEPENDENCIES
|
|||
dotenv-rails (~> 2.8)
|
||||
ed25519 (~> 1.3)
|
||||
fabrication (~> 2.30)
|
||||
faker (~> 3.1)
|
||||
faker (~> 3.2)
|
||||
fast_blank (~> 1.0)
|
||||
fastimage
|
||||
fog-core (<= 2.4.0)
|
||||
|
|
|
@ -7,8 +7,9 @@ class AccountsController < ApplicationController
|
|||
include AccountControllerConcern
|
||||
include SignatureAuthentication
|
||||
|
||||
vary_by -> { public_fetch_mode? ? 'Accept' : 'Accept, Signature' }
|
||||
|
||||
before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :set_cache_headers
|
||||
|
||||
skip_around_action :set_locale, if: -> { [:json, :rss].include?(request.format&.to_sym) }
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
|
|
@ -7,10 +7,6 @@ class ActivityPub::BaseController < Api::BaseController
|
|||
|
||||
private
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Vary'] = 'Signature' if authorized_fetch_mode?
|
||||
end
|
||||
|
||||
def skip_temporary_suspension_response?
|
||||
false
|
||||
end
|
||||
|
|
|
@ -4,11 +4,12 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
|||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_items
|
||||
before_action :set_size
|
||||
before_action :set_type
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
expires_in 3.minutes, public: public_fetch_mode?
|
||||
|
|
|
@ -4,9 +4,10 @@ class ActivityPub::FollowersSynchronizationsController < ActivityPub::BaseContro
|
|||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!
|
||||
before_action :set_items
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
expires_in 0, public: false
|
||||
|
|
|
@ -6,9 +6,10 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
include SignatureVerification
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? || page_requested? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_statuses
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show
|
||||
if page_requested?
|
||||
|
@ -16,6 +17,7 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
else
|
||||
expires_in(3.minutes, public: public_fetch_mode?)
|
||||
end
|
||||
|
||||
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||
end
|
||||
|
||||
|
@ -80,8 +82,4 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
def set_account
|
||||
@account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Vary'] = 'Signature' if authorized_fetch_mode? || page_requested?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,9 +7,10 @@ class ActivityPub::RepliesController < ActivityPub::BaseController
|
|||
|
||||
DESCENDANTS_LIMIT = 60
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
before_action :require_account_signature!, if: :authorized_fetch_mode?
|
||||
before_action :set_status
|
||||
before_action :set_cache_headers
|
||||
before_action :set_replies
|
||||
|
||||
def index
|
||||
|
|
|
@ -8,6 +8,8 @@ module Admin
|
|||
layout 'admin'
|
||||
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
after_action :verify_authorized
|
||||
|
||||
private
|
||||
|
@ -16,6 +18,10 @@ module Admin
|
|||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
|
||||
def set_user
|
||||
@user = Account.find(params[:account_id]).user || raise(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ class Api::BaseController < ApplicationController
|
|||
|
||||
before_action :require_authenticated_user!, if: :disallow_unauthenticated_api_access?
|
||||
before_action :require_not_suspended!
|
||||
before_action :set_cache_headers
|
||||
before_action :set_cache_control_defaults
|
||||
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
|
@ -148,8 +148,8 @@ class Api::BaseController < ApplicationController
|
|||
doorkeeper_authorize!(*scopes) if doorkeeper_token
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
def set_cache_control_defaults
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
|
||||
def disallow_unauthenticated_api_access?
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Admin::Trends::Links::PreviewCardProvidersController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
LIMIT = 100
|
||||
|
||||
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
|
||||
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
|
||||
before_action :set_providers, only: :index
|
||||
|
||||
after_action :verify_authorized
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
PAGINATION_PARAMS = %i(limit).freeze
|
||||
|
||||
def index
|
||||
authorize :preview_card_provider, :index?
|
||||
|
||||
render json: @providers, each_serializer: REST::Admin::Trends::Links::PreviewCardProviderSerializer
|
||||
end
|
||||
|
||||
def approve
|
||||
authorize :preview_card_provider, :review?
|
||||
|
||||
provider = PreviewCardProvider.find(params[:id])
|
||||
provider.update(trendable: true, reviewed_at: Time.now.utc)
|
||||
render json: provider, serializer: REST::Admin::Trends::Links::PreviewCardProviderSerializer
|
||||
end
|
||||
|
||||
def reject
|
||||
authorize :preview_card_provider, :review?
|
||||
|
||||
provider = PreviewCardProvider.find(params[:id])
|
||||
provider.update(trendable: false, reviewed_at: Time.now.utc)
|
||||
render json: provider, serializer: REST::Admin::Trends::Links::PreviewCardProviderSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_providers
|
||||
@providers = PreviewCardProvider.all.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id))
|
||||
end
|
||||
|
||||
def insert_pagination_headers
|
||||
set_pagination_headers(next_path, prev_path)
|
||||
end
|
||||
|
||||
def next_path
|
||||
api_v1_admin_trends_links_preview_card_providers_url(pagination_params(max_id: pagination_max_id)) if records_continue?
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_admin_trends_links_preview_card_providers_url(pagination_params(min_id: pagination_since_id)) unless @providers.empty?
|
||||
end
|
||||
|
||||
def pagination_max_id
|
||||
@providers.last.id
|
||||
end
|
||||
|
||||
def pagination_since_id
|
||||
@providers.first.id
|
||||
end
|
||||
|
||||
def records_continue?
|
||||
@providers.size == limit_param(LIMIT)
|
||||
end
|
||||
|
||||
def pagination_params(core_params)
|
||||
params.slice(*PAGINATION_PARAMS).permit(*PAGINATION_PARAMS).merge(core_params)
|
||||
end
|
||||
end
|
|
@ -1,7 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Admin::Trends::LinksController < Api::V1::Trends::LinksController
|
||||
before_action -> { authorize_if_got_token! :'admin:read' }
|
||||
include Authorization
|
||||
|
||||
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
|
||||
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
|
||||
|
||||
after_action :verify_authorized, except: :index
|
||||
|
||||
def index
|
||||
if current_user&.can?(:manage_taxonomies)
|
||||
render json: @links, each_serializer: REST::Admin::Trends::LinkSerializer
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def approve
|
||||
authorize :preview_card, :review?
|
||||
|
||||
link = PreviewCard.find(params[:id])
|
||||
link.update(trendable: true)
|
||||
render json: link, serializer: REST::Admin::Trends::LinkSerializer
|
||||
end
|
||||
|
||||
def reject
|
||||
authorize :preview_card, :review?
|
||||
|
||||
link = PreviewCard.find(params[:id])
|
||||
link.update(trendable: false)
|
||||
render json: link, serializer: REST::Admin::Trends::LinkSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
@ -1,7 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Admin::Trends::StatusesController < Api::V1::Trends::StatusesController
|
||||
before_action -> { authorize_if_got_token! :'admin:read' }
|
||||
include Authorization
|
||||
|
||||
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
|
||||
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
|
||||
|
||||
after_action :verify_authorized, except: :index
|
||||
|
||||
def index
|
||||
if current_user&.can?(:manage_taxonomies)
|
||||
render json: @statuses, each_serializer: REST::Admin::Trends::StatusSerializer
|
||||
else
|
||||
super
|
||||
end
|
||||
end
|
||||
|
||||
def approve
|
||||
authorize [:admin, :status], :review?
|
||||
|
||||
status = Status.find(params[:id])
|
||||
status.update(trendable: true)
|
||||
render json: status, serializer: REST::Admin::Trends::StatusSerializer
|
||||
end
|
||||
|
||||
def reject
|
||||
authorize [:admin, :status], :review?
|
||||
|
||||
status = Status.find(params[:id])
|
||||
status.update(trendable: false)
|
||||
render json: status, serializer: REST::Admin::Trends::StatusSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Admin::Trends::TagsController < Api::V1::Trends::TagsController
|
||||
before_action -> { authorize_if_got_token! :'admin:read' }
|
||||
include Authorization
|
||||
|
||||
before_action -> { authorize_if_got_token! :'admin:read' }, only: :index
|
||||
before_action -> { authorize_if_got_token! :'admin:write' }, except: :index
|
||||
|
||||
after_action :verify_authorized, except: :index
|
||||
|
||||
def index
|
||||
if current_user&.can?(:manage_taxonomies)
|
||||
|
@ -11,6 +16,22 @@ class Api::V1::Admin::Trends::TagsController < Api::V1::Trends::TagsController
|
|||
end
|
||||
end
|
||||
|
||||
def approve
|
||||
authorize :tag, :review?
|
||||
|
||||
tag = Tag.find(params[:id])
|
||||
tag.update(trendable: true, reviewed_at: Time.now.utc)
|
||||
render json: tag, serializer: REST::Admin::TagSerializer
|
||||
end
|
||||
|
||||
def reject
|
||||
authorize :tag, :review?
|
||||
|
||||
tag = Tag.find(params[:id])
|
||||
tag.update(trendable: false, reviewed_at: Time.now.utc)
|
||||
render json: tag, serializer: REST::Admin::TagSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def enabled?
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::CustomEmojisController < Api::BaseController
|
||||
skip_before_action :set_cache_headers
|
||||
|
||||
def index
|
||||
expires_in 3.minutes, public: true
|
||||
render_with_cache(each_serializer: REST::CustomEmojiSerializer) { CustomEmoji.listed.includes(:category) }
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
class Api::V1::Instances::ActivityController < Api::BaseController
|
||||
before_action :require_enabled_api!
|
||||
|
||||
skip_before_action :set_cache_headers
|
||||
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
|
||||
|
||||
def show
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
class Api::V1::Instances::PeersController < Api::BaseController
|
||||
before_action :require_enabled_api!
|
||||
|
||||
skip_before_action :set_cache_headers
|
||||
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
|
||||
|
||||
def index
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::InstancesController < Api::BaseController
|
||||
skip_before_action :set_cache_headers
|
||||
skip_before_action :require_authenticated_user!, unless: :whitelist_mode?
|
||||
|
||||
def show
|
||||
|
|
|
@ -152,6 +152,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -155,8 +155,16 @@ module CacheConcern
|
|||
end
|
||||
end
|
||||
|
||||
class_methods do
|
||||
def vary_by(value)
|
||||
before_action do |controller|
|
||||
response.headers['Vary'] = value.respond_to?(:call) ? controller.instance_exec(&value) : value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def render_with_cache(**options)
|
||||
raise ArgumentError, 'only JSON render calls are supported' unless options.key?(:json) || block_given?
|
||||
raise ArgumentError, 'Only JSON render calls are supported' unless options.key?(:json) || block_given?
|
||||
|
||||
key = options.delete(:key) || [[params[:controller], params[:action]].join('/'), options[:json].respond_to?(:cache_key) ? options[:json].cache_key : nil, options[:fields].nil? ? nil : options[:fields].join(',')].compact.join(':')
|
||||
expires_in = options.delete(:expires_in) || 3.minutes
|
||||
|
@ -176,10 +184,6 @@ module CacheConcern
|
|||
end
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Vary'] = public_fetch_mode? ? 'Accept' : 'Accept, Signature'
|
||||
end
|
||||
|
||||
def cache_collection(raw, klass)
|
||||
return raw unless klass.respond_to?(:with_includes)
|
||||
|
||||
|
|
|
@ -1,18 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CustomCssController < ApplicationController
|
||||
skip_before_action :store_current_location
|
||||
skip_before_action :require_functional!
|
||||
skip_before_action :update_user_sign_in
|
||||
skip_before_action :set_session_activity
|
||||
|
||||
skip_around_action :set_locale
|
||||
|
||||
before_action :set_cache_headers
|
||||
|
||||
class CustomCssController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||
def show
|
||||
expires_in 3.minutes, public: true
|
||||
request.session_options[:skip] = true
|
||||
render content_type: 'text/css'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -9,10 +9,15 @@ class Disputes::BaseController < ApplicationController
|
|||
|
||||
before_action :set_body_classes
|
||||
before_action :authenticate_user!
|
||||
before_action :set_cache_headers
|
||||
|
||||
private
|
||||
|
||||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
|
||||
class EmojisController < ApplicationController
|
||||
before_action :set_emoji
|
||||
before_action :set_cache_headers
|
||||
|
||||
vary_by -> { 'Signature' if authorized_fetch_mode? }
|
||||
|
||||
def show
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
expires_in 3.minutes, public: true
|
||||
render_with_cache json: @emoji, content_type: 'application/activity+json', serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ class Filters::StatusesController < ApplicationController
|
|||
before_action :set_filter
|
||||
before_action :set_status_filters
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
PER_PAGE = 20
|
||||
|
||||
|
@ -44,4 +45,8 @@ class Filters::StatusesController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ class FiltersController < ApplicationController
|
|||
before_action :authenticate_user!
|
||||
before_action :set_filter, only: [:edit, :update, :destroy]
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
def index
|
||||
@filters = current_account.custom_filters.includes(:keywords, :statuses).order(:phrase)
|
||||
|
@ -54,4 +55,8 @@ class FiltersController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,8 +5,9 @@ class FollowerAccountsController < ApplicationController
|
|||
include SignatureVerification
|
||||
include WebAppControllerConcern
|
||||
|
||||
vary_by -> { public_fetch_mode? ? 'Accept' : 'Accept, Signature' }
|
||||
|
||||
before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :set_cache_headers
|
||||
|
||||
skip_around_action :set_locale, if: -> { request.format == :json }
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
|
|
@ -5,8 +5,9 @@ class FollowingAccountsController < ApplicationController
|
|||
include SignatureVerification
|
||||
include WebAppControllerConcern
|
||||
|
||||
vary_by -> { public_fetch_mode? ? 'Accept' : 'Accept, Signature' }
|
||||
|
||||
before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :set_cache_headers
|
||||
|
||||
skip_around_action :set_locale, if: -> { request.format == :json }
|
||||
skip_before_action :require_functional!, unless: :whitelist_mode?
|
||||
|
|
|
@ -7,6 +7,7 @@ class InvitesController < ApplicationController
|
|||
|
||||
before_action :authenticate_user!
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
def index
|
||||
authorize :invite, :create?
|
||||
|
@ -49,4 +50,8 @@ class InvitesController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ManifestsController < ApplicationController
|
||||
skip_before_action :store_current_location
|
||||
skip_before_action :require_functional!
|
||||
|
||||
class ManifestsController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||
def show
|
||||
expires_in 3.minutes, public: true
|
||||
render json: InstancePresenter.new, serializer: ManifestSerializer, root: 'instance'
|
||||
|
|
|
@ -34,6 +34,6 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
|
|||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
|||
before_action :authenticate_resource_owner!
|
||||
before_action :require_not_suspended!, only: :destroy
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
skip_before_action :require_functional!
|
||||
|
||||
|
@ -30,4 +31,8 @@ class Oauth::AuthorizedApplicationsController < Doorkeeper::AuthorizedApplicatio
|
|||
def require_not_suspended!
|
||||
forbidden if current_account.suspended?
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,6 +7,7 @@ class RelationshipsController < ApplicationController
|
|||
before_action :set_accounts, only: :show
|
||||
before_action :set_relationships, only: :show
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
helper_method :following_relationship?, :followed_by_relationship?, :mutual_relationship?
|
||||
|
||||
|
@ -70,4 +71,8 @@ class RelationshipsController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,7 +14,7 @@ class Settings::BaseController < ApplicationController
|
|||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.headers['Cache-Control'] = 'private, no-store'
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
|
||||
def require_not_suspended!
|
||||
|
|
|
@ -6,6 +6,7 @@ class StatusesCleanupController < ApplicationController
|
|||
before_action :authenticate_user!
|
||||
before_action :set_policy
|
||||
before_action :set_body_classes
|
||||
before_action :set_cache_headers
|
||||
|
||||
def show; end
|
||||
|
||||
|
@ -36,4 +37,8 @@ class StatusesCleanupController < ApplicationController
|
|||
def set_body_classes
|
||||
@body_classes = 'admin'
|
||||
end
|
||||
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,11 +6,12 @@ class StatusesController < ApplicationController
|
|||
include Authorization
|
||||
include AccountOwnedConcern
|
||||
|
||||
vary_by -> { public_fetch_mode? ? 'Accept' : 'Accept, Signature' }
|
||||
|
||||
before_action :require_account_signature!, only: [:show, :activity], if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :set_status
|
||||
before_action :set_instance_presenter
|
||||
before_action :redirect_to_original, only: :show
|
||||
before_action :set_cache_headers
|
||||
before_action :set_body_classes, only: :embed
|
||||
|
||||
after_action :set_link_headers
|
||||
|
|
|
@ -7,6 +7,8 @@ class TagsController < ApplicationController
|
|||
PAGE_SIZE = 20
|
||||
PAGE_SIZE_MAX = 200
|
||||
|
||||
vary_by -> { public_fetch_mode? ? 'Accept' : 'Accept, Signature' }
|
||||
|
||||
before_action :require_account_signature!, if: -> { request.format == :json && authorized_fetch_mode? }
|
||||
before_action :authenticate_user!, if: :whitelist_mode?
|
||||
before_action :set_local
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module WellKnown
|
||||
class HostMetaController < ActionController::Base
|
||||
class HostMetaController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||
include RoutingHelper
|
||||
|
||||
before_action { response.headers['Vary'] = 'Accept' }
|
||||
|
||||
def show
|
||||
@webfinger_template = "#{webfinger_url}?resource={uri}"
|
||||
expires_in 3.days, public: true
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module WellKnown
|
||||
class NodeInfoController < ActionController::Base
|
||||
class NodeInfoController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||
include CacheConcern
|
||||
|
||||
before_action { response.headers['Vary'] = 'Accept' }
|
||||
|
||||
def index
|
||||
expires_in 3.days, public: true
|
||||
render_with_cache json: {}, serializer: NodeInfo::DiscoverySerializer, adapter: NodeInfo::Adapter, expires_in: 3.days, root: 'nodeinfo'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module WellKnown
|
||||
class WebfingerController < ActionController::Base
|
||||
class WebfingerController < ActionController::Base # rubocop:disable Rails/ApplicationController
|
||||
include RoutingHelper
|
||||
|
||||
before_action :set_account
|
||||
|
@ -34,7 +34,12 @@ module WellKnown
|
|||
end
|
||||
|
||||
def check_account_suspension
|
||||
expires_in(3.minutes, public: true) && gone if @account.suspended_permanently?
|
||||
gone if @account.suspended_permanently?
|
||||
end
|
||||
|
||||
def gone
|
||||
expires_in(3.minutes, public: true)
|
||||
head 410
|
||||
end
|
||||
|
||||
def bad_request
|
||||
|
@ -46,9 +51,5 @@ module WellKnown
|
|||
expires_in(3.minutes, public: true)
|
||||
head 404
|
||||
end
|
||||
|
||||
def gone
|
||||
head 410
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -32,17 +32,14 @@ function ShortNumber({ value, renderer, children }) {
|
|||
const shortNumber = toShortNumber(value);
|
||||
const [, division] = shortNumber;
|
||||
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (children != null && renderer != null) {
|
||||
console.warn('Both renderer prop and renderer as a child provided. This is a mistake and you really should fix that. Only renderer passed as a child will be used.');
|
||||
}
|
||||
|
||||
// eslint-disable-next-line eqeqeq
|
||||
const customRenderer = children != null ? children : renderer;
|
||||
|
||||
const displayNumber = <ShortNumberCounter value={shortNumber} />;
|
||||
|
||||
// eslint-disable-next-line eqeqeq
|
||||
return customRenderer != null
|
||||
? customRenderer(displayNumber, pluralReady(value, division))
|
||||
: displayNumber;
|
||||
|
|
|
@ -60,7 +60,6 @@ export function toShortNumber(sourceNumber) {
|
|||
* // => 1790
|
||||
*/
|
||||
export function pluralReady(sourceNumber, division) {
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (division == null || division < DECIMAL_UNITS.HUNDRED) {
|
||||
return sourceNumber;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#
|
||||
|
||||
class PreviewCardProvider < ApplicationRecord
|
||||
include Paginable
|
||||
include DomainNormalizable
|
||||
include Attachmentable
|
||||
|
||||
|
|
9
app/serializers/rest/admin/trends/link_serializer.rb
Normal file
9
app/serializers/rest/admin/trends/link_serializer.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class REST::Admin::Trends::LinkSerializer < REST::Trends::LinkSerializer
|
||||
attributes :id, :requires_review
|
||||
|
||||
def requires_review
|
||||
object.requires_review?
|
||||
end
|
||||
end
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class REST::Admin::Trends::Links::PreviewCardProviderSerializer < ActiveModel::Serializer
|
||||
attributes :id, :domain, :trendable, :reviewed_at,
|
||||
:requested_review_at, :requires_review
|
||||
|
||||
def requires_review
|
||||
object.requires_review?
|
||||
end
|
||||
end
|
9
app/serializers/rest/admin/trends/status_serializer.rb
Normal file
9
app/serializers/rest/admin/trends/status_serializer.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class REST::Admin::Trends::StatusSerializer < REST::StatusSerializer
|
||||
attributes :requires_review
|
||||
|
||||
def requires_review
|
||||
object.requires_review?
|
||||
end
|
||||
end
|
|
@ -43,6 +43,7 @@ require_relative '../lib/chewy/strategy/bypass_with_warning'
|
|||
require_relative '../lib/webpacker/manifest_extensions'
|
||||
require_relative '../lib/webpacker/helper_extensions'
|
||||
require_relative '../lib/rails/engine_extensions'
|
||||
require_relative '../lib/action_controller/conditional_get_extensions'
|
||||
require_relative '../lib/active_record/database_tasks_extensions'
|
||||
require_relative '../lib/active_record/batches'
|
||||
require_relative '../lib/simple_navigation/item_extensions'
|
||||
|
|
|
@ -676,9 +676,33 @@ Rails.application.routes.draw do
|
|||
resources :ip_blocks, only: [:index, :show, :update, :create, :destroy]
|
||||
|
||||
namespace :trends do
|
||||
resources :tags, only: [:index]
|
||||
resources :links, only: [:index]
|
||||
resources :statuses, only: [:index]
|
||||
resources :tags, only: [:index] do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
resources :links, only: [:index] do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
resources :statuses, only: [:index] do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
|
||||
namespace :links do
|
||||
resources :preview_card_providers, only: [:index], path: :publishers do
|
||||
member do
|
||||
post :approve
|
||||
post :reject
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
post :measures, to: 'measures#create'
|
||||
|
|
15
lib/action_controller/conditional_get_extensions.rb
Normal file
15
lib/action_controller/conditional_get_extensions.rb
Normal file
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ActionController
|
||||
module ConditionalGetExtensions
|
||||
def expires_in(*)
|
||||
# This backports a fix from Rails 7 so that a more private Cache-Control
|
||||
# can be overriden by calling expires_in on a specific controller action
|
||||
response.cache_control.delete(:no_store)
|
||||
|
||||
super
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ActionController::ConditionalGet.prepend(ActionController::ConditionalGetExtensions)
|
|
@ -189,9 +189,10 @@ module Mastodon
|
|||
user.disabled = true if options[:disable]
|
||||
user.approved = true if options[:approve]
|
||||
user.otp_required_for_login = false if options[:disable_2fa]
|
||||
user.confirm if options[:confirm]
|
||||
|
||||
if user.save
|
||||
user.confirm if options[:confirm]
|
||||
|
||||
say('OK', :green)
|
||||
say("New password: #{password}") if options[:reset_password]
|
||||
else
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
"fuzzysort": "^2.0.4",
|
||||
"glob": "^10.0.0",
|
||||
"history": "^4.10.1",
|
||||
"http-link-header": "^1.1.0",
|
||||
"http-link-header": "^1.1.1",
|
||||
"immutable": "^4.3.0",
|
||||
"imports-loader": "^1.2.0",
|
||||
"intl": "^1.2.5",
|
||||
|
@ -83,7 +83,7 @@
|
|||
"path-complete-extname": "^1.0.0",
|
||||
"pg": "^8.5.0",
|
||||
"pg-connection-string": "^2.5.0",
|
||||
"postcss": "^8.4.21",
|
||||
"postcss": "^8.4.22",
|
||||
"postcss-loader": "^4.3.0",
|
||||
"promise.prototype.finally": "^3.1.4",
|
||||
"prop-types": "^15.8.1",
|
||||
|
@ -113,7 +113,7 @@
|
|||
"redux-thunk": "^2.4.2",
|
||||
"regenerator-runtime": "^0.13.11",
|
||||
"requestidlecallback": "^0.3.0",
|
||||
"reselect": "^4.1.7",
|
||||
"reselect": "^4.1.8",
|
||||
"rimraf": "^5.0.0",
|
||||
"sass": "^1.61.0",
|
||||
"sass-loader": "^10.2.0",
|
||||
|
|
|
@ -17,6 +17,10 @@ RSpec.describe AccountsController, type: :controller do
|
|||
expect(session).to be_empty
|
||||
end
|
||||
|
||||
it 'returns Vary header' do
|
||||
expect(response.headers['Vary']).to include 'Accept'
|
||||
end
|
||||
|
||||
it 'returns public Cache-Control header' do
|
||||
expect(response.headers['Cache-Control']).to include 'public'
|
||||
end
|
||||
|
|
|
@ -18,6 +18,14 @@ describe Admin::BaseController, type: :controller do
|
|||
expect(response).to have_http_status(403)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
routes.draw { get 'success' => 'admin/base#success' }
|
||||
sign_in(Fabricate(:user, role: UserRole.find_by(name: 'Moderator')))
|
||||
get :success
|
||||
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
|
||||
it 'renders admin layout as a moderator' do
|
||||
routes.draw { get 'success' => 'admin/base#success' }
|
||||
sign_in(Fabricate(:user, role: UserRole.find_by(name: 'Moderator')))
|
||||
|
|
|
@ -15,6 +15,12 @@ describe Api::BaseController do
|
|||
end
|
||||
end
|
||||
|
||||
it 'returns private cache control headers by default' do
|
||||
routes.draw { get 'success' => 'api/base#success' }
|
||||
get :success
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
|
||||
describe 'forgery protection' do
|
||||
before do
|
||||
routes.draw { post 'success' => 'api/base#success' }
|
||||
|
|
|
@ -17,5 +17,9 @@ RSpec.describe Api::OEmbedController, type: :controller do
|
|||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Admin::Trends::Links::PreviewCardProvidersController do
|
||||
render_views
|
||||
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:preview_card_provider) { Fabricate(:preview_card_provider) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong scope' do |wrong_scope|
|
||||
let(:scopes) { wrong_scope }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong role' do |wrong_role|
|
||||
let(:role) { UserRole.find_by(name: wrong_role) }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #approve' do
|
||||
before do
|
||||
post :approve, params: { id: preview_card_provider.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #reject' do
|
||||
before do
|
||||
post :reject, params: { id: preview_card_provider.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,14 +5,33 @@ require 'rails_helper'
|
|||
describe Api::V1::Admin::Trends::LinksController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') }
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:preview_card) { Fabricate(:preview_card) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong scope' do |wrong_scope|
|
||||
let(:scopes) { wrong_scope }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong role' do |wrong_role|
|
||||
let(:role) { UserRole.find_by(name: wrong_role) }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
@ -20,4 +39,30 @@ describe Api::V1::Admin::Trends::LinksController do
|
|||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #approve' do
|
||||
before do
|
||||
post :approve, params: { id: preview_card.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #reject' do
|
||||
before do
|
||||
post :reject, params: { id: preview_card.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,14 +5,33 @@ require 'rails_helper'
|
|||
describe Api::V1::Admin::Trends::StatusesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') }
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:status) { Fabricate(:status) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong scope' do |wrong_scope|
|
||||
let(:scopes) { wrong_scope }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong role' do |wrong_role|
|
||||
let(:role) { UserRole.find_by(name: wrong_role) }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
@ -20,4 +39,30 @@ describe Api::V1::Admin::Trends::StatusesController do
|
|||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #approve' do
|
||||
before do
|
||||
post :approve, params: { id: status.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #reject' do
|
||||
before do
|
||||
post :reject, params: { id: status.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,14 +5,33 @@ require 'rails_helper'
|
|||
describe Api::V1::Admin::Trends::TagsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'admin:read') }
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong scope' do |wrong_scope|
|
||||
let(:scopes) { wrong_scope }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'forbidden for wrong role' do |wrong_role|
|
||||
let(:role) { UserRole.find_by(name: wrong_role) }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
@ -20,4 +39,30 @@ describe Api::V1::Admin::Trends::TagsController do
|
|||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #approve' do
|
||||
before do
|
||||
post :approve, params: { id: tag.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #reject' do
|
||||
before do
|
||||
post :reject, params: { id: tag.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -33,27 +33,42 @@ RSpec.describe Auth::RegistrationsController, type: :controller do
|
|||
end
|
||||
|
||||
describe 'GET #edit' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
sign_in(Fabricate(:user))
|
||||
get :edit
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control header' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #update' do
|
||||
it 'returns http success' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
sign_in(Fabricate(:user), scope: :user)
|
||||
sign_in(user, scope: :user)
|
||||
post :update
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
|
||||
context 'when suspended' do
|
||||
let(:user) { Fabricate(:user, account_attributes: { username: 'test', suspended_at: Time.now.utc }) }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
request.env['devise.mapping'] = Devise.mappings[:user]
|
||||
sign_in(Fabricate(:user, account_attributes: { username: 'test', suspended_at: Time.now.utc }), scope: :user)
|
||||
post :update
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,9 +6,25 @@ describe CustomCssController do
|
|||
render_views
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns public cache control header' do
|
||||
expect(response.headers['Cache-Control']).to include('public')
|
||||
end
|
||||
|
||||
it 'does not set cookies' do
|
||||
expect(response.cookies).to be_empty
|
||||
expect(response.headers['Set-Cookies']).to be_nil
|
||||
end
|
||||
|
||||
it 'does not set sessions' do
|
||||
expect(session).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,21 +18,27 @@ describe Filters::StatusesController do
|
|||
|
||||
context 'with a signed in user' do
|
||||
context 'with the filter user signed in' do
|
||||
before { sign_in(filter.account.user) }
|
||||
before do
|
||||
sign_in(filter.account.user)
|
||||
get :index, params: { filter_id: filter }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index, params: { filter_id: filter }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with another user signed in' do
|
||||
before { sign_in(Fabricate(:user)) }
|
||||
before do
|
||||
sign_in(Fabricate(:user))
|
||||
get :index, params: { filter_id: filter }
|
||||
end
|
||||
|
||||
it 'returns http not found' do
|
||||
get :index, params: { filter_id: filter }
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,21 +7,28 @@ describe FiltersController do
|
|||
|
||||
describe 'GET #index' do
|
||||
context 'with signed out user' do
|
||||
it 'redirects' do
|
||||
before do
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'redirects' do
|
||||
expect(response).to be_redirect
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a signed in user' do
|
||||
before { sign_in(Fabricate(:user)) }
|
||||
before do
|
||||
sign_in(Fabricate(:user))
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,35 +5,40 @@ require 'rails_helper'
|
|||
describe InvitesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
sign_in user
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
subject { get :index }
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let!(:invite) { Fabricate(:invite, user: user) }
|
||||
before do
|
||||
Fabricate(:invite, user: user)
|
||||
end
|
||||
|
||||
context 'when everyone can invite' do
|
||||
before do
|
||||
UserRole.everyone.update(permissions: UserRole.everyone.permissions | UserRole::FLAGS[:invite_users])
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'renders index page' do
|
||||
expect(subject).to render_template :index
|
||||
expect(assigns(:invites)).to include invite
|
||||
expect(assigns(:invites).count).to eq 1
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not everyone can invite' do
|
||||
before do
|
||||
UserRole.everyone.update(permissions: UserRole.everyone.permissions & ~UserRole::FLAGS[:invite_users])
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns 403' do
|
||||
expect(subject).to have_http_status 403
|
||||
it 'returns http forbidden' do
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -42,8 +47,6 @@ describe InvitesController do
|
|||
subject { post :create, params: { invite: { max_uses: '10', expires_in: 1800 } } }
|
||||
|
||||
context 'when everyone can invite' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
UserRole.everyone.update(permissions: UserRole.everyone.permissions | UserRole::FLAGS[:invite_users])
|
||||
end
|
||||
|
@ -56,26 +59,28 @@ describe InvitesController do
|
|||
end
|
||||
|
||||
context 'when not everyone can invite' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
before do
|
||||
UserRole.everyone.update(permissions: UserRole.everyone.permissions & ~UserRole::FLAGS[:invite_users])
|
||||
end
|
||||
|
||||
it 'returns 403' do
|
||||
expect(subject).to have_http_status 403
|
||||
it 'returns http forbidden' do
|
||||
expect(subject).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #create' do
|
||||
subject { delete :destroy, params: { id: invite.id } }
|
||||
let(:invite) { Fabricate(:invite, user: user, expires_at: nil) }
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let!(:invite) { Fabricate(:invite, user: user, expires_at: nil) }
|
||||
before do
|
||||
delete :destroy, params: { id: invite.id }
|
||||
end
|
||||
|
||||
it 'redirects' do
|
||||
expect(response).to redirect_to invites_path
|
||||
end
|
||||
|
||||
it 'expires invite' do
|
||||
expect(subject).to redirect_to invites_path
|
||||
expect(invite.reload).to be_expired
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,11 +7,24 @@ describe ManifestsController do
|
|||
|
||||
describe 'GET #show' do
|
||||
before do
|
||||
get :show, format: :json
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns public cache control header' do
|
||||
expect(response.headers['Cache-Control']).to include('public')
|
||||
end
|
||||
|
||||
it 'does not set cookies' do
|
||||
expect(response.cookies).to be_empty
|
||||
expect(response.headers['Set-Cookies']).to be_nil
|
||||
end
|
||||
|
||||
it 'does not set sessions' do
|
||||
expect(session).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,6 +31,11 @@ RSpec.describe Oauth::AuthorizationsController, type: :controller do
|
|||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
subject
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
|
||||
it 'gives options to authorize and deny' do
|
||||
subject
|
||||
expect(response.body).to match(/Authorize/)
|
||||
|
|
|
@ -27,6 +27,11 @@ describe Oauth::AuthorizedApplicationsController do
|
|||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
subject
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
|
||||
include_examples 'stores location for user'
|
||||
end
|
||||
|
||||
|
|
|
@ -7,42 +7,39 @@ describe RelationshipsController do
|
|||
|
||||
let(:user) { Fabricate(:user) }
|
||||
|
||||
shared_examples 'authenticate user' do
|
||||
it 'redirects when not signed in' do
|
||||
expect(subject).to redirect_to '/auth/sign_in'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
subject { get :show, params: { page: 2, relationship: 'followed_by' } }
|
||||
|
||||
it 'assigns @accounts' do
|
||||
Fabricate(:account, domain: 'old').follow!(user.account)
|
||||
Fabricate(:account, domain: 'recent').follow!(user.account)
|
||||
|
||||
context 'when signed in' do
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
subject
|
||||
|
||||
assigned = assigns(:accounts).per(1).to_a
|
||||
expect(assigned.size).to eq 1
|
||||
expect(assigned[0].domain).to eq 'old'
|
||||
get :show, params: { page: 2, relationship: 'followed_by' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
sign_in user, scope: :user
|
||||
subject
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
include_examples 'authenticate user'
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not signed in' do
|
||||
before do
|
||||
get :show, params: { page: 2, relationship: 'followed_by' }
|
||||
end
|
||||
|
||||
it 'redirects when not signed in' do
|
||||
expect(response).to redirect_to '/auth/sign_in'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #update' do
|
||||
let(:poopfeast) { Fabricate(:account, username: 'poopfeast', domain: 'example.com') }
|
||||
let(:alice) { Fabricate(:account, username: 'alice', domain: 'example.com') }
|
||||
|
||||
shared_examples 'redirects back to followers page' do
|
||||
it 'redirects back to followers page' do
|
||||
poopfeast.follow!(user.account)
|
||||
alice.follow!(user.account)
|
||||
|
||||
sign_in user, scope: :user
|
||||
subject
|
||||
|
@ -58,27 +55,36 @@ describe RelationshipsController do
|
|||
end
|
||||
|
||||
context 'when select parameter is provided' do
|
||||
subject { patch :update, params: { form_account_batch: { account_ids: [poopfeast.id] }, remove_domains_from_followers: '' } }
|
||||
subject { patch :update, params: { form_account_batch: { account_ids: [alice.id] }, remove_domains_from_followers: '' } }
|
||||
|
||||
it 'soft-blocks followers from selected domains' do
|
||||
poopfeast.follow!(user.account)
|
||||
alice.follow!(user.account)
|
||||
|
||||
sign_in user, scope: :user
|
||||
subject
|
||||
|
||||
expect(poopfeast.following?(user.account)).to be false
|
||||
expect(alice.following?(user.account)).to be false
|
||||
end
|
||||
|
||||
it 'does not unfollow users from selected domains' do
|
||||
user.account.follow!(poopfeast)
|
||||
user.account.follow!(alice)
|
||||
|
||||
sign_in user, scope: :user
|
||||
subject
|
||||
|
||||
expect(user.account.following?(poopfeast)).to be true
|
||||
expect(user.account.following?(alice)).to be true
|
||||
end
|
||||
|
||||
context 'when not signed in' do
|
||||
before do
|
||||
subject
|
||||
end
|
||||
|
||||
it 'redirects when not signed in' do
|
||||
expect(response).to redirect_to '/auth/sign_in'
|
||||
end
|
||||
end
|
||||
|
||||
include_examples 'authenticate user'
|
||||
include_examples 'redirects back to followers page'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,10 +13,17 @@ describe Settings::AliasesController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
|
|
|
@ -13,13 +13,17 @@ describe Settings::ApplicationsController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
let!(:other_app) { Fabricate(:application) }
|
||||
|
||||
it 'shows apps' do
|
||||
before do
|
||||
Fabricate(:application)
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
expect(assigns(:applications)).to include(app)
|
||||
expect(assigns(:applications)).to_not include(other_app)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -11,20 +11,27 @@ describe Settings::DeletesController do
|
|||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'renders confirmation page' do
|
||||
get :show
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
|
||||
context 'when suspended' do
|
||||
let(:user) { Fabricate(:user, account_attributes: { suspended_at: Time.now.utc }) }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
get :show
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -11,16 +11,16 @@ describe Settings::ExportsController do
|
|||
|
||||
before do
|
||||
sign_in user, scope: :user
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'renders export' do
|
||||
get :show
|
||||
|
||||
export = assigns(:export)
|
||||
expect(export).to be_instance_of Export
|
||||
expect(export.account).to eq user.account
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when not signed in' do
|
||||
|
|
|
@ -10,10 +10,17 @@ RSpec.describe Settings::ImportsController, type: :controller do
|
|||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
|
|
|
@ -12,9 +12,16 @@ describe Settings::LoginActivitiesController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,10 +12,17 @@ describe Settings::Migration::RedirectsController do
|
|||
end
|
||||
|
||||
describe 'GET #new' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :new
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
|
|
|
@ -12,11 +12,17 @@ describe Settings::Preferences::AppearanceController do
|
|||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
|
|
|
@ -12,10 +12,17 @@ describe Settings::Preferences::NotificationsController do
|
|||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
|
|
|
@ -12,10 +12,17 @@ describe Settings::Preferences::OtherController do
|
|||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
|
|
|
@ -13,10 +13,17 @@ RSpec.describe Settings::ProfilesController, type: :controller do
|
|||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
|
|
|
@ -26,23 +26,25 @@ describe Settings::TwoFactorAuthenticationMethodsController do
|
|||
describe 'when user has enabled otp' do
|
||||
before do
|
||||
user.update(otp_required_for_login: true)
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'when user has not enabled otp' do
|
||||
before do
|
||||
user.update(otp_required_for_login: false)
|
||||
get :index
|
||||
end
|
||||
|
||||
it 'redirects to enable otp' do
|
||||
get :index
|
||||
|
||||
expect(response).to redirect_to(settings_otp_authentication_path)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,19 +11,32 @@ RSpec.describe StatusesCleanupController, type: :controller do
|
|||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
it 'returns http success' do
|
||||
before do
|
||||
get :show
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #update' do
|
||||
it 'updates the account status cleanup policy' do
|
||||
before do
|
||||
put :update, params: { account_statuses_cleanup_policy: { enabled: true, min_status_age: 2.weeks.seconds, keep_direct: false, keep_polls: true } }
|
||||
expect(response).to redirect_to(statuses_cleanup_path)
|
||||
end
|
||||
|
||||
it 'updates the account status cleanup policy' do
|
||||
expect(@user.account.statuses_cleanup_policy.enabled).to be true
|
||||
expect(@user.account.statuses_cleanup_policy.keep_direct).to be false
|
||||
expect(@user.account.statuses_cleanup_policy.keep_polls).to be true
|
||||
end
|
||||
|
||||
it 'redirects' do
|
||||
expect(response).to redirect_to(statuses_cleanup_path)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,10 @@ describe StatusesController do
|
|||
expect(session).to be_empty
|
||||
end
|
||||
|
||||
it 'returns Vary header' do
|
||||
expect(response.headers['Vary']).to include 'Accept'
|
||||
end
|
||||
|
||||
it 'returns public Cache-Control header' do
|
||||
expect(response.headers['Cache-Control']).to include 'public'
|
||||
end
|
||||
|
|
|
@ -6,21 +6,50 @@ RSpec.describe TagsController, type: :controller do
|
|||
render_views
|
||||
|
||||
describe 'GET #show' do
|
||||
let!(:tag) { Fabricate(:tag, name: 'test') }
|
||||
let!(:local) { Fabricate(:status, tags: [tag], text: 'local #test') }
|
||||
let!(:remote) { Fabricate(:status, tags: [tag], text: 'remote #test', account: Fabricate(:account, domain: 'remote')) }
|
||||
let!(:late) { Fabricate(:status, tags: [tag], text: 'late #test') }
|
||||
let(:format) { 'html' }
|
||||
let(:tag) { Fabricate(:tag, name: 'test') }
|
||||
let(:tag_name) { tag&.name }
|
||||
|
||||
before do
|
||||
get :show, params: { id: tag_name, format: format }
|
||||
end
|
||||
|
||||
context 'when tag exists' do
|
||||
context 'when requested as HTML' do
|
||||
it 'returns http success' do
|
||||
get :show, params: { id: 'test', max_id: late.id }
|
||||
expect(response).to have_http_status(200)
|
||||
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
|
||||
end
|
||||
|
||||
context 'when requested as JSON' do
|
||||
let(:format) { 'json' }
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
context 'when tag does not exist' do
|
||||
let(:tag_name) { 'hoge' }
|
||||
|
||||
it 'returns http not found' do
|
||||
get :show, params: { id: 'none' }
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
|
34
yarn.lock
34
yarn.lock
|
@ -6032,10 +6032,10 @@ http-errors@~1.6.2:
|
|||
setprototypeof "1.1.0"
|
||||
statuses ">= 1.4.0 < 2"
|
||||
|
||||
http-link-header@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.1.0.tgz#a1ca87efdbcb7778d8d0d4525de1e6964ec1f129"
|
||||
integrity sha512-pj6N1yxOz/ANO8HHsWGg/OoIL1kmRYvQnXQ7PIRpgp+15AnEsRH8fmIJE6D1OdWG2Bov+BJHVla1fFXxg1JbbA==
|
||||
http-link-header@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/http-link-header/-/http-link-header-1.1.1.tgz#f0e6971b0ed86e858d2077066ecb7ba4f2e50de9"
|
||||
integrity sha512-mW3N/rTYpCn99s1do0zx6nzFZSwLH9HGfUM4ZqLWJ16ylmYaC2v5eYGqrNTQlByx8AzUgGI+V/32gXPugs1+Sw==
|
||||
|
||||
http-parser-js@>=0.5.1:
|
||||
version "0.5.3"
|
||||
|
@ -8005,10 +8005,10 @@ nan@^2.12.1:
|
|||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
|
||||
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
|
||||
|
||||
nanoid@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
|
||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||
nanoid@^3.3.6:
|
||||
version "3.3.6"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
|
||||
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
|
||||
|
||||
nanomatch@^1.2.9:
|
||||
version "1.2.13"
|
||||
|
@ -9007,12 +9007,12 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0:
|
|||
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
|
||||
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
|
||||
|
||||
postcss@^8.2.15, postcss@^8.4.21:
|
||||
version "8.4.21"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4"
|
||||
integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==
|
||||
postcss@^8.2.15, postcss@^8.4.21, postcss@^8.4.22:
|
||||
version "8.4.22"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.22.tgz#c29e6776b60ab3af602d4b513d5bd2ff9aa85dc1"
|
||||
integrity sha512-XseknLAfRHzVWjCEtdviapiBtfLdgyzExD50Rg2ePaucEesyh8Wv4VPdW0nbyDa1ydbrAxV19jvMT4+LFmcNUA==
|
||||
dependencies:
|
||||
nanoid "^3.3.4"
|
||||
nanoid "^3.3.6"
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
|
@ -9789,10 +9789,10 @@ requires-port@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=
|
||||
|
||||
reselect@^4.1.7:
|
||||
version "4.1.7"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.7.tgz#56480d9ff3d3188970ee2b76527bd94a95567a42"
|
||||
integrity sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==
|
||||
reselect@^4.1.8:
|
||||
version "4.1.8"
|
||||
resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524"
|
||||
integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==
|
||||
|
||||
resolve-cwd@^2.0.0:
|
||||
version "2.0.0"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue