diff --git a/Gemfile b/Gemfile index 4cce095ec595bc..bcb19421ab9afe 100644 --- a/Gemfile +++ b/Gemfile @@ -47,7 +47,6 @@ gem 'color_diff', '~> 0.1' gem 'csv', '~> 3.2' gem 'discard', '~> 1.2' gem 'doorkeeper', '~> 5.6' -gem 'ed25519', '~> 1.3' gem 'fast_blank', '~> 1.0' gem 'fastimage' gem 'hiredis', '~> 0.6' diff --git a/Gemfile.lock b/Gemfile.lock index 4a139155f5bb14..79e542014c1ef2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -100,8 +100,8 @@ GEM attr_required (1.0.2) awrence (1.2.1) aws-eventstream (1.3.0) - aws-partitions (1.974.0) - aws-sdk-core (3.205.0) + aws-partitions (1.977.0) + aws-sdk-core (3.206.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.9) @@ -109,11 +109,11 @@ GEM aws-sdk-kms (1.91.0) aws-sdk-core (~> 3, >= 3.205.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.162.0) + aws-sdk-s3 (1.163.0) aws-sdk-core (~> 3, >= 3.205.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) - aws-sigv4 (1.9.1) + aws-sigv4 (1.10.0) aws-eventstream (~> 1, >= 1.0.2) azure-storage-blob (2.0.3) azure-storage-common (~> 2.0) @@ -197,7 +197,7 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-two-factor (5.1.0) + devise-two-factor (6.0.0) activesupport (~> 7.0) devise (~> 4.0) railties (~> 7.0) @@ -212,9 +212,8 @@ GEM domain_name (0.6.20240107) doorkeeper (5.7.1) railties (>= 5) - dotenv (3.1.2) + dotenv (3.1.4) drb (2.2.1) - ed25519 (1.3.0) elasticsearch (7.17.11) elasticsearch-api (= 7.17.11) elasticsearch-transport (= 7.17.11) @@ -429,7 +428,7 @@ GEM addressable (~> 2.5) azure-storage-blob (~> 2.0.1) hashie (~> 5.0) - memory_profiler (1.0.2) + memory_profiler (1.1.0) mime-types (3.5.2) mime-types-data (~> 3.2015) mime-types-data (3.2024.0820) @@ -610,7 +609,7 @@ GEM psych (5.1.2) stringio public_suffix (6.0.1) - puma (6.4.2) + puma (6.4.3) nio4r (~> 2.0) pundit (2.4.0) activesupport (>= 3.0.0) @@ -937,7 +936,6 @@ DEPENDENCIES discard (~> 1.2) doorkeeper (~> 5.6) dotenv - ed25519 (~> 1.3) email_spec fabrication (~> 2.30) faker (~> 3.2) diff --git a/app/controllers/activitypub/claims_controller.rb b/app/controllers/activitypub/claims_controller.rb deleted file mode 100644 index 480baaf2bcce0f..00000000000000 --- a/app/controllers/activitypub/claims_controller.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -class ActivityPub::ClaimsController < ActivityPub::BaseController - skip_before_action :authenticate_user! - - before_action :require_account_signature! - before_action :set_claim_result - - def create - render json: @claim_result, serializer: ActivityPub::OneTimeKeySerializer - end - - private - - def set_claim_result - @claim_result = ::Keys::ClaimService.new.call(@account.id, params[:id]) - end -end diff --git a/app/controllers/activitypub/collections_controller.rb b/app/controllers/activitypub/collections_controller.rb index 15985c7f65e65c..e9779260f32fba 100644 --- a/app/controllers/activitypub/collections_controller.rb +++ b/app/controllers/activitypub/collections_controller.rb @@ -22,8 +22,6 @@ def set_items @items = @items.map { |item| item.distributable? ? item : ActivityPub::TagManager.instance.uri_for(item) } when 'tags' @items = for_signed_account { @account.featured_tags } - when 'devices' - @items = @account.devices else not_found end @@ -31,7 +29,7 @@ def set_items def set_size case params[:id] - when 'featured', 'devices', 'tags' + when 'featured', 'tags' @size = @items.size else not_found @@ -42,7 +40,7 @@ def set_type case params[:id] when 'featured' @type = :ordered - when 'devices', 'tags' + when 'tags' @type = :unordered else not_found diff --git a/app/controllers/api/oembed_controller.rb b/app/controllers/api/oembed_controller.rb index 66da65bedaf741..b7f22824a7afbf 100644 --- a/app/controllers/api/oembed_controller.rb +++ b/app/controllers/api/oembed_controller.rb @@ -7,7 +7,7 @@ class Api::OEmbedController < Api::BaseController before_action :require_public_status! def show - render json: @status, serializer: OEmbedSerializer, width: maxwidth_or_default, height: maxheight_or_default + render json: @status, serializer: OEmbedSerializer, width: params[:maxwidth], height: params[:maxheight] end private @@ -23,12 +23,4 @@ def require_public_status! def status_finder StatusFinder.new(params[:url]) end - - def maxwidth_or_default - (params[:maxwidth].presence || 400).to_i - end - - def maxheight_or_default - params[:maxheight].present? ? params[:maxheight].to_i : nil - end end diff --git a/app/controllers/api/v1/crypto/deliveries_controller.rb b/app/controllers/api/v1/crypto/deliveries_controller.rb deleted file mode 100644 index aa9df6e03b20f2..00000000000000 --- a/app/controllers/api/v1/crypto/deliveries_controller.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::Crypto::DeliveriesController < Api::BaseController - before_action -> { doorkeeper_authorize! :crypto } - before_action :require_user! - before_action :set_current_device - - def create - devices.each do |device_params| - DeliverToDeviceService.new.call(current_account, @current_device, device_params) - end - - render_empty - end - - private - - def set_current_device - @current_device = Device.find_by!(access_token: doorkeeper_token) - end - - def resource_params - params.require(:device) - params.permit(device: [:account_id, :device_id, :type, :body, :hmac]) - end - - def devices - Array(resource_params[:device]) - end -end diff --git a/app/controllers/api/v1/crypto/encrypted_messages_controller.rb b/app/controllers/api/v1/crypto/encrypted_messages_controller.rb deleted file mode 100644 index 93ae0e777139c3..00000000000000 --- a/app/controllers/api/v1/crypto/encrypted_messages_controller.rb +++ /dev/null @@ -1,47 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::Crypto::EncryptedMessagesController < Api::BaseController - LIMIT = 80 - - before_action -> { doorkeeper_authorize! :crypto } - before_action :require_user! - before_action :set_current_device - - before_action :set_encrypted_messages, only: :index - after_action :insert_pagination_headers, only: :index - - def index - render json: @encrypted_messages, each_serializer: REST::EncryptedMessageSerializer - end - - def clear - @current_device.encrypted_messages.up_to(params[:up_to_id]).delete_all - render_empty - end - - private - - def set_current_device - @current_device = Device.find_by!(access_token: doorkeeper_token) - end - - def set_encrypted_messages - @encrypted_messages = @current_device.encrypted_messages.to_a_paginated_by_id(limit_param(LIMIT), params_slice(:max_id, :since_id, :min_id)) - end - - def next_path - api_v1_crypto_encrypted_messages_url pagination_params(max_id: pagination_max_id) if records_continue? - end - - def prev_path - api_v1_crypto_encrypted_messages_url pagination_params(min_id: pagination_since_id) unless @encrypted_messages.empty? - end - - def pagination_collection - @encrypted_messages - end - - def records_continue? - @encrypted_messages.size == limit_param(LIMIT) - end -end diff --git a/app/controllers/api/v1/crypto/keys/claims_controller.rb b/app/controllers/api/v1/crypto/keys/claims_controller.rb deleted file mode 100644 index f9d202d67b8ed8..00000000000000 --- a/app/controllers/api/v1/crypto/keys/claims_controller.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::Crypto::Keys::ClaimsController < Api::BaseController - before_action -> { doorkeeper_authorize! :crypto } - before_action :require_user! - before_action :set_claim_results - - def create - render json: @claim_results, each_serializer: REST::Keys::ClaimResultSerializer - end - - private - - def set_claim_results - @claim_results = devices.filter_map { |device_params| ::Keys::ClaimService.new.call(current_account, device_params[:account_id], device_params[:device_id]) } - end - - def resource_params - params.permit(device: [:account_id, :device_id]) - end - - def devices - Array(resource_params[:device]) - end -end diff --git a/app/controllers/api/v1/crypto/keys/counts_controller.rb b/app/controllers/api/v1/crypto/keys/counts_controller.rb deleted file mode 100644 index ffd7151b78291e..00000000000000 --- a/app/controllers/api/v1/crypto/keys/counts_controller.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::Crypto::Keys::CountsController < Api::BaseController - before_action -> { doorkeeper_authorize! :crypto } - before_action :require_user! - before_action :set_current_device - - def show - render json: { one_time_keys: @current_device.one_time_keys.count } - end - - private - - def set_current_device - @current_device = Device.find_by!(access_token: doorkeeper_token) - end -end diff --git a/app/controllers/api/v1/crypto/keys/queries_controller.rb b/app/controllers/api/v1/crypto/keys/queries_controller.rb deleted file mode 100644 index e6ce9f9192ac86..00000000000000 --- a/app/controllers/api/v1/crypto/keys/queries_controller.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::Crypto::Keys::QueriesController < Api::BaseController - before_action -> { doorkeeper_authorize! :crypto } - before_action :require_user! - before_action :set_accounts - before_action :set_query_results - - def create - render json: @query_results, each_serializer: REST::Keys::QueryResultSerializer - end - - private - - def set_accounts - @accounts = Account.where(id: account_ids).includes(:devices) - end - - def set_query_results - @query_results = @accounts.filter_map { |account| ::Keys::QueryService.new.call(account) } - end - - def account_ids - Array(params[:id]).map(&:to_i) - end -end diff --git a/app/controllers/api/v1/crypto/keys/uploads_controller.rb b/app/controllers/api/v1/crypto/keys/uploads_controller.rb deleted file mode 100644 index fc4abf63b3a421..00000000000000 --- a/app/controllers/api/v1/crypto/keys/uploads_controller.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -class Api::V1::Crypto::Keys::UploadsController < Api::BaseController - before_action -> { doorkeeper_authorize! :crypto } - before_action :require_user! - - def create - device = Device.find_or_initialize_by(access_token: doorkeeper_token) - - device.transaction do - device.account = current_account - device.update!(resource_params[:device]) - - if resource_params[:one_time_keys].present? && resource_params[:one_time_keys].is_a?(Enumerable) - resource_params[:one_time_keys].each do |one_time_key_params| - device.one_time_keys.create!(one_time_key_params) - end - end - end - - render json: device, serializer: REST::Keys::DeviceSerializer - end - - private - - def resource_params - params.permit(device: [:device_id, :name, :fingerprint_key, :identity_key], one_time_keys: [:key_id, :key, :signature]) - end -end diff --git a/app/controllers/api/v1/peers/search_controller.rb b/app/controllers/api/v1/peers/search_controller.rb index 1780554c5d8bc0..d9c82327022194 100644 --- a/app/controllers/api/v1/peers/search_controller.rb +++ b/app/controllers/api/v1/peers/search_controller.rb @@ -7,6 +7,8 @@ class Api::V1::Peers::SearchController < Api::BaseController skip_before_action :require_authenticated_user!, unless: :limited_federation_mode? skip_around_action :set_locale + LIMIT = 10 + vary_by '' def index @@ -35,10 +37,10 @@ def set_domains field: 'accounts_count', modifier: 'log2p', }, - }).limit(10).pluck(:domain) + }).limit(LIMIT).pluck(:domain) else domain = normalized_domain - @domains = Instance.searchable.domain_starts_with(domain).limit(10).pluck(:domain) + @domains = Instance.searchable.domain_starts_with(domain).limit(LIMIT).pluck(:domain) end rescue Addressable::URI::InvalidURIError @domains = [] diff --git a/app/controllers/api/web/embeds_controller.rb b/app/controllers/api/web/embeds_controller.rb index 63c3f2d90a79c6..f82c1c50d79502 100644 --- a/app/controllers/api/web/embeds_controller.rb +++ b/app/controllers/api/web/embeds_controller.rb @@ -9,7 +9,7 @@ def show return not_found if @status.hidden? if @status.local? - render json: @status, serializer: OEmbedSerializer, width: 400 + render json: @status, serializer: OEmbedSerializer else return not_found unless user_signed_in? diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index a2fed644fe7f10..ecac4c5ba8e517 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -20,11 +20,6 @@ class Auth::SessionsController < Devise::SessionsController p.form_action(false) end - def check_suspicious! - user = find_user - @login_is_suspicious = suspicious_sign_in?(user) unless user.nil? - end - def create super do |resource| # We only need to call this if this hasn't already been @@ -101,6 +96,11 @@ def require_no_authentication private + def check_suspicious! + user = find_user + @login_is_suspicious = suspicious_sign_in?(user) unless user.nil? + end + def home_paths(resource) paths = [about_path, '/explore'] diff --git a/app/helpers/context_helper.rb b/app/helpers/context_helper.rb index 71e19207d02f6e..b36e25c092b57e 100644 --- a/app/helpers/context_helper.rb +++ b/app/helpers/context_helper.rb @@ -24,23 +24,6 @@ module ContextHelper indexable: { 'toot' => 'http://joinmastodon.org/ns#', 'indexable' => 'toot:indexable' }, memorial: { 'toot' => 'http://joinmastodon.org/ns#', 'memorial' => 'toot:memorial' }, voters_count: { 'toot' => 'http://joinmastodon.org/ns#', 'votersCount' => 'toot:votersCount' }, - olm: { - 'toot' => 'http://joinmastodon.org/ns#', - 'Device' => 'toot:Device', - 'Ed25519Signature' => 'toot:Ed25519Signature', - 'Ed25519Key' => 'toot:Ed25519Key', - 'Curve25519Key' => 'toot:Curve25519Key', - 'EncryptedMessage' => 'toot:EncryptedMessage', - 'publicKeyBase64' => 'toot:publicKeyBase64', - 'deviceId' => 'toot:deviceId', - 'claim' => { '@type' => '@id', '@id' => 'toot:claim' }, - 'fingerprintKey' => { '@type' => '@id', '@id' => 'toot:fingerprintKey' }, - 'identityKey' => { '@type' => '@id', '@id' => 'toot:identityKey' }, - 'devices' => { '@type' => '@id', '@id' => 'toot:devices' }, - 'messageFranking' => 'toot:messageFranking', - 'messageType' => 'toot:messageType', - 'cipherText' => 'toot:cipherText', - }, suspended: { 'toot' => 'http://joinmastodon.org/ns#', 'suspended' => 'toot:suspended' }, attribution_domains: { 'toot' => 'http://joinmastodon.org/ns#', 'attributionDomains' => { '@id' => 'toot:attributionDomains', '@type' => '@id' } }, }.freeze diff --git a/app/javascript/flavours/glitch/actions/alerts.js b/app/javascript/flavours/glitch/actions/alerts.js index 42834146bf5ba6..48dee2587fe523 100644 --- a/app/javascript/flavours/glitch/actions/alerts.js +++ b/app/javascript/flavours/glitch/actions/alerts.js @@ -1,5 +1,7 @@ import { defineMessages } from 'react-intl'; +import { AxiosError } from 'axios'; + const messages = defineMessages({ unexpectedTitle: { id: 'alert.unexpected.title', defaultMessage: 'Oops!' }, unexpectedMessage: { id: 'alert.unexpected.message', defaultMessage: 'An unexpected error occurred.' }, @@ -50,6 +52,11 @@ export const showAlertForError = (error, skipNotFound = false) => { }); } + // An aborted request, e.g. due to reloading the browser window, it not really error + if (error.code === AxiosError.ECONNABORTED) { + return { type: ALERT_NOOP }; + } + console.error(error); return showAlert({ diff --git a/app/javascript/flavours/glitch/api.ts b/app/javascript/flavours/glitch/api.ts index 24672290c74f94..25bb25547cf94d 100644 --- a/app/javascript/flavours/glitch/api.ts +++ b/app/javascript/flavours/glitch/api.ts @@ -42,6 +42,9 @@ const authorizationTokenFromInitialState = (): RawAxiosRequestHeaders => { // eslint-disable-next-line import/no-default-export export default function api(withAuthorization = true) { return axios.create({ + transitional: { + clarifyTimeoutError: true, + }, headers: { ...csrfHeader, ...(withAuthorization ? authorizationTokenFromInitialState() : {}), diff --git a/app/javascript/flavours/glitch/components/modal_root.jsx b/app/javascript/flavours/glitch/components/modal_root.jsx index f338c4ec0eda5c..71b875cfeeb547 100644 --- a/app/javascript/flavours/glitch/components/modal_root.jsx +++ b/app/javascript/flavours/glitch/components/modal_root.jsx @@ -153,7 +153,7 @@ class ModalRoot extends PureComponent { return (
- + -@@ -57,10 +85,10 @@ def html end def width - instance_options[:width] + (instance_options[:width] || DEFAULT_WIDTH).to_i end def height - instance_options[:height] + instance_options[:height].presence&.to_i end end diff --git a/app/serializers/rest/encrypted_message_serializer.rb b/app/serializers/rest/encrypted_message_serializer.rb deleted file mode 100644 index 80c26d060ea32f..00000000000000 --- a/app/serializers/rest/encrypted_message_serializer.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -class REST::EncryptedMessageSerializer < ActiveModel::Serializer - attributes :id, :account_id, :device_id, - :type, :body, :digest, :message_franking, - :created_at - - def id - object.id.to_s - end - - def account_id - object.from_account_id.to_s - end - - def device_id - object.from_device_id - end -end diff --git a/app/serializers/rest/keys/claim_result_serializer.rb b/app/serializers/rest/keys/claim_result_serializer.rb deleted file mode 100644 index 145044f557231d..00000000000000 --- a/app/serializers/rest/keys/claim_result_serializer.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -class REST::Keys::ClaimResultSerializer < ActiveModel::Serializer - attributes :account_id, :device_id, :key_id, :key, :signature - - def account_id - object.account.id.to_s - end -end diff --git a/app/serializers/rest/keys/device_serializer.rb b/app/serializers/rest/keys/device_serializer.rb deleted file mode 100644 index f9b821b79ca1d8..00000000000000 --- a/app/serializers/rest/keys/device_serializer.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true - -class REST::Keys::DeviceSerializer < ActiveModel::Serializer - attributes :device_id, :name, :identity_key, - :fingerprint_key -end diff --git a/app/serializers/rest/keys/query_result_serializer.rb b/app/serializers/rest/keys/query_result_serializer.rb deleted file mode 100644 index 8f8bdde289fdb2..00000000000000 --- a/app/serializers/rest/keys/query_result_serializer.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -class REST::Keys::QueryResultSerializer < ActiveModel::Serializer - attributes :account_id - - has_many :devices, serializer: REST::Keys::DeviceSerializer - - def account_id - object.account.id.to_s - end -end diff --git a/app/services/activitypub/fetch_replies_service.rb b/app/services/activitypub/fetch_replies_service.rb index e2ecdef1659990..46cab6caf93dc3 100644 --- a/app/services/activitypub/fetch_replies_service.rb +++ b/app/services/activitypub/fetch_replies_service.rb @@ -49,7 +49,7 @@ def fetch_collection(collection_or_uri) rescue Mastodon::UnexpectedResponseError => e raise unless e.response && e.response.code == 401 && Addressable::URI.parse(collection_or_uri).query.present? - fetch_resource_without_id_validation(collection_or_uri, nil, true, request_options: { with_query_string: true }) + fetch_resource_without_id_validation(collection_or_uri, nil, true, request_options: { omit_query_string: false }) end end diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 1e2d614d72452e..a7422b5d02af7b 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -108,7 +108,6 @@ def set_immediate_protocol_attributes! def set_immediate_attributes! @account.featured_collection_url = @json['featured'] || '' - @account.devices_url = @json['devices'] || '' @account.display_name = @json['name'] || '' @account.note = @json['summary'] || '' @account.locked = @json['manuallyApprovesFollowers'] || false diff --git a/app/services/delete_account_service.rb b/app/services/delete_account_service.rb index 328d8ae8f83965..0c03267d43d0b3 100644 --- a/app/services/delete_account_service.rb +++ b/app/services/delete_account_service.rb @@ -13,7 +13,6 @@ class DeleteAccountService < BaseService conversation_mutes conversations custom_filters - devices domain_blocks featured_tags follow_requests @@ -40,7 +39,6 @@ class DeleteAccountService < BaseService conversation_mutes conversations custom_filters - devices domain_blocks featured_tags follow_requests diff --git a/app/services/deliver_to_device_service.rb b/app/services/deliver_to_device_service.rb deleted file mode 100644 index 71711945c06564..00000000000000 --- a/app/services/deliver_to_device_service.rb +++ /dev/null @@ -1,78 +0,0 @@ -# frozen_string_literal: true - -class DeliverToDeviceService < BaseService - include Payloadable - - class EncryptedMessage < ActiveModelSerializers::Model - attributes :source_account, :target_account, :source_device, - :target_device_id, :type, :body, :digest, - :message_franking - end - - def call(source_account, source_device, options = {}) - @source_account = source_account - @source_device = source_device - @target_account = Account.find(options[:account_id]) - @target_device_id = options[:device_id] - @body = options[:body] - @type = options[:type] - @hmac = options[:hmac] - - set_message_franking! - - if @target_account.local? - deliver_to_local! - else - deliver_to_remote! - end - end - - private - - def set_message_franking! - @message_franking = message_franking.to_token - end - - def deliver_to_local! - target_device = @target_account.devices.find_by!(device_id: @target_device_id) - - target_device.encrypted_messages.create!( - from_account: @source_account, - from_device_id: @source_device.device_id, - type: @type, - body: @body, - digest: @hmac, - message_franking: @message_franking - ) - end - - def deliver_to_remote! - ActivityPub::DeliveryWorker.perform_async( - Oj.dump(serialize_payload(ActivityPub::ActivityPresenter.from_encrypted_message(encrypted_message), ActivityPub::ActivitySerializer)), - @source_account.id, - @target_account.inbox_url - ) - end - - def message_franking - MessageFranking.new( - source_account_id: @source_account.id, - target_account_id: @target_account.id, - hmac: @hmac, - timestamp: Time.now.utc - ) - end - - def encrypted_message - EncryptedMessage.new( - source_account: @source_account, - target_account: @target_account, - source_device: @source_device, - target_device_id: @target_device_id, - type: @type, - body: @body, - digest: @hmac, - message_franking: @message_franking - ) - end -end diff --git a/app/services/keys/claim_service.rb b/app/services/keys/claim_service.rb deleted file mode 100644 index ebce9cce7d8c16..00000000000000 --- a/app/services/keys/claim_service.rb +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: true - -class Keys::ClaimService < BaseService - HEADERS = { 'Content-Type' => 'application/activity+json' }.freeze - - class Result < ActiveModelSerializers::Model - attributes :account, :device_id, :key_id, - :key, :signature - - def initialize(account, device_id, key_attributes = {}) - super( - account: account, - device_id: device_id, - key_id: key_attributes[:key_id], - key: key_attributes[:key], - signature: key_attributes[:signature], - ) - end - end - - def call(source_account, target_account_id, device_id) - @source_account = source_account - @target_account = Account.find(target_account_id) - @device_id = device_id - - if @target_account.local? - claim_local_key! - else - claim_remote_key! - end - rescue ActiveRecord::RecordNotFound - nil - end - - private - - def claim_local_key! - device = @target_account.devices.find_by(device_id: @device_id) - key = nil - - ApplicationRecord.transaction do - key = device.one_time_keys.order(Arel.sql('random()')).first! - key.destroy! - end - - @result = Result.new(@target_account, @device_id, key) - end - - def claim_remote_key! - query_result = QueryService.new.call(@target_account) - device = query_result.find(@device_id) - - return unless device.present? && device.valid_claim_url? - - json = fetch_resource_with_post(device.claim_url) - - return unless json.present? && json['publicKeyBase64'].present? - - @result = Result.new(@target_account, @device_id, key_id: json['id'], key: json['publicKeyBase64'], signature: json.dig('signature', 'signatureValue')) - rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e - Rails.logger.debug { "Claiming one-time key for #{@target_account.acct}:#{@device_id} failed: #{e}" } - nil - end - - def fetch_resource_with_post(uri) - build_post_request(uri).perform do |response| - raise Mastodon::UnexpectedResponseError, response unless response_successful?(response) || response_error_unsalvageable?(response) - - body_to_json(response.body_with_limit) if response.code == 200 - end - end - - def build_post_request(uri) - Request.new(:post, uri).tap do |request| - request.on_behalf_of(@source_account) - request.add_headers(HEADERS) - end - end -end diff --git a/app/services/keys/query_service.rb b/app/services/keys/query_service.rb deleted file mode 100644 index 33e13293f3155f..00000000000000 --- a/app/services/keys/query_service.rb +++ /dev/null @@ -1,79 +0,0 @@ -# frozen_string_literal: true - -class Keys::QueryService < BaseService - include JsonLdHelper - - class Result < ActiveModelSerializers::Model - attributes :account, :devices - - def initialize(account, devices) - super( - account: account, - devices: devices || [], - ) - end - - def find(device_id) - @devices.find { |device| device.device_id == device_id } - end - end - - class Device < ActiveModelSerializers::Model - attributes :device_id, :name, :identity_key, :fingerprint_key - - def initialize(attributes = {}) - super( - device_id: attributes[:device_id], - name: attributes[:name], - identity_key: attributes[:identity_key], - fingerprint_key: attributes[:fingerprint_key], - ) - @claim_url = attributes[:claim_url] - end - - def valid_claim_url? - return false if @claim_url.blank? - - begin - parsed_url = Addressable::URI.parse(@claim_url).normalize - rescue Addressable::URI::InvalidURIError - return false - end - - %w(http https).include?(parsed_url.scheme) && parsed_url.host.present? - end - end - - def call(account) - @account = account - - if @account.local? - query_local_devices! - else - query_remote_devices! - end - - Result.new(@account, @devices) - end - - private - - def query_local_devices! - @devices = @account.devices.map { |device| Device.new(device) } - end - - def query_remote_devices! - return if @account.devices_url.blank? - - json = fetch_resource(@account.devices_url) - - return if json['items'].blank? - - @devices = as_array(json['items']).map do |device| - Device.new(device_id: device['id'], name: device['name'], identity_key: device.dig('identityKey', 'publicKeyBase64'), fingerprint_key: device.dig('fingerprintKey', 'publicKeyBase64'), claim_url: device['claim']) - end - rescue HTTP::Error, OpenSSL::SSL::SSLError, Mastodon::Error => e - Rails.logger.debug { "Querying devices for #{@account.acct} failed: #{e}" } - nil - end -end diff --git a/app/validators/ed25519_key_validator.rb b/app/validators/ed25519_key_validator.rb deleted file mode 100644 index adf49296b2fb51..00000000000000 --- a/app/validators/ed25519_key_validator.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -class Ed25519KeyValidator < ActiveModel::EachValidator - def validate_each(record, attribute, value) - return if value.blank? - - key = Base64.decode64(value) - - record.errors.add(attribute, I18n.t('crypto.errors.invalid_key')) unless verified?(key) - end - - private - - def verified?(key) - Ed25519.validate_key_bytes(key) - rescue ArgumentError - false - end -end diff --git a/app/validators/ed25519_signature_validator.rb b/app/validators/ed25519_signature_validator.rb deleted file mode 100644 index 0e74c231ece4a3..00000000000000 --- a/app/validators/ed25519_signature_validator.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -class Ed25519SignatureValidator < ActiveModel::EachValidator - def validate_each(record, attribute, value) - return if value.blank? - - verify_key = Ed25519::VerifyKey.new(Base64.decode64(option_to_value(record, :verify_key))) - signature = Base64.decode64(value) - message = option_to_value(record, :message) - - record.errors.add(attribute, I18n.t('crypto.errors.invalid_signature')) unless verified?(verify_key, signature, message) - end - - private - - def verified?(verify_key, signature, message) - verify_key.verify(signature, message) - rescue Ed25519::VerifyError, ArgumentError - false - end - - def option_to_value(record, key) - if options[key].is_a?(Proc) - options[key].call(record) - else - record.public_send(options[key]) - end - end -end diff --git a/app/views/admin/reports/_status.html.haml b/app/views/admin/reports/_status.html.haml index e0870503d6c70c..f4630ed25ae978 100644 --- a/app/views/admin/reports/_status.html.haml +++ b/app/views/admin/reports/_status.html.haml @@ -18,7 +18,7 @@ - if status.application = status.application.name · - = link_to ActivityPub::TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do + = link_to ActivityPub::TagManager.instance.url_for(status.proper), class: 'detailed-status__datetime', target: stream_link_target, rel: 'noopener noreferrer' do %time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at) - if status.edited? · diff --git a/app/views/admin/trends/links/preview_card_providers/index.html.haml b/app/views/admin/trends/links/preview_card_providers/index.html.haml index b43b8dfff9f4e4..93daf25f31a74d 100644 --- a/app/views/admin/trends/links/preview_card_providers/index.html.haml +++ b/app/views/admin/trends/links/preview_card_providers/index.html.haml @@ -12,7 +12,7 @@ %li= filter_link_to t('generic.all'), status: nil %li= filter_link_to t('admin.trends.approved'), status: 'approved' %li= filter_link_to t('admin.trends.rejected'), status: 'rejected' - %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{PreviewCardProvider.pending_review.count})"], ' '), status: 'pending_review' + %li= filter_link_to safe_join([t('admin.accounts.moderation.pending'), "(#{PreviewCardProvider.unreviewed.count})"], ' '), status: 'pending_review' .back-link = link_to admin_trends_links_path do = material_symbol 'chevron_left' diff --git a/app/workers/push_encrypted_message_worker.rb b/app/workers/push_encrypted_message_worker.rb deleted file mode 100644 index 6bee12675b0db4..00000000000000 --- a/app/workers/push_encrypted_message_worker.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -class PushEncryptedMessageWorker - include Sidekiq::Worker - include Redisable - - def perform(encrypted_message_id) - encrypted_message = EncryptedMessage.find(encrypted_message_id) - message = InlineRenderer.render(encrypted_message, nil, :encrypted_message) - timeline_id = "timeline:#{encrypted_message.device.account_id}:#{encrypted_message.device.device_id}" - - redis.publish(timeline_id, Oj.dump(event: :encrypted_message, payload: message)) - rescue ActiveRecord::RecordNotFound - true - end -end diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 86fde3cacf74dc..b47e76c08bc60a 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -118,8 +118,7 @@ :'admin:write:domain_blocks', :'admin:write:ip_blocks', :'admin:write:email_domain_blocks', - :'admin:write:canonical_email_blocks', - :crypto + :'admin:write:canonical_email_blocks' # Change the way client credentials are retrieved from the request object. # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index ba459e19f22c0d..2b0563f4d32a3a 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -19,7 +19,6 @@ inflect.acronym 'CLI' inflect.acronym 'DeepL' inflect.acronym 'DSL' - inflect.acronym 'Ed25519' inflect.acronym 'JsonLd' inflect.acronym 'OEmbed' inflect.acronym 'OStatus' diff --git a/config/locales/activerecord.ko.yml b/config/locales/activerecord.ko.yml index 294d614bca63c6..6d437b72b0dfde 100644 --- a/config/locales/activerecord.ko.yml +++ b/config/locales/activerecord.ko.yml @@ -15,6 +15,12 @@ ko: user/invite_request: text: 이유 errors: + attributes: + domain: + invalid: 올바른 도메인 네임이 아닙니다 + messages: + invalid_domain_on_line: "%{value}는 올바른 도메인 네임이 아닙니다" + too_many_lines: "%{limit}줄 제한을 초과합니다" models: account: attributes: diff --git a/config/locales/activerecord.ru.yml b/config/locales/activerecord.ru.yml index 92d85af4d9d28d..203d8e2c34d0d7 100644 --- a/config/locales/activerecord.ru.yml +++ b/config/locales/activerecord.ru.yml @@ -15,6 +15,12 @@ ru: user/invite_request: text: Причина errors: + attributes: + domain: + invalid: не является действующим доменным именем + messages: + invalid_domain_on_line: "%{value} Не является действительным доменным именем" + too_many_lines: Превышает предел %{limit} строк models: account: attributes: diff --git a/config/locales/an.yml b/config/locales/an.yml index 589bb39836c567..2f181e0757da43 100644 --- a/config/locales/an.yml +++ b/config/locales/an.yml @@ -953,7 +953,6 @@ an: crypto: errors: invalid_key: no ye una clau Ed25519 u Curve25519 valida - invalid_signature: no ye una sinyatura Ed25519 valida date: formats: default: "%d %b %Y" diff --git a/config/locales/ar.yml b/config/locales/ar.yml index 7512e03fd50f18..81705acba045d6 100644 --- a/config/locales/ar.yml +++ b/config/locales/ar.yml @@ -1178,7 +1178,6 @@ ar: crypto: errors: invalid_key: ليس بمفتاح Ed25519 أو Curve25519 صالح - invalid_signature: ليس بتوقيع Ed25519 صالح date: formats: default: "%d %b %Y" diff --git a/config/locales/ast.yml b/config/locales/ast.yml index be3441507eacfb..a7d4a9917eebdb 100644 --- a/config/locales/ast.yml +++ b/config/locales/ast.yml @@ -486,7 +486,6 @@ ast: crypto: errors: invalid_key: nun ye una clave ed25519 o curve25519 válida - invalid_signature: nun ye una clave ed25519 válida datetime: distance_in_words: about_x_hours: "%{count} h" diff --git a/config/locales/be.yml b/config/locales/be.yml index 48ca5751cc806d..d45f443b75f06c 100644 --- a/config/locales/be.yml +++ b/config/locales/be.yml @@ -1189,7 +1189,6 @@ be: crypto: errors: invalid_key: гэта не сапраўдны Ed25519 або Curve25519 ключ - invalid_signature: гэта не сапраўдная Ed25519 сігнатура date: formats: default: "%d.%m.%Y" diff --git a/config/locales/bg.yml b/config/locales/bg.yml index 604eeca4808ba9..e2c246827afb4b 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -1115,7 +1115,6 @@ bg: crypto: errors: invalid_key: не е валиден ключ Ed25519 или Curve25519 - invalid_signature: не е валиден подпис Ed25519 date: formats: default: "%b %d, %Y" diff --git a/config/locales/ca.yml b/config/locales/ca.yml index d985a2ac42f858..33a1d4e88f7bfe 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -1171,7 +1171,6 @@ ca: crypto: errors: invalid_key: no és una clau Ed25519 o Curve25519 vàlida - invalid_signature: no és una signatura Ed25519 vàlida date: formats: default: "%b %d, %Y" diff --git a/config/locales/ckb.yml b/config/locales/ckb.yml index 8af3d8638831aa..bc668d2ce4c7e4 100644 --- a/config/locales/ckb.yml +++ b/config/locales/ckb.yml @@ -608,7 +608,6 @@ ckb: crypto: errors: invalid_key: کلیلی باوڕپێکراو Ed25519 یان Curve25519 دروست نییە - invalid_signature: واژووی Ed25519 بڕوادار نییە date: formats: default: "%b %d, %Y" diff --git a/config/locales/co.yml b/config/locales/co.yml index b072e5e4eff0f7..58ddd7d01b593f 100644 --- a/config/locales/co.yml +++ b/config/locales/co.yml @@ -569,7 +569,6 @@ co: crypto: errors: invalid_key: ùn hè micca una chjave Ed25519 o Curve25519 valida - invalid_signature: ùn hè micca una firma Ed25519 valida date: formats: default: "%d %b %Y" diff --git a/config/locales/cs.yml b/config/locales/cs.yml index 1000442870cc35..b7fc8ab1b0bc26 100644 --- a/config/locales/cs.yml +++ b/config/locales/cs.yml @@ -1149,7 +1149,6 @@ cs: crypto: errors: invalid_key: není platný klíč Ed25519 nebo Curve25519 - invalid_signature: není platný podpis typu Ed25519 date: formats: default: "%d. %b %Y" diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 9d3c0c82f352d3..c2c193d9434292 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -1246,7 +1246,6 @@ cy: crypto: errors: invalid_key: ddim yn allwedd Ed25519 na Curve25519 dilys - invalid_signature: ddim yn llofnod Ed25519 dilys date: formats: default: "%b %d %Y" diff --git a/config/locales/da.yml b/config/locales/da.yml index 6f781742a85ecb..a177b97de76fd2 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1174,7 +1174,6 @@ da: crypto: errors: invalid_key: er ikke en gyldig Ed25519- eller Curve25519-nøgle - invalid_signature: er ikke en gylidig Ed25519-signatur date: formats: default: "%d. %b %Y" diff --git a/config/locales/de.yml b/config/locales/de.yml index 040ddaaf6903bf..85e24c230ec339 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1174,7 +1174,6 @@ de: crypto: errors: invalid_key: ist kein gültiger Ed25519- oder Curve25519-Schlüssel - invalid_signature: ist keine gültige Ed25519-Signatur date: formats: default: "%d. %b %Y" diff --git a/config/locales/doorkeeper.es-MX.yml b/config/locales/doorkeeper.es-MX.yml index b5987676d2824c..49ff9a1e43d15d 100644 --- a/config/locales/doorkeeper.es-MX.yml +++ b/config/locales/doorkeeper.es-MX.yml @@ -167,7 +167,7 @@ es-MX: admin:write:reports: realizar acciones de moderación en informes crypto: usar cifrado de extremo a extremo follow: seguir, bloquear, desbloquear y dejar de seguir cuentas - profile: leer sólo la información del perfil de tu cuenta + profile: leer solamente la información del perfil de tu cuenta push: recibir tus notificaciones push read: leer los datos de tu cuenta read:accounts: ver información de cuentas diff --git a/config/locales/el.yml b/config/locales/el.yml index 1f408e26ea96b7..0da957cdb28de7 100644 --- a/config/locales/el.yml +++ b/config/locales/el.yml @@ -1128,7 +1128,6 @@ el: crypto: errors: invalid_key: δεν είναι έγκυρο κλειδί Ed25519 ή Curve25519 - invalid_signature: δεν είναι έγκυρη υπογραφή Ed25519 date: formats: default: "%b %d, %Y" diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 56255f5d7ae9e1..577978ce88d54f 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -1174,7 +1174,6 @@ en-GB: crypto: errors: invalid_key: is not a valid Ed25519 or Curve25519 key - invalid_signature: is not a valid Ed25519 signature date: formats: default: "%b %d, %Y" diff --git a/config/locales/en.yml b/config/locales/en.yml index b1c100da0c6fda..625f53f2e57108 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1174,7 +1174,6 @@ en: crypto: errors: invalid_key: is not a valid Ed25519 or Curve25519 key - invalid_signature: is not a valid Ed25519 signature date: formats: default: "%b %d, %Y" diff --git a/config/locales/eo.yml b/config/locales/eo.yml index 46c6cbcf866908..7ebf0748194067 100644 --- a/config/locales/eo.yml +++ b/config/locales/eo.yml @@ -1041,7 +1041,6 @@ eo: crypto: errors: invalid_key: 올바른 Ed25519 혹은 Curve25519 키가 아닙니다 - invalid_signature: 올바른 Ed25519 시그니처가 아닙니다 date: formats: default: "%Y-%b-%d" diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index 4d60d080a2f3ab..9f1dc46c9df8ce 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1174,7 +1174,6 @@ es-AR: crypto: errors: invalid_key: no es una clave Ed25519 o Curve25519 válida - invalid_signature: no es una firma Ed25519 válida date: formats: default: "%d de %b de %Y" diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index ebe26c3f14f398..8aac7cbb47b2c2 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -175,7 +175,7 @@ es-MX: approve_appeal: Aprobar apelación approve_user: Aprobar Usuario assigned_to_self_report: Asignar Reporte - change_email_user: Cambiar Correo Electrónico del Usuario + change_email_user: Cambiar correo electrónico por usuario change_role_user: Cambiar rol del usuario confirm_user: Confirmar Usuario create_account_warning: Crear Advertencia @@ -202,10 +202,10 @@ es-MX: destroy_user_role: Destruir Rol disable_2fa_user: Deshabilitar 2FA disable_custom_emoji: Deshabilitar Emoji Personalizado - disable_sign_in_token_auth_user: Deshabilitar la Autenticación por Token de Correo Electrónico para el Usuario + disable_sign_in_token_auth_user: Deshabilitar la autenticación por token de correo electrónico para el usuario disable_user: Deshabilitar Usuario enable_custom_emoji: Habilitar Emoji Personalizado - enable_sign_in_token_auth_user: Habilitar la Autenticación por Token de Correo Electrónico para el Usuario + enable_sign_in_token_auth_user: Habilitar la autenticación por token de correo electrónico para el usuario enable_user: Habilitar Usuario memorialize_account: Transformar en Cuenta Conmemorativa promote_user: Promover Usuario @@ -761,7 +761,7 @@ es-MX: desc_html: Esto se basa en scripts externos de hCaptcha, que pueden suponer una preocupación de seguridad y privacidad. Además, esto puede volver el proceso de registro significativamente menos accesible para algunas personas (especialmente con discapacidades). Por estas razones, por favor, considera medidas alternativas como el registro por aprobación manual o con invitación. title: Solicita a los nuevos usuarios que resuelvan un CAPTCHA para confirmar su cuenta content_retention: - danger_zone: Zona peligrosa + danger_zone: Zona de peligro preamble: Controlar cómo el contenido generado por el usuario se almacena en Mastodon. title: Retención de contenido default_noindex: @@ -896,7 +896,7 @@ es-MX: reviewed: Revisada title: Estado trendable: Puede ser tendencia - unreviewed: Sin revisar + unreviewed: No revisado usable: Disponible name: Nombre newest: Más reciente @@ -944,9 +944,9 @@ es-MX: statuses: allow: Permitir publicación allow_account: Permitir autor - confirm_allow: "¿Estás seguro de que deseas permitir los estados seleccionados?" + confirm_allow: "¿Estás seguro de que deseas permitir las publicaciones seleccionadas?" confirm_allow_account: "¿Estás seguro de que deseas permitir las cuentas seleccionadas?" - confirm_disallow: "¿Estás seguro de que deseas restringir los estados seleccionados?" + confirm_disallow: "¿Estás seguro de que deseas restringir las publicaciones seleccionadas?" confirm_disallow_account: "¿Estás seguro de que deseas restringir las cuentas seleccionadas?" description_html: Estos son publicaciones que su servidor conoce que están siendo compartidas y marcadas como favoritas mucho en este momento. Pueden ayudar a tus usuarios nuevos y retornantes a encontrar más gente a la que seguir. No hay mensajes que se muestren públicamente hasta que apruebes el autor y el autor permita que su cuenta sea sugerida a otros. También puedes permitir o rechazar mensajes individuales. disallow: Rechazar publicación @@ -1152,7 +1152,7 @@ es-MX: title: Crear cuenta de Mastodon en %{domain}. status: account_status: Estado de la cuenta - confirming: Esperando confirmación de correo electrónico. + confirming: Esperando a que se complete la confirmación por correo electrónico. functional: Tu cuenta está completamente operativa. pending: Tu solicitud está pendiente de revisión por nuestro personal. Eso puede tardar un tiempo. Recibirás un correo electrónico cuando tu solicitud sea aprobada. redirecting_to: Tu cuenta se encuentra inactiva porque está siendo redirigida a %{acct}. @@ -1174,7 +1174,6 @@ es-MX: crypto: errors: invalid_key: no es una clave Ed25519 o Curve25519 válida - invalid_signature: no es una firma Ed25519 válida date: formats: default: "%d %b %Y" @@ -1538,7 +1537,7 @@ es-MX: update: subject: "%{name} editó una publicación" notifications: - administration_emails: Notificaciones administrativas por correo + administration_emails: Notificaciones de administración por correo electrónico email_events: Eventos para notificaciones por correo electrónico email_events_hint: 'Selecciona los eventos para los que deseas recibir notificaciones:' number: diff --git a/config/locales/es.yml b/config/locales/es.yml index c652876f3a9ef3..2815ada77957ce 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1174,7 +1174,6 @@ es: crypto: errors: invalid_key: no es una clave Ed25519 o Curve25519 válida - invalid_signature: no es una firma Ed25519 válida date: formats: default: "%d %b %Y" diff --git a/config/locales/et.yml b/config/locales/et.yml index aca4f93c4db164..60f98a471e37a2 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -1174,7 +1174,6 @@ et: crypto: errors: invalid_key: ei ole õige Ed25519 ega Curve25519 võti - invalid_signature: ei ole õige Ed25519 allkiri date: formats: default: "%d. %b %Y" diff --git a/config/locales/eu.yml b/config/locales/eu.yml index 6260033990d309..7c7f995a7143b1 100644 --- a/config/locales/eu.yml +++ b/config/locales/eu.yml @@ -1091,7 +1091,6 @@ eu: crypto: errors: invalid_key: ez da baliozko Ed25519 edo Curve25519 gakoa - invalid_signature: ez da baliozko Ed25519 sinadura date: formats: default: "%Y(e)ko %b %d" diff --git a/config/locales/fa.yml b/config/locales/fa.yml index 996c8d6cd2abdf..c2c22af4c46a51 100644 --- a/config/locales/fa.yml +++ b/config/locales/fa.yml @@ -971,7 +971,6 @@ fa: crypto: errors: invalid_key: یک کلید معتبر Ed25519 یا Curve25519 نیست - invalid_signature: یک امضای معتبر Ed25519 نیست date: formats: default: "%d %b %Y" diff --git a/config/locales/fi.yml b/config/locales/fi.yml index b48b499bbe463a..5df82bff9fa440 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1174,7 +1174,6 @@ fi: crypto: errors: invalid_key: ei ole kelvollinen Ed25519- tai Curve25519-avain - invalid_signature: ei ole kelvollinen Ed25519-allekirjoitus date: formats: default: "%b %d, %Y" diff --git a/config/locales/fo.yml b/config/locales/fo.yml index 266b73bb10aa1d..ce21aa3be7c44f 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1174,7 +1174,6 @@ fo: crypto: errors: invalid_key: er ikki ein gildur Ed25519 ella Curve25519 lykil - invalid_signature: er ikki ein gildug Ed25519 undirskrift date: formats: default: "%b %d, %Y" diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml index b70a515fd16eec..3f9252ffabff7b 100644 --- a/config/locales/fr-CA.yml +++ b/config/locales/fr-CA.yml @@ -1175,7 +1175,6 @@ fr-CA: crypto: errors: invalid_key: n’est pas une clé Ed25519 ou Curve25519 valide - invalid_signature: n’est pas une signature Ed25519 valide date: formats: default: "%d %b %Y" diff --git a/config/locales/fr.yml b/config/locales/fr.yml index bc616d28963b55..cb76ae2243c33d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1175,7 +1175,6 @@ fr: crypto: errors: invalid_key: n’est pas une clé Ed25519 ou Curve25519 valide - invalid_signature: n’est pas une signature Ed25519 valide date: formats: default: "%d %b %Y" diff --git a/config/locales/fy.yml b/config/locales/fy.yml index 6afdecd556d40d..8b854494d4b555 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -1164,7 +1164,6 @@ fy: crypto: errors: invalid_key: is gjin jildige Ed25519- of Curve25519-kaai - invalid_signature: is gjin jildige Ed25519-hantekening date: formats: default: "%d %b %Y" diff --git a/config/locales/ga.yml b/config/locales/ga.yml index 1071871c952327..a6369354cd8a56 100644 --- a/config/locales/ga.yml +++ b/config/locales/ga.yml @@ -1228,7 +1228,6 @@ ga: crypto: errors: invalid_key: nach eochair bhailí Ed25519 nó Curve25519 í - invalid_signature: nach síniú bailí Ed25519 é date: formats: default: "%b %d, %Y" diff --git a/config/locales/gd.yml b/config/locales/gd.yml index 5e63b5bd2300d0..b5cbc4a73ed372 100644 --- a/config/locales/gd.yml +++ b/config/locales/gd.yml @@ -1210,7 +1210,6 @@ gd: crypto: errors: invalid_key: "– chan e iuchair Ed25519 no Curve25519 dhligheach a th’ ann" - invalid_signature: "– chan e soidhneadh Ed25519 dligheach a th’ ann" date: formats: default: "%d %b %Y" diff --git a/config/locales/gl.yml b/config/locales/gl.yml index 58fd2d9bab50c4..9813514a7bf6cf 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -1174,7 +1174,6 @@ gl: crypto: errors: invalid_key: non é unha chave Ed25519 ou Curve25519 válida - invalid_signature: non é unha sinatura Ed25519 válida date: formats: default: "%d %b, %Y" diff --git a/config/locales/he.yml b/config/locales/he.yml index 7a2d0a1d987459..13a1f6f05d30d3 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1210,7 +1210,6 @@ he: crypto: errors: invalid_key: זהו לא מפתח Ed25519 או Curve25519 קביל - invalid_signature: היא לא חתימת Ed25519 קבילה date: formats: default: "%b %d, %Y" diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 10c7506b01159a..9767c488345493 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1174,7 +1174,6 @@ hu: crypto: errors: invalid_key: érvénytelen Ed25519 vagy Curve25519 kulcs - invalid_signature: érvénytelen Ed25519 aláírás date: formats: default: "%Y. %b %d." diff --git a/config/locales/hy.yml b/config/locales/hy.yml index 80dbc77991c24c..1fda020c0790a4 100644 --- a/config/locales/hy.yml +++ b/config/locales/hy.yml @@ -495,7 +495,6 @@ hy: crypto: errors: invalid_key: անվաւեր Ed25519 կամ Curve25519 բանալի - invalid_signature: անվաւեր Ed25519 բանալի date: formats: default: "%b %d, %Y" diff --git a/config/locales/ia.yml b/config/locales/ia.yml index 957bae39915b7d..6632af061ec364 100644 --- a/config/locales/ia.yml +++ b/config/locales/ia.yml @@ -1158,7 +1158,6 @@ ia: crypto: errors: invalid_key: non es un clave Ed25519 o Curve25519 valide - invalid_signature: non es un signatura Ed25519 valide date: formats: default: "%d %b %Y" diff --git a/config/locales/id.yml b/config/locales/id.yml index 222d2b56803f4f..96a5022a7c81da 100644 --- a/config/locales/id.yml +++ b/config/locales/id.yml @@ -936,7 +936,6 @@ id: crypto: errors: invalid_key: bukan kunci Ed25519 atau Curve25519 yang valid - invalid_signature: bukan tanda tangan Ed25519 yang valid date: formats: default: "%d %b %Y" diff --git a/config/locales/ie.yml b/config/locales/ie.yml index 6a79686f484984..513a8eda7eb930 100644 --- a/config/locales/ie.yml +++ b/config/locales/ie.yml @@ -1089,7 +1089,6 @@ ie: crypto: errors: invalid_key: ne es un valid clave Ed25519 o Curve25519 - invalid_signature: ne es un valid signatura Ed25519 date: formats: default: "%d.%m.%Y" diff --git a/config/locales/io.yml b/config/locales/io.yml index dbbe228e72c236..97cc417df0f82e 100644 --- a/config/locales/io.yml +++ b/config/locales/io.yml @@ -1064,7 +1064,6 @@ io: crypto: errors: invalid_key: ne esas valida klefo Ed25519 o Curve25519 - invalid_signature: ne esas valida parafo Ed25519 date: formats: default: "%d %b, %Y" diff --git a/config/locales/is.yml b/config/locales/is.yml index 78dfd6048fe965..590805ad3027b0 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1178,7 +1178,6 @@ is: crypto: errors: invalid_key: er ekki gildur Ed25519 eða Curve25519-lykill - invalid_signature: er ekki gild Ed25519 undirritun date: formats: default: "%d. %b, %Y" diff --git a/config/locales/it.yml b/config/locales/it.yml index 792add14e35e22..fe6fec17d778aa 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -1176,7 +1176,6 @@ it: crypto: errors: invalid_key: non è una chiave Ed25519 o Curve25519 valida - invalid_signature: non è una firma Ed25519 valida date: formats: default: "%d %b %Y" diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 13f59e981b00e7..ed6293e1cabaa9 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1146,7 +1146,6 @@ ja: crypto: errors: invalid_key: 有効なEd25519またはCurve25519キーではありません - invalid_signature: 有効なEd25519署名ではありません date: formats: default: "%Y年%m月%d日" diff --git a/config/locales/kab.yml b/config/locales/kab.yml index 7c3d526702665e..7044983ac9fe90 100644 --- a/config/locales/kab.yml +++ b/config/locales/kab.yml @@ -703,6 +703,7 @@ kab: prev: Win iɛeddan preferences: other: Wiyaḍ + posting_defaults: Iɣewwaṛen n usuffeɣ imezwura privacy: privacy: Tabaḍnit search: Anadi @@ -779,6 +780,7 @@ kab: import: Kter import_and_export: Taktert d usifeḍ migrate: Tunigin n umiḍan + notifications: Alɣuten s imayl preferences: Imenyafen profile: Ameɣnu relationships: Imeḍfaṛen akked wid i teṭṭafaṛeḍ diff --git a/config/locales/ko.yml b/config/locales/ko.yml index cbcc09a4dab1e3..216e4687620368 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -22,6 +22,7 @@ ko: admin: account_actions: action: 조치 취하기 + already_silenced: 이 계정은 이미 제한되었습니다. already_suspended: 이 계정은 이미 정지되었습니다. title: "%{acct} 계정에 중재 취하기" account_moderation_notes: @@ -1143,6 +1144,12 @@ ko: view_strikes: 내 계정에 대한 과거 중재 기록 보기 too_fast: 너무 빠르게 양식이 제출되었습니다, 다시 시도하세요. use_security_key: 보안 키 사용 + author_attribution: + example_title: 예시 텍스트 + hint_html: 링크가 마스토돈에 공유될 때 내가 어떻게 표시될 지를 제어합니다. + more_from_html: "%{name}의 게시물 더 보기" + s_blog: "%{name}의 블로그" + title: 작성자 기여 challenge: confirm: 계속 hint_html: "팁: 한 시간 동안 다시 암호를 묻지 않을 것입니다." @@ -1151,7 +1158,6 @@ ko: crypto: errors: invalid_key: 유효하지 않은 Ed25519 또는 Curve25519 키 - invalid_signature: 유효하지 않은 Ed25519 서명 date: formats: default: "%Y-%m-%d" @@ -1907,6 +1913,7 @@ ko: instructions_html: 웹사이트에 아래 코드를 복사해 붙여 넣으세요. 그리고 "프로필 수정" 탭에서 그 웹사이트 주소를 프로필의 추가 필드 중 하나에 넣고 변경사항을 저장하세요. verification: 검증 verified_links: 인증된 링크들 + website_verification: 웹사이트 인증 webauthn_credentials: add: 보안 키 추가 create: diff --git a/config/locales/ku.yml b/config/locales/ku.yml index 6b80e32ba809c3..08843f645e2078 100644 --- a/config/locales/ku.yml +++ b/config/locales/ku.yml @@ -950,7 +950,6 @@ ku: crypto: errors: invalid_key: ed25519 ne derbasdare ne jî Curve25519 kilîta - invalid_signature: Ed25519 ne îmzeyek derbasdar e date: formats: default: "%b%d%Y" diff --git a/config/locales/lad.yml b/config/locales/lad.yml index 2f5eb1553e417e..3d1f1a61e2447d 100644 --- a/config/locales/lad.yml +++ b/config/locales/lad.yml @@ -1122,7 +1122,6 @@ lad: crypto: errors: invalid_key: no es una yave Ed25519 o Curve25519 valida - invalid_signature: no es una firma Ed25519 valida date: formats: default: "%d %b %Y" diff --git a/config/locales/lv.yml b/config/locales/lv.yml index 55a0751811efad..4aeec5ceca73dc 100644 --- a/config/locales/lv.yml +++ b/config/locales/lv.yml @@ -1,7 +1,7 @@ --- lv: about: - about_mastodon_html: 'Nākotnes sociālais tīkls: bez reklāmām, bez korporatīvās uzraudzības, ētisks dizains un decentralizācija! Pārvaldi savus datus ar Mastodon!' + about_mastodon_html: 'Nākotnes sabiedriskais tīkls: bez reklāmām, bez korporatīvās novērošanas, ētiska projektēšana un decentralizēšana. Pārvaldi savus datus ar Mastodon!' contact_missing: Nav uzstādīts contact_unavailable: N/A hosted_on: Mastodon mitināts %{domain} @@ -613,6 +613,7 @@ lv: created_at: Ziņoti delete_and_resolve: Izdzēst rakstus forwarded: Pārsūtīti + forwarded_replies_explanation: Šis ziņojums ir no attāla lietotāja un par attālu saturu. Tas tika pārvirzīts šeit, jo saturs, par kuru tika ziņots, ir atbilde vienam no šī servera lietotājiem. forwarded_to: Pārsūtīti %{domain} mark_as_resolved: Atzīmēt kā atrisinātu mark_as_sensitive: Atzīmēt kā sensitīvu @@ -633,6 +634,7 @@ lv: report: 'Ziņojums #%{id}' reported_account: Ziņotais konts reported_by: Ziņoja + reported_with_application: Ziņots no lietotnes resolved: Atrisināts resolved_msg: Ziņojums veiksmīgi atrisināts! skip_to_actions: Pāriet uz darbībām @@ -876,7 +878,13 @@ lv: pending_review: Gaida pārskatīšanu review_requested: Pieprasīta pārskatīšana reviewed: Pārskatīts + title: Stāvoklis + name: Nosaukums + newest: Jaunākie + oldest: Vecākie + reset: Atiestatīt review: Pārskatīt stāvokli + search: Meklēt title: Tēmturi updated_msg: Tēmtura iestatījumi ir veiksmīgi atjaunināti title: Administrēšana @@ -1106,7 +1114,7 @@ lv: new_confirmation_instructions_sent: Pēc dažām minūtēm saņemsi jaunu e-pasta ziņojumu ar apstiprinājuma saiti. title: Pārbaudi savu iesūtni sign_in: - preamble_html: Jāpiesakās ar saviem %{domain} piekļuves datiem. Ja Tavs konts tiek mitināts citā serverī, Tu nevarēsi šeit pieteikties. + preamble_html: Jāpiesakās ar saviem %{domain} piekļuves datiem. Ja konts tiek mitināts citā serverī, šeit nevarēs pieteikties. title: Pierakstīties %{domain} sign_up: manual_review: Reģistrācijas domēnā %{domain} manuāli pārbauda mūsu moderatori. Lai palīdzētu mums apstrādāt tavu reģistrāciju, uzraksti mazliet par sevi un to, kāpēc vēlies kontu %{domain}. @@ -1121,6 +1129,9 @@ lv: view_strikes: Skati iepriekšējos brīdinājumus par savu kontu too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz. use_security_key: Lietot drošības atslēgu + author_attribution: + s_blog: "%{name} emuāri" + title: Autora attiecinājums challenge: confirm: Turpināt hint_html: "Padoms: Nākamās stundas laikā mēs tev vairs neprasīsim paroli." @@ -1129,7 +1140,6 @@ lv: crypto: errors: invalid_key: nav derīga Ed25519 vai Curve25519 atslēga - invalid_signature: nav derīgs Ed25519 paraksts date: formats: default: "%b %d, %Y" @@ -1158,6 +1168,9 @@ lv: before: 'Pirms turpināšanas lūgums uzmanīgi izlasīt šīs piezīmes:' caches: Citu serveru kešatmiņā saglabātais saturs var saglabāties data_removal: Tavas ziņas un citi dati tiks neatgriezeniski noņemti + email_change_html: Savu e-pasta adresi var mainīt bez sava konta izdzēšanas + email_contact_html: Ja tas joprojām nav saņemts, var nosūtīt e-pastu uz %{email}, lai saņemtu palīdzību + email_reconfirmation_html: Ja netiek saņemts apstiprinājuma e-pasta ziņojums, to var pieprasīt vēlreiz irreversible: Tu nevarēsi atjaunot vai atkārtoti aktivizēt savu kontu more_details_html: Plašāku informāciju skatīt privātuma politika. username_available: Tavs lietotājvārds atkal būs pieejams @@ -1377,6 +1390,7 @@ lv: '86400': 1 diena expires_in_prompt: Nekad generate: Ģenerēt uzaicinājuma saiti + invalid: Šis uzaicinājums nav derīgs invited_by: 'Tevi uzaicināja:' max_uses: one: 1 lietojums @@ -1395,6 +1409,7 @@ lv: authentication_methods: otp: divpakāpju autentifikācijas lietotne password: parole + sign_in_token: e-pasta drošības kods webauthn: drošības atslēgas description_html: Ja pamani darbības, kuras neatpazīsti, jāapsver iespēja nomainīt savu paroli un iespējot divpakāpju autentifikāciju. empty: Nav pieejama autentifikācijas vēsture @@ -1820,14 +1835,20 @@ lv: explanation: Šeit ir daži padomi, kā sākt darbu feature_action: Uzzināt vairāk feature_creativity: Mastodon nodrošina skaņas, video un attēlu ierakstus, pieejamības aprakstus, aptaujas, satura brīdinājumus, animētus profila attēlus, pielāgotas emocijzīmes, sīktēlu apgriešanas vadīklas un vēl, lai palīdzētu Tev sevi izpaust tiešsaistē. Vai Tu izplati savu mākslu, mūziku vai aplādes, Mastodon ir šeit ar Tevi. + feature_moderation_title: Moderēšana, kādai tai būtu jābūt follow_action: Sekot + follow_step: Sekošana aizraujošiem cilvēkiem ir viss, par ko ir Mastodon. follow_title: Pielāgo savu mājas barotni + follows_subtitle: Seko labi zināmiem kontiem follows_title: Kam sekot follows_view_more: Rādīt vairāk cilvēku, kuriem sekot hashtags_recent_count: one: "%{people} cilvēks pēdējās 2 dienās" other: "%{people} cilvēki pēdējās 2 dienās" zero: "%{people} cilvēku pēdējās divās dienās" + hashtags_subtitle: Izpēti, kas pēdējās divās dienāš ir piesasitījis cilvēku uzmanību + hashtags_title: Izplatīti tēmturi + hashtags_view_more: Skatīt vairāk izplatītu tēmturu post_action: Rakstīt post_step: Pasveicini pasauli ar tekstu, fotoattēliem, video vai aptaujām! post_title: Izveido savu pirmo ierakstu @@ -1843,6 +1864,7 @@ lv: invalid_otp_token: Nederīgs divfaktora kods otp_lost_help_html: Ja esi zaudējis piekļuvi abiem, tu vari sazināties ar %{email} rate_limited: Pārāk daudz autentifikācijas mēģinājumu, vēlāk jāmēģina vēlreiz. + seamless_external_login: Tu esi pieteicies caur ārēju pakalpojumu, tāpēc paroles un e-pasta iestatījumi nav pieejami. signed_in_as: 'Pieteicies kā:' verification: extra_instructions_html: Padoms: saite Tavā vietnē var būt neredzama. Svarīga daļa irPost by @#{object.account.pretty_acct}@#{provider_name}-View on Mastodon+Post by @#{object.account.pretty_acct}@#{provider_name}+View on Mastodon
rel="me"
, kas novērš uzdošanos vietnēs ar lietotāju izveidotu saturu. Tu pat vari lapas galvenē izmantot tagu link
, nevis a
, taču HTML ir jābūt pieejamam bez JavaScript izpildīšanas.
@@ -1851,6 +1873,7 @@ lv:
instructions_html: Ievieto starpliktuvē un ielīmē tālāk norādīto kodu savas tīmekļvietnes HTML! Tad pievieno savas tīmekļvietnes adresi vienā no papildu laukiem savā profila cilnē "Labot profilu" un saglabā izmaiņas!
verification: Pārbaude
verified_links: Tavas verifikācijas saites
+ website_verification: Tīmekļvietnes apliecināšana
webauthn_credentials:
add: Pievienot jaunu drošības atslēgu
create:
diff --git a/config/locales/ms.yml b/config/locales/ms.yml
index 39c695a5398adf..0c0ffb69bfc849 100644
--- a/config/locales/ms.yml
+++ b/config/locales/ms.yml
@@ -1051,7 +1051,6 @@ ms:
crypto:
errors:
invalid_key: bukan kunci Ed25519 atau Curve25519 yang sah
- invalid_signature: bukan tandatangan Ed25519 yang sah
date:
formats:
default: "%b %d, %Y"
diff --git a/config/locales/my.yml b/config/locales/my.yml
index 92464523a06049..6acaa34cdc5c74 100644
--- a/config/locales/my.yml
+++ b/config/locales/my.yml
@@ -1044,7 +1044,6 @@ my:
crypto:
errors:
invalid_key: မှန်ကန်သော Ed25519 သို့မဟုတ် Curve25519 ကီး မဟုတ်ပါ။
- invalid_signature: မှန်ကန်သော Ed25519 လက်မှတ်မဟုတ်ပါ
date:
formats:
default: "%b %d, %Y"
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 63656991a843a6..afc4652bf600cc 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -1174,7 +1174,6 @@ nl:
crypto:
errors:
invalid_key: is geen geldige Ed25519- of Curve25519-sleutel
- invalid_signature: is geen geldige Ed25519-handtekening
date:
formats:
default: "%d %b %Y"
diff --git a/config/locales/nn.yml b/config/locales/nn.yml
index b7beeb4263ed53..dcf571a7923c46 100644
--- a/config/locales/nn.yml
+++ b/config/locales/nn.yml
@@ -1174,7 +1174,6 @@ nn:
crypto:
errors:
invalid_key: er ikkje ein gild Ed25519 eller Curve25519 nykel
- invalid_signature: er ikkje ein gild Ed25519-signatur
date:
formats:
default: "%d. %b, %Y"
diff --git a/config/locales/no.yml b/config/locales/no.yml
index 635ceedde4c4d3..1f0b6baccecfd8 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -1083,7 +1083,6 @@
crypto:
errors:
invalid_key: er ikke en gyldig Ed25519- eller Curve25519-nøkkel
- invalid_signature: er ikke en gyldig Ed25519-signatur
date:
formats:
default: "%d. %b, %Y"
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index f0d09cb2d30178..314adf885f8dc6 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -1210,7 +1210,6 @@ pl:
crypto:
errors:
invalid_key: nie jest prawidłowym kluczem Ed25519 lub Curve25519
- invalid_signature: nie jest prawidłowym podpisem Ed25519
date:
formats:
default: "%d. %b %Y"
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index d1140f36454458..7742a80569c1c8 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -1174,7 +1174,6 @@ pt-BR:
crypto:
errors:
invalid_key: não é uma chave Ed25519 ou Curve25519 válida
- invalid_signature: não é uma assinatura Ed25519 válida
date:
formats:
default: "%d %b, %Y"
diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml
index f155490eb5f2c2..d6c5c4a6ff01f7 100644
--- a/config/locales/pt-PT.yml
+++ b/config/locales/pt-PT.yml
@@ -1174,7 +1174,6 @@ pt-PT:
crypto:
errors:
invalid_key: não é uma chave Ed25519 ou Curve25519 válida
- invalid_signature: não é uma assinatura Ed25519 válida
date:
formats:
default: "%d %b %Y"
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index d66dded89be07d..387772749006e1 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -28,6 +28,8 @@ ru:
admin:
account_actions:
action: Выполнить действие
+ already_silenced: Эта учетная запись уже ограничена.
+ already_suspended: Действие этой учетной записи уже приостановлено.
title: Произвести модерацию учётной записи %{acct}
account_moderation_notes:
create: Создать
@@ -49,6 +51,7 @@ ru:
title: Сменить e-mail для %{username}
change_role:
changed_msg: Роль успешно изменена!
+ edit_roles: Управление ролями пользователей
label: Изменить роль
no_role: Нет роли
title: Изменить роль %{username}
@@ -61,6 +64,7 @@ ru:
demote: Разжаловать
destroyed_msg: Данные %{username} поставлены в очередь на удаление
disable: Заморозка
+ disable_sign_in_token_auth: Отключите аутентификацию с помощью маркера электронной почты
disable_two_factor_authentication: Отключить 2FA
disabled: Отключено
display_name: Отображаемое имя
@@ -69,6 +73,7 @@ ru:
email: E-mail
email_status: Статус e-mail
enable: Включить
+ enable_sign_in_token_auth: Включите аутентификацию с помощью маркера электронной почты
enabled: Включен
enabled_msg: Учётная запись %{username} успешно разморожена
followers: Подписчики
@@ -135,6 +140,7 @@ ru:
resubscribe: Переподписаться
role: Роль
search: Поиск
+ search_same_email_domain: Другие пользователи с тем же почтовым доменом
search_same_ip: Другие пользователи с таким же IP
security: Безопасность
security_measures:
@@ -180,17 +186,21 @@ ru:
confirm_user: Подтверждение пользователей
create_account_warning: Выдача предупреждения
create_announcement: Создание объявлений
+ create_canonical_email_block: Создать блок электронной почты
create_custom_emoji: Добавление эмодзи
create_domain_allow: Разрешение доменов
create_domain_block: Блокировка доменов
+ create_email_domain_block: Создать блок домена электронной почты
create_ip_block: Создание правил для IP-адресов
create_unavailable_domain: Добавление домена в список недоступных
create_user_role: Создать роль
demote_user: Разжалование пользователей
destroy_announcement: Удаление объявлений
+ destroy_canonical_email_block: Удалить блок электронной почты
destroy_custom_emoji: Удаление эмодзи
destroy_domain_allow: Отзыв разрешений для доменов
destroy_domain_block: Разблокировка доменов
+ destroy_email_domain_block: Удалить блок домена электронной почты
destroy_instance: Очистить домен
destroy_ip_block: Удаление правил для IP-адресов
destroy_status: Удаление постов
@@ -198,8 +208,10 @@ ru:
destroy_user_role: Удалить роль
disable_2fa_user: Отключение 2FA
disable_custom_emoji: Отключение эмодзи
+ disable_sign_in_token_auth_user: Отключить аутентификацию пользователя с помощью токена электронной почты
disable_user: Заморозка пользователей
enable_custom_emoji: Включение эмодзи
+ enable_sign_in_token_auth_user: Включить аутентификацию пользователя с помощью токена электронной почты
enable_user: Разморозка пользователей
memorialize_account: Присвоение пользователям статуса «мемориала»
promote_user: Повышение пользователей
@@ -229,20 +241,26 @@ ru:
approve_appeal_html: "%{name} одобрил апелляцию на умеренное решение от %{target}"
approve_user_html: "%{name} утвердил(а) регистрацию %{target}"
assigned_to_self_report_html: "%{name} назначил(а) себя для решения жалобы %{target}"
+ change_email_user_html: "%{name} изменил адрес электронной почты пользователя %{target}"
change_role_user_html: "%{name} изменил(а) роль %{target}"
+ confirm_user_html: "%{name} подтвержденный адрес электронной почты пользователя %{target}"
create_account_warning_html: "%{name} выдал(а) предупреждение %{target}"
create_announcement_html: "%{name} создал(а) новое объявление %{target}"
+ create_canonical_email_block_html: "%{name} заблокировал письмо с хэшем %{target}"
create_custom_emoji_html: "%{name} загрузил(а) новый эмодзи %{target}"
create_domain_allow_html: "%{name} разрешил(а) федерацию с доменом %{target}"
create_domain_block_html: "%{name} заблокировал(а) домен %{target}"
+ create_email_domain_block_html: "%{name} заблокированный почтовый домен %{target}"
create_ip_block_html: "%{name} создал(а) правило для IP %{target}"
create_unavailable_domain_html: "%{name} приостановил доставку на узел %{target}"
create_user_role_html: "%{name} создал(а) роль %{target}"
demote_user_html: "%{name} разжаловал(а) пользователя %{target}"
destroy_announcement_html: "%{name} удалил(а) объявление %{target}"
+ destroy_canonical_email_block_html: "%{name} разблокированное письмо с хэшем %{target}"
destroy_custom_emoji_html: "%{name} удалил(а) эмодзи %{target}"
destroy_domain_allow_html: "%{name} запретил(а) федерацию с доменом %{target}"
destroy_domain_block_html: "%{name} снял(а) блокировку с домена %{target}"
+ destroy_email_domain_block_html: "%{name} разблокированный почтовый домен %{target}"
destroy_instance_html: "%{name} очистил(а) данные для домена %{target}"
destroy_ip_block_html: "%{name} удалил(а) правило для IP %{target}"
destroy_status_html: "%{name} удалил(а) пост пользователя %{target}"
@@ -250,8 +268,10 @@ ru:
destroy_user_role_html: "%{name} удалил(а) роль %{target}"
disable_2fa_user_html: "%{name} отключил(а) требование двухэтапной авторизации для пользователя %{target}"
disable_custom_emoji_html: "%{name} отключил(а) эмодзи %{target}"
+ disable_sign_in_token_auth_user_html: "%{name} отключил аутентификацию по маркеру электронной почты для %{target}"
disable_user_html: "%{name} заморозил(а) пользователя %{target}"
enable_custom_emoji_html: "%{name} включил(а) эмодзи %{target}"
+ enable_sign_in_token_auth_user_html: "%{name} включил аутентификацию с помощью маркера электронной почты для %{target}"
enable_user_html: "%{name} разморозил(а) пользователя %{target}"
memorialize_account_html: "%{name} перевел(а) учётную запись пользователя %{target} в статус памятника"
promote_user_html: "%{name} повысил(а) пользователя %{target}"
@@ -259,6 +279,7 @@ ru:
reject_user_html: "%{name} отклонил(а) регистрацию %{target}"
remove_avatar_user_html: "%{name} убрал(а) аватарку пользователя %{target}"
reopen_report_html: "%{name} повторно открыл(а) жалобу %{target}"
+ resend_user_html: "%{name} повторно отправил письмо с подтверждением для %{target}"
reset_password_user_html: "%{name} сбросил(а) пароль пользователя %{target}"
resolve_report_html: "%{name} решил(а) жалобу %{target}"
sensitive_account_html: "%{name} установил(а) отметку файлов %{target} как «деликатного характера»"
@@ -273,6 +294,7 @@ ru:
update_custom_emoji_html: "%{name} обновил(а) эмодзи %{target}"
update_domain_block_html: "%{name} обновил(а) блокировку домена для %{target}"
update_ip_block_html: "%{name} изменил(а) правило для IP %{target}"
+ update_report_html: "%{name} обновленный отчет %{target}"
update_status_html: "%{name} изменил(а) пост пользователя %{target}"
update_user_role_html: "%{name} изменил(а) роль %{target}"
deleted_account: удалённая учётная запись
@@ -437,6 +459,8 @@ ru:
new:
create: Создать блокировку
resolve: Проверить домен
+ title: Блокировка нового почтового домена
+ no_email_domain_block_selected: Блоки почтовых доменов не были изменены, так как ни один из них не был выбран
not_permitted: Не разрешено
resolved_through_html: Разрешено через %{domain}
title: Заблокированные e-mail домены
@@ -464,6 +488,9 @@ ru:
title: Рекомендации подписок
unsuppress: Восстановить рекомендацию
instances:
+ audit_log:
+ title: Последние журналы аудита
+ view_all: Просмотр полных журналов аудита
availability:
description_html:
few: Если доставка в домен завершается сбоем %{count} дня, дальнейшие попытки доставки предприниматься не будут, пока не будет получена доставка из домена.
@@ -599,6 +626,7 @@ ru:
silence_description_html: Учетная запись будет видна только тем пользователям, которые уже подписаны на неё, либо открыли его вручную. Это действие можно отменить в любой момент, и отменяет все жалобы против аккаунта.
suspend_description_html: Аккаунт и все его содержимое будут недоступны и в конечном итоге удалены, и взаимодействие с ним будет невозможно. Это действие можно отменить в течение 30 дней. Отменяет все жалобы против этого аккаунта.
actions_description_remote_html: Решите вопрос о том, какие меры необходимо принять для урегулирования этой жалобы. Это повлияет только на то, как ваш сервер взаимодействует с этим удаленным аккаунтом и обрабатывает его содержимое.
+ actions_no_posts: У этого отчета нет связанных с ним сообщений для удаления
add_to_report: Прикрепить ещё
already_suspended_badges:
local: На этом сервере уже забанен
@@ -639,6 +667,7 @@ ru:
report: Жалоба №%{id}
reported_account: Учётная запись нарушителя
reported_by: Отправитель жалобы
+ reported_with_application: Сообщается с приложением
resolved: Решённые
resolved_msg: Жалоба обработана, спасибо!
skip_to_actions: Перейти к действиям
@@ -661,6 +690,7 @@ ru:
delete_data_html: Удалить профиль и контент @%{acct} через 30 дней, если за это время они не будут разблокированы
preview_preamble_html: "@%{acct} получит предупреждение со следующим содержанием:"
record_strike_html: Запишите замечание против @%{acct}, чтобы помочь вам в решении будущих нарушений с этого аккаунта
+ send_email_html: Отправить @%{acct} предупреждающее письмо
warning_placeholder: Необязательное дополнительное обоснование действия модерации.
target_origin: Происхождение объекта жалобы
title: Жалобы
@@ -704,6 +734,7 @@ ru:
manage_appeals: Управление апелляциями
manage_appeals_description: Позволяет пользователям просматривать апелляции на действия модерации
manage_blocks: Управление блоками
+ manage_blocks_description: Позволить пользователям блокировать провайдеров электронной почты и IP-адреса
manage_custom_emojis: Управление смайлами
manage_custom_emojis_description: Позволяет пользователям управлять пользовательскими эмодзи на сервере
manage_federation: Управление Федерацией
@@ -776,6 +807,7 @@ ru:
disabled: Никому
users: Залогиненным локальным пользователям
registrations:
+ moderation_recommandation: Убедитесь, что у вас есть адекватная и оперативная команда модераторов, прежде чем открывать регистрацию для всех желающих!
preamble: Контролируйте, кто может создать учетную запись на вашем сервере.
title: Регистрации
registrations_mode:
@@ -783,6 +815,7 @@ ru:
approved: Для регистрации требуется подтверждение
none: Никто не может регистрироваться
open: Все могут регистрироваться
+ warning_hint: Мы рекомендуем использовать "Требуется одобрение для регистрации", если вы не уверены, что ваша команда модераторов сможет своевременно справиться со спамом и вредоносными регистрациями.
security:
authorized_fetch: Требовать аутентификацию от федеративных серверов
authorized_fetch_hint: Требование аутентификации от федеративных серверов позволяет более строго соблюдать блокировки как на уровне пользователя, так и на уровне сервера. Однако при этом снижается производительность, уменьшается охват ваших ответов и могут возникнуть проблемы совместимости с некоторыми федеративными сервисами. Кроме того, это не помешает специальным исполнителям получать ваши публичные сообщения и учётные записи.
@@ -794,6 +827,7 @@ ru:
destroyed_msg: Файл успешно удалён.
software_updates:
critical_update: Критично — пожалуйста, обновите как можно скорее
+ description: Рекомендуется поддерживать установку Mastodon в актуальном состоянии, чтобы воспользоваться последними исправлениями и функциями. Кроме того, иногда очень важно своевременно обновлять Mastodon, чтобы избежать проблем с безопасностью. По этим причинам Mastodon проверяет наличие обновлений каждые 30 минут и уведомляет вас об этом в соответствии с вашими предпочтениями в отношении уведомлений по электронной почте.
documentation_link: Узнать больше
release_notes: Примечания к выпуску
title: Доступные обновления
@@ -881,17 +915,38 @@ ru:
message_html: "Ваше хранилище объектов неправильно настроено. Безопасность ваших пользователей находится под угрозой"
tags:
moderation:
+ not_trendable: Не в тренде
+ not_usable: Невозможно использовать
+ pending_review: В ожидании обзора
+ review_requested: Обзор запрошен
+ reviewed: Рассмотрено
title: Статус
+ trendable: Трендовый
+ unreviewed: Без рецензии
+ usable: Полезное
+ name: Название
+ newest: Новейший
+ oldest: Старейший
+ open: Посмотреть публично
+ reset: Сброс
review: Состояние проверки
+ search: Поиск
+ title: Хэштеги
updated_msg: Настройки хэштега обновлены
title: Администрирование
trends:
allow: Разрешить
approved: Принятые
+ confirm_allow: Вы уверены, что хотите разрешить выбранные теги?
+ confirm_disallow: Вы уверены, что хотите запретить выбранные теги?
disallow: Отклонить
links:
allow: Разрешить ссылку
allow_provider: Разрешить издание
+ confirm_allow: Вы уверены, что хотите разрешить выбранные ссылки?
+ confirm_allow_provider: Вы уверены, что хотите разрешить выбранных провайдеров?
+ confirm_disallow: Вы уверены, что хотите запретить выбранные ссылки?
+ confirm_disallow_provider: Вы уверены, что хотите запретить выбранных поставщиков?
description_html: Это ссылки, которыми в настоящее время много пользуются аккаунты, с которых ваш сервер видит сообщения. Это может помочь вашим пользователям узнать, что происходит в мире. Никакие ссылки не отображаются публично, пока вы не одобрите издателя. Вы также можете разрешить или отклонить индивидуальные ссылки.
disallow: Запретить ссылку
disallow_provider: Отклонить издание
@@ -917,6 +972,10 @@ ru:
statuses:
allow: Разрешить пост
allow_account: Разрешить автора
+ confirm_allow: Вы уверены, что хотите разрешить выбранные статусы?
+ confirm_allow_account: Вы уверены, что хотите разрешить выбранные учетные записи?
+ confirm_disallow: Вы уверены, что хотите запретить выбранные статусы?
+ confirm_disallow_account: Вы уверены, что хотите запретить выбранные учетные записи?
description_html: Это посты, которыми на вашем сервере в данный момент часто делятся и предпочитают, что может помочь вашим новым и постоянным пользователям найти больше людей, чтобы на них подписаться. Посты не будут отображаться публично, пока вы не одобрите автора, а автор не разрешит предлагать его аккаунт другим. Вы также можете разрешить или отклонить отдельные сообщения.
disallow: Запретить пост
disallow_account: Запретить автора
@@ -953,12 +1012,14 @@ ru:
many: За последнюю неделю использовало %{count} человек
one: За последнюю неделю использовал один человек
other: За последнюю неделю использовал %{count} человек
+ title: Рекомендации и тенденции
trending: Популярное
warning_presets:
add_new: Добавить
delete: Удалить
edit_preset: Удалить шаблон предупреждения
empty: Вы еще не определили пресеты предупреждений.
+ title: Предупреждающие пред установки
webhooks:
add_new: Добавить конечную точку
delete: Удалить
@@ -982,6 +1043,9 @@ ru:
title: Вебхуки
webhook: Вебхук
admin_mailer:
+ auto_close_registrations:
+ body: В связи с отсутствием активности модераторов в последнее время, регистрация на %{instance} была автоматически переведена в режим, требующий ручной проверки, чтобы предотвратить использование %{instance} в качестве платформы для потенциальных плохих игроков. Вы можете в любой момент переключить его обратно на открытые регистрации.
+ subject: Регистрации для %{instance} были автоматически переведены в разряд требующих одобрения
new_appeal:
actions:
delete_statuses: удалить их посты
@@ -1035,7 +1099,9 @@ ru:
guide_link_text: Каждый может внести свой вклад.
sensitive_content: Содержимое деликатного характера
application_mailer:
+ notification_preferences: Изменение предпочтений электронной почты
salutation: "%{name},"
+ settings: 'Измените настройки электронной почты: %{link}'
unsubscribe: Отписаться
view: 'Просмотр:'
view_profile: Просмотреть профиль
@@ -1055,6 +1121,7 @@ ru:
hint_html: Еще одна вещь! Нам нужно подтвердить, что вы человек (так что мы можем держать спам!). Решите капчу ниже и нажмите кнопку «Продолжить».
title: Проверка безопасности
confirmations:
+ awaiting_review: Ваш адрес электронной почты подтвержден! Сотрудники %{domain} сейчас рассматривают вашу регистрацию. Вы получите письмо, если они одобрят вашу учетную запись!
awaiting_review_title: Ваша регистрация проверяется
clicking_this_link: нажатие на эту ссылку
login_link: войти
@@ -1062,6 +1129,7 @@ ru:
redirect_to_app_html: Вы должны были перенаправлены на приложение %{app_name}. Если этого не произошло, попробуйте %{clicking_this_link} или вернитесь к приложению вручную.
registration_complete: Ваша регистрация на %{domain} завершена!
welcome_title: Добро пожаловать, %{name}!
+ wrong_email_hint: Если этот адрес электронной почты неверен, вы можете изменить его в настройках аккаунта.
delete_account: Удалить учётную запись
delete_account_html: Удалить свою учётную запись можно в два счёта здесь, но прежде у вас будет спрошено подтверждение.
description:
@@ -1082,6 +1150,7 @@ ru:
or_log_in_with: Или войти с помощью
privacy_policy_agreement_html: Мной прочитана и принята политика конфиденциальности
progress:
+ confirm: Подтвердите электронную почту
details: Ваши данные
review: Наш обзор
rules: Принять правила
@@ -1103,8 +1172,10 @@ ru:
security: Безопасность
set_new_password: Задать новый пароль
setup:
+ email_below_hint_html: Проверьте папку "Спам" или запросите другую. Вы можете исправить свой адрес электронной почты, если он неправильный.
email_settings_hint_html: Нажмите на ссылку, которую мы отправили вам для проверки %{email}. Мы будем ждать прямо здесь.
link_not_received: Не получили ссылку?
+ new_confirmation_instructions_sent: Через несколько минут вы получите новое письмо со ссылкой для подтверждения!
title: Проверьте свой почтовый ящик
sign_in:
preamble_html: Войдите, используя ваши учётные данные %{domain}. Если ваша учётная запись размещена на другом сервере, вы не сможете здесь войти.
@@ -1115,12 +1186,20 @@ ru:
title: Зарегистрируйтесь в %{domain}.
status:
account_status: Статус учётной записи
+ confirming: Жду подтверждения по электронной почте.
functional: Ваша учётная запись в полном порядке.
+ pending: Ваша заявка находится на рассмотрении у наших сотрудников. Это может занять некоторое время. Вы получите электронное письмо, если ваша заявка будет одобрена.
redirecting_to: Ваша учётная запись деактивированна, потому что вы настроили перенаправление на %{acct}.
self_destruct: Поскольку %{domain} закрывается, вы получите ограниченный доступ к вашей учетной записи.
view_strikes: Просмотр предыдущих замечаний в адрес вашей учетной записи
too_fast: Форма отправлена слишком быстро, попробуйте еще раз.
use_security_key: Использовать ключ безопасности
+ author_attribution:
+ example_title: Образец текста
+ hint_html: Контролируйте, как вы будете отмечены при обмене ссылками на Mastodon.
+ more_from_html: Больше от %{name}
+ s_blog: "%{name}'S Блог"
+ title: Авторская атрибуция
challenge:
confirm: Продолжить
hint_html: "Подсказка: мы не будем спрашивать пароль повторно в течение часа."
@@ -1129,7 +1208,6 @@ ru:
crypto:
errors:
invalid_key: не является допустимым Ed25519 или Curve25519 ключом
- invalid_signature: не является допустимой Ed25519 подписью
date:
formats:
default: "%d %b %Y"
@@ -1158,6 +1236,9 @@ ru:
before: 'Внимательно прочитайте следующую информацию перед началом:'
caches: Некоторые данные, обработанные другими узлами, однако, могут храниться ещё какое-то время
data_removal: Все ваши золотые посты, шикарный профиль и прочие данные будут безвозвратно уничтожены
+ email_change_html: Вы можете изменить свой адрес электронной почты, не удаляя свою учетную запись
+ email_contact_html: Если оно все еще не пришло, вы можете обратиться за помощью по электронной почте %{email}
+ email_reconfirmation_html: Если вы не получили подтверждение по электронной почте, вы можете запросить его снова
irreversible: После удаления восстановить или повторно активировать учётную запись не получится
more_details_html: За всеми подробностями, изучите политику конфиденциальности.
username_available: Ваше имя пользователя снова станет доступным
@@ -1404,6 +1485,7 @@ ru:
authentication_methods:
otp: приложение двухфакторной аутентификации
password: пароль
+ sign_in_token: код безопасности электронной почты
webauthn: ключи безопасности
description_html: Если вы видите неопознанное действие, смените пароль и/или включите двухфакторную авторизацию.
empty: Нет доступной истории входов
@@ -1414,10 +1496,20 @@ ru:
unsubscribe:
action: Да, отписаться
complete: Подписка отменена
+ emails:
+ notification_emails:
+ favourite: любимые электронные письма с уведомлениями
+ follow: Следить за электронными сообщениями
+ follow_request: Письма с просьбой о помощи
+ mention: Упоминание электронных писем с уведомлениями
+ reblog: Уведомления по электронной почте
+ resubscribe_html: Если вы отписались от рассылки по ошибке, вы можете повторно подписаться на рассылку в настройках настроек почтовых уведомлений.
+ success_html: Вы больше не будете получать %{type} для Mastodon на %{domain} на вашу электронную почту %{email}.
title: Отписаться
media_attachments:
validations:
images_and_video: Нельзя добавить видео к посту с изображениями
+ not_found: Медиа %{ids} не найдено или уже прикреплено к другому сообщению
not_ready: Не удаётся прикрепить файлы, обработка которых не завершена. Повторите попытку чуть позже!
too_many: Нельзя добавить более 4 файлов
migrations:
@@ -1494,6 +1586,8 @@ ru:
update:
subject: "%{name} изменил(а) пост"
notifications:
+ administration_emails: Уведомления администратора по электронной почте
+ email_events: События для уведомлений по электронной почте
email_events_hint: 'Выберите события, для которых вы хотели бы получать уведомления:'
number:
human:
@@ -1652,16 +1746,26 @@ ru:
import: Импорт
import_and_export: Импорт и экспорт
migrate: Миграция учётной записи
+ notifications: E-mail уведомление
preferences: Настройки
profile: Профиль
relationships: Подписки и подписчики
+ severed_relationships: Разорванные отношения
statuses_cleanup: Авто-удаление постов
strikes: Замечания модерации
two_factor_authentication: Подтверждение входа
webauthn_authentication: Ключи безопасности
severed_relationships:
+ download: Скачать (%{count})
event_type:
+ account_suspension: Приостановка аккаунта (%{target_name})
+ domain_block: Приостановка сервера (%{target_name})
user_domain_block: Вы заблокировали %{target_name}
+ lost_followers: Потерянные подписчики
+ lost_follows: Потерянный следует
+ preamble: Вы можете потерять подписчиков и последователей, если заблокируете домен или, если ваши модераторы решат приостановить работу удаленного сервера. Когда это произойдет, вы сможете загрузить списки разорванных отношений, чтобы проверить их и, возможно, импортировать на другой сервер.
+ purged: Информация об этом сервере была удалена администраторами вашего сервера.
+ type: Событие
statuses:
attached:
audio:
@@ -1752,6 +1856,7 @@ ru:
contrast: Mastodon (высококонтрастная)
default: Mastodon (тёмная)
mastodon-light: Mastodon (светлая)
+ system: Автоматически (используйте системную тему)
time:
formats:
default: "%d %b %Y, %H:%M"
@@ -1840,8 +1945,45 @@ ru:
suspend: Учётная запись заблокирована
welcome:
apps_android_action: Скачать на Google Play
+ apps_ios_action: Скачать в App Store
+ apps_step: Загрузите наши официальные приложения.
+ apps_title: Приложения Mastodon
+ checklist_subtitle: 'Давайте начнем знакомство с этим новым социальным рубежом:'
+ checklist_title: Приветственный контрольный список
+ edit_profile_action: Персонализация
+ edit_profile_step: Усильте взаимодействие, заполнив полный профиль.
+ edit_profile_title: Персонализируйте свой профиль
explanation: Вот несколько советов для новичков
feature_action: Подробнее
+ feature_audience: Mastodon предоставляет вам уникальную возможность управлять своей аудиторией без посредников. Mastodon, развернутый на вашей собственной инфраструктуре, позволяет вам следить и быть преследуемым с любого другого сервера Mastodon в Интернете и не контролируется никем, кроме вас.
+ feature_audience_title: Создайте уверенную аудиторию
+ feature_control: Вы сами знаете, что хотите видеть в своей ленте. Никаких алгоритмов или рекламы, чтобы тратить ваше время. Следите за любым человеком на любом сервере Mastodon с одного аккаунта и получайте его сообщения в хронологическом порядке, а также сделайте свой уголок интернета немного больше похожим на себя.
+ feature_control_title: Контролируйте свой график
+ feature_creativity: Mastodon поддерживает аудио-, видео- и фотопосты, описания доступности, опросы, предупреждения о содержании, анимированные аватары, пользовательские emojis, управление обрезкой миниатюр и многое другое, чтобы помочь вам выразить себя в Интернете. Публикуете ли вы свои работы, музыку или подкаст, Mastodon всегда готов помочь вам.
+ feature_creativity_title: Непревзойденная креативность
+ feature_moderation: Mastodon возвращает принятие решений в ваши руки. Каждый сервер создает свои собственные правила и нормы, которые соблюдаются локально, а не сверху вниз, как в корпоративных социальных сетях, что позволяет наиболее гибко реагировать на потребности различных групп людей. Присоединяйтесь к серверу с правилами, с которыми вы согласны, или создайте свой собственный.
+ feature_moderation_title: Модерирование, каким оно должно быть
+ follow_action: Следуйте за
+ follow_step: Следить за интересными людьми - вот что такое Mastodon.
+ follow_title: Персонализируйте свою домашнюю ленту
+ follows_subtitle: Следите за известными аккаунтами
+ follows_title: За кем следить
+ follows_view_more: Посмотреть больше людей, за которыми стоит следить
+ hashtags_recent_count:
+ few: "%{people} человека за последние 2 дня"
+ many: "%{people} человек за последние 2 дня"
+ one: "%{people} человек за последние 2 дня"
+ other: "%{people} человек за последние 2 дня"
+ hashtags_subtitle: Изучите, что было в тренде за последние 2 дня
+ hashtags_title: Модные хэштеги
+ hashtags_view_more: Посмотреть другие трендовые хэштеги
+ post_action: Составить
+ post_step: Поприветствуйте мир с помощью текста, фотографий, видео или опросов.
+ post_title: Сделайте свой первый пост
+ share_action: Поделиться
+ share_step: Пусть ваши друзья знают, как найти вас на Mastodon.
+ share_title: Поделитесь информацией о компании Mastodon
+ sign_in_action: Зарегистрироваться
subject: Добро пожаловать в Mastodon
title: Добро пожаловать на борт, %{name}!
users:
@@ -1850,6 +1992,7 @@ ru:
invalid_otp_token: Введен неверный код двухфакторной аутентификации
otp_lost_help_html: Если Вы потеряли доступ к обоим, свяжитесь с %{email}
rate_limited: Слишком много попыток аутентификации, повторите попытку позже.
+ seamless_external_login: Вы вошли в систему через внешнюю службу, поэтому настройки пароля и электронной почты недоступны.
signed_in_as: 'Выполнен вход под именем:'
verification:
extra_instructions_html: Подсказка: Ссылка на вашем сайте может быть невидимой. Важной частью является rel="me"
, который предотвращает выдачу себя за другое лицо на сайтах с пользовательским контентом. Вы даже можете использовать тег link
в заголовке страницы вместо a
, но HTML должен быть доступен без выполнения JavaScript.
@@ -1858,6 +2001,7 @@ ru:
instructions_html: Скопируйте и вставьте код ниже в HTML вашего сайта. Затем, добавьте адрес вашего веб сайта в одно из дополнительных полей на вкладке "Редактировать профиль" и сохраните изменения.
verification: Верификация ссылок
verified_links: Ваши ссылки подтверждения
+ website_verification: Проверка веб-сайта
webauthn_credentials:
add: Добавить новый ключ безопасности
create:
diff --git a/config/locales/sc.yml b/config/locales/sc.yml
index 435749f4706385..780270ddf17b2e 100644
--- a/config/locales/sc.yml
+++ b/config/locales/sc.yml
@@ -693,7 +693,6 @@ sc:
crypto:
errors:
invalid_key: no est una crae Ed25519 o Curve25519 vàlida
- invalid_signature: no est una firma Ed25519 vàlida
date:
formats:
default: "%d %b, %Y"
diff --git a/config/locales/sco.yml b/config/locales/sco.yml
index 70143a968e84cb..97eaa21ed6d0d6 100644
--- a/config/locales/sco.yml
+++ b/config/locales/sco.yml
@@ -940,7 +940,6 @@ sco:
crypto:
errors:
invalid_key: isnae a valid Ed25519 or Curve25519 key
- invalid_signature: isnae a valid Ed25519 signature
date:
formats:
default: "%b %d, %Y"
diff --git a/config/locales/si.yml b/config/locales/si.yml
index 135a99ceb21703..8460de01da9f6a 100644
--- a/config/locales/si.yml
+++ b/config/locales/si.yml
@@ -829,7 +829,6 @@ si:
crypto:
errors:
invalid_key: වලංගු Ed25519 හෝ Curve25519 යතුරක් නොවේ
- invalid_signature: වලංගු Ed25519 අත්සනක් නොවේ
date:
formats:
default: "%Y %b %d"
diff --git a/config/locales/simple_form.es-MX.yml b/config/locales/simple_form.es-MX.yml
index 2a2d06ce9b2974..f2108828d5643b 100644
--- a/config/locales/simple_form.es-MX.yml
+++ b/config/locales/simple_form.es-MX.yml
@@ -16,12 +16,12 @@ es-MX:
account_migration:
acct: Especifique el nombre de usuario@dominio de la cuenta a la cual desea migrar
account_warning_preset:
- text: Puede usar sintaxis de toots, como URLs, hashtags y menciones
+ text: Puede usar sintaxis de publicaciones, como URLs, etiquetas y menciones
title: Opcional. No visible para el destinatario
admin_account_action:
- include_statuses: El usuario verá qué toots han causado la acción de moderación o advertencia
+ include_statuses: El usuario verá qué publicaciones han causado la acción de moderación o advertencia
send_email_notification: El usuario recibirá una explicación de lo que sucedió con respecto a su cuenta
- text_html: Opcional. Puede usar sintaxis de toots. Puede añadir configuraciones predefinidas de advertencia para ahorrar tiempo
+ text_html: Opcional. Puede usar sintaxis de publicaciones. Puede añadir configuraciones predefinidas de advertencia para ahorrar tiempo
type_html: Elige qué hacer con %{acct}
types:
disable: Evitar que el usuario utilice su cuenta, pero no eliminar ni ocultar sus contenidos.
@@ -35,7 +35,7 @@ es-MX:
ends_at: Opcional. El anuncio desaparecerá automáticamente en este momento
scheduled_at: Dejar en blanco para publicar el anuncio inmediatamente
starts_at: Opcional. En caso de que su anuncio esté vinculado a un intervalo de tiempo específico
- text: Puedes usar la sintaxis toot. Por favor ten en cuenta el espacio que ocupará el anuncio en la pantalla del usuario
+ text: Puedes usar la sintaxis de publicaciones. Por favor ten en cuenta el espacio que ocupará el anuncio en la pantalla del usuario
appeal:
text: Sólo puede apelar una amonestación a la vez
defaults:
@@ -49,12 +49,12 @@ es-MX:
email: Se le enviará un correo de confirmación
header: WEBP, PNG, GIF o JPG. Máximo %{size}. Será escalado a %{dimensions}px
inbox_url: Copia la URL de la página principal del relés que quieres utilizar
- irreversible: Los toots filtrados desaparecerán irreversiblemente, incluso si este filtro es eliminado más adelante
+ irreversible: Las publicaciones filtradas desaparecerán irreversiblemente, incluso si este filtro es eliminado más adelante
locale: El idioma de la interfaz de usuario, correos y notificaciones push
password: Utilice al menos 8 caracteres
- phrase: Se aplicará sin importar las mayúsculas o los avisos de contenido de un toot
+ phrase: Se aplicará sin importar las mayúsculas o los avisos de contenido de una publicación
scopes: Qué APIs de la aplicación tendrán acceso. Si seleccionas el alcance de nivel mas alto, no necesitas seleccionar las individuales.
- setting_aggregate_reblogs: No mostrar nuevos retoots para los toots que han sido recientemente retooteados (sólo afecta a los retoots recibidos recientemente)
+ setting_aggregate_reblogs: No mostrar nuevos impulsos para las publicaciones que han sido recientemente impulsadas (sólo afecta a las publicaciones recibidas recientemente)
setting_always_send_emails: Normalmente las notificaciones por correo electrónico no se enviarán cuando estés usando Mastodon activamente
setting_default_sensitive: El contenido multimedia sensible está oculto por defecto y puede ser mostrado con un click
setting_display_media_default: Ocultar contenido multimedia marcado como sensible
@@ -84,7 +84,7 @@ es-MX:
closed_registrations_message: Mostrado cuando los registros están cerrados
content_cache_retention_period: Todas las publicaciones de otros servidores (incluso impulsos y respuestas) se eliminarán después del número de días especificado, sin tener en cuenta la interacción del usuario local con esos mensajes. Esto incluye mensajes donde un usuario local los ha marcado como marcadores o favoritos. Las menciones privadas entre usuarios de diferentes instancias también se perderán sin posibilidad de recuperación. El uso de esta configuración está destinado a instancias de propósito especial, y rompe muchas expectativas de los usuarios cuando se implementa para un uso de propósito general.
custom_css: Puedes aplicar estilos personalizados a la versión web de Mastodon.
- favicon: WEBP, PNG, GIF o JPG. Reemplaza el favicon predeterminado de Mastodon con un icono personalizado.
+ favicon: WEBP, PNG, GIF o JPG. Reemplaza el icono predeterminado de Mastodon con un icono personalizado.
mascot: Reemplaza la ilustración en la interfaz web avanzada.
media_cache_retention_period: Los archivos multimedia de las publicaciones creadas por usuarios remotos se almacenan en caché en tu servidor. Cuando se establece un valor positivo, estos archivos se eliminarán después del número especificado de días. Si los datos multimedia se solicitan después de eliminarse, se volverán a descargar, si el contenido fuente todavía está disponible. Debido a restricciones en la frecuencia con la que las tarjetas de previsualización de enlaces realizan peticiones a sitios de terceros, se recomienda establecer este valor a al menos 14 días, o las tarjetas de previsualización de enlaces no se actualizarán bajo demanda antes de ese momento.
peers_api_enabled: Una lista de nombres de dominio que este servidor ha encontrado en el fediverso. Aquí no se incluye ningún dato sobre si usted federa con un servidor determinado, sólo que su servidor lo sabe. Esto es utilizado por los servicios que recopilan estadísticas sobre la federación en un sentido general.
@@ -130,7 +130,7 @@ es-MX:
tag:
name: Sólo se puede cambiar el cajón de las letras, por ejemplo, para que sea más legible
user:
- chosen_languages: Cuando se marca, solo se mostrarán los toots en los idiomas seleccionados en los timelines públicos
+ chosen_languages: Cuando se marca, solo se mostrarán las publicaciones en los idiomas seleccionados en las líneas de tiempo públicas
role: El rol controla qué permisos tiene el usuario.
user_role:
color: Color que se utilizará para el rol a lo largo de la interfaz de usuario, como RGB en formato hexadecimal
@@ -160,7 +160,7 @@ es-MX:
text: Texto predefinido
title: Título
admin_account_action:
- include_statuses: Incluir en el correo electrónico a los toots denunciados
+ include_statuses: Incluir en el correo electrónico a las publicaciones denunciadas
send_email_notification: Notificar al usuario por correo electrónico
text: Aviso personalizado
type: Acción
@@ -205,21 +205,21 @@ es-MX:
password: Contraseña
phrase: Palabra clave o frase
setting_advanced_layout: Habilitar interfaz web avanzada
- setting_aggregate_reblogs: Agrupar retoots en las líneas de tiempo
+ setting_aggregate_reblogs: Agrupar impulsos en las líneas de tiempo
setting_always_send_emails: Enviar siempre notificaciones por correo
setting_auto_play_gif: Reproducir automáticamente los GIFs animados
- setting_boost_modal: Mostrar ventana de confirmación antes de un Retoot
+ setting_boost_modal: Mostrar ventana de confirmación antes de impulsar
setting_default_language: Idioma de publicación
setting_default_privacy: Privacidad de publicaciones
setting_default_sensitive: Marcar siempre imágenes como sensibles
- setting_delete_modal: Mostrar diálogo de confirmación antes de borrar un toot
+ setting_delete_modal: Mostrar diálogo de confirmación antes de borrar una publicación
setting_disable_hover_cards: Desactivar vista previa del perfil al pasar el cursor
setting_disable_swiping: Deshabilitar movimientos de deslizamiento
setting_display_media: Visualización multimedia
setting_display_media_default: Por defecto
setting_display_media_hide_all: Ocultar todo
setting_display_media_show_all: Mostrar todo
- setting_expand_spoilers: Siempre expandir los toots marcados con advertencias de contenido
+ setting_expand_spoilers: Siempre expandir las publicaciones marcadas con advertencias de contenido
setting_hide_network: Ocultar tu red
setting_reduce_motion: Reducir el movimiento de las animaciones
setting_system_font_ui: Utilizar la tipografía por defecto del sistema
diff --git a/config/locales/simple_form.kab.yml b/config/locales/simple_form.kab.yml
index 68fc629d9ecebf..203b02371539a8 100644
--- a/config/locales/simple_form.kab.yml
+++ b/config/locales/simple_form.kab.yml
@@ -20,6 +20,7 @@ kab:
irreversible: Tisuffaɣ i tessazedgeḍ ad ttwakksent i lebda, ula ma tekkseḍ imsizdeg-nni ar zdat
locale: Tutlayt n ugrudem, imaylen d walɣuten yettudemren
password: Seqdec ma drus 8 n yisekkilen
+ setting_always_send_emails: S umata, ilɣa s yimayl ur d-ttwaceyyεen ara mi ara tesseqdaceḍ Mastodon s wudem urmid
setting_display_media_default: Ffer imidyaten yettwacreḍ d infariyen
setting_display_media_hide_all: Ffer yal tikkelt akk taywalt
setting_display_media_show_all: Ffer yal tikkelt teywalt yettwacreḍ d tanafrit
@@ -84,8 +85,9 @@ kab:
password: Awal uffir
phrase: Awal n tsarut neɣ tafyirt
setting_advanced_layout: Rmed agrudem n web leqqayen
- setting_default_language: Tutlayt n tira
- setting_default_privacy: Tabaḍnit n tira
+ setting_always_send_emails: Dima ttazen-d ilɣa s yimayl
+ setting_default_language: Tutlayt n usuffeɣ
+ setting_default_privacy: Tabaḍnit n usuffeɣ
setting_display_media: Askanay n imidyaten
setting_display_media_default: Akk-a kan
setting_display_media_hide_all: Ffer-iten akk
diff --git a/config/locales/simple_form.ko.yml b/config/locales/simple_form.ko.yml
index fee07fa5e0ff66..a649b4ec5a90df 100644
--- a/config/locales/simple_form.ko.yml
+++ b/config/locales/simple_form.ko.yml
@@ -3,6 +3,7 @@ ko:
simple_form:
hints:
account:
+ attribution_domains_as_text: 가짜 기여로부터 보호합니다.
discoverable: 내 공개 게시물과 프로필이 마스토돈의 다양한 추천 기능에 나타날 수 있고 프로필이 다른 사용자에게 제안될 수 있습니다
display_name: 진짜 이름 또는 재미난 이름.
fields: 홈페이지, 호칭, 나이, 뭐든지 적고 싶은 것들.
@@ -143,6 +144,7 @@ ko:
url: 이벤트가 어디로 전송될 지
labels:
account:
+ attribution_domains_as_text: 특정 웹사이트만 허용하기
discoverable: 발견하기 알고리즘에 프로필과 게시물을 추천하기
fields:
name: 라벨
diff --git a/config/locales/simple_form.lv.yml b/config/locales/simple_form.lv.yml
index 4369c3c42bb52e..ed27e08bc33466 100644
--- a/config/locales/simple_form.lv.yml
+++ b/config/locales/simple_form.lv.yml
@@ -3,7 +3,7 @@ lv:
simple_form:
hints:
account:
- attribution_domains_as_text: Aizsargā no nepatiesas piedēvēšanas.
+ attribution_domains_as_text: Aizsargā no nepatiesa attiecinājuma.
discoverable: Tavas publiskās ziņas un profils var tikt piedāvāti vai ieteikti dažādās Mastodon vietās, un tavs profils var tikt ieteikts citiem lietotājiem.
display_name: Tavs pilnais vārds vai tavs joku vārds.
fields: Tava mājas lapa, vietniekvārdi, vecums, viss, ko vēlies.
diff --git a/config/locales/simple_form.ru.yml b/config/locales/simple_form.ru.yml
index b41457e86ac6ce..3ff746451b3279 100644
--- a/config/locales/simple_form.ru.yml
+++ b/config/locales/simple_form.ru.yml
@@ -3,6 +3,7 @@ ru:
simple_form:
hints:
account:
+ attribution_domains_as_text: Защищает от ложных атрибуций.
discoverable: Ваши публичные сообщения и профиль могут быть показаны или рекомендованы в различных разделах Mastodon, и ваш профиль может быть предложен другим пользователям.
display_name: Ваше полное имя или псевдоним.
fields: Ваша домашняя страница, местоимения, возраст - все, что угодно.
@@ -77,11 +78,15 @@ ru:
warn: Скрыть отфильтрованный контент за предупреждением с указанием названия фильтра
form_admin_settings:
activity_api_enabled: Подсчёт количества локальных постов, активных пользователей и новых регистраций на еженедельной основе
+ app_icon: WEBP, PNG, GIF или JPG. Замените значок приложения по умолчанию на мобильных устройствах пользовательским значком.
backups_retention_period: Пользователи могут создавать архивы своих постов, чтобы потом их забрать. Если задать положительное значение, эти архивы автоматически удалятся с вашего хранилища через указанное число дней.
bootstrap_timeline_accounts: Эти аккаунты будут рекомендованы для подписки новым пользователям.
closed_registrations_message: Отображается, когда регистрация закрыта
+ content_cache_retention_period: Все сообщения с других серверов (включая бусты и ответы) будут удалены через указанное количество дней, независимо от того, как локальный пользователь взаимодействовал с этими сообщениями. Это касается и тех сообщений, которые локальный пользователь пометил в закладки или избранное. Приватные упоминания между пользователями из разных инстансов также будут потеряны и не смогут быть восстановлены. Использование этой настройки предназначено для экземпляров специального назначения и нарушает многие ожидания пользователей при использовании в общих целях.
custom_css: Вы можете применять пользовательские стили в веб-версии Mastodon.
+ favicon: WEBP, PNG, GIF или JPG. Заменяет стандартный фавикон Mastodon на собственный значок.
mascot: Заменяет иллюстрацию в расширенном веб-интерфейсе.
+ media_cache_retention_period: Медиафайлы из сообщений, сделанных удаленными пользователями, кэшируются на вашем сервере. При положительном значении медиафайлы будут удалены через указанное количество дней. Если медиаданные будут запрошены после удаления, они будут загружены повторно, если исходный контент все еще доступен. В связи с ограничениями на частоту опроса карточек предварительного просмотра ссылок на сторонних сайтах рекомендуется устанавливать значение не менее 14 дней, иначе карточки предварительного просмотра ссылок не будут обновляться по запросу до этого времени.
peers_api_enabled: Список доменных имен, с которыми сервер столкнулся в fediverse. Здесь нет данных о том, федерировались ли вы с данным сервером, только что ваш сервер знает об этом. Это используется службами, которые собирают статистику по федерации в общем смысле.
profile_directory: В каталоге профилей перечислены все пользователи, которые согласились быть доступными для обнаружения.
require_invite_text: Когда регистрация требует ручного одобрения, сделайте текстовый ввод "Почему вы хотите присоединиться?" обязательным, а не опциональным
@@ -114,6 +119,7 @@ ru:
sign_up_requires_approval: Новые регистрации потребуют вашего одобрения
severity: Выберите, что будет происходить с запросами с этого IP
rule:
+ hint: Необязательно. Предоставьте дополнительные сведения о правиле
text: Опишите правило или требование для пользователей на этом сервере. Постарайтесь сделать его коротким и простым
sessions:
otp: 'Введите код двухфакторной аутентификации, сгенерированный в мобильном приложении, или используйте один из ваших кодов восстановления:'
@@ -125,6 +131,7 @@ ru:
name: Вы можете изменить только регистр букв чтобы, например, сделать тег более читаемым
user:
chosen_languages: Если выбрано, то в публичных лентах будут показаны только посты на выбранных языках.
+ role: Роль определяет, какими правами обладает пользователь.
user_role:
color: Цвет, который будет использоваться для роли в интерфейсе (UI), как RGB в формате HEX
highlighted: Это действие сделает роль публичной
@@ -137,6 +144,7 @@ ru:
url: Куда события будут отправляться
labels:
account:
+ attribution_domains_as_text: Разрешить только определенные сайты
discoverable: Профиль и сообщения в алгоритмах обнаружения
fields:
name: Пункт
@@ -241,6 +249,7 @@ ru:
backups_retention_period: Период хранения архива пользователя
bootstrap_timeline_accounts: Всегда рекомендовать эти учетные записи новым пользователям
closed_registrations_message: Сообщение, когда регистрация недоступна
+ content_cache_retention_period: Период хранения удаленного содержимого
custom_css: Пользовательский CSS
favicon: Favicon
mascot: Пользовательский маскот (устаревшее)
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index ef6d00b8d31a68..c8e806bf35efa9 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -1196,7 +1196,6 @@ sl:
crypto:
errors:
invalid_key: ni veljaven ključ Ed25519 ali Curve25519
- invalid_signature: ni veljaven podpis Ed25519
date:
formats:
default: "%d %b %Y"
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index 70d20592a5283d..294c8a888f043f 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -1166,7 +1166,6 @@ sq:
crypto:
errors:
invalid_key: s’është kyç Ed25519 ose Curve25519 i vlefshëm
- invalid_signature: s’është nënshkrim Ed25519 i vlefshëm
date:
formats:
default: "%d %b, %Y"
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index 91f0933398d5b8..bfb52c275b66b1 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -1110,7 +1110,6 @@ sr-Latn:
crypto:
errors:
invalid_key: nije validan Ed25519 ili Curve25519 ključ
- invalid_signature: nije validan Ed25519 potpis
date:
formats:
default: "%d. %b. %Y."
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 67aee931be8922..af7e7ab8d6945e 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -1140,7 +1140,6 @@ sr:
crypto:
errors:
invalid_key: није валидан Ed25519 или Curve25519 кључ
- invalid_signature: није валидан Ed25519 потпис
date:
formats:
default: "%d. %b. %Y."
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index 99b7ec9b3a1c52..6146cfc8d7feeb 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -1128,7 +1128,6 @@ sv:
crypto:
errors:
invalid_key: är inte en giltig Ed25519 eller Curve25519 nyckel
- invalid_signature: är inte en giltig Ed25519 signatur
date:
formats:
default: "%b %d, %Y"
diff --git a/config/locales/ta.yml b/config/locales/ta.yml
index 3a98b6a25d44e3..56b2895c74fa3f 100644
--- a/config/locales/ta.yml
+++ b/config/locales/ta.yml
@@ -188,7 +188,6 @@ ta:
crypto:
errors:
invalid_key: ஒரு முறையான Ed25519 அல்லது Curve25519 key அல்ல
- invalid_signature: ஒரு முறையான Ed25519 அடையாளம் அல்ல
filters:
index:
empty: தடுப்புகள் ஏதும் இல்லை.
diff --git a/config/locales/th.yml b/config/locales/th.yml
index 65424f4eb6c66c..d56385f2611add 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -1156,7 +1156,6 @@ th:
crypto:
errors:
invalid_key: ไม่ใช่กุญแจ Ed25519 หรือ Curve25519 ที่ถูกต้อง
- invalid_signature: ไม่ใช่ลายเซ็น Ed25519 ที่ถูกต้อง
date:
formats:
default: "%d %b %Y"
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index d6ca6b4276c9b7..16dd4c899ded7c 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -1174,7 +1174,6 @@ tr:
crypto:
errors:
invalid_key: geçerli bir Ed25519 veya Curve25519 anahtarı değil
- invalid_signature: geçerli bir Ed25519 imzası değil
date:
formats:
default: "%d %b %Y"
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index e8c4e689981712..0ef08a15555659 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -1210,7 +1210,6 @@ uk:
crypto:
errors:
invalid_key: не є припустимим ключем Ed25519 або Curve25519
- invalid_signature: не є дійсним підписом Ed25519
date:
formats:
default: "%b %d, %Y"
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index 8f047a2cb7b2c4..98696aef7c8b63 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -1156,7 +1156,6 @@ vi:
crypto:
errors:
invalid_key: không phải là mã khóa Ed25519 hoặc Curve25519 đúng
- invalid_signature: không phải là chữ ký số Ed25519 đúng
date:
formats:
default: "%-d %B, %Y"
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index 277785f683aa97..8b34da076a0162 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -1156,7 +1156,6 @@ zh-CN:
crypto:
errors:
invalid_key: 不是有效的 Ed25519 或者 Curve25519 密钥
- invalid_signature: 不是有效的 Ed25519 签名
date:
formats:
default: "%Y年%m月%d日"
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index 7682712759c240..598c65d0494ec7 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -1071,7 +1071,6 @@ zh-HK:
crypto:
errors:
invalid_key: 不是一個有效的 Ed25519 或 Curve25519 密鑰
- invalid_signature: 不是一個有效的 Ed25519 簽名
date:
formats:
default: "%Y年%b月%d日"
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 35f000b6016edb..41c4c8a534e482 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -1158,7 +1158,6 @@ zh-TW:
crypto:
errors:
invalid_key: 這不是一把有效的 Ed25519 或 Curve25519 金鑰
- invalid_signature: 這不是有效的 Ed25519 簽章
date:
formats:
default: "%Y年%b月%d日"
diff --git a/config/routes.rb b/config/routes.rb
index 242ca062623bdf..86248dda412fc3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -135,7 +135,6 @@ def redirect_with_vary(path)
scope module: :activitypub do
resource :outbox, only: [:show]
resource :inbox, only: [:create]
- resource :claim, only: [:create]
resources :collections, only: [:show]
resource :followers_synchronization, only: [:show]
end
diff --git a/config/routes/api.rb b/config/routes/api.rb
index 4d422de373907c..48b35cc154218c 100644
--- a/config/routes/api.rb
+++ b/config/routes/api.rb
@@ -69,23 +69,6 @@
end
end
- # namespace :crypto do
- # resources :deliveries, only: :create
-
- # namespace :keys do
- # resource :upload, only: [:create]
- # resource :query, only: [:create]
- # resource :claim, only: [:create]
- # resource :count, only: [:show]
- # end
-
- # resources :encrypted_messages, only: [:index] do
- # collection do
- # post :clear
- # end
- # end
- # end
-
resources :conversations, only: [:index, :destroy] do
member do
post :read
diff --git a/db/post_migrate/20240720140205_drop_end_to_end_message_tables.rb b/db/post_migrate/20240720140205_drop_end_to_end_message_tables.rb
new file mode 100644
index 00000000000000..dd5662885c59b3
--- /dev/null
+++ b/db/post_migrate/20240720140205_drop_end_to_end_message_tables.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+class DropEndToEndMessageTables < ActiveRecord::Migration[7.1]
+ def up
+ drop_table :system_keys
+ drop_table :one_time_keys
+ drop_table :encrypted_messages
+ drop_table :devices
+ safety_assured { remove_column :accounts, :devices_url }
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration
+ end
+end
diff --git a/db/post_migrate/20240916190140_remove_crypto_scope_values.rb b/db/post_migrate/20240916190140_remove_crypto_scope_values.rb
new file mode 100644
index 00000000000000..8caf5b801dac88
--- /dev/null
+++ b/db/post_migrate/20240916190140_remove_crypto_scope_values.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+class RemoveCryptoScopeValues < ActiveRecord::Migration[7.1]
+ def up
+ applications.in_batches do |records|
+ records.update_all(<<~SQL.squish)
+ scopes = TRIM(REPLACE(scopes, 'crypto', ''))
+ SQL
+ end
+
+ tokens.in_batches do |records|
+ records.update_all(<<~SQL.squish)
+ scopes = TRIM(REPLACE(scopes, 'crypto', ''))
+ SQL
+ end
+ end
+
+ def down
+ raise ActiveRecord::IrreversibleMigration
+ end
+
+ private
+
+ def applications
+ Doorkeeper::Application
+ .where("scopes LIKE '%crypto%'")
+ end
+
+ def tokens
+ Doorkeeper::AccessToken
+ .where("scopes LIKE '%crypto%'")
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4c32e2a9dabe80..332854a05ac835 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
+ActiveRecord::Schema[7.1].define(version: 2024_09_16_190140) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -193,7 +193,6 @@
t.boolean "hide_collections"
t.integer "avatar_storage_schema_version"
t.integer "header_storage_schema_version"
- t.string "devices_url"
t.datetime "sensitized_at", precision: nil
t.integer "suspension_origin"
t.boolean "trendable"
@@ -412,19 +411,6 @@
t.index ["account_id"], name: "index_custom_filters_on_account_id"
end
- create_table "devices", force: :cascade do |t|
- t.bigint "access_token_id"
- t.bigint "account_id"
- t.string "device_id", default: "", null: false
- t.string "name", default: "", null: false
- t.text "fingerprint_key", default: "", null: false
- t.text "identity_key", default: "", null: false
- t.datetime "created_at", precision: nil, null: false
- t.datetime "updated_at", precision: nil, null: false
- t.index ["access_token_id"], name: "index_devices_on_access_token_id"
- t.index ["account_id"], name: "index_devices_on_account_id"
- end
-
create_table "domain_allows", force: :cascade do |t|
t.string "domain", default: "", null: false
t.datetime "created_at", precision: nil, null: false
@@ -454,20 +440,6 @@
t.index ["domain"], name: "index_email_domain_blocks_on_domain", unique: true
end
- create_table "encrypted_messages", id: :bigint, default: -> { "timestamp_id('encrypted_messages'::text)" }, force: :cascade do |t|
- t.bigint "device_id"
- t.bigint "from_account_id"
- t.string "from_device_id", default: "", null: false
- t.integer "type", default: 0, null: false
- t.text "body", default: "", null: false
- t.text "digest", default: "", null: false
- t.text "message_franking", default: "", null: false
- t.datetime "created_at", precision: nil, null: false
- t.datetime "updated_at", precision: nil, null: false
- t.index ["device_id"], name: "index_encrypted_messages_on_device_id"
- t.index ["from_account_id"], name: "index_encrypted_messages_on_from_account_id"
- end
-
create_table "favourites", force: :cascade do |t|
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
@@ -781,17 +753,6 @@
t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true
end
- create_table "one_time_keys", force: :cascade do |t|
- t.bigint "device_id"
- t.string "key_id", default: "", null: false
- t.text "key", default: "", null: false
- t.text "signature", default: "", null: false
- t.datetime "created_at", precision: nil, null: false
- t.datetime "updated_at", precision: nil, null: false
- t.index ["device_id"], name: "index_one_time_keys_on_device_id"
- t.index ["key_id"], name: "index_one_time_keys_on_key_id"
- end
-
create_table "pghero_space_stats", force: :cascade do |t|
t.text "database"
t.text "schema"
@@ -1107,12 +1068,6 @@
t.index ["status_id"], name: "index_statuses_tags_on_status_id"
end
- create_table "system_keys", force: :cascade do |t|
- t.binary "key"
- t.datetime "created_at", precision: nil, null: false
- t.datetime "updated_at", precision: nil, null: false
- end
-
create_table "tag_follows", force: :cascade do |t|
t.bigint "tag_id", null: false
t.bigint "account_id", null: false
@@ -1309,11 +1264,7 @@
add_foreign_key "custom_filter_statuses", "custom_filters", on_delete: :cascade
add_foreign_key "custom_filter_statuses", "statuses", on_delete: :cascade
add_foreign_key "custom_filters", "accounts", on_delete: :cascade
- add_foreign_key "devices", "accounts", on_delete: :cascade
- add_foreign_key "devices", "oauth_access_tokens", column: "access_token_id", on_delete: :cascade
add_foreign_key "email_domain_blocks", "email_domain_blocks", column: "parent_id", on_delete: :cascade
- add_foreign_key "encrypted_messages", "accounts", column: "from_account_id", on_delete: :cascade
- add_foreign_key "encrypted_messages", "devices", on_delete: :cascade
add_foreign_key "favourites", "accounts", name: "fk_5eb6c2b873", on_delete: :cascade
add_foreign_key "favourites", "statuses", name: "fk_b0e856845e", on_delete: :cascade
add_foreign_key "featured_tags", "accounts", on_delete: :cascade
@@ -1356,7 +1307,6 @@
add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id", name: "fk_f5fc4c1ee3", on_delete: :cascade
add_foreign_key "oauth_access_tokens", "users", column: "resource_owner_id", name: "fk_e84df68546", on_delete: :cascade
add_foreign_key "oauth_applications", "users", column: "owner_id", name: "fk_b0988c7c0a", on_delete: :cascade
- add_foreign_key "one_time_keys", "devices", on_delete: :cascade
add_foreign_key "poll_votes", "accounts", on_delete: :cascade
add_foreign_key "poll_votes", "polls", on_delete: :cascade
add_foreign_key "polls", "accounts", on_delete: :cascade
diff --git a/spec/controllers/activitypub/claims_controller_spec.rb b/spec/controllers/activitypub/claims_controller_spec.rb
deleted file mode 100644
index e887be2cbe1ae2..00000000000000
--- a/spec/controllers/activitypub/claims_controller_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe ActivityPub::ClaimsController do
- let(:account) { Fabricate(:account) }
-
- describe 'POST #create' do
- context 'without signature' do
- before do
- post :create, params: { account_username: account.username }, body: '{}'
- end
-
- it 'returns http not authorized' do
- expect(response).to have_http_status(401)
- end
- end
- end
-end
diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb
index 3cc3460718caed..713ea3ff16c5bf 100644
--- a/spec/controllers/auth/sessions_controller_spec.rb
+++ b/spec/controllers/auth/sessions_controller_spec.rb
@@ -412,44 +412,4 @@
end
end
end
-
- describe 'GET #webauthn_options' do
- subject { get :webauthn_options, session: { attempt_user_id: user.id } }
-
- let!(:user) do
- Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32))
- end
-
- context 'with WebAuthn and OTP enabled as second factor' do
- let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" }
-
- let(:fake_client) { WebAuthn::FakeClient.new(domain) }
-
- before do
- user.update(webauthn_id: WebAuthn.generate_user_id)
- public_key_credential = WebAuthn::Credential.from_create(fake_client.create)
- user.webauthn_credentials.create(
- nickname: 'SecurityKeyNickname',
- external_id: public_key_credential.id,
- public_key: public_key_credential.public_key,
- sign_count: '1000'
- )
- post :create, params: { user: { email: user.email, password: user.password } }
- end
-
- it 'returns http success' do
- subject
-
- expect(response).to have_http_status 200
- end
- end
-
- context 'when WebAuthn not enabled' do
- it 'returns http unauthorized' do
- subject
-
- expect(response).to have_http_status 401
- end
- end
- end
end
diff --git a/spec/controllers/settings/exports_controller_spec.rb b/spec/controllers/settings/exports_controller_spec.rb
deleted file mode 100644
index 1eafabc7e50129..00000000000000
--- a/spec/controllers/settings/exports_controller_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe Settings::ExportsController do
- render_views
-
- describe 'GET #show' do
- context 'when signed in' do
- let(:user) { Fabricate(:user) }
-
- before do
- sign_in user, scope: :user
- get :show
- end
-
- it 'returns http success with private cache control headers', :aggregate_failures do
- expect(response).to have_http_status(200)
- expect(response.headers['Cache-Control']).to include('private, no-store')
- end
- end
-
- context 'when not signed in' do
- it 'redirects' do
- get :show
- expect(response).to redirect_to '/auth/sign_in'
- end
- end
- end
-
- describe 'POST #create' do
- before do
- sign_in Fabricate(:user), scope: :user
- end
-
- it 'redirects to settings_export_path' do
- post :create
- expect(response).to redirect_to(settings_export_path)
- end
-
- it 'queues BackupWorker job by 1' do
- expect do
- post :create
- end.to change(BackupWorker.jobs, :size).by(1)
- end
- end
-end
diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb
index 5042523df82864..d9702251f41d0a 100644
--- a/spec/controllers/statuses_controller_spec.rb
+++ b/spec/controllers/statuses_controller_spec.rb
@@ -63,7 +63,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('public'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.body).to include status.text
end
@@ -79,7 +79,7 @@
expect(response.headers).to include(
'Content-Type' => include('application/activity+json'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
@@ -168,7 +168,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.body).to include status.text
end
@@ -184,7 +184,7 @@
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
@@ -212,7 +212,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.body).to include status.text
end
@@ -228,7 +228,7 @@
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
@@ -278,7 +278,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.body).to include status.text
end
@@ -294,7 +294,7 @@
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
@@ -370,7 +370,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.body).to include status.text
end
@@ -385,7 +385,7 @@
.and have_cacheable_headers.with_vary('Accept, Accept-Language, Cookie')
expect(response.headers).to include(
'Content-Type' => include('application/activity+json'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
@@ -412,7 +412,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.body).to include status.text
end
@@ -428,7 +428,7 @@
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.parsed_body)
@@ -479,7 +479,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.body).to include status.text
end
@@ -495,7 +495,7 @@
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('private'),
'Content-Type' => include('application/activity+json'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
expect(response.parsed_body)
.to include(content: include(status.text))
@@ -779,7 +779,7 @@
expect(response.headers).to include(
'Vary' => 'Accept, Accept-Language, Cookie',
'Cache-Control' => include('public'),
- 'Link' => satisfy { |header| header.to_s.include?('activity+json') }
+ 'Link' => include('activity+json')
)
end
end
diff --git a/spec/fabricators/device_fabricator.rb b/spec/fabricators/device_fabricator.rb
deleted file mode 100644
index 37a2e8977d133b..00000000000000
--- a/spec/fabricators/device_fabricator.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:device) do
- access_token { Fabricate.build(:access_token) }
- account { Fabricate.build(:account) }
- device_id { Faker::Number.number(digits: 5) }
- name { Faker::App.name }
- fingerprint_key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) }
- identity_key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) }
-end
diff --git a/spec/fabricators/encrypted_message_fabricator.rb b/spec/fabricators/encrypted_message_fabricator.rb
deleted file mode 100644
index 349b659c2f515c..00000000000000
--- a/spec/fabricators/encrypted_message_fabricator.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:encrypted_message) do
- device { Fabricate.build(:device) }
- from_account { Fabricate.build(:account) }
- from_device_id { Faker::Number.number(digits: 5) }
-end
diff --git a/spec/fabricators/one_time_key_fabricator.rb b/spec/fabricators/one_time_key_fabricator.rb
deleted file mode 100644
index 505282e05ddfbc..00000000000000
--- a/spec/fabricators/one_time_key_fabricator.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:one_time_key) do
- device { Fabricate.build(:device) }
- key_id { Faker::Alphanumeric.alphanumeric(number: 10) }
- key { Base64.strict_encode64(Ed25519::SigningKey.generate.verify_key.to_bytes) }
-
- signature do |attrs|
- signing_key = Ed25519::SigningKey.generate
- attrs[:device].update(fingerprint_key: Base64.strict_encode64(signing_key.verify_key.to_bytes))
- Base64.strict_encode64(signing_key.sign(attrs[:key]))
- end
-end
diff --git a/spec/fabricators/system_key_fabricator.rb b/spec/fabricators/system_key_fabricator.rb
deleted file mode 100644
index bcb3bd5577b14f..00000000000000
--- a/spec/fabricators/system_key_fabricator.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# frozen_string_literal: true
-
-Fabricator(:system_key)
diff --git a/spec/lib/activitypub/activity/create_spec.rb b/spec/lib/activitypub/activity/create_spec.rb
index fbaf672b5aa216..83ea6566e41402 100644
--- a/spec/lib/activitypub/activity/create_spec.rb
+++ b/spec/lib/activitypub/activity/create_spec.rb
@@ -982,64 +982,6 @@ def activity_for_object(json)
end
end
- context 'with an encrypted message' do
- subject { described_class.new(json, sender, delivery: true, delivered_to_account_id: recipient.id) }
-
- let(:recipient) { Fabricate(:account) }
- let(:object_json) do
- {
- id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
- type: 'EncryptedMessage',
- attributedTo: {
- type: 'Device',
- deviceId: '1234',
- },
- to: {
- type: 'Device',
- deviceId: target_device.device_id,
- },
- messageType: 1,
- cipherText: 'Foo',
- messageFranking: 'Baz678',
- digest: {
- digestAlgorithm: 'Bar456',
- digestValue: 'Foo123',
- },
- }
- end
- let(:target_device) { Fabricate(:device, account: recipient) }
-
- before do
- subject.perform
- end
-
- it 'creates an encrypted message' do
- encrypted_message = target_device.encrypted_messages.reload.first
-
- expect(encrypted_message)
- .to be_present
- .and have_attributes(
- from_device_id: eq('1234'),
- from_account: eq(sender),
- type: eq(1),
- body: eq('Foo'),
- digest: eq('Foo123')
- )
- end
-
- it 'creates a message franking' do
- encrypted_message = target_device.encrypted_messages.reload.first
- message_franking = encrypted_message.message_franking
-
- crypt = ActiveSupport::MessageEncryptor.new(SystemKey.current_key, serializer: Oj)
- json = crypt.decrypt_and_verify(message_franking)
-
- expect(json['source_account_id']).to eq sender.id
- expect(json['target_account_id']).to eq recipient.id
- expect(json['original_franking']).to eq 'Baz678'
- end
- end
-
context 'when sender is followed by local users' do
subject { described_class.new(json, sender, delivery: true) }
diff --git a/spec/lib/vacuum/system_keys_vacuum_spec.rb b/spec/lib/vacuum/system_keys_vacuum_spec.rb
deleted file mode 100644
index 84cae30411e760..00000000000000
--- a/spec/lib/vacuum/system_keys_vacuum_spec.rb
+++ /dev/null
@@ -1,24 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe Vacuum::SystemKeysVacuum do
- subject { described_class.new }
-
- describe '#perform' do
- let!(:expired_system_key) { Fabricate(:system_key, created_at: (SystemKey::ROTATION_PERIOD * 4).ago) }
- let!(:current_system_key) { Fabricate(:system_key) }
-
- before do
- subject.perform
- end
-
- it 'deletes the expired key' do
- expect { expired_system_key.reload }.to raise_error ActiveRecord::RecordNotFound
- end
-
- it 'does not delete the current key' do
- expect { current_system_key.reload }.to_not raise_error
- end
- end
-end
diff --git a/spec/models/account_deletion_request_spec.rb b/spec/models/account_deletion_request_spec.rb
new file mode 100644
index 00000000000000..7dbfbed12a1b5a
--- /dev/null
+++ b/spec/models/account_deletion_request_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe AccountDeletionRequest do
+ describe 'Associations' do
+ it { is_expected.to belong_to(:account).required }
+ end
+
+ describe '#due_at' do
+ before { stub_const 'AccountDeletionRequest::DELAY_TO_DELETION', 1.day }
+
+ it 'returns time from created at with delay added' do
+ account_deletion_request = Fabricate :account_deletion_request, created_at: Date.current.at_midnight
+ expect(account_deletion_request.due_at)
+ .to be_within(0.1).of(Date.tomorrow.at_midnight)
+ end
+ end
+end
diff --git a/spec/models/one_time_key_spec.rb b/spec/models/one_time_key_spec.rb
deleted file mode 100644
index 17fcdf37883987..00000000000000
--- a/spec/models/one_time_key_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe OneTimeKey do
- describe 'validations' do
- context 'with an invalid signature' do
- let(:one_time_key) { Fabricate.build(:one_time_key, signature: 'wrong!') }
-
- it 'is invalid' do
- expect(one_time_key).to_not be_valid
- end
- end
-
- context 'with an invalid key' do
- let(:one_time_key) { Fabricate.build(:one_time_key, key: 'wrong!') }
-
- it 'is invalid' do
- expect(one_time_key).to_not be_valid
- end
- end
- end
-end
diff --git a/spec/models/preview_card_provider_spec.rb b/spec/models/preview_card_provider_spec.rb
index 12bca83440f126..a3bd4f49ad1b8b 100644
--- a/spec/models/preview_card_provider_spec.rb
+++ b/spec/models/preview_card_provider_spec.rb
@@ -24,21 +24,5 @@
expect(results).to eq([not_trendable_and_not_reviewed])
end
end
-
- describe 'reviewed' do
- it 'returns the relevant records' do
- results = described_class.reviewed
-
- expect(results).to eq([trendable_and_reviewed])
- end
- end
-
- describe 'pending_review' do
- it 'returns the relevant records' do
- results = described_class.pending_review
-
- expect(results).to eq([not_trendable_and_not_reviewed])
- end
- end
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index fcff4c0d3bd435..972453cd690835 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -4,6 +4,8 @@
require 'devise_two_factor/spec_helpers'
RSpec.describe User do
+ subject { described_class.new(account: account) }
+
let(:password) { 'abcd1234' }
let(:account) { Fabricate(:account, username: 'alice') }
diff --git a/spec/requests/api/oembed_spec.rb b/spec/requests/api/oembed_spec.rb
index b9578b37c817df..767f20dddf4837 100644
--- a/spec/requests/api/oembed_spec.rb
+++ b/spec/requests/api/oembed_spec.rb
@@ -14,6 +14,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.headers['Cache-Control'])
.to include('private, no-store')
end
@@ -27,6 +29,8 @@
expect(response)
.to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/accounts/credentials_spec.rb b/spec/requests/api/v1/accounts/credentials_spec.rb
index 77b815945ea214..966d1f598e9cfe 100644
--- a/spec/requests/api/v1/accounts/credentials_spec.rb
+++ b/spec/requests/api/v1/accounts/credentials_spec.rb
@@ -20,6 +20,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include({
source: hash_including({
discoverable: false,
@@ -36,6 +38,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include({
locked: true,
@@ -75,6 +79,8 @@
it 'returns http success' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -84,6 +90,8 @@
it 'returns http unprocessable entity' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -92,6 +100,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include({
source: hash_including({
diff --git a/spec/requests/api/v1/accounts/familiar_followers_spec.rb b/spec/requests/api/v1/accounts/familiar_followers_spec.rb
index 8edfa4c8831f60..c698c2d6892a72 100644
--- a/spec/requests/api/v1/accounts/familiar_followers_spec.rb
+++ b/spec/requests/api/v1/accounts/familiar_followers_spec.rb
@@ -14,6 +14,8 @@
get '/api/v1/accounts/familiar_followers', params: { account_id: account.id, limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there are duplicate account IDs in the params' do
diff --git a/spec/requests/api/v1/accounts/featured_tags_spec.rb b/spec/requests/api/v1/accounts/featured_tags_spec.rb
index f48ed01def00be..632db65c443fd8 100644
--- a/spec/requests/api/v1/accounts/featured_tags_spec.rb
+++ b/spec/requests/api/v1/accounts/featured_tags_spec.rb
@@ -23,6 +23,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to contain_exactly(a_hash_including({
name: 'bar',
url: "https://cb6e6126.ngrok.io/@#{account.username}/tagged/bar",
@@ -37,6 +39,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to contain_exactly(a_hash_including({
name: 'bar',
url: "https://cb6e6126.ngrok.io/@#{account.pretty_acct}/tagged/bar",
diff --git a/spec/requests/api/v1/accounts/follower_accounts_spec.rb b/spec/requests/api/v1/accounts/follower_accounts_spec.rb
index 2672615390a36e..7db9884a57a8f7 100644
--- a/spec/requests/api/v1/accounts/follower_accounts_spec.rb
+++ b/spec/requests/api/v1/accounts/follower_accounts_spec.rb
@@ -21,6 +21,8 @@
get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq 2
expect([response.parsed_body[0][:id], response.parsed_body[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
end
@@ -30,6 +32,8 @@
get "/api/v1/accounts/#{account.id}/followers", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq 1
expect(response.parsed_body[0][:id]).to eq alice.id.to_s
end
diff --git a/spec/requests/api/v1/accounts/following_accounts_spec.rb b/spec/requests/api/v1/accounts/following_accounts_spec.rb
index 19105ebf2f3e0b..ffb7332c4eb7b9 100644
--- a/spec/requests/api/v1/accounts/following_accounts_spec.rb
+++ b/spec/requests/api/v1/accounts/following_accounts_spec.rb
@@ -21,6 +21,8 @@
get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq 2
expect([response.parsed_body[0][:id], response.parsed_body[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
end
@@ -30,6 +32,8 @@
get "/api/v1/accounts/#{account.id}/following", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq 1
expect(response.parsed_body[0][:id]).to eq alice.id.to_s
end
diff --git a/spec/requests/api/v1/accounts/identity_proofs_spec.rb b/spec/requests/api/v1/accounts/identity_proofs_spec.rb
index d1d9db8e737973..ba04ed45b9f8b5 100644
--- a/spec/requests/api/v1/accounts/identity_proofs_spec.rb
+++ b/spec/requests/api/v1/accounts/identity_proofs_spec.rb
@@ -14,6 +14,8 @@
get "/api/v1/accounts/#{account.id}/identity_proofs", params: { limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/accounts/lists_spec.rb b/spec/requests/api/v1/accounts/lists_spec.rb
index 8b04f07f652519..cb1ff6b9f28a7c 100644
--- a/spec/requests/api/v1/accounts/lists_spec.rb
+++ b/spec/requests/api/v1/accounts/lists_spec.rb
@@ -20,6 +20,8 @@
get "/api/v1/accounts/#{account.id}/lists", headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/accounts/lookup_spec.rb b/spec/requests/api/v1/accounts/lookup_spec.rb
index dfd9fad49d8a96..77c09c0902b502 100644
--- a/spec/requests/api/v1/accounts/lookup_spec.rb
+++ b/spec/requests/api/v1/accounts/lookup_spec.rb
@@ -14,6 +14,8 @@
get '/api/v1/accounts/lookup', params: { account_id: account.id, acct: account.acct }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/accounts/notes_spec.rb b/spec/requests/api/v1/accounts/notes_spec.rb
index b8c493abcc96d0..1677ec07e3d6d6 100644
--- a/spec/requests/api/v1/accounts/notes_spec.rb
+++ b/spec/requests/api/v1/accounts/notes_spec.rb
@@ -22,6 +22,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(AccountNote.find_by(account_id: user.account.id, target_account_id: account.id).comment).to eq comment
end
end
@@ -33,6 +35,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(AccountNote.where(account_id: user.account.id, target_account_id: account.id)).to_not exist
end
end
diff --git a/spec/requests/api/v1/accounts/pins_spec.rb b/spec/requests/api/v1/accounts/pins_spec.rb
index c66b80c7fd98d5..8ebcb27d282e01 100644
--- a/spec/requests/api/v1/accounts/pins_spec.rb
+++ b/spec/requests/api/v1/accounts/pins_spec.rb
@@ -21,6 +21,8 @@
subject
end.to change { AccountPin.where(account: user.account, target_account: kevin.account).count }.by(1)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -36,6 +38,8 @@
subject
end.to change { AccountPin.where(account: user.account, target_account: kevin.account).count }.by(-1)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/accounts/relationships_spec.rb b/spec/requests/api/v1/accounts/relationships_spec.rb
index 9570d1214c6d04..52aeb0132807ad 100644
--- a/spec/requests/api/v1/accounts/relationships_spec.rb
+++ b/spec/requests/api/v1/accounts/relationships_spec.rb
@@ -29,6 +29,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Enumerable)
.and contain_exactly(
@@ -50,6 +52,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Enumerable)
.and have_attributes(
@@ -70,6 +74,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Enumerable)
.and have_attributes(
@@ -149,6 +155,8 @@ def bob_item
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Enumerable)
@@ -171,6 +179,8 @@ def bob_item
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Enumerable)
diff --git a/spec/requests/api/v1/accounts/search_spec.rb b/spec/requests/api/v1/accounts/search_spec.rb
index f6ab7a85319da1..dc24813e7392ad 100644
--- a/spec/requests/api/v1/accounts/search_spec.rb
+++ b/spec/requests/api/v1/accounts/search_spec.rb
@@ -13,6 +13,8 @@
get '/api/v1/accounts/search', params: { q: 'query' }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/accounts/statuses_spec.rb b/spec/requests/api/v1/accounts/statuses_spec.rb
index e056a7890158fe..1e219502874352 100644
--- a/spec/requests/api/v1/accounts/statuses_spec.rb
+++ b/spec/requests/api/v1/accounts/statuses_spec.rb
@@ -19,6 +19,8 @@
prev: api_v1_account_statuses_url(limit: 1, min_id: status.id),
next: api_v1_account_statuses_url(limit: 1, max_id: status.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'with only media' do
@@ -26,6 +28,8 @@
get "/api/v1/accounts/#{user.account.id}/statuses", params: { only_media: true }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -41,6 +45,8 @@
it 'returns posts along with self replies', :aggregate_failures do
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to have_attributes(size: 2)
.and contain_exactly(
@@ -61,6 +67,8 @@
expect(response)
.to have_http_status(200)
.and include_pagination_headers(prev: api_v1_account_statuses_url(pinned: true, min_id: Status.first.id))
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -79,6 +87,8 @@
prev: api_v1_account_statuses_url(pinned: true, min_id: Status.first.id),
next: api_v1_account_statuses_url(pinned: true, max_id: Status.first.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -96,6 +106,8 @@
get "/api/v1/accounts/#{account.id}/statuses", params: { pinned: true }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when user does not follow account' do
@@ -122,6 +134,8 @@
a_hash_including(id: status.id.to_s),
a_hash_including(id: private_status.id.to_s)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/accounts_spec.rb b/spec/requests/api/v1/accounts_spec.rb
index 2ebe56fa7d0281..45e66f07445d8d 100644
--- a/spec/requests/api/v1/accounts_spec.rb
+++ b/spec/requests/api/v1/accounts_spec.rb
@@ -17,6 +17,8 @@
get '/api/v1/accounts', headers: headers, params: { id: [account.id, other_account.id, 123_123] }
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to contain_exactly(
hash_including(id: account.id.to_s),
hash_including(id: other_account.id.to_s)
@@ -32,6 +34,8 @@
get "/api/v1/accounts/#{account.id}"
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:id]).to eq(account.id.to_s)
end
end
@@ -41,6 +45,8 @@
get '/api/v1/accounts/1'
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:error]).to eq('Record not found')
end
end
@@ -57,6 +63,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:id]).to eq(account.id.to_s)
end
@@ -80,6 +88,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:access_token]).to_not be_blank
user = User.find_by(email: 'hello@world.tld')
@@ -93,6 +103,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -113,6 +125,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -133,6 +147,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -203,6 +219,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.following?(other_account)).to be false
end
@@ -225,6 +243,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.followed_by?(other_account)).to be false
end
@@ -247,6 +267,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.following?(other_account)).to be false
expect(user.account.blocking?(other_account)).to be true
end
@@ -270,6 +292,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.blocking?(other_account)).to be false
end
@@ -292,6 +316,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.following?(other_account)).to be true
expect(user.account.muting?(other_account)).to be true
expect(user.account.muting_notifications?(other_account)).to be true
@@ -316,6 +342,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.following?(other_account)).to be true
expect(user.account.muting?(other_account)).to be true
expect(user.account.muting_notifications?(other_account)).to be false
@@ -340,6 +368,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.following?(other_account)).to be true
expect(user.account.muting?(other_account)).to be true
expect(user.account.muting_notifications?(other_account)).to be true
@@ -364,6 +394,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.muting?(other_account)).to be false
end
diff --git a/spec/requests/api/v1/admin/account_actions_spec.rb b/spec/requests/api/v1/admin/account_actions_spec.rb
index 5bcf809401da4c..4884dba9c79dfc 100644
--- a/spec/requests/api/v1/admin/account_actions_spec.rb
+++ b/spec/requests/api/v1/admin/account_actions_spec.rb
@@ -61,6 +61,8 @@ def latest_admin_action_log
it 'disables the target account' do
expect { subject }.to change { target_account.reload.user_disabled? }.from(false).to(true)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -75,6 +77,8 @@ def latest_admin_action_log
it 'marks the target account as sensitive' do
expect { subject }.to change { target_account.reload.sensitized? }.from(false).to(true)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -89,6 +93,8 @@ def latest_admin_action_log
it 'marks the target account as silenced' do
expect { subject }.to change { target_account.reload.silenced? }.from(false).to(true)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -103,6 +109,8 @@ def latest_admin_action_log
it 'marks the target account as suspended' do
expect { subject }.to change { target_account.reload.suspended? }.from(false).to(true)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -115,6 +123,8 @@ def latest_admin_action_log
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -125,6 +135,8 @@ def latest_admin_action_log
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -135,6 +147,8 @@ def latest_admin_action_log
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/accounts_spec.rb b/spec/requests/api/v1/admin/accounts_spec.rb
index 2dc45d5eb25505..6a681f9c5e5b2a 100644
--- a/spec/requests/api/v1/admin/accounts_spec.rb
+++ b/spec/requests/api/v1/admin/accounts_spec.rb
@@ -19,6 +19,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.pluck(:id)).to match_array(expected_results.map { |a| a.id.to_s })
end
end
@@ -93,6 +95,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(params[:limit])
end
end
@@ -112,6 +116,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
a_hash_including(id: account.id.to_s, username: account.username, email: account.user.email)
)
@@ -122,6 +128,8 @@
get '/api/v1/admin/accounts/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -145,6 +153,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(account.reload.user_approved?).to be(true)
end
@@ -166,6 +176,8 @@
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -174,6 +186,8 @@
post '/api/v1/admin/accounts/-1/approve', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -193,15 +207,13 @@
it_behaves_like 'forbidden for wrong scope', 'write write:accounts read admin:read'
it_behaves_like 'forbidden for wrong role', ''
- it 'removes the user successfully', :aggregate_failures do
+ it 'removes the user successfully and logs action', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(User.where(id: account.user.id)).to_not exist
- end
-
- it 'logs action', :aggregate_failures do
- subject
expect(latest_admin_action_log)
.to be_present
@@ -218,6 +230,8 @@
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -226,6 +240,8 @@
post '/api/v1/admin/accounts/-1/reject', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -248,6 +264,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(account.reload.user_disabled?).to be false
end
@@ -256,6 +274,8 @@
post '/api/v1/admin/accounts/-1/enable', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -279,6 +299,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(account.reload.suspended?).to be false
end
end
@@ -288,6 +310,8 @@
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -296,6 +320,8 @@
post '/api/v1/admin/accounts/-1/unsuspend', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -318,6 +344,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(account.reload.sensitized?).to be false
end
@@ -326,6 +354,8 @@
post '/api/v1/admin/accounts/-1/unsensitive', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -348,6 +378,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(account.reload.silenced?).to be false
end
@@ -356,6 +388,8 @@
post '/api/v1/admin/accounts/-1/unsilence', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -380,6 +414,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(Admin::AccountDeletionWorker).to have_received(:perform_async).with(account.id).once
end
end
@@ -397,6 +433,8 @@
delete '/api/v1/admin/accounts/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/canonical_email_blocks_spec.rb b/spec/requests/api/v1/admin/canonical_email_blocks_spec.rb
index dd7e119911cbe9..eaa011d5167716 100644
--- a/spec/requests/api/v1/admin/canonical_email_blocks_spec.rb
+++ b/spec/requests/api/v1/admin/canonical_email_blocks_spec.rb
@@ -24,6 +24,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there is no canonical email block' do
@@ -96,6 +98,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
id: eq(canonical_email_block.id.to_s),
@@ -109,6 +113,8 @@
get '/api/v1/admin/canonical_email_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -131,6 +137,8 @@
subject
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -142,6 +150,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.first[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
end
end
@@ -151,6 +161,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be_empty
end
end
@@ -173,6 +185,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
end
@@ -183,6 +197,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -193,6 +209,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:canonical_email_hash]).to eq(params[:canonical_email_hash])
end
end
@@ -204,6 +222,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
end
end
@@ -217,6 +237,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -237,6 +259,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(CanonicalEmailBlock.find_by(id: canonical_email_block.id)).to be_nil
end
@@ -245,6 +269,8 @@
delete '/api/v1/admin/canonical_email_blocks/0', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/dimensions_spec.rb b/spec/requests/api/v1/admin/dimensions_spec.rb
index a28c2a9e3e521a..81fb580ba72f37 100644
--- a/spec/requests/api/v1/admin/dimensions_spec.rb
+++ b/spec/requests/api/v1/admin/dimensions_spec.rb
@@ -15,6 +15,8 @@
expect(response)
.to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -27,6 +29,9 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_an(Array)
end
diff --git a/spec/requests/api/v1/admin/domain_allows_spec.rb b/spec/requests/api/v1/admin/domain_allows_spec.rb
index 26c962b347a61f..eb5128e420834d 100644
--- a/spec/requests/api/v1/admin/domain_allows_spec.rb
+++ b/spec/requests/api/v1/admin/domain_allows_spec.rb
@@ -24,6 +24,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there is no allowed domains' do
@@ -79,6 +81,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:domain]).to eq domain_allow.domain
end
@@ -87,6 +91,8 @@
get '/api/v1/admin/domain_allows/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -107,6 +113,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:domain]).to eq 'foo.bar.com'
expect(DomainAllow.find_by(domain: 'foo.bar.com')).to be_present
end
@@ -119,6 +127,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -129,6 +139,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -160,6 +172,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(DomainAllow.find_by(id: domain_allow.id)).to be_nil
end
@@ -168,6 +182,8 @@
delete '/api/v1/admin/domain_allows/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/domain_blocks_spec.rb b/spec/requests/api/v1/admin/domain_blocks_spec.rb
index 3f2cbbf1135788..1a506bd9bebca7 100644
--- a/spec/requests/api/v1/admin/domain_blocks_spec.rb
+++ b/spec/requests/api/v1/admin/domain_blocks_spec.rb
@@ -24,6 +24,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there are no domain blocks' do
@@ -94,6 +96,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
id: domain_block.id.to_s,
domain: domain_block.domain,
@@ -113,6 +117,8 @@
get '/api/v1/admin/domain_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -132,6 +138,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match a_hash_including(
{
domain: 'foo.bar.com',
@@ -153,6 +161,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match a_hash_including(
{
domain: 'foo.bar.com',
@@ -173,6 +183,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:existing_domain_block][:domain]).to eq('foo.bar.com')
end
end
@@ -186,6 +198,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:existing_domain_block][:domain]).to eq('bar.com')
end
end
@@ -197,6 +211,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -217,6 +233,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match a_hash_including(
{
id: domain_block.id.to_s,
@@ -236,6 +254,8 @@
put '/api/v1/admin/domain_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -255,6 +275,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(DomainBlock.find_by(id: domain_block.id)).to be_nil
end
@@ -263,6 +285,8 @@
delete '/api/v1/admin/domain_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/email_domain_blocks_spec.rb b/spec/requests/api/v1/admin/email_domain_blocks_spec.rb
index aa3073341a9a24..3f51a3ea2d4fb6 100644
--- a/spec/requests/api/v1/admin/email_domain_blocks_spec.rb
+++ b/spec/requests/api/v1/admin/email_domain_blocks_spec.rb
@@ -25,6 +25,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there is no email domain block' do
@@ -97,6 +99,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:domain]).to eq(email_domain_block.domain)
end
end
@@ -106,6 +110,8 @@
get '/api/v1/admin/email_domain_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -125,6 +131,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:domain]).to eq(params[:domain])
end
@@ -135,6 +143,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -145,6 +155,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -157,6 +169,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -176,6 +190,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be_empty
expect(EmailDomainBlock.find_by(id: email_domain_block.id)).to be_nil
end
@@ -185,6 +201,8 @@
delete '/api/v1/admin/email_domain_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/ip_blocks_spec.rb b/spec/requests/api/v1/admin/ip_blocks_spec.rb
index b18f8f885cfe9d..c096aa33283cae 100644
--- a/spec/requests/api/v1/admin/ip_blocks_spec.rb
+++ b/spec/requests/api/v1/admin/ip_blocks_spec.rb
@@ -24,6 +24,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there is no ip block' do
@@ -88,6 +90,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -101,6 +105,8 @@
get '/api/v1/admin/ip_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -120,6 +126,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
ip: eq("#{params[:ip]}/32"),
@@ -135,6 +143,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -145,6 +155,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -157,6 +169,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -167,6 +181,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -185,6 +201,8 @@
.and change_comment_value
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(hash_including({
ip: "#{ip_block.ip}/#{ip_block.ip.prefix}",
severity: 'sign_up_requires_approval',
@@ -205,6 +223,8 @@ def change_comment_value
put '/api/v1/admin/ip_blocks/-1', headers: headers, params: params
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -220,6 +240,8 @@ def change_comment_value
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be_empty
expect(IpBlock.find_by(id: ip_block.id)).to be_nil
end
@@ -229,6 +251,8 @@ def change_comment_value
delete '/api/v1/admin/ip_blocks/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/measures_spec.rb b/spec/requests/api/v1/admin/measures_spec.rb
index de359a5ccdfea1..519b5cc7b3ca6c 100644
--- a/spec/requests/api/v1/admin/measures_spec.rb
+++ b/spec/requests/api/v1/admin/measures_spec.rb
@@ -32,6 +32,8 @@
expect(response)
.to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -43,6 +45,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Array)
diff --git a/spec/requests/api/v1/admin/reports_spec.rb b/spec/requests/api/v1/admin/reports_spec.rb
index 2c40f56dc8adea..a0e7b0a369a3e1 100644
--- a/spec/requests/api/v1/admin/reports_spec.rb
+++ b/spec/requests/api/v1/admin/reports_spec.rb
@@ -23,6 +23,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there are no reports' do
@@ -126,6 +128,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include(
{
id: report.id.to_s,
@@ -156,6 +160,8 @@
.and create_an_action_log
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
report.reload
@@ -190,6 +196,8 @@
.to change { report.reload.unresolved? }.from(true).to(false)
.and create_an_action_log
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -208,6 +216,8 @@
.to change { report.reload.unresolved? }.from(false).to(true)
.and create_an_action_log
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -226,6 +236,8 @@
.to change { report.reload.assigned_account_id }.from(nil).to(user.account.id)
.and create_an_action_log
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -244,6 +256,8 @@
.to change { report.reload.assigned_account_id }.from(user.account.id).to(nil)
.and create_an_action_log
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
diff --git a/spec/requests/api/v1/admin/retention_spec.rb b/spec/requests/api/v1/admin/retention_spec.rb
index c28fa6de815bfa..e28bc2a94f815c 100644
--- a/spec/requests/api/v1/admin/retention_spec.rb
+++ b/spec/requests/api/v1/admin/retention_spec.rb
@@ -15,6 +15,8 @@
expect(response)
.to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -26,6 +28,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Array)
diff --git a/spec/requests/api/v1/admin/tags_spec.rb b/spec/requests/api/v1/admin/tags_spec.rb
index 2f730cdeb8dfaf..3623c09ac7ad58 100644
--- a/spec/requests/api/v1/admin/tags_spec.rb
+++ b/spec/requests/api/v1/admin/tags_spec.rb
@@ -24,6 +24,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when there are no tags' do
@@ -73,14 +75,12 @@
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
it_behaves_like 'forbidden for wrong role', ''
- it 'returns http success' do
+ it 'returns http success and expected tag content' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns expected tag content' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:id].to_i).to eq(tag.id)
expect(response.parsed_body[:name]).to eq(tag.name)
@@ -91,6 +91,8 @@
get '/api/v1/admin/tags/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -107,14 +109,12 @@
it_behaves_like 'forbidden for wrong scope', 'admin:read'
it_behaves_like 'forbidden for wrong role', ''
- it 'returns http success' do
+ it 'returns http success and updates tag' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns updated tag' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:id].to_i).to eq(tag.id)
expect(response.parsed_body[:name]).to eq(tag.name.upcase)
@@ -127,6 +127,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -135,6 +137,8 @@
get '/api/v1/admin/tags/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/trends/links/links_spec.rb b/spec/requests/api/v1/admin/trends/links/links_spec.rb
index c436b7081e615f..51e800734aaaec 100644
--- a/spec/requests/api/v1/admin/trends/links/links_spec.rb
+++ b/spec/requests/api/v1/admin/trends/links/links_spec.rb
@@ -18,6 +18,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -36,6 +38,8 @@
.to change_link_trendable_to_true
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expects_correct_link_data
end
@@ -60,6 +64,8 @@ def expects_correct_link_data
post '/api/v1/admin/trends/links/-1/approve', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -70,6 +76,8 @@ def expects_correct_link_data
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -89,6 +97,8 @@ def expects_correct_link_data
.to_not change_link_trendable
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
def change_link_trendable
@@ -114,6 +124,8 @@ def change_link_trendable
post '/api/v1/admin/trends/links/-1/reject', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -124,6 +136,8 @@ def change_link_trendable
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/trends/links/preview_card_providers_spec.rb b/spec/requests/api/v1/admin/trends/links/preview_card_providers_spec.rb
index 193906ab057b6d..d46d0ff5555404 100644
--- a/spec/requests/api/v1/admin/trends/links/preview_card_providers_spec.rb
+++ b/spec/requests/api/v1/admin/trends/links/preview_card_providers_spec.rb
@@ -16,6 +16,8 @@
get '/api/v1/admin/trends/links/publishers', params: { account_id: account.id, limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -29,6 +31,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -42,6 +46,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/trends/statuses_spec.rb b/spec/requests/api/v1/admin/trends/statuses_spec.rb
index e33a9658a9ff1e..c63d8d925c7c98 100644
--- a/spec/requests/api/v1/admin/trends/statuses_spec.rb
+++ b/spec/requests/api/v1/admin/trends/statuses_spec.rb
@@ -16,6 +16,8 @@
get '/api/v1/admin/trends/statuses', params: { account_id: account.id, limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -29,6 +31,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -42,6 +46,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/admin/trends/tags_spec.rb b/spec/requests/api/v1/admin/trends/tags_spec.rb
index 748a27283c14b7..433cc6c5a6e5f3 100644
--- a/spec/requests/api/v1/admin/trends/tags_spec.rb
+++ b/spec/requests/api/v1/admin/trends/tags_spec.rb
@@ -16,6 +16,8 @@
get '/api/v1/admin/trends/tags', params: { account_id: account.id, limit: 2 }, headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -29,6 +31,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -42,6 +46,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/announcements/reactions_spec.rb b/spec/requests/api/v1/announcements/reactions_spec.rb
index ffacb2b0afa270..82154b4a265210 100644
--- a/spec/requests/api/v1/announcements/reactions_spec.rb
+++ b/spec/requests/api/v1/announcements/reactions_spec.rb
@@ -15,7 +15,9 @@
it 'returns http unauthorized' do
put "/api/v1/announcements/#{announcement.id}/reactions/#{escaped_emoji}"
- expect(response).to have_http_status 401
+ expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -26,6 +28,8 @@
it 'creates reaction', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to_not be_nil
end
end
@@ -39,7 +43,9 @@
context 'without token' do
it 'returns http unauthorized' do
delete "/api/v1/announcements/#{announcement.id}/reactions/#{escaped_emoji}"
- expect(response).to have_http_status 401
+ expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -50,6 +56,8 @@
it 'creates reaction', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to be_nil
end
end
diff --git a/spec/requests/api/v1/announcements_spec.rb b/spec/requests/api/v1/announcements_spec.rb
index 1624b76012563b..97a4442aa98855 100644
--- a/spec/requests/api/v1/announcements_spec.rb
+++ b/spec/requests/api/v1/announcements_spec.rb
@@ -15,7 +15,9 @@
it 'returns http unprocessable entity' do
get '/api/v1/announcements'
- expect(response).to have_http_status 422
+ expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -26,6 +28,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -35,7 +39,9 @@
it 'returns http unauthorized' do
post "/api/v1/announcements/#{announcement.id}/dismiss"
- expect(response).to have_http_status 401
+ expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -48,6 +54,8 @@
it 'dismisses announcement', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(announcement.announcement_mutes.find_by(account: user.account)).to_not be_nil
end
end
diff --git a/spec/requests/api/v1/annual_reports_spec.rb b/spec/requests/api/v1/annual_reports_spec.rb
index 8051a654847ecc..b9831d17e2c4f9 100644
--- a/spec/requests/api/v1/annual_reports_spec.rb
+++ b/spec/requests/api/v1/annual_reports_spec.rb
@@ -14,6 +14,8 @@
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -33,6 +35,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
@@ -51,6 +55,8 @@
.to change { annual_report.reload.viewed? }.to(true)
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/apps/credentials_spec.rb b/spec/requests/api/v1/apps/credentials_spec.rb
index 1cd6a4178fcd8e..30200ed60c3471 100644
--- a/spec/requests/api/v1/apps/credentials_spec.rb
+++ b/spec/requests/api/v1/apps/credentials_spec.rb
@@ -17,6 +17,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
a_hash_including(
@@ -36,6 +38,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:client_id]).to_not be_present
expect(response.parsed_body[:client_secret]).to_not be_present
@@ -47,14 +51,12 @@
let(:token) { Fabricate(:accessible_access_token, application: application) }
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
- it 'returns http success' do
+ it 'returns http success and returns app information' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns the app information correctly' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
a_hash_including(
@@ -78,6 +80,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -90,6 +94,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
it 'returns the error in the json response' do
@@ -108,14 +114,12 @@
let(:token) { Fabricate(:accessible_access_token, application: application) }
let(:headers) { { 'Authorization' => "Bearer #{token.token}-invalid" } }
- it 'returns http authorization error' do
+ it 'returns http authorization error with json error' do
subject
expect(response).to have_http_status(401)
- end
-
- it 'returns the error in the json response' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
a_hash_including(
diff --git a/spec/requests/api/v1/apps_spec.rb b/spec/requests/api/v1/apps_spec.rb
index 51a0c3fd0c6dc7..cf43e14d62c267 100644
--- a/spec/requests/api/v1/apps_spec.rb
+++ b/spec/requests/api/v1/apps_spec.rb
@@ -28,6 +28,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name)
@@ -59,6 +61,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(Doorkeeper::Application.find_by(name: client_name)).to be_present
expect(response.parsed_body)
@@ -76,6 +80,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name)
@@ -96,6 +102,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -106,6 +114,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(Doorkeeper::Application.find_by(name: client_name).scopes.to_s).to eq 'read'
end
end
@@ -117,6 +127,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -127,6 +139,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -137,6 +151,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -148,6 +164,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -158,6 +176,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name)
@@ -180,6 +200,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name)
@@ -202,6 +224,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -212,6 +236,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -222,6 +248,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -232,6 +260,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -242,6 +272,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
app = Doorkeeper::Application.find_by(name: client_name)
diff --git a/spec/requests/api/v1/blocks_spec.rb b/spec/requests/api/v1/blocks_spec.rb
index d2f1c46a5b9839..498cf932756de8 100644
--- a/spec/requests/api/v1/blocks_spec.rb
+++ b/spec/requests/api/v1/blocks_spec.rb
@@ -26,21 +26,20 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(expected_response)
end
context 'with limit param' do
let(:params) { { limit: 2 } }
- it 'returns only the requested number of blocked accounts' do
+ it 'returns only the requested number of blocked accounts and sets link header pagination' do
subject
expect(response.parsed_body.size).to eq(params[:limit])
- end
-
- it 'sets correct link header pagination' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response)
.to include_pagination_headers(
prev: api_v1_blocks_url(limit: params[:limit], since_id: blocks.last.id),
diff --git a/spec/requests/api/v1/bookmarks_spec.rb b/spec/requests/api/v1/bookmarks_spec.rb
index 95a71abcac706b..c78e6912365b51 100644
--- a/spec/requests/api/v1/bookmarks_spec.rb
+++ b/spec/requests/api/v1/bookmarks_spec.rb
@@ -24,15 +24,12 @@
it_behaves_like 'forbidden for wrong scope', 'write'
- it 'returns http success' do
+ it 'returns http success and the bookmarked statuses' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns the bookmarked statuses' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(expected_response)
end
@@ -45,6 +42,8 @@
expect(response.parsed_body.size)
.to eq(params[:limit])
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response)
.to include_pagination_headers(
prev: api_v1_bookmarks_url(limit: params[:limit], min_id: bookmarks.last.id),
@@ -60,6 +59,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/conversations_spec.rb b/spec/requests/api/v1/conversations_spec.rb
index bd3cbfd0e7f43f..6e2ac1df53e0a8 100644
--- a/spec/requests/api/v1/conversations_spec.rb
+++ b/spec/requests/api/v1/conversations_spec.rb
@@ -26,6 +26,8 @@
prev: api_v1_conversations_url(limit: 1, min_id: Status.first.id),
next: api_v1_conversations_url(limit: 1, max_id: Status.first.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
it 'returns conversations', :aggregate_failures do
diff --git a/spec/requests/api/v1/custom_emojis_spec.rb b/spec/requests/api/v1/custom_emojis_spec.rb
index 0942734ff3d809..e860fbeb17c105 100644
--- a/spec/requests/api/v1/custom_emojis_spec.rb
+++ b/spec/requests/api/v1/custom_emojis_spec.rb
@@ -18,6 +18,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
@@ -33,6 +35,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
diff --git a/spec/requests/api/v1/directories_spec.rb b/spec/requests/api/v1/directories_spec.rb
index aa602a71cd65e3..282be9a582551e 100644
--- a/spec/requests/api/v1/directories_spec.rb
+++ b/spec/requests/api/v1/directories_spec.rb
@@ -82,6 +82,8 @@
get '/api/v1/directory', headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(2)
expect(response.parsed_body.pluck(:id)).to contain_exactly(eligible_remote_account.id.to_s, local_discoverable_account.id.to_s)
end
@@ -101,6 +103,8 @@
get '/api/v1/directory', headers: headers, params: { local: '1' }
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(1)
expect(response.parsed_body.first[:id]).to include(local_account.id.to_s)
expect(response.body).to_not include(remote_account.id.to_s)
@@ -115,6 +119,8 @@
get '/api/v1/directory', headers: headers, params: { order: 'active' }
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(2)
expect(response.parsed_body.first[:id]).to include(new_stat.account_id.to_s)
expect(response.parsed_body.second[:id]).to include(old_stat.account_id.to_s)
@@ -130,6 +136,8 @@
get '/api/v1/directory', headers: headers, params: { order: 'new' }
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(2)
expect(response.parsed_body.first[:id]).to include(account_new.id.to_s)
expect(response.parsed_body.second[:id]).to include(account_old.id.to_s)
diff --git a/spec/requests/api/v1/domain_blocks_spec.rb b/spec/requests/api/v1/domain_blocks_spec.rb
index 8184c26bed101f..339f49fe761f75 100644
--- a/spec/requests/api/v1/domain_blocks_spec.rb
+++ b/spec/requests/api/v1/domain_blocks_spec.rb
@@ -26,6 +26,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(blocked_domains)
end
@@ -53,6 +55,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.domain_blocking?(params[:domain])).to be(true)
end
@@ -63,6 +67,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -73,6 +79,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -94,6 +102,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.domain_blocking?('example.com')).to be(false)
end
@@ -104,6 +114,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/emails/confirmations_spec.rb b/spec/requests/api/v1/emails/confirmations_spec.rb
index 0a419a10cfb937..1408ad05067318 100644
--- a/spec/requests/api/v1/emails/confirmations_spec.rb
+++ b/spec/requests/api/v1/emails/confirmations_spec.rb
@@ -26,6 +26,8 @@
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -41,6 +43,8 @@
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when user changed e-mail and has not confirmed it' do
@@ -52,6 +56,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -61,6 +67,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -71,6 +79,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.reload.unconfirmed_email).to eq('foo@bar.com')
end
end
@@ -82,6 +92,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -94,6 +106,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -111,6 +125,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be false
end
end
@@ -122,6 +138,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be true
end
end
@@ -139,6 +157,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be false
end
end
@@ -150,6 +170,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be true
end
end
@@ -162,6 +184,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/endorsements_spec.rb b/spec/requests/api/v1/endorsements_spec.rb
index 25917f527a1645..730ba6350cf05e 100644
--- a/spec/requests/api/v1/endorsements_spec.rb
+++ b/spec/requests/api/v1/endorsements_spec.rb
@@ -14,6 +14,8 @@
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -36,6 +38,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
@@ -51,6 +55,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to_not be_present
diff --git a/spec/requests/api/v1/favourites_spec.rb b/spec/requests/api/v1/favourites_spec.rb
index 78e9d61551fab7..44d0239556b2ab 100644
--- a/spec/requests/api/v1/favourites_spec.rb
+++ b/spec/requests/api/v1/favourites_spec.rb
@@ -24,35 +24,29 @@
it_behaves_like 'forbidden for wrong scope', 'write'
- it 'returns http success' do
+ it 'returns http success and includes the favourites' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns the favourites' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(expected_response)
end
context 'with limit param' do
let(:params) { { limit: 1 } }
- it 'returns only the requested number of favourites' do
+ it 'returns only the requested number of favourites and sets pagination headers' do
subject
expect(response.parsed_body.size).to eq(params[:limit])
- end
-
- it 'sets the correct pagination headers' do
- subject
-
expect(response)
.to include_pagination_headers(
prev: api_v1_favourites_url(limit: params[:limit], min_id: favourites.last.id),
next: api_v1_favourites_url(limit: params[:limit], max_id: favourites.second.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -63,6 +57,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/featured_tags/suggestions_spec.rb b/spec/requests/api/v1/featured_tags/suggestions_spec.rb
index 8815c65cf1ee39..5fbbec50976f08 100644
--- a/spec/requests/api/v1/featured_tags/suggestions_spec.rb
+++ b/spec/requests/api/v1/featured_tags/suggestions_spec.rb
@@ -32,6 +32,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to contain_exactly(
include(name: used_tag.name)
diff --git a/spec/requests/api/v1/featured_tags_spec.rb b/spec/requests/api/v1/featured_tags_spec.rb
index 423cc0c560ff60..b9c78cc11bdf5c 100644
--- a/spec/requests/api/v1/featured_tags_spec.rb
+++ b/spec/requests/api/v1/featured_tags_spec.rb
@@ -22,6 +22,8 @@
get '/api/v1/featured_tags'
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -29,6 +31,8 @@
get '/api/v1/featured_tags', headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when the requesting user has no featured tag' do
@@ -58,15 +62,12 @@
describe 'POST /api/v1/featured_tags' do
let(:params) { { name: 'tag' } }
- it 'returns http success' do
+ it 'returns http success and includes correct tag name' do
post '/api/v1/featured_tags', headers: headers, params: params
expect(response).to have_http_status(200)
- end
-
- it 'returns the correct tag name' do
- post '/api/v1/featured_tags', headers: headers, params: params
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
name: params[:name]
@@ -94,6 +95,8 @@
post '/api/v1/featured_tags', params: params
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -102,6 +105,8 @@
post '/api/v1/featured_tags', headers: headers
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -112,6 +117,8 @@
post '/api/v1/featured_tags', headers: headers, params: params
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -124,6 +131,8 @@
post '/api/v1/featured_tags', headers: headers, params: params
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -132,23 +141,15 @@
let!(:featured_tag) { FeaturedTag.create(name: 'tag', account: user.account) }
let(:id) { featured_tag.id }
- it 'returns http success' do
+ it 'returns http success with an empty body and deletes the featured tag', :inline_jobs do
delete "/api/v1/featured_tags/#{id}", headers: headers
expect(response).to have_http_status(200)
- end
-
- it 'returns an empty body' do
- delete "/api/v1/featured_tags/#{id}", headers: headers
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to be_empty
- end
-
- it 'deletes the featured tag', :inline_jobs do
- delete "/api/v1/featured_tags/#{id}", headers: headers
featured_tag = FeaturedTag.find_by(id: id)
-
expect(featured_tag).to be_nil
end
@@ -165,6 +166,8 @@
delete "/api/v1/featured_tags/#{id}"
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -173,6 +176,8 @@
delete '/api/v1/featured_tags/0', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -184,6 +189,8 @@
delete "/api/v1/featured_tags/#{id}", headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/filters_spec.rb b/spec/requests/api/v1/filters_spec.rb
index 93ed78b34606c8..51f03cc04d44c7 100644
--- a/spec/requests/api/v1/filters_spec.rb
+++ b/spec/requests/api/v1/filters_spec.rb
@@ -15,6 +15,8 @@
it 'returns http success' do
get '/api/v1/filters', headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to contain_exactly(
include(id: custom_filter_keyword.id.to_s)
@@ -35,6 +37,8 @@
filter = user.account.custom_filters.first
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(filter).to_not be_nil
expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
expect(filter.context).to eq %w(home)
@@ -50,6 +54,8 @@
filter = user.account.custom_filters.first
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(filter).to_not be_nil
expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
expect(filter.context).to eq %w(home)
@@ -68,6 +74,8 @@
get "/api/v1/filters/#{keyword.id}", headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -82,6 +90,8 @@
it 'updates the filter', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(keyword.reload.phrase).to eq 'updated'
end
end
@@ -97,6 +107,8 @@
it 'removes the filter', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound
end
end
diff --git a/spec/requests/api/v1/follow_requests_spec.rb b/spec/requests/api/v1/follow_requests_spec.rb
index c143ccaec1944e..f0f73d38ad0d9e 100644
--- a/spec/requests/api/v1/follow_requests_spec.rb
+++ b/spec/requests/api/v1/follow_requests_spec.rb
@@ -36,6 +36,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(expected_response)
end
@@ -66,6 +68,8 @@
it 'allows the requesting follower to follow', :aggregate_failures do
expect { subject }.to change { follower.following?(user.account) }.from(false).to(true)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:followed_by]).to be true
end
end
@@ -87,6 +91,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(FollowRequest.where(target_account: user.account, account: follower)).to_not exist
expect(response.parsed_body[:followed_by]).to be false
end
diff --git a/spec/requests/api/v1/followed_tags_spec.rb b/spec/requests/api/v1/followed_tags_spec.rb
index f7787cb76360b3..b0191b523fc308 100644
--- a/spec/requests/api/v1/followed_tags_spec.rb
+++ b/spec/requests/api/v1/followed_tags_spec.rb
@@ -28,29 +28,24 @@
it_behaves_like 'forbidden for wrong scope', 'write write:follows'
- it 'returns http success' do
+ it 'returns http success and includes followed tags' do
subject
expect(response).to have_http_status(:success)
- end
-
- it 'returns the followed tags correctly' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(expected_response)
end
context 'with limit param' do
let(:params) { { limit: 1 } }
- it 'returns only the requested number of follow tags' do
+ it 'returns only the requested number of follow tags and sets pagination headers' do
subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(params[:limit])
- end
-
- it 'sets the correct pagination headers' do
- subject
expect(response)
.to include_pagination_headers(
diff --git a/spec/requests/api/v1/instance_spec.rb b/spec/requests/api/v1/instance_spec.rb
index 42b6753bc34c76..62c90f55b2d64a 100644
--- a/spec/requests/api/v1/instance_spec.rb
+++ b/spec/requests/api/v1/instance_spec.rb
@@ -14,6 +14,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
@@ -27,6 +29,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
diff --git a/spec/requests/api/v1/instances/activity_spec.rb b/spec/requests/api/v1/instances/activity_spec.rb
index 72e3faeb650dd3..c2f94cc578a1e6 100644
--- a/spec/requests/api/v1/instances/activity_spec.rb
+++ b/spec/requests/api/v1/instances/activity_spec.rb
@@ -13,6 +13,9 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_present
.and(be_an(Array))
diff --git a/spec/requests/api/v1/instances/domain_blocks_spec.rb b/spec/requests/api/v1/instances/domain_blocks_spec.rb
index 460d338607bc9d..b214fda73b5a54 100644
--- a/spec/requests/api/v1/instances/domain_blocks_spec.rb
+++ b/spec/requests/api/v1/instances/domain_blocks_spec.rb
@@ -17,6 +17,9 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_present
.and(be_an(Array))
diff --git a/spec/requests/api/v1/instances/extended_descriptions_spec.rb b/spec/requests/api/v1/instances/extended_descriptions_spec.rb
index bf6d58216a0b0f..62a7fff2eccc33 100644
--- a/spec/requests/api/v1/instances/extended_descriptions_spec.rb
+++ b/spec/requests/api/v1/instances/extended_descriptions_spec.rb
@@ -9,6 +9,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
diff --git a/spec/requests/api/v1/instances/languages_spec.rb b/spec/requests/api/v1/instances/languages_spec.rb
index 79ea62c5996433..3d188d23c05bde 100644
--- a/spec/requests/api/v1/instances/languages_spec.rb
+++ b/spec/requests/api/v1/instances/languages_spec.rb
@@ -8,11 +8,10 @@
get '/api/v1/instance/languages'
end
- it 'returns http success' do
+ it 'returns http success and includes supported languages' do
expect(response).to have_http_status(200)
- end
-
- it 'returns the supported languages' do
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.pluck(:code)).to match_array LanguagesHelper::SUPPORTED_LOCALES.keys.map(&:to_s)
end
end
diff --git a/spec/requests/api/v1/instances/peers_spec.rb b/spec/requests/api/v1/instances/peers_spec.rb
index 1140612f0a9438..8ebfc933579055 100644
--- a/spec/requests/api/v1/instances/peers_spec.rb
+++ b/spec/requests/api/v1/instances/peers_spec.rb
@@ -12,6 +12,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Array)
diff --git a/spec/requests/api/v1/instances/privacy_policies_spec.rb b/spec/requests/api/v1/instances/privacy_policies_spec.rb
index 93490542cdd4d7..519c2b29d048bd 100644
--- a/spec/requests/api/v1/instances/privacy_policies_spec.rb
+++ b/spec/requests/api/v1/instances/privacy_policies_spec.rb
@@ -9,6 +9,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
diff --git a/spec/requests/api/v1/instances/rules_spec.rb b/spec/requests/api/v1/instances/rules_spec.rb
index 620c991ae2c3b0..b73004886392be 100644
--- a/spec/requests/api/v1/instances/rules_spec.rb
+++ b/spec/requests/api/v1/instances/rules_spec.rb
@@ -9,6 +9,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_an(Array)
diff --git a/spec/requests/api/v1/instances/translation_languages_spec.rb b/spec/requests/api/v1/instances/translation_languages_spec.rb
index 0de5ec3bc236ae..fef8700db928e4 100644
--- a/spec/requests/api/v1/instances/translation_languages_spec.rb
+++ b/spec/requests/api/v1/instances/translation_languages_spec.rb
@@ -10,6 +10,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to eq({})
@@ -24,6 +26,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to match({ und: %w(en de), en: ['de'] })
diff --git a/spec/requests/api/v1/lists/accounts_spec.rb b/spec/requests/api/v1/lists/accounts_spec.rb
index d147b21ee7f5eb..3911d1f28b50f7 100644
--- a/spec/requests/api/v1/lists/accounts_spec.rb
+++ b/spec/requests/api/v1/lists/accounts_spec.rb
@@ -34,6 +34,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(expected_response)
end
@@ -68,6 +70,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(list.accounts).to include(bob)
end
end
@@ -81,6 +85,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(list.accounts).to include(bob)
end
end
@@ -90,6 +96,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(list.accounts).to_not include(bob)
end
end
@@ -105,6 +113,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -118,6 +128,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -139,16 +151,13 @@
list.accounts << [bob, peter]
end
- it 'removes the specified account from the list', :aggregate_failures do
+ it 'removes the specified account from the list but keeps other accounts in the list', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(list.accounts).to_not include(bob)
- end
-
- it 'does not remove any other account from the list' do
- subject
-
expect(list.accounts).to include(peter)
end
@@ -159,6 +168,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(list.accounts).to contain_exactly(bob, peter)
end
end
@@ -172,6 +183,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/lists_spec.rb b/spec/requests/api/v1/lists_spec.rb
index 2042a64d5ceb00..20f27a74310574 100644
--- a/spec/requests/api/v1/lists_spec.rb
+++ b/spec/requests/api/v1/lists_spec.rb
@@ -43,6 +43,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(expected_response)
end
end
@@ -60,6 +62,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match({
id: list.id.to_s,
title: list.title,
@@ -75,6 +79,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -83,6 +89,8 @@
get '/api/v1/lists/-1', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -100,6 +108,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(a_hash_including(title: 'my list', replies_policy: 'none', exclusive: true))
expect(List.where(account: user.account).count).to eq(1)
end
@@ -111,6 +121,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -121,6 +133,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -142,6 +156,8 @@
.and change_list_exclusive
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
list.reload
expect(response.parsed_body).to match({
@@ -169,6 +185,8 @@ def change_list_exclusive
put '/api/v1/lists/-1', headers: headers, params: params
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -179,6 +197,8 @@ def change_list_exclusive
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -196,6 +216,8 @@ def change_list_exclusive
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(List.where(id: list.id)).to_not exist
end
@@ -214,6 +236,8 @@ def change_list_exclusive
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/markers_spec.rb b/spec/requests/api/v1/markers_spec.rb
index a10d2dc3e280ec..d7cd78924bcec1 100644
--- a/spec/requests/api/v1/markers_spec.rb
+++ b/spec/requests/api/v1/markers_spec.rb
@@ -18,6 +18,8 @@
it 'returns markers', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
home: include(last_read_id: '123'),
@@ -34,6 +36,8 @@
it 'creates a marker', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.markers.first.timeline).to eq 'home'
expect(user.markers.first.last_read_id).to eq 69_420
end
@@ -47,6 +51,8 @@
it 'updates a marker', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.markers.first.timeline).to eq 'home'
expect(user.markers.first.last_read_id).to eq 70_120
end
@@ -61,6 +67,8 @@
it 'returns error json' do
expect(response)
.to have_http_status(409)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(error: /Conflict during update/)
end
diff --git a/spec/requests/api/v1/media_spec.rb b/spec/requests/api/v1/media_spec.rb
index d0af334825e35c..d7d0b92f11bfb5 100644
--- a/spec/requests/api/v1/media_spec.rb
+++ b/spec/requests/api/v1/media_spec.rb
@@ -17,15 +17,12 @@
it_behaves_like 'forbidden for wrong scope', 'read'
- it 'returns http success' do
+ it 'returns http success with media information' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns the media information' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
a_hash_including(
id: media.id.to_s,
@@ -44,6 +41,8 @@
subject
expect(response).to have_http_status(206)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -54,6 +53,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -64,6 +65,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -80,6 +83,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(MediaAttachment.first).to be_present
expect(MediaAttachment.first).to have_attached_file(:file)
@@ -107,6 +112,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -117,6 +124,8 @@
subject
expect(response).to have_http_status(500)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -158,6 +167,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -176,6 +187,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/mutes_spec.rb b/spec/requests/api/v1/mutes_spec.rb
index 6402c908ffe4ce..61e32cb9ae0452 100644
--- a/spec/requests/api/v1/mutes_spec.rb
+++ b/spec/requests/api/v1/mutes_spec.rb
@@ -18,32 +18,26 @@
it_behaves_like 'forbidden for wrong scope', 'write write:mutes'
- it 'returns http success' do
+ it 'returns http success with muted accounts' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns the muted accounts' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
muted_accounts = mutes.map(&:target_account)
-
expect(response.parsed_body.pluck(:id)).to match_array(muted_accounts.map { |account| account.id.to_s })
end
context 'with limit param' do
let(:params) { { limit: 1 } }
- it 'returns only the requested number of muted accounts' do
+ it 'returns only the requested number of muted accounts with pagination headers' do
subject
expect(response.parsed_body.size).to eq(params[:limit])
- end
-
- it 'sets the correct pagination headers', :aggregate_failures do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response)
.to include_pagination_headers(
prev: api_v1_mutes_url(limit: params[:limit], since_id: mutes.last.id),
@@ -81,6 +75,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/notifications/policies_spec.rb b/spec/requests/api/v1/notifications/policies_spec.rb
index 8bafcad2fe397d..ac24501526fa38 100644
--- a/spec/requests/api/v1/notifications/policies_spec.rb
+++ b/spec/requests/api/v1/notifications/policies_spec.rb
@@ -26,6 +26,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include(
filter_not_following: false,
filter_not_followers: false,
@@ -54,6 +56,8 @@
.to change { NotificationPolicy.find_or_initialize_by(account: user.account).for_not_following.to_sym }.from(:accept).to(:filter)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include(
filter_not_following: true,
filter_not_followers: false,
diff --git a/spec/requests/api/v1/notifications/requests_spec.rb b/spec/requests/api/v1/notifications/requests_spec.rb
index dc125bc7aa8ef4..bee9d3a3da93f3 100644
--- a/spec/requests/api/v1/notifications/requests_spec.rb
+++ b/spec/requests/api/v1/notifications/requests_spec.rb
@@ -26,6 +26,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -39,15 +41,12 @@
it_behaves_like 'forbidden for wrong scope', 'read read:notifications'
- it 'returns http success' do
+ it 'returns http success and creates notification permission' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'creates notification permission' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(NotificationPermission.find_by(account: notification_request.account, from_account: notification_request.from_account)).to_not be_nil
end
@@ -58,6 +57,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -75,6 +76,8 @@
expect { subject }.to change(NotificationRequest, :count).by(-1)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when notification request belongs to someone else' do
@@ -84,6 +87,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -102,6 +107,8 @@
expect(NotificationPermission.find_by(account: notification_request.account, from_account: notification_request.from_account)).to_not be_nil
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -118,6 +125,8 @@
expect { subject }.to change(NotificationRequest, :count).by(-1)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -133,6 +142,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match({ merged: true })
end
end
@@ -146,6 +157,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match({ merged: false })
end
end
diff --git a/spec/requests/api/v1/notifications_spec.rb b/spec/requests/api/v1/notifications_spec.rb
index b74adb5dffc5e1..0e8eb6ad3ba2e6 100644
--- a/spec/requests/api/v1/notifications_spec.rb
+++ b/spec/requests/api/v1/notifications_spec.rb
@@ -31,6 +31,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 5
end
end
@@ -45,6 +47,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 2
end
end
@@ -56,6 +60,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 4
end
end
@@ -67,6 +73,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 2
end
end
@@ -80,6 +88,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq Api::V1::NotificationsController::DEFAULT_NOTIFICATIONS_COUNT_LIMIT
end
end
@@ -111,6 +121,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq 5
expect(body_json_types).to include('reblog', 'mention', 'favourite', 'follow')
expect(response.parsed_body.any? { |x| x[:filtered] }).to be false
@@ -124,6 +136,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq 6
expect(body_json_types).to include('reblog', 'mention', 'favourite', 'follow')
expect(response.parsed_body.any? { |x| x[:filtered] }).to be true
@@ -137,6 +151,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_account_ids.uniq).to eq [tom.account.id.to_s]
end
@@ -152,6 +168,8 @@ def body_json_account_ids
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq 0
end
end
@@ -163,6 +181,8 @@ def body_json_account_ids
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to_not eq 0
expect(body_json_types.uniq).to_not include 'mention'
end
@@ -175,6 +195,8 @@ def body_json_account_ids
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_types.uniq).to eq ['mention']
end
end
@@ -216,6 +238,8 @@ def body_json_types
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when notification belongs to someone else' do
@@ -225,6 +249,8 @@ def body_json_types
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -242,6 +268,8 @@ def body_json_types
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect { notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
@@ -252,6 +280,8 @@ def body_json_types
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -272,6 +302,8 @@ def body_json_types
expect(user.account.reload.notifications).to be_empty
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/peers/search_spec.rb b/spec/requests/api/v1/peers/search_spec.rb
index dc5f550d0e092d..d00a2437f279d6 100644
--- a/spec/requests/api/v1/peers/search_spec.rb
+++ b/spec/requests/api/v1/peers/search_spec.rb
@@ -23,6 +23,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_blank
end
@@ -34,6 +36,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_blank
end
@@ -49,6 +53,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size)
.to eq(1)
expect(response.parsed_body.first)
diff --git a/spec/requests/api/v1/polls/votes_spec.rb b/spec/requests/api/v1/polls/votes_spec.rb
index 669f64b6e4577e..d3f7eb431d93b5 100644
--- a/spec/requests/api/v1/polls/votes_spec.rb
+++ b/spec/requests/api/v1/polls/votes_spec.rb
@@ -18,6 +18,8 @@
it 'creates a vote', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(vote).to_not be_nil
expect(vote.choice).to eq 1
@@ -30,6 +32,8 @@
it 'returns http bad request' do
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
diff --git a/spec/requests/api/v1/polls_spec.rb b/spec/requests/api/v1/polls_spec.rb
index 138a37a73ce990..fd38297931a155 100644
--- a/spec/requests/api/v1/polls_spec.rb
+++ b/spec/requests/api/v1/polls_spec.rb
@@ -23,6 +23,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
a_hash_including(
id: poll.id.to_s,
@@ -41,6 +43,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/preferences_spec.rb b/spec/requests/api/v1/preferences_spec.rb
index d6991ca90ca71e..e03b9cf1087cd6 100644
--- a/spec/requests/api/v1/preferences_spec.rb
+++ b/spec/requests/api/v1/preferences_spec.rb
@@ -14,6 +14,8 @@
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -34,6 +36,9 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_present
end
diff --git a/spec/requests/api/v1/profiles_spec.rb b/spec/requests/api/v1/profiles_spec.rb
index 26a9b848e56e50..fd3ab4bf587afd 100644
--- a/spec/requests/api/v1/profiles_spec.rb
+++ b/spec/requests/api/v1/profiles_spec.rb
@@ -28,31 +28,16 @@
it_behaves_like 'forbidden for wrong scope', 'read'
end
- it 'returns http success' do
+ it 'returns http success and deletes the avatar, preserves the header, queues up distribution' do
delete '/api/v1/profile/avatar', headers: headers
expect(response).to have_http_status(200)
- end
-
- it 'deletes the avatar' do
- delete '/api/v1/profile/avatar', headers: headers
+ expect(response.content_type)
+ .to start_with('application/json')
account.reload
-
expect(account.avatar).to_not exist
- end
-
- it 'does not delete the header' do
- delete '/api/v1/profile/avatar', headers: headers
-
- account.reload
-
expect(account.header).to exist
- end
-
- it 'queues up an account update distribution' do
- delete '/api/v1/profile/avatar', headers: headers
-
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
end
end
@@ -66,31 +51,16 @@
it_behaves_like 'forbidden for wrong scope', 'read'
end
- it 'returns http success' do
+ it 'returns http success, preserves the avatar, deletes the header, queues up distribution' do
delete '/api/v1/profile/header', headers: headers
expect(response).to have_http_status(200)
- end
-
- it 'does not delete the avatar' do
- delete '/api/v1/profile/header', headers: headers
+ expect(response.content_type)
+ .to start_with('application/json')
account.reload
-
expect(account.avatar).to exist
- end
-
- it 'deletes the header' do
- delete '/api/v1/profile/header', headers: headers
-
- account.reload
-
expect(account.header).to_not exist
- end
-
- it 'queues up an account update distribution' do
- delete '/api/v1/profile/header', headers: headers
-
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(account.id)
end
end
diff --git a/spec/requests/api/v1/push/subscriptions_spec.rb b/spec/requests/api/v1/push/subscriptions_spec.rb
index a9587f8d58343f..8ad672c95ee961 100644
--- a/spec/requests/api/v1/push/subscriptions_spec.rb
+++ b/spec/requests/api/v1/push/subscriptions_spec.rb
@@ -45,6 +45,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(endpoint_push_subscriptions.count).to eq(0)
expect(endpoint_push_subscription).to be_nil
end
diff --git a/spec/requests/api/v1/reports_spec.rb b/spec/requests/api/v1/reports_spec.rb
index a176bd78a6ef32..18b894bf632714 100644
--- a/spec/requests/api/v1/reports_spec.rb
+++ b/spec/requests/api/v1/reports_spec.rb
@@ -37,6 +37,8 @@
emails = capture_emails { subject }
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match(
a_hash_including(
status_ids: [status.id.to_s],
@@ -65,6 +67,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
diff --git a/spec/requests/api/v1/scheduled_status_spec.rb b/spec/requests/api/v1/scheduled_status_spec.rb
index eb03827c9ab0d5..3a1b81ce65c1d4 100644
--- a/spec/requests/api/v1/scheduled_status_spec.rb
+++ b/spec/requests/api/v1/scheduled_status_spec.rb
@@ -14,6 +14,8 @@
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -33,6 +35,8 @@
expect(response)
.to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -45,6 +49,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to_not be_present
@@ -59,6 +65,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to be_present
diff --git a/spec/requests/api/v1/statuses/bookmarks_spec.rb b/spec/requests/api/v1/statuses/bookmarks_spec.rb
index f1bcfda0ff638b..583f5b6a0ef641 100644
--- a/spec/requests/api/v1/statuses/bookmarks_spec.rb
+++ b/spec/requests/api/v1/statuses/bookmarks_spec.rb
@@ -18,15 +18,13 @@
it_behaves_like 'forbidden for wrong scope', 'read'
context 'with public status' do
- it 'bookmarks the status successfully', :aggregate_failures do
+ it 'bookmarks the status successfully and includes updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.bookmarked?(status)).to be true
- end
-
- it 'returns json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, bookmarked: true)
@@ -41,6 +39,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -55,6 +55,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.bookmarked?(status)).to be true
end
end
@@ -64,6 +66,8 @@
post '/api/v1/statuses/-1/bookmark', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -74,6 +78,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -93,15 +99,13 @@
Bookmark.find_or_create_by!(account: user.account, status: status)
end
- it 'unbookmarks the status successfully', :aggregate_failures do
+ it 'unbookmarks the status successfully and includes updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.bookmarked?(status)).to be false
- end
-
- it 'returns json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, bookmarked: false)
@@ -117,15 +121,13 @@
status.account.block!(user.account)
end
- it 'unbookmarks the status successfully', :aggregate_failures do
+ it 'unbookmarks the status successfully and includes updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.bookmarked?(status)).to be false
- end
-
- it 'returns json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, bookmarked: false)
@@ -138,6 +140,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -149,6 +153,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses/favourited_by_accounts_spec.rb b/spec/requests/api/v1/statuses/favourited_by_accounts_spec.rb
index 24bd03d343b207..6471697154c7df 100644
--- a/spec/requests/api/v1/statuses/favourited_by_accounts_spec.rb
+++ b/spec/requests/api/v1/statuses/favourited_by_accounts_spec.rb
@@ -33,6 +33,8 @@
prev: api_v1_status_favourited_by_index_url(limit: 2, since_id: Favourite.last.id),
next: api_v1_status_favourited_by_index_url(limit: 2, max_id: Favourite.first.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size)
.to eq(2)
@@ -72,6 +74,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -88,6 +92,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses/favourites_spec.rb b/spec/requests/api/v1/statuses/favourites_spec.rb
index f9f0ff62990cfa..3d1021e29d6ef9 100644
--- a/spec/requests/api/v1/statuses/favourites_spec.rb
+++ b/spec/requests/api/v1/statuses/favourites_spec.rb
@@ -18,15 +18,13 @@
it_behaves_like 'forbidden for wrong scope', 'read read:favourites'
context 'with public status' do
- it 'favourites the status successfully', :aggregate_failures do
+ it 'favourites the status successfully and includes updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.favourited?(status)).to be true
- end
-
- it 'returns json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, favourites_count: 1, favourited: true)
@@ -41,6 +39,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -55,6 +55,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.favourited?(status)).to be true
end
end
@@ -66,6 +68,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -84,16 +88,14 @@
FavouriteService.new.call(user.account, status)
end
- it 'unfavourites the status successfully', :aggregate_failures do
+ it 'unfavourites the status successfully and includes updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.favourited?(status)).to be false
- end
-
- it 'returns json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, favourites_count: 0, favourited: false)
@@ -107,16 +109,14 @@
status.account.block!(user.account)
end
- it 'unfavourites the status successfully', :aggregate_failures do
+ it 'unfavourites the status successfully and includes updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.favourited?(status)).to be false
- end
-
- it 'returns json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, favourites_count: 0, favourited: false)
@@ -129,6 +129,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -139,6 +141,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses/histories_spec.rb b/spec/requests/api/v1/statuses/histories_spec.rb
index 4115a52fa8cc0e..9c7f93d3437f86 100644
--- a/spec/requests/api/v1/statuses/histories_spec.rb
+++ b/spec/requests/api/v1/statuses/histories_spec.rb
@@ -18,6 +18,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to_not be 0
end
end
diff --git a/spec/requests/api/v1/statuses/mutes_spec.rb b/spec/requests/api/v1/statuses/mutes_spec.rb
index 69ae948852888a..55313482d6e8a4 100644
--- a/spec/requests/api/v1/statuses/mutes_spec.rb
+++ b/spec/requests/api/v1/statuses/mutes_spec.rb
@@ -18,6 +18,8 @@
it 'creates a conversation mute', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(ConversationMute.find_by(account: user.account, conversation_id: status.conversation_id)).to_not be_nil
end
end
@@ -32,6 +34,8 @@
it 'destroys the conversation mute', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(ConversationMute.find_by(account: user.account, conversation_id: status.conversation_id)).to be_nil
end
end
diff --git a/spec/requests/api/v1/statuses/pins_spec.rb b/spec/requests/api/v1/statuses/pins_spec.rb
index 56e60c6d368c2c..05d8f570cc8455 100644
--- a/spec/requests/api/v1/statuses/pins_spec.rb
+++ b/spec/requests/api/v1/statuses/pins_spec.rb
@@ -18,15 +18,13 @@
it_behaves_like 'forbidden for wrong scope', 'read read:accounts'
context 'when the status is public' do
- it 'pins the status successfully', :aggregate_failures do
+ it 'pins the status successfully and returns updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.pinned?(status)).to be true
- end
-
- it 'return json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, pinned: true)
@@ -41,6 +39,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.pinned?(status)).to be true
end
end
@@ -52,6 +52,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -60,6 +62,8 @@
post '/api/v1/statuses/-1/pin', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -70,6 +74,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -86,15 +92,13 @@
Fabricate(:status_pin, status: status, account: user.account)
end
- it 'unpins the status successfully', :aggregate_failures do
+ it 'unpins the status successfully and includes updated json', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(user.account.pinned?(status)).to be false
- end
-
- it 'return json with updated attributes' do
- subject
expect(response.parsed_body).to match(
a_hash_including(id: status.id.to_s, pinned: false)
@@ -107,6 +111,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -115,6 +121,8 @@
post '/api/v1/statuses/-1/unpin', headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -125,6 +133,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses/reblogged_by_accounts_spec.rb b/spec/requests/api/v1/statuses/reblogged_by_accounts_spec.rb
index bd26c22f08e388..40457f6e894a57 100644
--- a/spec/requests/api/v1/statuses/reblogged_by_accounts_spec.rb
+++ b/spec/requests/api/v1/statuses/reblogged_by_accounts_spec.rb
@@ -32,6 +32,8 @@
prev: api_v1_status_reblogged_by_index_url(limit: 2, since_id: bob.statuses.first.id),
next: api_v1_status_reblogged_by_index_url(limit: 2, max_id: alice.statuses.first.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size)
.to eq(2)
@@ -71,6 +73,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -87,6 +91,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses/reblogs_spec.rb b/spec/requests/api/v1/statuses/reblogs_spec.rb
index 8c7894d875b0b4..5e88690074e22d 100644
--- a/spec/requests/api/v1/statuses/reblogs_spec.rb
+++ b/spec/requests/api/v1/statuses/reblogs_spec.rb
@@ -19,6 +19,8 @@
context 'with public status' do
it 'reblogs the status', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(status.reblogs.count).to eq 1
@@ -40,6 +42,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -55,6 +59,8 @@
it 'destroys the reblog', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(status.reblogs.count).to eq 0
@@ -80,6 +86,8 @@
it 'destroys the reblog', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(status.reblogs.count).to eq 0
@@ -103,6 +111,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses/sources_spec.rb b/spec/requests/api/v1/statuses/sources_spec.rb
index c23fa91b0dbc84..b9c09f672155cc 100644
--- a/spec/requests/api/v1/statuses/sources_spec.rb
+++ b/spec/requests/api/v1/statuses/sources_spec.rb
@@ -22,6 +22,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match({
id: status.id.to_s,
text: status.text,
@@ -38,6 +40,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -52,6 +56,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match({
id: status.id.to_s,
text: status.text,
@@ -68,6 +74,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses/translations_spec.rb b/spec/requests/api/v1/statuses/translations_spec.rb
index 047b2f0485548e..e316bd451b0b16 100644
--- a/spec/requests/api/v1/statuses/translations_spec.rb
+++ b/spec/requests/api/v1/statuses/translations_spec.rb
@@ -20,6 +20,8 @@
it 'returns http unprocessable entity' do
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -38,6 +40,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/statuses_spec.rb b/spec/requests/api/v1/statuses_spec.rb
index 057800a266cae9..ddf5945d2562cd 100644
--- a/spec/requests/api/v1/statuses_spec.rb
+++ b/spec/requests/api/v1/statuses_spec.rb
@@ -18,6 +18,8 @@
get '/api/v1/statuses', headers: headers, params: { id: [status.id, other_status.id, 123_123] }
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to contain_exactly(
hash_including(id: status.id.to_s),
hash_including(id: other_status.id.to_s)
@@ -39,6 +41,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when post includes filtered terms' do
@@ -52,6 +56,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:filtered][0]).to include({
filter: a_hash_including({
id: user.account.custom_filters.first.id.to_s,
@@ -75,6 +81,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:filtered][0]).to include({
filter: a_hash_including({
id: user.account.custom_filters.first.id.to_s,
@@ -97,6 +105,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:reblog][:filtered][0]).to include({
filter: a_hash_including({
id: user.account.custom_filters.first.id.to_s,
@@ -121,6 +131,8 @@
get "/api/v1/statuses/#{status.id}/context", headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -139,6 +151,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
expect(response.headers['X-RateLimit-Remaining']).to eq (RateLimiter::FAMILIES[:statuses][:limit] - 1).to_s
end
@@ -154,6 +168,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:unexpected_accounts].map { |a| a.slice(:id, :acct) }).to match [{ id: bob.id.to_s, acct: bob.acct }]
end
end
@@ -165,6 +181,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
end
end
@@ -179,6 +197,8 @@
subject
expect(response).to have_http_status(429)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
expect(response.headers['X-RateLimit-Remaining']).to eq '0'
end
@@ -191,6 +211,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -202,6 +224,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
it 'creates a scheduled status' do
@@ -215,6 +239,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(account.scheduled_statuses).to be_empty
end
end
@@ -235,6 +261,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(Status.find_by(id: status.id)).to be_nil
end
end
@@ -253,6 +281,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(status.reload.text).to eq 'I am updated'
end
end
@@ -267,6 +297,8 @@
get "/api/v1/statuses/#{status.id}"
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -279,6 +311,8 @@
get "/api/v1/statuses/#{status.id}/context"
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -291,6 +325,8 @@
get "/api/v1/statuses/#{status.id}"
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -303,6 +339,8 @@
get "/api/v1/statuses/#{status.id}/context"
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/streaming_spec.rb b/spec/requests/api/v1/streaming_spec.rb
index a1f64846cf7d6a..62b43d657a5f25 100644
--- a/spec/requests/api/v1/streaming_spec.rb
+++ b/spec/requests/api/v1/streaming_spec.rb
@@ -17,6 +17,8 @@
get '/api/v1/streaming'
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/suggestions_spec.rb b/spec/requests/api/v1/suggestions_spec.rb
index 8267bb92a047db..0a32d8899bce43 100644
--- a/spec/requests/api/v1/suggestions_spec.rb
+++ b/spec/requests/api/v1/suggestions_spec.rb
@@ -23,15 +23,12 @@
it_behaves_like 'forbidden for wrong scope', 'write'
- it 'returns http success' do
+ it 'returns http success with accounts' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns accounts' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to contain_exactly(include(id: bob.id.to_s), include(id: jeff.id.to_s))
end
@@ -53,6 +50,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -72,15 +71,12 @@
it_behaves_like 'forbidden for wrong scope', 'read'
- it 'returns http success' do
+ it 'returns http success and removes suggestion' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'removes the specified suggestion' do
- subject
-
+ expect(response.content_type)
+ .to start_with('application/json')
expect(FollowRecommendationMute.exists?(account: user.account, target_account: jeff)).to be true
end
diff --git a/spec/requests/api/v1/tags_spec.rb b/spec/requests/api/v1/tags_spec.rb
index 9637823d457a1c..f6ff7c614fe328 100644
--- a/spec/requests/api/v1/tags_spec.rb
+++ b/spec/requests/api/v1/tags_spec.rb
@@ -21,6 +21,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:name]).to eq(name)
end
end
@@ -32,6 +34,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -42,6 +46,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -61,6 +67,8 @@
subject
expect(response).to have_http_status(:success)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(TagFollow.where(tag: tag, account: user.account)).to exist
end
end
@@ -72,6 +80,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(Tag.where(name: name)).to exist
expect(TagFollow.where(tag: Tag.find_by(name: name), account: user.account)).to exist
end
@@ -84,6 +94,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -95,6 +107,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -117,6 +131,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(TagFollow.where(tag: tag, account: user.account)).to_not exist
end
@@ -127,6 +143,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -138,6 +156,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/timelines/home_spec.rb b/spec/requests/api/v1/timelines/home_spec.rb
index afad2988ca2a10..2023b189ecb8a0 100644
--- a/spec/requests/api/v1/timelines/home_spec.rb
+++ b/spec/requests/api/v1/timelines/home_spec.rb
@@ -31,14 +31,12 @@
PostStatusService.new.call(ana, text: 'New toot from ana.')
end
- it 'returns http success' do
+ it 'returns http success and statuses of followed users' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns the statuses of followed users' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.pluck(:id)).to match_array(home_statuses.map { |status| status.id.to_s })
end
@@ -46,20 +44,18 @@
context 'with limit param' do
let(:params) { { limit: 1 } }
- it 'returns only the requested number of statuses' do
+ it 'returns only the requested number of statuses with pagination headers', :aggregate_failures do
subject
expect(response.parsed_body.size).to eq(params[:limit])
- end
-
- it 'sets the correct pagination headers', :aggregate_failures do
- subject
expect(response)
.to include_pagination_headers(
prev: api_v1_timelines_home_url(limit: params[:limit], min_id: ana.statuses.first.id),
next: api_v1_timelines_home_url(limit: params[:limit], max_id: ana.statuses.first.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -75,6 +71,8 @@
subject
expect(response).to have_http_status(206)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -85,6 +83,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -97,6 +97,8 @@
expect(response)
.to have_http_status(422)
.and not_have_http_link_header
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/timelines/link_spec.rb b/spec/requests/api/v1/timelines/link_spec.rb
index d7fd1076fef770..dc4d0d9506ea74 100644
--- a/spec/requests/api/v1/timelines/link_spec.rb
+++ b/spec/requests/api/v1/timelines/link_spec.rb
@@ -13,6 +13,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.pluck(:id)).to match_array(expected_statuses.map { |status| status.id.to_s })
end
end
@@ -50,6 +52,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -62,6 +66,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -74,6 +80,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -91,6 +99,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -101,6 +111,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -127,15 +139,13 @@
context 'with limit param' do
let(:params) { { limit: 1, url: url } }
- it 'returns only the requested number of statuses', :aggregate_failures do
+ it 'returns only the requested number of statuses with pagination headers', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(params[:limit])
- end
-
- it 'sets the correct pagination headers', :aggregate_failures do
- subject
expect(response)
.to include_pagination_headers(
diff --git a/spec/requests/api/v1/timelines/list_spec.rb b/spec/requests/api/v1/timelines/list_spec.rb
index eb4395d1f97b54..1be754f264d750 100644
--- a/spec/requests/api/v1/timelines/list_spec.rb
+++ b/spec/requests/api/v1/timelines/list_spec.rb
@@ -23,6 +23,8 @@
get "/api/v1/timelines/list/#{list.id}", headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -36,6 +38,8 @@
get "/api/v1/timelines/list/#{list.id}", headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v1/timelines/public_spec.rb b/spec/requests/api/v1/timelines/public_spec.rb
index 53398b68ec0d03..83d903935637f0 100644
--- a/spec/requests/api/v1/timelines/public_spec.rb
+++ b/spec/requests/api/v1/timelines/public_spec.rb
@@ -13,6 +13,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.pluck(:id)).to match_array(expected_statuses.map { |status| status.id.to_s })
end
end
@@ -81,15 +83,13 @@
context 'with limit param' do
let(:params) { { limit: 1 } }
- it 'returns only the requested number of statuses', :aggregate_failures do
+ it 'returns only the requested number of statuses and sets pagination headers', :aggregate_failures do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to eq(params[:limit])
- end
-
- it 'sets the correct pagination headers', :aggregate_failures do
- subject
expect(response)
.to include_pagination_headers(
@@ -114,6 +114,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -124,6 +126,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
diff --git a/spec/requests/api/v1/timelines/tag_spec.rb b/spec/requests/api/v1/timelines/tag_spec.rb
index 554b5fd3e3b0f7..1d6844364d6161 100644
--- a/spec/requests/api/v1/timelines/tag_spec.rb
+++ b/spec/requests/api/v1/timelines/tag_spec.rb
@@ -23,6 +23,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.pluck(:id))
.to match_array(expected_statuses.map { |status| status.id.to_s })
.and not_include(private_status.id)
@@ -85,6 +87,8 @@
prev: api_v1_timelines_tag_url(limit: params[:limit], min_id: love_status.id),
next: api_v1_timelines_tag_url(limit: params[:limit], max_id: love_status.id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -111,6 +115,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
diff --git a/spec/requests/api/v1/trends/links_spec.rb b/spec/requests/api/v1/trends/links_spec.rb
index 012d0359072c74..b1b77e7fd8c7ce 100644
--- a/spec/requests/api/v1/trends/links_spec.rb
+++ b/spec/requests/api/v1/trends/links_spec.rb
@@ -10,7 +10,11 @@
it 'returns http success' do
get '/api/v1/trends/links'
- expect(response).to have_http_status(200)
+ expect(response)
+ .to have_http_status(200)
+ .and not_have_http_link_header
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -22,8 +26,11 @@
stub_const('Api::V1::Trends::LinksController::DEFAULT_LINKS_LIMIT', 2)
get '/api/v1/trends/links'
- expect(response).to have_http_status(200)
- expect(response.headers).to include('Link')
+ expect(response)
+ .to have_http_status(200)
+ .and have_http_link_header(api_v1_trends_links_url(offset: 2)).for(rel: 'next')
+ expect(response.content_type)
+ .to start_with('application/json')
end
def prepare_trends
diff --git a/spec/requests/api/v1/trends/statuses_spec.rb b/spec/requests/api/v1/trends/statuses_spec.rb
index 3b906e8f822b44..fe00c9c6458564 100644
--- a/spec/requests/api/v1/trends/statuses_spec.rb
+++ b/spec/requests/api/v1/trends/statuses_spec.rb
@@ -10,7 +10,11 @@
it 'returns http success' do
get '/api/v1/trends/statuses'
- expect(response).to have_http_status(200)
+ expect(response)
+ .to have_http_status(200)
+ .and not_have_http_link_header
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -22,8 +26,11 @@
stub_const('Api::BaseController::DEFAULT_STATUSES_LIMIT', 2)
get '/api/v1/trends/statuses'
- expect(response).to have_http_status(200)
- expect(response.headers).to include('Link')
+ expect(response)
+ .to have_http_status(200)
+ .and have_http_link_header(api_v1_trends_statuses_url(offset: 2)).for(rel: 'next')
+ expect(response.content_type)
+ .to start_with('application/json')
end
def prepare_trends
diff --git a/spec/requests/api/v1/trends/tags_spec.rb b/spec/requests/api/v1/trends/tags_spec.rb
index 598f4e7752714d..14ab73fc96c30e 100644
--- a/spec/requests/api/v1/trends/tags_spec.rb
+++ b/spec/requests/api/v1/trends/tags_spec.rb
@@ -10,8 +10,11 @@
it 'returns http success' do
get '/api/v1/trends/tags'
- expect(response).to have_http_status(200)
- expect(response.headers).to_not include('Link')
+ expect(response)
+ .to have_http_status(200)
+ .and not_have_http_link_header
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -23,8 +26,11 @@
stub_const('Api::V1::Trends::TagsController::DEFAULT_TAGS_LIMIT', 2)
get '/api/v1/trends/tags'
- expect(response).to have_http_status(200)
- expect(response.headers).to include('Link')
+ expect(response)
+ .to have_http_status(200)
+ .and have_http_link_header(api_v1_trends_tags_url(offset: 2)).for(rel: 'next')
+ expect(response.content_type)
+ .to start_with('application/json')
end
def prepare_trends
diff --git a/spec/requests/api/v2/admin/accounts_spec.rb b/spec/requests/api/v2/admin/accounts_spec.rb
index 17c38e2e557b85..bc3db4f8860fcf 100644
--- a/spec/requests/api/v2/admin/accounts_spec.rb
+++ b/spec/requests/api/v2/admin/accounts_spec.rb
@@ -34,6 +34,8 @@
it 'returns the correct accounts' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_ids).to eq([admin_account.id])
end
end
@@ -43,6 +45,8 @@
it 'returns the correct accounts' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_ids).to include(remote_account.id)
expect(body_json_ids).to_not include(other_remote_account.id)
end
@@ -53,6 +57,8 @@
it 'returns the correct accounts' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_ids).to include(suspended_remote.id, suspended_account.id)
end
end
@@ -62,6 +68,8 @@
it 'returns the correct accounts' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_ids).to include(disabled_account.id)
end
end
@@ -71,6 +79,8 @@
it 'returns the correct accounts' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_ids).to include(pending_account.id)
end
end
@@ -85,6 +95,8 @@ def body_json_ids
it 'sets the correct pagination headers' do
expect(response)
.to include_pagination_headers(next: api_v2_admin_accounts_url(limit: 1, max_id: admin_account.id))
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v2/filters/keywords_spec.rb b/spec/requests/api/v2/filters/keywords_spec.rb
index a31accaa5cd72d..f0d62e9ecc6ae3 100644
--- a/spec/requests/api/v2/filters/keywords_spec.rb
+++ b/spec/requests/api/v2/filters/keywords_spec.rb
@@ -17,6 +17,8 @@
it 'returns http success' do
get "/api/v2/filters/#{filter.id}/keywords", headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to contain_exactly(
include(id: keyword.id.to_s)
@@ -27,6 +29,8 @@
it 'returns http not found' do
get "/api/v2/filters/#{other_filter.id}/keywords", headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -41,6 +45,8 @@
it 'creates a filter', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -58,6 +64,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -72,6 +80,8 @@
it 'responds with the keyword', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -85,6 +95,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -99,6 +111,8 @@
it 'updates the keyword', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(keyword.reload.keyword).to eq 'updated'
end
@@ -108,6 +122,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -122,6 +138,8 @@
it 'destroys the keyword', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound
end
@@ -131,6 +149,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v2/filters/statuses_spec.rb b/spec/requests/api/v2/filters/statuses_spec.rb
index aed8934a5e3838..f20a6ae5e6d245 100644
--- a/spec/requests/api/v2/filters/statuses_spec.rb
+++ b/spec/requests/api/v2/filters/statuses_spec.rb
@@ -17,6 +17,8 @@
it 'returns http success' do
get "/api/v2/filters/#{filter.id}/statuses", headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to contain_exactly(
include(id: status_filter.id.to_s)
@@ -27,6 +29,8 @@
it 'returns http not found' do
get "/api/v2/filters/#{other_filter.id}/statuses", headers: headers
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -42,6 +46,8 @@
it 'creates a filter', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -58,6 +64,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -72,6 +80,8 @@
it 'responds with the filter', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -98,6 +108,8 @@
it 'destroys the filter', :aggregate_failures do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect { status_filter.reload }.to raise_error ActiveRecord::RecordNotFound
end
@@ -107,6 +119,8 @@
it 'returns http not found' do
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v2/filters_spec.rb b/spec/requests/api/v2/filters_spec.rb
index 850c773df3d7a3..3b5c44cefa3e15 100644
--- a/spec/requests/api/v2/filters_spec.rb
+++ b/spec/requests/api/v2/filters_spec.rb
@@ -15,6 +15,8 @@
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -32,6 +34,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.pluck(:id)).to match_array(filters.map { |filter| filter.id.to_s })
end
end
@@ -49,14 +53,12 @@
context 'with valid params' do
let(:params) { { title: 'magic', context: %w(home), filter_action: 'hide', keywords_attributes: [keyword: 'magic'] } }
- it 'returns http success' do
+ it 'returns http success with a filter with keywords in json and creates a filter', :aggregate_failures do
subject
expect(response).to have_http_status(200)
- end
-
- it 'returns a filter with keywords', :aggregate_failures do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
@@ -67,10 +69,6 @@
include(keyword: 'magic', whole_word: true)
)
)
- end
-
- it 'creates a filter', :aggregate_failures do
- subject
filter = user.account.custom_filters.first
@@ -89,6 +87,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -99,6 +99,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -109,6 +111,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -127,6 +131,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body)
.to include(
id: filter.id.to_s
@@ -140,6 +146,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -166,6 +174,8 @@
filter.reload
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(filter.title).to eq 'updated'
expect(filter.reload.context).to eq %w(home public)
end
@@ -178,6 +188,8 @@
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -189,20 +201,14 @@
allow(redis).to receive_messages(publish: nil)
end
- it 'returns http success' do
+ it 'returns http success and updates keyword and sends a filters_changed event' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'updates the keyword' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect(keyword.reload.keyword).to eq 'updated'
- end
-
- it 'sends exactly one filters_changed event' do
- subject
expect(redis).to have_received(:publish).with("timeline:#{user.account.id}", Oj.dump(event: :filters_changed)).once
end
@@ -215,6 +221,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -229,14 +237,12 @@
it_behaves_like 'forbidden for wrong scope', 'read read:filters'
it_behaves_like 'unauthorized for invalid token'
- it 'returns http success' do
+ it 'returns http success and removes the filter' do
subject
expect(response).to have_http_status(200)
- end
-
- it 'removes the filter' do
- subject
+ expect(response.content_type)
+ .to start_with('application/json')
expect { filter.reload }.to raise_error ActiveRecord::RecordNotFound
end
@@ -248,6 +254,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v2/instance_spec.rb b/spec/requests/api/v2/instance_spec.rb
index 6f7519ad1e2c1d..85d92f68d0eec5 100644
--- a/spec/requests/api/v2/instance_spec.rb
+++ b/spec/requests/api/v2/instance_spec.rb
@@ -15,6 +15,9 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_present
.and include(title: 'Mastodon Glitch Edition')
@@ -30,6 +33,9 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_present
.and include(title: 'Mastodon Glitch Edition')
diff --git a/spec/requests/api/v2/media_spec.rb b/spec/requests/api/v2/media_spec.rb
index 06ce0053e87689..70e0679f57442c 100644
--- a/spec/requests/api/v2/media_spec.rb
+++ b/spec/requests/api/v2/media_spec.rb
@@ -21,6 +21,9 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_a(Hash)
end
@@ -38,6 +41,9 @@
expect(response)
.to have_http_status(202)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_a(Hash)
end
@@ -63,6 +69,9 @@
expect(response)
.to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_a(Hash)
.and include(error: /File type/)
@@ -80,6 +89,9 @@
expect(response)
.to have_http_status(500)
+ expect(response.content_type)
+ .to start_with('application/json')
+
expect(response.parsed_body)
.to be_a(Hash)
.and include(error: /processing/)
diff --git a/spec/requests/api/v2/notifications/accounts_spec.rb b/spec/requests/api/v2/notifications/accounts_spec.rb
index 102b009c0b9f4a..29880a4c0a6c6a 100644
--- a/spec/requests/api/v2/notifications/accounts_spec.rb
+++ b/spec/requests/api/v2/notifications/accounts_spec.rb
@@ -30,6 +30,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
# The group we are interested in is only favorites
notifications = user.account.notifications.where(type: 'favourite').reorder(id: :desc)
@@ -55,6 +57,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
# The group we are interested in is only favorites
notifications = user.account.notifications.where(type: 'favourite').reorder(id: :desc)
diff --git a/spec/requests/api/v2/notifications/policies_spec.rb b/spec/requests/api/v2/notifications/policies_spec.rb
index dc205b6ebb6d25..f080bc730fdcd1 100644
--- a/spec/requests/api/v2/notifications/policies_spec.rb
+++ b/spec/requests/api/v2/notifications/policies_spec.rb
@@ -26,6 +26,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include(
for_not_following: 'accept',
for_not_followers: 'accept',
@@ -56,6 +58,8 @@
.and change { NotificationPolicy.find_or_initialize_by(account: user.account).for_limited_accounts.to_sym }.from(:filter).to(:drop)
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to include(
for_not_following: 'filter',
for_not_followers: 'accept',
diff --git a/spec/requests/api/v2/notifications_spec.rb b/spec/requests/api/v2/notifications_spec.rb
index edf333ecd85586..ffa0a71c779e1b 100644
--- a/spec/requests/api/v2/notifications_spec.rb
+++ b/spec/requests/api/v2/notifications_spec.rb
@@ -31,6 +31,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 4
end
end
@@ -42,6 +44,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 5
end
end
@@ -56,6 +60,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 2
end
end
@@ -67,6 +73,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 3
end
end
@@ -78,6 +86,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq 2
end
end
@@ -91,6 +101,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:count]).to eq Api::V2::NotificationsController::DEFAULT_NOTIFICATIONS_COUNT_LIMIT
end
end
@@ -125,6 +137,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:notification_groups]).to eq []
end
end
@@ -134,6 +148,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_types).to include('reblog', 'mention', 'favourite', 'follow')
end
end
@@ -145,6 +161,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:notification_groups]).to contain_exactly(
a_hash_including(
type: 'reblog',
@@ -177,6 +195,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body.size).to_not eq 0
expect(body_json_types.uniq).to_not include 'mention'
end
@@ -189,6 +209,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(body_json_types.uniq).to eq ['mention']
expect(response.parsed_body.dig(:notification_groups, 0, :page_min_id)).to_not be_nil
end
@@ -211,6 +233,8 @@
# not the last that has been skipped, so pagination is very likely to give overlap
next: api_v2_notifications_url(limit: params[:limit], max_id: notifications[3].id)
)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -224,6 +248,8 @@
expect(response.parsed_body[:notification_groups].size)
.to eq(2)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response)
.to include_pagination_headers(
prev: api_v2_notifications_url(limit: params[:limit], min_id: notifications.first.id),
@@ -247,6 +273,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:partial_accounts].size).to be > 0
expect(response.parsed_body[:partial_accounts][0].keys.map(&:to_sym)).to contain_exactly(:acct, :avatar, :avatar_static, :bot, :id, :locked, :url)
expect(response.parsed_body[:partial_accounts].pluck(:id)).to_not include(recent_account.id.to_s)
@@ -261,6 +289,8 @@
subject
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -282,6 +312,8 @@ def body_json_types
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when notification belongs to someone else' do
@@ -291,6 +323,8 @@ def body_json_types
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -308,16 +342,21 @@ def body_json_types
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect { notification.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
context 'when notification belongs to someone else' do
- let(:notification) { Fabricate(:notification) }
+ let(:notification) { Fabricate(:notification, group_key: 'foobar') }
- it 'returns http not found' do
- subject
+ it 'leaves the notification alone' do
+ expect { subject }
+ .to_not change(Notification, :count)
- expect(response).to have_http_status(404)
+ expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -338,6 +377,8 @@ def body_json_types
expect(user.account.reload.notifications).to be_empty
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/v2/search_spec.rb b/spec/requests/api/v2/search_spec.rb
index a59ec7ca6b1807..5a2346dc39eda0 100644
--- a/spec/requests/api/v2/search_spec.rb
+++ b/spec/requests/api/v2/search_spec.rb
@@ -19,6 +19,8 @@
get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'when searching accounts' do
@@ -37,6 +39,8 @@
get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -47,6 +51,8 @@
get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -57,6 +63,8 @@
get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -67,6 +75,8 @@
get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -92,6 +102,8 @@
get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -102,6 +114,8 @@
get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -118,6 +132,8 @@
context 'without a `q` param' do
it 'returns http bad_request' do
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -126,6 +142,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -134,6 +152,8 @@
it 'returns http success' do
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
context 'with truthy `resolve`' do
@@ -141,6 +161,8 @@
it 'returns http unauthorized' do
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.body).to match('resolve remote resources')
end
end
@@ -150,6 +172,8 @@
it 'returns http unauthorized' do
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.body).to match('pagination is not supported')
end
end
diff --git a/spec/requests/api/v2/suggestions_spec.rb b/spec/requests/api/v2/suggestions_spec.rb
index e92507ed661fe8..099d9bc3b22735 100644
--- a/spec/requests/api/v2/suggestions_spec.rb
+++ b/spec/requests/api/v2/suggestions_spec.rb
@@ -21,6 +21,8 @@
get '/api/v2/suggestions', headers: headers
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body).to match_array(
[bob, jeff].map do |account|
diff --git a/spec/requests/api/web/embeds_spec.rb b/spec/requests/api/web/embeds_spec.rb
index 2b28502835843c..3cc2f977f87fb5 100644
--- a/spec/requests/api/web/embeds_spec.rb
+++ b/spec/requests/api/web/embeds_spec.rb
@@ -18,6 +18,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:html]).to be_present
end
end
@@ -29,6 +31,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -42,6 +46,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -52,6 +58,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -71,6 +79,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:html]).to be_present
end
@@ -83,6 +93,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -98,6 +110,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -123,6 +137,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -133,6 +149,8 @@
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
expect(response.parsed_body[:html]).to be_present
end
end
@@ -146,6 +164,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -156,6 +176,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -167,6 +189,8 @@
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
diff --git a/spec/requests/api/web/settings_spec.rb b/spec/requests/api/web/settings_spec.rb
index 81b8b449535a18..3873bc179b62d1 100644
--- a/spec/requests/api/web/settings_spec.rb
+++ b/spec/requests/api/web/settings_spec.rb
@@ -17,6 +17,8 @@
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -29,6 +31,8 @@
expect(response)
.to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
diff --git a/spec/requests/auth/sessions/security_key_options_spec.rb b/spec/requests/auth/sessions/security_key_options_spec.rb
new file mode 100644
index 00000000000000..6246e4beb315f7
--- /dev/null
+++ b/spec/requests/auth/sessions/security_key_options_spec.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'webauthn/fake_client'
+
+RSpec.describe 'Security Key Options' do
+ describe 'GET /auth/sessions/security_key_options' do
+ let!(:user) do
+ Fabricate(:user, email: 'x@y.com', password: 'abcdefgh', otp_required_for_login: true, otp_secret: User.generate_otp_secret(32))
+ end
+
+ context 'with WebAuthn and OTP enabled as second factor' do
+ let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" }
+
+ let(:fake_client) { WebAuthn::FakeClient.new(domain) }
+ let(:public_key_credential) { WebAuthn::Credential.from_create(fake_client.create) }
+
+ before do
+ user.update(webauthn_id: WebAuthn.generate_user_id)
+ Fabricate(
+ :webauthn_credential,
+ user_id: user.id,
+ external_id: public_key_credential.id,
+ public_key: public_key_credential.public_key
+ )
+ post '/auth/sign_in', params: { user: { email: user.email, password: user.password } }
+ end
+
+ it 'returns http success' do
+ get '/auth/sessions/security_key_options'
+
+ expect(response)
+ .to have_http_status 200
+ expect(response.content_type)
+ .to start_with('application/json')
+ end
+ end
+
+ context 'when WebAuthn not enabled' do
+ it 'returns http unauthorized' do
+ get '/auth/sessions/security_key_options'
+
+ expect(response)
+ .to have_http_status 401
+ expect(response.content_type)
+ .to start_with('application/json')
+ end
+ end
+ end
+end
diff --git a/spec/requests/settings/exports_spec.rb b/spec/requests/settings/exports_spec.rb
new file mode 100644
index 00000000000000..db823ac770fe2f
--- /dev/null
+++ b/spec/requests/settings/exports_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Settings / Exports' do
+ context 'when not signed in' do
+ describe 'GET /settings/export' do
+ it 'redirects to sign in page' do
+ get settings_export_path
+
+ expect(response)
+ .to redirect_to new_user_session_path
+ end
+ end
+
+ describe 'POST /settings/export' do
+ it 'redirects to sign in page' do
+ post settings_export_path
+
+ expect(response)
+ .to redirect_to new_user_session_path
+ end
+ end
+ end
+end
diff --git a/spec/requests/severed_relationships_spec.rb b/spec/requests/severed_relationships_spec.rb
new file mode 100644
index 00000000000000..ac98ab8f94fdbe
--- /dev/null
+++ b/spec/requests/severed_relationships_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Severed Relationships' do
+ let(:account_rs_event) { Fabricate :account_relationship_severance_event }
+
+ before { sign_in Fabricate(:user) }
+
+ describe 'GET /severed_relationships/:id/following' do
+ it 'returns a CSV file with correct data' do
+ get following_severed_relationship_path(account_rs_event, format: :csv)
+
+ expect(response)
+ .to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('text/csv')
+ expect(response.headers['Content-Disposition'])
+ .to match(<<~FILENAME.squish)
+ attachment; filename="following-example.com-#{Date.current}.csv"
+ FILENAME
+ expect(response.body)
+ .to include('Account address')
+ end
+ end
+
+ describe 'GET /severed_relationships/:id/followers' do
+ it 'returns a CSV file with correct data' do
+ get followers_severed_relationship_path(account_rs_event, format: :csv)
+
+ expect(response)
+ .to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('text/csv')
+ expect(response.headers['Content-Disposition'])
+ .to match(<<~FILENAME.squish)
+ attachment; filename="followers-example.com-#{Date.current}.csv"
+ FILENAME
+ expect(response.body)
+ .to include('Account address')
+ end
+ end
+end
diff --git a/spec/serializers/activitypub/device_serializer_spec.rb b/spec/serializers/activitypub/device_serializer_spec.rb
deleted file mode 100644
index 226e1364465407..00000000000000
--- a/spec/serializers/activitypub/device_serializer_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe ActivityPub::DeviceSerializer do
- let(:serialization) { serialized_record_json(record, described_class) }
- let(:record) { Fabricate(:device) }
-
- describe 'type' do
- it 'returns correct serialized type' do
- expect(serialization['type']).to eq('Device')
- end
- end
-end
diff --git a/spec/serializers/activitypub/one_time_key_serializer_spec.rb b/spec/serializers/activitypub/one_time_key_serializer_spec.rb
deleted file mode 100644
index b9792ebae35445..00000000000000
--- a/spec/serializers/activitypub/one_time_key_serializer_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe ActivityPub::OneTimeKeySerializer do
- let(:serialization) { serialized_record_json(record, described_class) }
- let(:record) { Fabricate(:one_time_key) }
-
- describe 'type' do
- it 'returns correct serialized type' do
- expect(serialization['type']).to eq('Curve25519Key')
- end
- end
-end
diff --git a/spec/serializers/rest/encrypted_message_serializer_spec.rb b/spec/serializers/rest/encrypted_message_serializer_spec.rb
deleted file mode 100644
index a4b8ee83b2a1e9..00000000000000
--- a/spec/serializers/rest/encrypted_message_serializer_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe REST::EncryptedMessageSerializer do
- let(:serialization) { serialized_record_json(record, described_class) }
- let(:record) { Fabricate(:encrypted_message) }
-
- describe 'account' do
- it 'returns the associated account' do
- expect(serialization['account_id']).to eq(record.from_account.id.to_s)
- end
- end
-end
diff --git a/spec/serializers/rest/keys/claim_result_serializer_spec.rb b/spec/serializers/rest/keys/claim_result_serializer_spec.rb
deleted file mode 100644
index e45112705b70cd..00000000000000
--- a/spec/serializers/rest/keys/claim_result_serializer_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe REST::Keys::ClaimResultSerializer do
- let(:serialization) { serialized_record_json(record, described_class) }
- let(:record) { Keys::ClaimService::Result.new(Account.new(id: 123), 456) }
-
- describe 'account' do
- it 'returns the associated account' do
- expect(serialization['account_id']).to eq('123')
- end
- end
-end
diff --git a/spec/serializers/rest/keys/device_serializer_spec.rb b/spec/serializers/rest/keys/device_serializer_spec.rb
deleted file mode 100644
index b8370beac706f6..00000000000000
--- a/spec/serializers/rest/keys/device_serializer_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe REST::Keys::DeviceSerializer do
- let(:serialization) { serialized_record_json(record, described_class) }
- let(:record) { Device.new(name: 'Device name') }
-
- describe 'name' do
- it 'returns the name' do
- expect(serialization['name']).to eq('Device name')
- end
- end
-end
diff --git a/spec/serializers/rest/keys/query_result_serializer_spec.rb b/spec/serializers/rest/keys/query_result_serializer_spec.rb
deleted file mode 100644
index 41492f5e78f265..00000000000000
--- a/spec/serializers/rest/keys/query_result_serializer_spec.rb
+++ /dev/null
@@ -1,14 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe REST::Keys::QueryResultSerializer do
- let(:serialization) { serialized_record_json(record, described_class) }
- let(:record) { Keys::QueryService::Result.new(Account.new(id: 123), []) }
-
- describe 'account' do
- it 'returns the associated account id' do
- expect(serialization['account_id']).to eq('123')
- end
- end
-end
diff --git a/spec/support/examples/models/concerns/reviewable.rb b/spec/support/examples/models/concerns/reviewable.rb
index b63e44b43f9853..144019d969af3e 100644
--- a/spec/support/examples/models/concerns/reviewable.rb
+++ b/spec/support/examples/models/concerns/reviewable.rb
@@ -6,6 +6,31 @@
let(:reviewed_at) { nil }
let(:requested_review_at) { nil }
+ describe 'Scopes' do
+ let!(:reviewed_record) { Fabricate factory_name, reviewed_at: 10.days.ago }
+ let!(:un_reviewed_record) { Fabricate factory_name, reviewed_at: nil }
+
+ describe '.reviewed' do
+ it 'returns reviewed records' do
+ expect(described_class.reviewed)
+ .to include(reviewed_record)
+ .and not_include(un_reviewed_record)
+ end
+ end
+
+ describe '.unreviewed' do
+ it 'returns non reviewed records' do
+ expect(described_class.unreviewed)
+ .to include(un_reviewed_record)
+ .and not_include(reviewed_record)
+ end
+ end
+
+ def factory_name
+ described_class.name.underscore.to_sym
+ end
+ end
+
describe '#requires_review?' do
it { is_expected.to be_requires_review }
diff --git a/spec/system/settings/exports_spec.rb b/spec/system/settings/exports_spec.rb
new file mode 100644
index 00000000000000..2cc2961a0bcee1
--- /dev/null
+++ b/spec/system/settings/exports_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Export page' do
+ let(:user) { Fabricate :user }
+
+ before { sign_in user }
+
+ describe 'Viewing the export page' do
+ context 'when signed in' do
+ it 'shows the export page', :aggregate_failures do
+ visit settings_export_path
+
+ expect(page)
+ .to have_content(takeout_summary)
+ .and have_private_cache_control
+ end
+ end
+ end
+
+ describe 'Creating a new archive' do
+ it 'queues a worker and redirects' do
+ visit settings_export_path
+
+ expect { request_archive }
+ .to change(BackupWorker.jobs, :size).by(1)
+ expect(page)
+ .to have_content(takeout_summary)
+ end
+
+ def request_archive
+ click_on I18n.t('exports.archive_takeout.request')
+ end
+ end
+
+ def takeout_summary
+ I18n.t('settings.export')
+ end
+end
diff --git a/spec/workers/push_encrypted_message_worker_spec.rb b/spec/workers/push_encrypted_message_worker_spec.rb
deleted file mode 100644
index 311545cf562297..00000000000000
--- a/spec/workers/push_encrypted_message_worker_spec.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe PushEncryptedMessageWorker do
- let(:worker) { described_class.new }
-
- describe 'perform' do
- it 'runs without error for missing record' do
- expect { worker.perform(nil) }.to_not raise_error
- end
- end
-end
diff --git a/streaming/index.js b/streaming/index.js
index f4aeadf23f5bbf..d792f95acf944b 100644
--- a/streaming/index.js
+++ b/streaming/index.js
@@ -44,7 +44,6 @@ initializeLogLevel(process.env, environment);
* @property {string[]} scopes
* @property {string} accountId
* @property {string[]} chosenLanguages
- * @property {string} deviceId
*/
@@ -355,7 +354,7 @@ const startServer = async () => {
* @returns {Promise