diff --git a/Gemfile b/Gemfile index 4cce095ec5..bcb19421ab 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 4a139155f5..79e542014c 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 480baaf2bc..0000000000 --- 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 15985c7f65..e9779260f3 100644 --- a/app/controllers/activitypub/collections_controller.rb +++ b/app/controllers/activitypub/collections_controller.rb @@ -22,8 +22,6 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController @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 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController def set_size case params[:id] - when 'featured', 'devices', 'tags' + when 'featured', 'tags' @size = @items.size else not_found @@ -42,7 +40,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController 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 66da65beda..b7f22824a7 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 @@ class Api::OEmbedController < Api::BaseController 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 aa9df6e03b..0000000000 --- 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 93ae0e7771..0000000000 --- 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 f9d202d67b..0000000000 --- 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 ffd7151b78..0000000000 --- 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 e6ce9f9192..0000000000 --- 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 fc4abf63b3..0000000000 --- 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 1780554c5d..d9c8232702 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 @@ class Api::V1::Peers::SearchController < Api::BaseController 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 63c3f2d90a..f82c1c50d7 100644 --- a/app/controllers/api/web/embeds_controller.rb +++ b/app/controllers/api/web/embeds_controller.rb @@ -9,7 +9,7 @@ class Api::Web::EmbedsController < Api::Web::BaseController 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 a2fed644fe..ecac4c5ba8 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 @@ class Auth::SessionsController < Devise::SessionsController 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 71e19207d0..b36e25c092 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/hooks/useSearchParam.ts b/app/javascript/hooks/useSearchParam.ts new file mode 100644 index 0000000000..2df8c0b3a9 --- /dev/null +++ b/app/javascript/hooks/useSearchParam.ts @@ -0,0 +1,31 @@ +import { useMemo, useCallback } from 'react'; + +import { useLocation, useHistory } from 'react-router'; + +export function useSearchParams() { + const { search } = useLocation(); + + return useMemo(() => new URLSearchParams(search), [search]); +} + +export function useSearchParam(name: string, defaultValue?: string) { + const searchParams = useSearchParams(); + const history = useHistory(); + + const value = searchParams.get(name) ?? defaultValue; + + const setValue = useCallback( + (value: string | null) => { + if (value === null) { + searchParams.delete(name); + } else { + searchParams.set(name, value); + } + + history.push({ search: searchParams.toString() }); + }, + [history, name, searchParams], + ); + + return [value, setValue] as const; +} diff --git a/app/javascript/mastodon/actions/alerts.js b/app/javascript/mastodon/actions/alerts.js index 42834146bf..48dee2587f 100644 --- a/app/javascript/mastodon/actions/alerts.js +++ b/app/javascript/mastodon/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/mastodon/api.ts b/app/javascript/mastodon/api.ts index 24672290c7..25bb25547c 100644 --- a/app/javascript/mastodon/api.ts +++ b/app/javascript/mastodon/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/mastodon/components/modal_root.jsx b/app/javascript/mastodon/components/modal_root.jsx index fd13564af2..e7fa5e6f9a 100644 --- a/app/javascript/mastodon/components/modal_root.jsx +++ b/app/javascript/mastodon/components/modal_root.jsx @@ -148,7 +148,7 @@ class ModalRoot extends PureComponent { return (
- + -@@ -57,10 +85,10 @@ class OEmbedSerializer < ActiveModel::Serializer 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 80c26d060e..0000000000 --- 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 145044f557..0000000000 --- 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 f9b821b79c..0000000000 --- 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 8f8bdde289..0000000000 --- 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 e2ecdef165..46cab6caf9 100644 --- a/app/services/activitypub/fetch_replies_service.rb +++ b/app/services/activitypub/fetch_replies_service.rb @@ -49,7 +49,7 @@ class ActivityPub::FetchRepliesService < BaseService 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 1e2d614d72..a7422b5d02 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -108,7 +108,6 @@ class ActivityPub::ProcessAccountService < BaseService 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 328d8ae8f8..0c03267d43 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 71711945c0..0000000000 --- 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 ebce9cce7d..0000000000 --- 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 33e13293f3..0000000000 --- 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 adf49296b2..0000000000 --- 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 0e74c231ec..0000000000 --- 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 e0870503d6..f4630ed25a 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 b43b8dfff9..93daf25f31 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 6bee12675b..0000000000 --- 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 86fde3cacf..b47e76c08b 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -118,8 +118,7 @@ Doorkeeper.configure do :'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 ba459e19f2..2b0563f4d3 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -19,7 +19,6 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| 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 294d614bca..6d437b72b0 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 92d85af4d9..203d8e2c34 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 589bb39836..2f181e0757 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 7512e03fd5..81705acba0 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 be3441507e..a7d4a9917e 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 48ca5751cc..d45f443b75 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 604eeca480..e2c246827a 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 d985a2ac42..33a1d4e88f 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 8af3d86388..bc668d2ce4 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 b072e5e4ef..58ddd7d01b 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 1000442870..b7fc8ab1b0 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 9d3c0c82f3..c2c193d943 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 6f781742a8..a177b97de7 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 040ddaaf69..85e24c230e 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 b5987676d2..49ff9a1e43 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 1f408e26ea..0da957cdb2 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 56255f5d7a..577978ce88 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 b1c100da0c..625f53f2e5 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 46c6cbcf86..7ebf074819 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 4d60d080a2..9f1dc46c9d 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 ebe26c3f14..8aac7cbb47 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 c652876f3a..2815ada779 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 aca4f93c4d..60f98a471e 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 6260033990..7c7f995a71 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 996c8d6cd2..c2c22af4c4 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 b48b499bbe..5df82bff9f 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 266b73bb10..ce21aa3be7 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 b70a515fd1..3f9252ffab 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 bc616d2896..cb76ae2243 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 6afdecd556..8b854494d4 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 1071871c95..a6369354cd 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 5e63b5bd23..b5cbc4a73e 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 58fd2d9bab..9813514a7b 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 7a2d0a1d98..13a1f6f05d 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 10c7506b01..9767c48834 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 80dbc77991..1fda020c07 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 957bae3991..6632af061e 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 222d2b5680..96a5022a7c 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 6a79686f48..513a8eda7e 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 dbbe228e72..97cc417df0 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 78dfd6048f..590805ad30 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 792add14e3..fe6fec17d7 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 13f59e981b..ed6293e1ca 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 7c3d526702..7044983ac9 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 cbcc09a4da..216e468762 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 6b80e32ba8..08843f645e 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 2f5eb1553e..3d1f1a61e2 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 55a0751811..4aeec5ceca 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 39c695a539..0c0ffb69bf 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 92464523a0..6acaa34cdc 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 63656991a8..afc4652bf6 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 b7beeb4263..dcf571a792 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 635ceedde4..1f0b6bacce 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 f0d09cb2d3..314adf885f 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 d1140f3645..7742a80569 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 f155490eb5..d6c5c4a6ff 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 d66dded89b..3877727490 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 435749f470..780270ddf1 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 70143a968e..97eaa21ed6 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 135a99ceb2..8460de01da 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 2a2d06ce9b..f2108828d5 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 68fc629d9e..203b023715 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 fee07fa5e0..a649b4ec5a 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 4369c3c42b..ed27e08bc3 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 b41457e86a..3ff746451b 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 ef6d00b8d3..c8e806bf35 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 70d20592a5..294c8a888f 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 91f0933398..bfb52c275b 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 67aee931be..af7e7ab8d6 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 99b7ec9b3a..6146cfc8d7 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 3a98b6a25d..56b2895c74 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 65424f4eb6..d56385f261 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 d6ca6b4276..16dd4c899d 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 e8c4e68998..0ef08a1555 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 8f047a2cb7..98696aef7c 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 277785f683..8b34da076a 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 7682712759..598c65d049 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 35f000b601..41c4c8a534 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 242ca06262..86248dda41 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -135,7 +135,6 @@ Rails.application.routes.draw do
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 4d422de373..48b35cc154 100644
--- a/config/routes/api.rb
+++ b/config/routes/api.rb
@@ -69,23 +69,6 @@ namespace :api, format: false do
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 0000000000..dd5662885c
--- /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 0000000000..8caf5b801d
--- /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 4c32e2a9da..332854a05a 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 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
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 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
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 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
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 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
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 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
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 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
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 @@ ActiveRecord::Schema[7.1].define(version: 2024_09_09_014637) do
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 e887be2cbe..0000000000
--- 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 3cc3460718..713ea3ff16 100644
--- a/spec/controllers/auth/sessions_controller_spec.rb
+++ b/spec/controllers/auth/sessions_controller_spec.rb
@@ -412,44 +412,4 @@ RSpec.describe Auth::SessionsController do
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 1eafabc7e5..0000000000
--- 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 5042523df8..d9702251f4 100644
--- a/spec/controllers/statuses_controller_spec.rb
+++ b/spec/controllers/statuses_controller_spec.rb
@@ -63,7 +63,7 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
'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 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
'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 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
'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 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
.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 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
'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 @@ RSpec.describe StatusesController do
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 @@ RSpec.describe StatusesController do
'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 @@ RSpec.describe StatusesController do
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 37a2e8977d..0000000000
--- 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 349b659c2f..0000000000
--- 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 505282e05d..0000000000
--- 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 bcb3bd5577..0000000000
--- 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 fbaf672b5a..83ea6566e4 100644
--- a/spec/lib/activitypub/activity/create_spec.rb
+++ b/spec/lib/activitypub/activity/create_spec.rb
@@ -982,64 +982,6 @@ RSpec.describe ActivityPub::Activity::Create do
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 84cae30411..0000000000
--- 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 0000000000..7dbfbed12a
--- /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 17fcdf3788..0000000000
--- 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 12bca83440..a3bd4f49ad 100644
--- a/spec/models/preview_card_provider_spec.rb
+++ b/spec/models/preview_card_provider_spec.rb
@@ -24,21 +24,5 @@ RSpec.describe PreviewCardProvider do
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 fcff4c0d3b..972453cd69 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -4,6 +4,8 @@ require 'rails_helper'
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 b9578b37c8..767f20dddf 100644
--- a/spec/requests/api/oembed_spec.rb
+++ b/spec/requests/api/oembed_spec.rb
@@ -14,6 +14,8 @@ RSpec.describe 'API OEmbed' do
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 @@ RSpec.describe 'API OEmbed' 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/accounts/credentials_spec.rb b/spec/requests/api/v1/accounts/credentials_spec.rb
index 77b815945e..966d1f598e 100644
--- a/spec/requests/api/v1/accounts/credentials_spec.rb
+++ b/spec/requests/api/v1/accounts/credentials_spec.rb
@@ -20,6 +20,8 @@ RSpec.describe 'credentials API' do
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 @@ RSpec.describe 'credentials API' do
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 @@ RSpec.describe 'credentials API' do
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 @@ RSpec.describe 'credentials API' do
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 @@ RSpec.describe 'credentials API' do
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 8edfa4c883..c698c2d689 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 @@ RSpec.describe 'Accounts Familiar Followers API' do
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 f48ed01def..632db65c44 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 @@ RSpec.describe 'account featured tags API' do
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 @@ RSpec.describe 'account featured tags API' do
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 2672615390..7db9884a57 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 @@ RSpec.describe 'API V1 Accounts FollowerAccounts' do
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 @@ RSpec.describe 'API V1 Accounts FollowerAccounts' do
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 19105ebf2f..ffb7332c4e 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 @@ RSpec.describe 'API V1 Accounts FollowingAccounts' do
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 @@ RSpec.describe 'API V1 Accounts FollowingAccounts' do
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 d1d9db8e73..ba04ed45b9 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 @@ RSpec.describe 'Accounts Identity Proofs API' do
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 8b04f07f65..cb1ff6b9f2 100644
--- a/spec/requests/api/v1/accounts/lists_spec.rb
+++ b/spec/requests/api/v1/accounts/lists_spec.rb
@@ -20,6 +20,8 @@ RSpec.describe 'Accounts Lists API' do
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 dfd9fad49d..77c09c0902 100644
--- a/spec/requests/api/v1/accounts/lookup_spec.rb
+++ b/spec/requests/api/v1/accounts/lookup_spec.rb
@@ -14,6 +14,8 @@ RSpec.describe 'Accounts Lookup API' do
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 b8c493abcc..1677ec07e3 100644
--- a/spec/requests/api/v1/accounts/notes_spec.rb
+++ b/spec/requests/api/v1/accounts/notes_spec.rb
@@ -22,6 +22,8 @@ RSpec.describe 'Accounts Notes API' do
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 @@ RSpec.describe 'Accounts Notes API' do
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 c66b80c7fd..8ebcb27d28 100644
--- a/spec/requests/api/v1/accounts/pins_spec.rb
+++ b/spec/requests/api/v1/accounts/pins_spec.rb
@@ -21,6 +21,8 @@ RSpec.describe 'Accounts Pins API' do
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 @@ RSpec.describe 'Accounts Pins API' do
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 9570d1214c..52aeb01328 100644
--- a/spec/requests/api/v1/accounts/relationships_spec.rb
+++ b/spec/requests/api/v1/accounts/relationships_spec.rb
@@ -29,6 +29,8 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
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 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
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 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
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 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
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 @@ RSpec.describe 'GET /api/v1/accounts/relationships' do
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 f6ab7a8531..dc24813e73 100644
--- a/spec/requests/api/v1/accounts/search_spec.rb
+++ b/spec/requests/api/v1/accounts/search_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe 'Accounts Search API' do
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 e056a78901..1e21950287 100644
--- a/spec/requests/api/v1/accounts/statuses_spec.rb
+++ b/spec/requests/api/v1/accounts/statuses_spec.rb
@@ -19,6 +19,8 @@ RSpec.describe 'API V1 Accounts Statuses' do
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 @@ RSpec.describe 'API V1 Accounts Statuses' do
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 @@ RSpec.describe 'API V1 Accounts Statuses' do
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 @@ RSpec.describe 'API V1 Accounts Statuses' do
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 @@ RSpec.describe 'API V1 Accounts Statuses' do
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 @@ RSpec.describe 'API V1 Accounts Statuses' do
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 @@ RSpec.describe 'API V1 Accounts Statuses' do
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 2ebe56fa7d..45e66f0744 100644
--- a/spec/requests/api/v1/accounts_spec.rb
+++ b/spec/requests/api/v1/accounts_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -113,6 +125,8 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 @@ RSpec.describe '/api/v1/accounts' do
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 5bcf809401..4884dba9c7 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 @@ RSpec.describe 'Account actions' do
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 @@ RSpec.describe 'Account actions' do
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 @@ RSpec.describe 'Account actions' do
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 @@ RSpec.describe 'Account actions' do
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 @@ RSpec.describe 'Account actions' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -125,6 +135,8 @@ RSpec.describe 'Account actions' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -135,6 +147,8 @@ RSpec.describe 'Account actions' do
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 2dc45d5eb2..6a681f9c5e 100644
--- a/spec/requests/api/v1/admin/accounts_spec.rb
+++ b/spec/requests/api/v1/admin/accounts_spec.rb
@@ -19,6 +19,8 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' 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
end
@@ -112,6 +116,8 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -174,6 +186,8 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -226,6 +240,8 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -296,6 +320,8 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 dd7e119911..eaa011d516 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 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
subject
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -142,6 +150,8 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -193,6 +209,8 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -237,6 +259,8 @@ RSpec.describe 'Canonical Email Blocks' do
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 @@ RSpec.describe 'Canonical Email Blocks' do
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 a28c2a9e3e..81fb580ba7 100644
--- a/spec/requests/api/v1/admin/dimensions_spec.rb
+++ b/spec/requests/api/v1/admin/dimensions_spec.rb
@@ -15,6 +15,8 @@ RSpec.describe 'Admin Dimensions' do
expect(response)
.to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -27,6 +29,9 @@ RSpec.describe 'Admin Dimensions' do
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 26c962b347..eb5128e420 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 @@ RSpec.describe 'Domain Allows' do
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 @@ RSpec.describe 'Domain Allows' do
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 @@ RSpec.describe 'Domain Allows' do
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 @@ RSpec.describe 'Domain Allows' do
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 @@ RSpec.describe 'Domain Allows' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -129,6 +139,8 @@ RSpec.describe 'Domain Allows' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -160,6 +172,8 @@ RSpec.describe 'Domain Allows' do
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 @@ RSpec.describe 'Domain Allows' do
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 3f2cbbf113..1a506bd9be 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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -217,6 +233,8 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 @@ RSpec.describe 'Domain Blocks' do
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 aa3073341a..3f51a3ea2d 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 @@ RSpec.describe 'Email Domain Blocks' do
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 @@ RSpec.describe 'Email Domain Blocks' do
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 @@ RSpec.describe 'Email Domain Blocks' do
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 @@ RSpec.describe 'Email Domain Blocks' do
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 @@ RSpec.describe 'Email Domain Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -145,6 +155,8 @@ RSpec.describe 'Email Domain Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -157,6 +169,8 @@ RSpec.describe 'Email Domain Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -176,6 +190,8 @@ RSpec.describe 'Email Domain Blocks' do
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 @@ RSpec.describe 'Email Domain Blocks' do
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 b18f8f885c..c096aa3328 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 @@ RSpec.describe 'IP Blocks' do
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 @@ RSpec.describe 'IP Blocks' do
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 @@ RSpec.describe 'IP Blocks' do
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 @@ RSpec.describe 'IP Blocks' do
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 @@ RSpec.describe 'IP Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -145,6 +155,8 @@ RSpec.describe 'IP Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -157,6 +169,8 @@ RSpec.describe 'IP Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -167,6 +181,8 @@ RSpec.describe 'IP Blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -185,6 +201,8 @@ RSpec.describe 'IP Blocks' do
.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 @@ RSpec.describe 'IP Blocks' do
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 @@ RSpec.describe 'IP Blocks' do
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 @@ RSpec.describe 'IP Blocks' do
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 de359a5ccd..519b5cc7b3 100644
--- a/spec/requests/api/v1/admin/measures_spec.rb
+++ b/spec/requests/api/v1/admin/measures_spec.rb
@@ -32,6 +32,8 @@ RSpec.describe 'Admin Measures' do
expect(response)
.to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -43,6 +45,8 @@ RSpec.describe 'Admin Measures' do
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 2c40f56dc8..a0e7b0a369 100644
--- a/spec/requests/api/v1/admin/reports_spec.rb
+++ b/spec/requests/api/v1/admin/reports_spec.rb
@@ -23,6 +23,8 @@ RSpec.describe 'Reports' do
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 @@ RSpec.describe 'Reports' do
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 @@ RSpec.describe 'Reports' do
.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 @@ RSpec.describe 'Reports' do
.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 @@ RSpec.describe 'Reports' do
.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 @@ RSpec.describe 'Reports' do
.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 @@ RSpec.describe 'Reports' do
.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 c28fa6de81..e28bc2a94f 100644
--- a/spec/requests/api/v1/admin/retention_spec.rb
+++ b/spec/requests/api/v1/admin/retention_spec.rb
@@ -15,6 +15,8 @@ RSpec.describe 'Admin Retention' do
expect(response)
.to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -26,6 +28,8 @@ RSpec.describe 'Admin Retention' do
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 2f730cdeb8..3623c09ac7 100644
--- a/spec/requests/api/v1/admin/tags_spec.rb
+++ b/spec/requests/api/v1/admin/tags_spec.rb
@@ -24,6 +24,8 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -135,6 +137,8 @@ RSpec.describe 'Tags' do
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 c436b7081e..51e800734a 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 @@ RSpec.describe 'Links' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -36,6 +38,8 @@ RSpec.describe 'Links' do
.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 @@ RSpec.describe 'Links' do
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 @@ RSpec.describe 'Links' do
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -89,6 +97,8 @@ RSpec.describe 'Links' do
.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 @@ RSpec.describe 'Links' do
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 @@ RSpec.describe 'Links' do
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 193906ab05..d46d0ff555 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 @@ RSpec.describe 'API V1 Admin Trends Links Preview Card Providers' do
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 @@ RSpec.describe 'API V1 Admin Trends Links Preview Card Providers' do
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 @@ RSpec.describe 'API V1 Admin Trends Links Preview Card Providers' do
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 e33a9658a9..c63d8d925c 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 @@ RSpec.describe 'API V1 Admin Trends Statuses' do
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 @@ RSpec.describe 'API V1 Admin Trends Statuses' do
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 @@ RSpec.describe 'API V1 Admin Trends Statuses' do
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 748a27283c..433cc6c5a6 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 @@ RSpec.describe 'API V1 Admin Trends Tags' do
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 @@ RSpec.describe 'API V1 Admin Trends Tags' do
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 @@ RSpec.describe 'API V1 Admin Trends Tags' do
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 ffacb2b0af..82154b4a26 100644
--- a/spec/requests/api/v1/announcements/reactions_spec.rb
+++ b/spec/requests/api/v1/announcements/reactions_spec.rb
@@ -15,7 +15,9 @@ RSpec.describe 'API V1 Announcements Reactions' do
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 @@ RSpec.describe 'API V1 Announcements Reactions' do
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 @@ RSpec.describe 'API V1 Announcements Reactions' do
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 @@ RSpec.describe 'API V1 Announcements Reactions' do
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 1624b76012..97a4442aa9 100644
--- a/spec/requests/api/v1/announcements_spec.rb
+++ b/spec/requests/api/v1/announcements_spec.rb
@@ -15,7 +15,9 @@ RSpec.describe 'API V1 Announcements' do
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 @@ RSpec.describe 'API V1 Announcements' do
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 @@ RSpec.describe 'API V1 Announcements' do
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 @@ RSpec.describe 'API V1 Announcements' do
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 8051a65484..b9831d17e2 100644
--- a/spec/requests/api/v1/annual_reports_spec.rb
+++ b/spec/requests/api/v1/annual_reports_spec.rb
@@ -14,6 +14,8 @@ RSpec.describe 'API V1 Annual Reports' do
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -33,6 +35,8 @@ RSpec.describe 'API V1 Annual Reports' do
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 @@ RSpec.describe 'API V1 Annual Reports' do
.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 1cd6a4178f..30200ed60c 100644
--- a/spec/requests/api/v1/apps/credentials_spec.rb
+++ b/spec/requests/api/v1/apps/credentials_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'Credentials' do
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 @@ RSpec.describe 'Credentials' do
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 @@ RSpec.describe 'Credentials' do
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 @@ RSpec.describe 'Credentials' do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -90,6 +94,8 @@ RSpec.describe 'Credentials' do
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 @@ RSpec.describe 'Credentials' do
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 51a0c3fd0c..cf43e14d62 100644
--- a/spec/requests/api/v1/apps_spec.rb
+++ b/spec/requests/api/v1/apps_spec.rb
@@ -28,6 +28,8 @@ RSpec.describe 'Apps' do
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 @@ RSpec.describe 'Apps' do
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 @@ RSpec.describe 'Apps' do
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 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -106,6 +114,8 @@ RSpec.describe 'Apps' do
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 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -127,6 +139,8 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -137,6 +151,8 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -148,6 +164,8 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -158,6 +176,8 @@ RSpec.describe 'Apps' do
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 @@ RSpec.describe 'Apps' do
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 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -212,6 +236,8 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -222,6 +248,8 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -232,6 +260,8 @@ RSpec.describe 'Apps' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -242,6 +272,8 @@ RSpec.describe 'Apps' do
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 d2f1c46a5b..498cf93275 100644
--- a/spec/requests/api/v1/blocks_spec.rb
+++ b/spec/requests/api/v1/blocks_spec.rb
@@ -26,21 +26,20 @@ RSpec.describe 'Blocks' do
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 95a71abcac..c78e691236 100644
--- a/spec/requests/api/v1/bookmarks_spec.rb
+++ b/spec/requests/api/v1/bookmarks_spec.rb
@@ -24,15 +24,12 @@ RSpec.describe 'Bookmarks' do
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 @@ RSpec.describe 'Bookmarks' do
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 @@ RSpec.describe 'Bookmarks' do
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 bd3cbfd0e7..6e2ac1df53 100644
--- a/spec/requests/api/v1/conversations_spec.rb
+++ b/spec/requests/api/v1/conversations_spec.rb
@@ -26,6 +26,8 @@ RSpec.describe 'API V1 Conversations' do
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 0942734ff3..e860fbeb17 100644
--- a/spec/requests/api/v1/custom_emojis_spec.rb
+++ b/spec/requests/api/v1/custom_emojis_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe 'Custom Emojis' do
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 @@ RSpec.describe 'Custom Emojis' do
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 aa602a71cd..282be9a582 100644
--- a/spec/requests/api/v1/directories_spec.rb
+++ b/spec/requests/api/v1/directories_spec.rb
@@ -82,6 +82,8 @@ RSpec.describe 'Directories API' do
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 @@ RSpec.describe 'Directories API' do
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 @@ RSpec.describe 'Directories API' do
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 @@ RSpec.describe 'Directories API' do
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 8184c26bed..339f49fe76 100644
--- a/spec/requests/api/v1/domain_blocks_spec.rb
+++ b/spec/requests/api/v1/domain_blocks_spec.rb
@@ -26,6 +26,8 @@ RSpec.describe 'Domain blocks' do
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 @@ RSpec.describe 'Domain blocks' do
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 @@ RSpec.describe 'Domain blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -73,6 +79,8 @@ RSpec.describe 'Domain blocks' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -94,6 +102,8 @@ RSpec.describe 'Domain blocks' do
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 @@ RSpec.describe 'Domain blocks' do
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 0a419a10cf..1408ad0506 100644
--- a/spec/requests/api/v1/emails/confirmations_spec.rb
+++ b/spec/requests/api/v1/emails/confirmations_spec.rb
@@ -26,6 +26,8 @@ RSpec.describe 'Confirmations' do
subject
expect(response).to have_http_status(403)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -41,6 +43,8 @@ RSpec.describe 'Confirmations' do
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 @@ RSpec.describe 'Confirmations' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -61,6 +67,8 @@ RSpec.describe 'Confirmations' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -71,6 +79,8 @@ RSpec.describe 'Confirmations' do
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 @@ RSpec.describe 'Confirmations' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -94,6 +106,8 @@ RSpec.describe 'Confirmations' do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -111,6 +125,8 @@ RSpec.describe 'Confirmations' do
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 @@ RSpec.describe 'Confirmations' do
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 @@ RSpec.describe 'Confirmations' do
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 @@ RSpec.describe 'Confirmations' do
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 @@ RSpec.describe 'Confirmations' do
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 25917f527a..730ba6350c 100644
--- a/spec/requests/api/v1/endorsements_spec.rb
+++ b/spec/requests/api/v1/endorsements_spec.rb
@@ -14,6 +14,8 @@ RSpec.describe 'Endorsements' do
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -36,6 +38,8 @@ RSpec.describe 'Endorsements' do
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 @@ RSpec.describe 'Endorsements' do
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 78e9d61551..44d0239556 100644
--- a/spec/requests/api/v1/favourites_spec.rb
+++ b/spec/requests/api/v1/favourites_spec.rb
@@ -24,35 +24,29 @@ RSpec.describe 'Favourites' do
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 @@ RSpec.describe 'Favourites' do
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 8815c65cf1..5fbbec5097 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 @@ RSpec.describe 'Featured Tags Suggestions API' do
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 423cc0c560..b9c78cc11b 100644
--- a/spec/requests/api/v1/featured_tags_spec.rb
+++ b/spec/requests/api/v1/featured_tags_spec.rb
@@ -22,6 +22,8 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 @@ RSpec.describe 'FeaturedTags' do
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 93ed78b346..51f03cc04d 100644
--- a/spec/requests/api/v1/filters_spec.rb
+++ b/spec/requests/api/v1/filters_spec.rb
@@ -15,6 +15,8 @@ RSpec.describe 'API V1 Filters' do
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 @@ RSpec.describe 'API V1 Filters' do
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 @@ RSpec.describe 'API V1 Filters' do
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 @@ RSpec.describe 'API V1 Filters' do
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 @@ RSpec.describe 'API V1 Filters' do
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 @@ RSpec.describe 'API V1 Filters' do
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 c143ccaec1..f0f73d38ad 100644
--- a/spec/requests/api/v1/follow_requests_spec.rb
+++ b/spec/requests/api/v1/follow_requests_spec.rb
@@ -36,6 +36,8 @@ RSpec.describe 'Follow requests' do
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 @@ RSpec.describe 'Follow requests' do
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 @@ RSpec.describe 'Follow requests' do
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 f7787cb763..b0191b523f 100644
--- a/spec/requests/api/v1/followed_tags_spec.rb
+++ b/spec/requests/api/v1/followed_tags_spec.rb
@@ -28,29 +28,24 @@ RSpec.describe 'Followed tags' do
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 42b6753bc3..62c90f55b2 100644
--- a/spec/requests/api/v1/instance_spec.rb
+++ b/spec/requests/api/v1/instance_spec.rb
@@ -14,6 +14,8 @@ RSpec.describe 'Instances' do
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 @@ RSpec.describe 'Instances' do
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 72e3faeb65..c2f94cc578 100644
--- a/spec/requests/api/v1/instances/activity_spec.rb
+++ b/spec/requests/api/v1/instances/activity_spec.rb
@@ -13,6 +13,9 @@ RSpec.describe 'Activity' do
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 460d338607..b214fda73b 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 @@ RSpec.describe 'Domain Blocks' do
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 bf6d58216a..62a7fff2ec 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 @@ RSpec.describe 'Extended Descriptions' do
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 79ea62c599..3d188d23c0 100644
--- a/spec/requests/api/v1/instances/languages_spec.rb
+++ b/spec/requests/api/v1/instances/languages_spec.rb
@@ -8,11 +8,10 @@ RSpec.describe 'Languages' do
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 1140612f0a..8ebfc93357 100644
--- a/spec/requests/api/v1/instances/peers_spec.rb
+++ b/spec/requests/api/v1/instances/peers_spec.rb
@@ -12,6 +12,8 @@ RSpec.describe 'Peers' do
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 93490542cd..519c2b29d0 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 @@ RSpec.describe 'Privacy Policy' do
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 620c991ae2..b730048863 100644
--- a/spec/requests/api/v1/instances/rules_spec.rb
+++ b/spec/requests/api/v1/instances/rules_spec.rb
@@ -9,6 +9,8 @@ RSpec.describe 'Rules' do
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 0de5ec3bc2..fef8700db9 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 @@ RSpec.describe 'Translation Languages' do
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 @@ RSpec.describe 'Translation Languages' do
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 d147b21ee7..3911d1f28b 100644
--- a/spec/requests/api/v1/lists/accounts_spec.rb
+++ b/spec/requests/api/v1/lists/accounts_spec.rb
@@ -34,6 +34,8 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -118,6 +128,8 @@ RSpec.describe 'Accounts' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -139,16 +151,13 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 @@ RSpec.describe 'Accounts' do
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 2042a64d5c..20f27a7431 100644
--- a/spec/requests/api/v1/lists_spec.rb
+++ b/spec/requests/api/v1/lists_spec.rb
@@ -43,6 +43,8 @@ RSpec.describe 'Lists' do
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 @@ RSpec.describe 'Lists' do
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 @@ RSpec.describe 'Lists' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -83,6 +89,8 @@ RSpec.describe 'Lists' do
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 @@ RSpec.describe 'Lists' do
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 @@ RSpec.describe 'Lists' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -121,6 +133,8 @@ RSpec.describe 'Lists' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -142,6 +156,8 @@ RSpec.describe 'Lists' do
.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 @@ RSpec.describe 'Lists' do
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 @@ RSpec.describe 'Lists' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -196,6 +216,8 @@ RSpec.describe 'Lists' do
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 @@ RSpec.describe 'Lists' do
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 a10d2dc3e2..d7cd78924b 100644
--- a/spec/requests/api/v1/markers_spec.rb
+++ b/spec/requests/api/v1/markers_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe 'API Markers' do
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 @@ RSpec.describe 'API Markers' do
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 @@ RSpec.describe 'API Markers' do
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 @@ RSpec.describe 'API Markers' do
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 d0af334825..d7d0b92f11 100644
--- a/spec/requests/api/v1/media_spec.rb
+++ b/spec/requests/api/v1/media_spec.rb
@@ -17,15 +17,12 @@ RSpec.describe 'Media' do
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 @@ RSpec.describe 'Media' do
subject
expect(response).to have_http_status(206)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -54,6 +53,8 @@ RSpec.describe 'Media' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -64,6 +65,8 @@ RSpec.describe 'Media' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -80,6 +83,8 @@ RSpec.describe 'Media' do
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 @@ RSpec.describe 'Media' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -117,6 +124,8 @@ RSpec.describe 'Media' do
subject
expect(response).to have_http_status(500)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -158,6 +167,8 @@ RSpec.describe 'Media' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -176,6 +187,8 @@ RSpec.describe 'Media' do
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 6402c908ff..61e32cb9ae 100644
--- a/spec/requests/api/v1/mutes_spec.rb
+++ b/spec/requests/api/v1/mutes_spec.rb
@@ -18,32 +18,26 @@ RSpec.describe 'Mutes' do
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 @@ RSpec.describe 'Mutes' do
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 8bafcad2fe..ac24501526 100644
--- a/spec/requests/api/v1/notifications/policies_spec.rb
+++ b/spec/requests/api/v1/notifications/policies_spec.rb
@@ -26,6 +26,8 @@ RSpec.describe 'Policies' do
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 @@ RSpec.describe 'Policies' do
.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 dc125bc7aa..bee9d3a3da 100644
--- a/spec/requests/api/v1/notifications/requests_spec.rb
+++ b/spec/requests/api/v1/notifications/requests_spec.rb
@@ -26,6 +26,8 @@ RSpec.describe 'Requests' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -39,15 +41,12 @@ RSpec.describe 'Requests' do
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 @@ RSpec.describe 'Requests' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -75,6 +76,8 @@ RSpec.describe 'Requests' do
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 @@ RSpec.describe 'Requests' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -102,6 +107,8 @@ RSpec.describe 'Requests' do
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 @@ RSpec.describe 'Requests' do
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 @@ RSpec.describe 'Requests' do
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 @@ RSpec.describe 'Requests' do
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 b74adb5dff..0e8eb6ad3b 100644
--- a/spec/requests/api/v1/notifications_spec.rb
+++ b/spec/requests/api/v1/notifications_spec.rb
@@ -31,6 +31,8 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' 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 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 @@ RSpec.describe 'Notifications' 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 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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' 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 0
end
end
@@ -163,6 +181,8 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -242,6 +268,8 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -272,6 +302,8 @@ RSpec.describe 'Notifications' do
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 dc5f550d0e..d00a2437f2 100644
--- a/spec/requests/api/v1/peers/search_spec.rb
+++ b/spec/requests/api/v1/peers/search_spec.rb
@@ -23,6 +23,8 @@ RSpec.describe 'API Peers Search' do
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 @@ RSpec.describe 'API Peers Search' do
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 @@ RSpec.describe 'API Peers Search' do
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 669f64b6e4..d3f7eb431d 100644
--- a/spec/requests/api/v1/polls/votes_spec.rb
+++ b/spec/requests/api/v1/polls/votes_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe 'API V1 Polls Votes' do
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 @@ RSpec.describe 'API V1 Polls Votes' 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
diff --git a/spec/requests/api/v1/polls_spec.rb b/spec/requests/api/v1/polls_spec.rb
index 138a37a73c..fd38297931 100644
--- a/spec/requests/api/v1/polls_spec.rb
+++ b/spec/requests/api/v1/polls_spec.rb
@@ -23,6 +23,8 @@ RSpec.describe 'Polls' do
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 @@ RSpec.describe 'Polls' do
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 d6991ca90c..e03b9cf108 100644
--- a/spec/requests/api/v1/preferences_spec.rb
+++ b/spec/requests/api/v1/preferences_spec.rb
@@ -14,6 +14,8 @@ RSpec.describe 'Preferences' do
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -34,6 +36,9 @@ RSpec.describe 'Preferences' do
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 26a9b848e5..fd3ab4bf58 100644
--- a/spec/requests/api/v1/profiles_spec.rb
+++ b/spec/requests/api/v1/profiles_spec.rb
@@ -28,31 +28,16 @@ RSpec.describe 'Deleting profile images' do
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 @@ RSpec.describe 'Deleting profile images' do
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 a9587f8d58..8ad672c95e 100644
--- a/spec/requests/api/v1/push/subscriptions_spec.rb
+++ b/spec/requests/api/v1/push/subscriptions_spec.rb
@@ -45,6 +45,8 @@ RSpec.describe 'API V1 Push Subscriptions' do
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 a176bd78a6..18b894bf63 100644
--- a/spec/requests/api/v1/reports_spec.rb
+++ b/spec/requests/api/v1/reports_spec.rb
@@ -37,6 +37,8 @@ RSpec.describe 'Reports' do
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 @@ RSpec.describe 'Reports' do
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 eb03827c9a..3a1b81ce65 100644
--- a/spec/requests/api/v1/scheduled_status_spec.rb
+++ b/spec/requests/api/v1/scheduled_status_spec.rb
@@ -14,6 +14,8 @@ RSpec.describe 'Scheduled Statuses' do
expect(response)
.to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -33,6 +35,8 @@ RSpec.describe 'Scheduled Statuses' do
expect(response)
.to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -45,6 +49,8 @@ RSpec.describe 'Scheduled Statuses' do
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 @@ RSpec.describe 'Scheduled Statuses' do
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 f1bcfda0ff..583f5b6a0e 100644
--- a/spec/requests/api/v1/statuses/bookmarks_spec.rb
+++ b/spec/requests/api/v1/statuses/bookmarks_spec.rb
@@ -18,15 +18,13 @@ RSpec.describe 'Bookmarks' do
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 @@ RSpec.describe 'Bookmarks' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -55,6 +55,8 @@ RSpec.describe 'Bookmarks' 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
end
@@ -64,6 +66,8 @@ RSpec.describe 'Bookmarks' do
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 @@ RSpec.describe 'Bookmarks' do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -93,15 +99,13 @@ RSpec.describe 'Bookmarks' do
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 @@ RSpec.describe 'Bookmarks' do
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 @@ RSpec.describe 'Bookmarks' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -149,6 +153,8 @@ RSpec.describe 'Bookmarks' do
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 24bd03d343..6471697154 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 @@ RSpec.describe 'API V1 Statuses Favourited by Accounts' do
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 @@ RSpec.describe 'API V1 Statuses Favourited by Accounts' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -88,6 +92,8 @@ RSpec.describe 'API V1 Statuses Favourited by Accounts' do
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 f9f0ff6299..3d1021e29d 100644
--- a/spec/requests/api/v1/statuses/favourites_spec.rb
+++ b/spec/requests/api/v1/statuses/favourites_spec.rb
@@ -18,15 +18,13 @@ RSpec.describe 'Favourites', :inline_jobs do
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 @@ RSpec.describe 'Favourites', :inline_jobs do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -55,6 +55,8 @@ RSpec.describe 'Favourites', :inline_jobs 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
end
@@ -66,6 +68,8 @@ RSpec.describe 'Favourites', :inline_jobs do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -84,16 +88,14 @@ RSpec.describe 'Favourites', :inline_jobs do
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 @@ RSpec.describe 'Favourites', :inline_jobs do
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 @@ RSpec.describe 'Favourites', :inline_jobs do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -139,6 +141,8 @@ RSpec.describe 'Favourites', :inline_jobs do
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 4115a52fa8..9c7f93d343 100644
--- a/spec/requests/api/v1/statuses/histories_spec.rb
+++ b/spec/requests/api/v1/statuses/histories_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe 'API V1 Statuses Histories' do
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 69ae948852..55313482d6 100644
--- a/spec/requests/api/v1/statuses/mutes_spec.rb
+++ b/spec/requests/api/v1/statuses/mutes_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe 'API V1 Statuses Mutes' do
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 @@ RSpec.describe 'API V1 Statuses Mutes' do
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 56e60c6d36..05d8f570cc 100644
--- a/spec/requests/api/v1/statuses/pins_spec.rb
+++ b/spec/requests/api/v1/statuses/pins_spec.rb
@@ -18,15 +18,13 @@ RSpec.describe 'Pins' do
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 @@ RSpec.describe 'Pins' 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
end
@@ -52,6 +52,8 @@ RSpec.describe 'Pins' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -60,6 +62,8 @@ RSpec.describe 'Pins' do
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 @@ RSpec.describe 'Pins' do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -86,15 +92,13 @@ RSpec.describe 'Pins' do
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 @@ RSpec.describe 'Pins' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -115,6 +121,8 @@ RSpec.describe 'Pins' do
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 @@ RSpec.describe 'Pins' do
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 bd26c22f08..40457f6e89 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 @@ RSpec.describe 'API V1 Statuses Reblogged by Accounts' do
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 @@ RSpec.describe 'API V1 Statuses Reblogged by Accounts' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -87,6 +91,8 @@ RSpec.describe 'API V1 Statuses Reblogged by Accounts' do
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 8c7894d875..5e88690074 100644
--- a/spec/requests/api/v1/statuses/reblogs_spec.rb
+++ b/spec/requests/api/v1/statuses/reblogs_spec.rb
@@ -19,6 +19,8 @@ RSpec.describe 'API V1 Statuses Reblogs' do
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 @@ RSpec.describe 'API V1 Statuses Reblogs' do
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 @@ RSpec.describe 'API V1 Statuses Reblogs' do
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 @@ RSpec.describe 'API V1 Statuses Reblogs' do
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 @@ RSpec.describe 'API V1 Statuses Reblogs' do
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 c23fa91b0d..b9c09f6721 100644
--- a/spec/requests/api/v1/statuses/sources_spec.rb
+++ b/spec/requests/api/v1/statuses/sources_spec.rb
@@ -22,6 +22,8 @@ RSpec.describe 'Sources' do
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 @@ RSpec.describe 'Sources' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -52,6 +56,8 @@ RSpec.describe 'Sources' do
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 @@ RSpec.describe 'Sources' do
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 047b2f0485..e316bd451b 100644
--- a/spec/requests/api/v1/statuses/translations_spec.rb
+++ b/spec/requests/api/v1/statuses/translations_spec.rb
@@ -20,6 +20,8 @@ RSpec.describe 'API V1 Statuses Translations' do
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 @@ RSpec.describe 'API V1 Statuses Translations' do
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 057800a266..ddf5945d25 100644
--- a/spec/requests/api/v1/statuses_spec.rb
+++ b/spec/requests/api/v1/statuses_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -202,6 +224,8 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 @@ RSpec.describe '/api/v1/statuses' do
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 a1f64846cf..62b43d657a 100644
--- a/spec/requests/api/v1/streaming_spec.rb
+++ b/spec/requests/api/v1/streaming_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'API V1 Streaming' do
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 8267bb92a0..0a32d8899b 100644
--- a/spec/requests/api/v1/suggestions_spec.rb
+++ b/spec/requests/api/v1/suggestions_spec.rb
@@ -23,15 +23,12 @@ RSpec.describe 'Suggestions' do
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 @@ RSpec.describe 'Suggestions' do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -72,15 +71,12 @@ RSpec.describe 'Suggestions' do
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 9637823d45..f6ff7c614f 100644
--- a/spec/requests/api/v1/tags_spec.rb
+++ b/spec/requests/api/v1/tags_spec.rb
@@ -21,6 +21,8 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
subject
expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -42,6 +46,8 @@ RSpec.describe 'Tags' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -61,6 +67,8 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -95,6 +107,8 @@ RSpec.describe 'Tags' do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -117,6 +131,8 @@ RSpec.describe 'Tags' do
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 @@ RSpec.describe 'Tags' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -138,6 +156,8 @@ RSpec.describe 'Tags' do
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 afad2988ca..2023b189ec 100644
--- a/spec/requests/api/v1/timelines/home_spec.rb
+++ b/spec/requests/api/v1/timelines/home_spec.rb
@@ -31,14 +31,12 @@ RSpec.describe 'Home', :inline_jobs do
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 @@ RSpec.describe 'Home', :inline_jobs do
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 @@ RSpec.describe 'Home', :inline_jobs do
subject
expect(response).to have_http_status(206)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -85,6 +83,8 @@ RSpec.describe 'Home', :inline_jobs do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -97,6 +97,8 @@ RSpec.describe 'Home', :inline_jobs do
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 d7fd1076fe..dc4d0d9506 100644
--- a/spec/requests/api/v1/timelines/link_spec.rb
+++ b/spec/requests/api/v1/timelines/link_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe 'Link' do
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 @@ RSpec.describe 'Link' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -62,6 +66,8 @@ RSpec.describe 'Link' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -74,6 +80,8 @@ RSpec.describe 'Link' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -91,6 +99,8 @@ RSpec.describe 'Link' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -101,6 +111,8 @@ RSpec.describe 'Link' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -127,15 +139,13 @@ RSpec.describe 'Link' do
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 eb4395d1f9..1be754f264 100644
--- a/spec/requests/api/v1/timelines/list_spec.rb
+++ b/spec/requests/api/v1/timelines/list_spec.rb
@@ -23,6 +23,8 @@ RSpec.describe 'API V1 Timelines List' do
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 @@ RSpec.describe 'API V1 Timelines List' do
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 53398b68ec..83d9039356 100644
--- a/spec/requests/api/v1/timelines/public_spec.rb
+++ b/spec/requests/api/v1/timelines/public_spec.rb
@@ -13,6 +13,8 @@ RSpec.describe 'Public' do
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 @@ RSpec.describe 'Public' do
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 @@ RSpec.describe 'Public' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -124,6 +126,8 @@ RSpec.describe 'Public' do
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 554b5fd3e3..1d6844364d 100644
--- a/spec/requests/api/v1/timelines/tag_spec.rb
+++ b/spec/requests/api/v1/timelines/tag_spec.rb
@@ -23,6 +23,8 @@ RSpec.describe 'Tag' do
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 @@ RSpec.describe 'Tag' do
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 @@ RSpec.describe 'Tag' do
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 012d035907..b1b77e7fd8 100644
--- a/spec/requests/api/v1/trends/links_spec.rb
+++ b/spec/requests/api/v1/trends/links_spec.rb
@@ -10,7 +10,11 @@ RSpec.describe 'API V1 Trends Links' do
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 @@ RSpec.describe 'API V1 Trends Links' do
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 3b906e8f82..fe00c9c645 100644
--- a/spec/requests/api/v1/trends/statuses_spec.rb
+++ b/spec/requests/api/v1/trends/statuses_spec.rb
@@ -10,7 +10,11 @@ RSpec.describe 'API V1 Trends Statuses' do
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 @@ RSpec.describe 'API V1 Trends Statuses' do
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 598f4e7752..14ab73fc96 100644
--- a/spec/requests/api/v1/trends/tags_spec.rb
+++ b/spec/requests/api/v1/trends/tags_spec.rb
@@ -10,8 +10,11 @@ RSpec.describe 'API V1 Trends Tags' do
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 @@ RSpec.describe 'API V1 Trends Tags' do
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 17c38e2e55..bc3db4f886 100644
--- a/spec/requests/api/v2/admin/accounts_spec.rb
+++ b/spec/requests/api/v2/admin/accounts_spec.rb
@@ -34,6 +34,8 @@ RSpec.describe 'API V2 Admin Accounts' do
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 @@ RSpec.describe 'API V2 Admin Accounts' do
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 @@ RSpec.describe 'API V2 Admin Accounts' do
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 @@ RSpec.describe 'API V2 Admin Accounts' do
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 @@ RSpec.describe 'API V2 Admin Accounts' do
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 @@ RSpec.describe 'API V2 Admin Accounts' do
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 a31accaa5c..f0d62e9ecc 100644
--- a/spec/requests/api/v2/filters/keywords_spec.rb
+++ b/spec/requests/api/v2/filters/keywords_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 @@ RSpec.describe 'API V2 Filters Keywords' do
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 aed8934a5e..f20a6ae5e6 100644
--- a/spec/requests/api/v2/filters/statuses_spec.rb
+++ b/spec/requests/api/v2/filters/statuses_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe 'API V2 Filters Statuses' do
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 @@ RSpec.describe 'API V2 Filters Statuses' do
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 @@ RSpec.describe 'API V2 Filters Statuses' do
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 @@ RSpec.describe 'API V2 Filters Statuses' do
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 @@ RSpec.describe 'API V2 Filters Statuses' do
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 @@ RSpec.describe 'API V2 Filters Statuses' do
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 @@ RSpec.describe 'API V2 Filters Statuses' do
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 850c773df3..3b5c44cefa 100644
--- a/spec/requests/api/v2/filters_spec.rb
+++ b/spec/requests/api/v2/filters_spec.rb
@@ -15,6 +15,8 @@ RSpec.describe 'Filters' do
subject
expect(response).to have_http_status(401)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -32,6 +34,8 @@ RSpec.describe 'Filters' do
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 @@ RSpec.describe 'Filters' do
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 @@ RSpec.describe 'Filters' do
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 @@ RSpec.describe 'Filters' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -99,6 +99,8 @@ RSpec.describe 'Filters' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -109,6 +111,8 @@ RSpec.describe 'Filters' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -127,6 +131,8 @@ RSpec.describe 'Filters' do
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 @@ RSpec.describe 'Filters' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -166,6 +174,8 @@ RSpec.describe 'Filters' do
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 @@ RSpec.describe 'Filters' do
subject
expect(response).to have_http_status(422)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -189,20 +201,14 @@ RSpec.describe 'Filters' do
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 @@ RSpec.describe 'Filters' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -229,14 +237,12 @@ RSpec.describe 'Filters' do
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 @@ RSpec.describe 'Filters' do
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 6f7519ad1e..85d92f68d0 100644
--- a/spec/requests/api/v2/instance_spec.rb
+++ b/spec/requests/api/v2/instance_spec.rb
@@ -15,6 +15,9 @@ RSpec.describe 'Instances' do
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 @@ RSpec.describe 'Instances' do
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 06ce0053e8..70e0679f57 100644
--- a/spec/requests/api/v2/media_spec.rb
+++ b/spec/requests/api/v2/media_spec.rb
@@ -21,6 +21,9 @@ RSpec.describe 'Media API', :attachment_processing do
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 @@ RSpec.describe 'Media API', :attachment_processing do
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 @@ RSpec.describe 'Media API', :attachment_processing do
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 @@ RSpec.describe 'Media API', :attachment_processing do
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 102b009c0b..29880a4c0a 100644
--- a/spec/requests/api/v2/notifications/accounts_spec.rb
+++ b/spec/requests/api/v2/notifications/accounts_spec.rb
@@ -30,6 +30,8 @@ RSpec.describe 'Accounts in grouped notifications' do
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 @@ RSpec.describe 'Accounts in grouped notifications' do
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 dc205b6ebb..f080bc730f 100644
--- a/spec/requests/api/v2/notifications/policies_spec.rb
+++ b/spec/requests/api/v2/notifications/policies_spec.rb
@@ -26,6 +26,8 @@ RSpec.describe 'Policies' do
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 @@ RSpec.describe 'Policies' do
.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 edf333ecd8..ffa0a71c77 100644
--- a/spec/requests/api/v2/notifications_spec.rb
+++ b/spec/requests/api/v2/notifications_spec.rb
@@ -31,6 +31,8 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
# 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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
subject
expect(response).to have_http_status(400)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -282,6 +312,8 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -308,16 +342,21 @@ RSpec.describe 'Notifications' do
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 @@ RSpec.describe 'Notifications' do
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 a59ec7ca6b..5a2346dc39 100644
--- a/spec/requests/api/v2/search_spec.rb
+++ b/spec/requests/api/v2/search_spec.rb
@@ -19,6 +19,8 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 @@ RSpec.describe 'Search API' do
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 e92507ed66..099d9bc3b2 100644
--- a/spec/requests/api/v2/suggestions_spec.rb
+++ b/spec/requests/api/v2/suggestions_spec.rb
@@ -21,6 +21,8 @@ RSpec.describe 'Suggestions API' do
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 2b28502835..3cc2f977f8 100644
--- a/spec/requests/api/web/embeds_spec.rb
+++ b/spec/requests/api/web/embeds_spec.rb
@@ -18,6 +18,8 @@ RSpec.describe '/api/web/embed' do
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 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -42,6 +46,8 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -52,6 +58,8 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -71,6 +79,8 @@ RSpec.describe '/api/web/embed' do
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 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -98,6 +110,8 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -123,6 +137,8 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -133,6 +149,8 @@ RSpec.describe '/api/web/embed' do
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 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -156,6 +176,8 @@ RSpec.describe '/api/web/embed' do
subject
expect(response).to have_http_status(404)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
end
@@ -167,6 +189,8 @@ RSpec.describe '/api/web/embed' do
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 81b8b44953..3873bc179b 100644
--- a/spec/requests/api/web/settings_spec.rb
+++ b/spec/requests/api/web/settings_spec.rb
@@ -17,6 +17,8 @@ RSpec.describe '/api/web/settings' do
expect(response)
.to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
end
end
@@ -29,6 +31,8 @@ RSpec.describe '/api/web/settings' do
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 0000000000..6246e4beb3
--- /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 0000000000..db823ac770
--- /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 0000000000..ac98ab8f94
--- /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 226e136446..0000000000
--- 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 b9792ebae3..0000000000
--- 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 a4b8ee83b2..0000000000
--- 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 e45112705b..0000000000
--- 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 b8370beac7..0000000000
--- 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 41492f5e78..0000000000
--- 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 b63e44b43f..144019d969 100644
--- a/spec/support/examples/models/concerns/reviewable.rb
+++ b/spec/support/examples/models/concerns/reviewable.rb
@@ -6,6 +6,31 @@ RSpec.shared_examples 'Reviewable' do
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 0000000000..2cc2961a0b
--- /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 311545cf56..0000000000
--- 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 f4aeadf23f..d792f95acf 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