mirror of
https://git.kescher.at/CatCatNya/catstodon.git
synced 2024-11-29 15:29:04 +01:00
Merge commit '967505ee9bcacf0e5189aa06c654ff586c198a46' into glitch-soc/merge-upstream
This commit is contained in:
commit
388672ff0d
11 changed files with 112 additions and 36 deletions
|
@ -8,7 +8,7 @@ class Api::V1::Polls::VotesController < Api::BaseController
|
||||||
before_action :set_poll
|
before_action :set_poll
|
||||||
|
|
||||||
def create
|
def create
|
||||||
VoteService.new.call(current_account, @poll, vote_params[:choices])
|
VoteService.new.call(current_account, @poll, vote_params)
|
||||||
render json: @poll, serializer: REST::PollSerializer
|
render json: @poll, serializer: REST::PollSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -22,6 +22,6 @@ class Api::V1::Polls::VotesController < Api::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def vote_params
|
def vote_params
|
||||||
params.permit(choices: [])
|
params.require(:choices)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
"about.contact": "Контакт:",
|
"about.contact": "Контакт:",
|
||||||
"about.disclaimer": "Mastodon є задарьнов проґрамов из удпертым кодом тай торговов значков Mastodon gGmbH.",
|
"about.disclaimer": "Mastodon є задарьнов проґрамов из удпертым кодом тай торговов значков Mastodon gGmbH.",
|
||||||
"about.domain_blocks.no_reason_available": "Причины не ясні",
|
"about.domain_blocks.no_reason_available": "Причины не ясні",
|
||||||
|
"about.domain_blocks.preamble": "Майбульш Mastodon поволят вам позирати контент тай комуніковати из хосновачами из другых федерованых серверув. Туй лиш уняткы учинені про сись конкретный сервер.",
|
||||||
|
"about.domain_blocks.silenced.explanation": "Вы майбульш не будете видіти профілі тай контент из сього сервера, кидь не будете го самі глядати авадь пудпишете ся на нього.",
|
||||||
"about.domain_blocks.silenced.title": "Обмежено",
|
"about.domain_blocks.silenced.title": "Обмежено",
|
||||||
"about.domain_blocks.suspended.explanation": "Ниякі податкы из сього сервера не будут уброблені, усокочені ци поміняні, што чинит невозможнов хоть-яку інтеракцію ци зязок из хосновачами из сього сервера.",
|
"about.domain_blocks.suspended.explanation": "Ниякі податкы из сього сервера не будут уброблені, усокочені ци поміняні, што чинит невозможнов хоть-яку інтеракцію ци зязок из хосновачами из сього сервера.",
|
||||||
"about.domain_blocks.suspended.title": "Заблоковано",
|
"about.domain_blocks.suspended.title": "Заблоковано",
|
||||||
|
@ -20,6 +22,7 @@
|
||||||
"account.browse_more_on_origin_server": "Позирайте бульше на ориґіналнум профілю",
|
"account.browse_more_on_origin_server": "Позирайте бульше на ориґіналнум профілю",
|
||||||
"account.cancel_follow_request": "Удмінити пудписку",
|
"account.cancel_follow_request": "Удмінити пудписку",
|
||||||
"account.copy": "Зкопіровати удкликованя на профіл",
|
"account.copy": "Зкопіровати удкликованя на профіл",
|
||||||
|
"account.direct": "Пошептати @{name}",
|
||||||
"account.disable_notifications": "Бульше не сповіщати ми коли {name} пише",
|
"account.disable_notifications": "Бульше не сповіщати ми коли {name} пише",
|
||||||
"account.domain_blocked": "Домен заблокованый",
|
"account.domain_blocked": "Домен заблокованый",
|
||||||
"account.edit_profile": "Управити профіл",
|
"account.edit_profile": "Управити профіл",
|
||||||
|
@ -39,8 +42,10 @@
|
||||||
"account.joined_short": "Датум прикапчованя",
|
"account.joined_short": "Датум прикапчованя",
|
||||||
"account.languages": "Поміняти убрані языкы",
|
"account.languages": "Поміняти убрані языкы",
|
||||||
"account.link_verified_on": "Властность сього удкликованя было звірено {date}",
|
"account.link_verified_on": "Властность сього удкликованя было звірено {date}",
|
||||||
|
"account.locked_info": "Сись профіл є замкнутый. Ґазда акаунта буде ручно провіряти тко го може зафоловити.",
|
||||||
"account.media": "Медіа",
|
"account.media": "Медіа",
|
||||||
"account.moved_to": "Хосновач {name} указав, ож новый профіл йим є:",
|
"account.mention": "Спомянути @{name}",
|
||||||
|
"account.moved_to": "Хосновач {name} указав, ож новый профіл му є:",
|
||||||
"account.mute": "Стишити {name}",
|
"account.mute": "Стишити {name}",
|
||||||
"account.mute_notifications_short": "Стишити голошіня",
|
"account.mute_notifications_short": "Стишити голошіня",
|
||||||
"account.mute_short": "Стишити",
|
"account.mute_short": "Стишити",
|
||||||
|
@ -60,9 +65,12 @@
|
||||||
"account.unblock_short": "Розблоковати",
|
"account.unblock_short": "Розблоковати",
|
||||||
"account.unendorse": "Не указовати на профілови",
|
"account.unendorse": "Не указовати на профілови",
|
||||||
"account.unfollow": "Удписати ся",
|
"account.unfollow": "Удписати ся",
|
||||||
|
"account.unmute": "Указовати {name}",
|
||||||
"account.unmute_notifications_short": "Указовати голошіня",
|
"account.unmute_notifications_short": "Указовати голошіня",
|
||||||
"account.unmute_short": "Указовати",
|
"account.unmute_short": "Указовати",
|
||||||
"account_note.placeholder": "Клопкніт обы додати примітку",
|
"account_note.placeholder": "Клопкніт обы додати примітку",
|
||||||
|
"admin.dashboard.retention.average": "Середньоє",
|
||||||
|
"admin.dashboard.retention.cohort": "Місяць прикапчованя",
|
||||||
"admin.dashboard.retention.cohort_size": "Нові хосновачі",
|
"admin.dashboard.retention.cohort_size": "Нові хосновачі",
|
||||||
"admin.impact_report.instance_accounts": "Профілі из акаунтув, котрі ся удалят",
|
"admin.impact_report.instance_accounts": "Профілі из акаунтув, котрі ся удалят",
|
||||||
"admin.impact_report.instance_followers": "Пудписникы, котрых стратят наші хосновачі",
|
"admin.impact_report.instance_followers": "Пудписникы, котрых стратят наші хосновачі",
|
||||||
|
@ -70,11 +78,38 @@
|
||||||
"admin.impact_report.title": "Вплыв цілком",
|
"admin.impact_report.title": "Вплыв цілком",
|
||||||
"alert.rate_limited.message": "Попробуйте зась по {retry_time, time, medium}.",
|
"alert.rate_limited.message": "Попробуйте зась по {retry_time, time, medium}.",
|
||||||
"alert.rate_limited.title": "Частота обмежена",
|
"alert.rate_limited.title": "Частота обмежена",
|
||||||
|
"alert.unexpected.message": "Стала ся нечекана хыба.",
|
||||||
|
"alert.unexpected.title": "Ийой!",
|
||||||
|
"announcement.announcement": "Голошіня",
|
||||||
|
"audio.hide": "Зпрятати звук",
|
||||||
|
"block_modal.show_less": "Указати менше",
|
||||||
|
"block_modal.show_more": "Указати бульше",
|
||||||
|
"block_modal.they_cant_mention": "Они не можут вас споминати авадь слідовати.",
|
||||||
|
"block_modal.they_cant_see_posts": "Они не можут видіти ваші публикації, тай наспак — вы йихні.",
|
||||||
|
"block_modal.they_will_know": "Они видят, ож сут заблоковані.",
|
||||||
|
"block_modal.title": "Заблоковати хосновача?",
|
||||||
|
"block_modal.you_wont_see_mentions": "Не будете видіти публикації тай споминкы сього хосновача.",
|
||||||
|
"boost_modal.combo": "Можете клынцнути {combo} другый раз обы сесе пропустити",
|
||||||
|
"bundle_column_error.copy_stacktrace": "Укопіровати звіт за хыбу",
|
||||||
|
"bundle_column_error.error.body": "Не годни сьме указати зажадану сторунку. Годно быти спозад хыбы у нашум сістемі, авадь проблемы зумісности бравзера.",
|
||||||
|
"bundle_column_error.error.title": "Ийой!",
|
||||||
|
"bundle_column_error.network.body": "Стала ся хыба як сьме пробовали напаровати сторунку. Годно ся йсе было стати спозад слабого споєня вашого інтернета, авадь сервера.",
|
||||||
|
"bundle_column_error.network.title": "Хыба споєня",
|
||||||
|
"bundle_column_error.retry": "Попробуйте зась",
|
||||||
"bundle_column_error.return": "Вернути ся на головну",
|
"bundle_column_error.return": "Вернути ся на головну",
|
||||||
"bundle_column_error.routing.body": "Не можеме найти сяку сторунку. Бизувні сьте, ож URL у адресному шорикови є добрый?",
|
"bundle_column_error.routing.body": "Не можеме найти сяку сторунку. Бизувні сьте, ож URL у адресному шорикови є добрый?",
|
||||||
"bundle_column_error.routing.title": "404",
|
"bundle_column_error.routing.title": "404",
|
||||||
"bundle_modal_error.close": "Заперти",
|
"bundle_modal_error.close": "Заперти",
|
||||||
"bundle_modal_error.message": "Штось ся показило, закидь сьме ладовали сись компонент.",
|
"bundle_modal_error.message": "Штось ся показило, закидь сьме ладовали сись компонент.",
|
||||||
"bundle_modal_error.retry": "Попробовати зась",
|
"bundle_modal_error.retry": "Попробовати зась",
|
||||||
"closed_registrations.other_server_instructions": "Mastodon є децентралізованов платформов, можете си учинити профіл и на другому серверови тай комуніковати из сим."
|
"closed_registrations.other_server_instructions": "Mastodon є децентралізованов платформов, можете си учинити профіл и на другому серверови тай комуніковати из сим.",
|
||||||
|
"closed_registrations_modal.description": "Раз не мож учинити профіл на {domain}, айбо не мусите мати профіл ипен на серверови {domain} обы хосновати Mastodon.",
|
||||||
|
"closed_registrations_modal.find_another_server": "Найти другый сервер",
|
||||||
|
"column.about": "За сайт",
|
||||||
|
"column.blocks": "Заблоковані хосновачі",
|
||||||
|
"column.bookmarks": "Усокоченоє",
|
||||||
|
"column.direct": "Шептаня",
|
||||||
|
"column.directory": "Никати профілі",
|
||||||
|
"column.domain_blocks": "Заблоковані домены",
|
||||||
|
"column.favourites": "Убраноє"
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,11 @@ class PreviewCard < ApplicationRecord
|
||||||
y_comp: 4,
|
y_comp: 4,
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
|
# URL size limit to safely store in PosgreSQL's unique indexes
|
||||||
|
# Technically this is a byte-size limit but we use it as a
|
||||||
|
# character limit to work with length validation
|
||||||
|
URL_CHARACTER_LIMIT = 2692
|
||||||
|
|
||||||
self.inheritance_column = false
|
self.inheritance_column = false
|
||||||
|
|
||||||
enum :type, { link: 0, photo: 1, video: 2, rich: 3 }
|
enum :type, { link: 0, photo: 1, video: 2, rich: 3 }
|
||||||
|
@ -63,7 +68,7 @@ class PreviewCard < ApplicationRecord
|
||||||
convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' },
|
convert_options: { all: '-quality 90 +profile "!icc,*" +set date:modify +set date:create +set date:timestamp' },
|
||||||
validate_media_type: false
|
validate_media_type: false
|
||||||
|
|
||||||
validates :url, presence: true, uniqueness: true, url: true
|
validates :url, presence: true, uniqueness: true, url: true, length: { maximum: URL_CHARACTER_LIMIT }
|
||||||
validates_attachment_content_type :image, content_type: IMAGE_MIME_TYPES
|
validates_attachment_content_type :image, content_type: IMAGE_MIME_TYPES
|
||||||
validates_attachment_size :image, less_than: LIMIT
|
validates_attachment_size :image, less_than: LIMIT
|
||||||
remotable_attachment :image, LIMIT
|
remotable_attachment :image, LIMIT
|
||||||
|
|
|
@ -15,9 +15,6 @@ class FetchLinkCardService < BaseService
|
||||||
)
|
)
|
||||||
}iox
|
}iox
|
||||||
|
|
||||||
# URL size limit to safely store in PosgreSQL's unique indexes
|
|
||||||
BYTESIZE_LIMIT = 2692
|
|
||||||
|
|
||||||
def call(status)
|
def call(status)
|
||||||
@status = status
|
@status = status
|
||||||
@original_url = parse_urls
|
@original_url = parse_urls
|
||||||
|
@ -32,7 +29,7 @@ class FetchLinkCardService < BaseService
|
||||||
end
|
end
|
||||||
|
|
||||||
attach_card if @card&.persisted?
|
attach_card if @card&.persisted?
|
||||||
rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, EncodingError => e
|
rescue HTTP::Error, OpenSSL::SSL::SSLError, Addressable::URI::InvalidURIError, Mastodon::HostValidationError, Mastodon::LengthValidationError, EncodingError, ActiveRecord::RecordInvalid => e
|
||||||
Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" }
|
Rails.logger.debug { "Error fetching link #{@original_url}: #{e}" }
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
@ -88,7 +85,7 @@ class FetchLinkCardService < BaseService
|
||||||
|
|
||||||
def bad_url?(uri)
|
def bad_url?(uri)
|
||||||
# Avoid local instance URLs and invalid URLs
|
# Avoid local instance URLs and invalid URLs
|
||||||
uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme) || uri.to_s.bytesize > BYTESIZE_LIMIT
|
uri.host.blank? || TagManager.instance.local_url?(uri.to_s) || !%w(http https).include?(uri.scheme)
|
||||||
end
|
end
|
||||||
|
|
||||||
def mention_link?(anchor)
|
def mention_link?(anchor)
|
||||||
|
|
|
@ -2,9 +2,21 @@
|
||||||
|
|
||||||
require_relative '../../lib/mastodon/sidekiq_middleware'
|
require_relative '../../lib/mastodon/sidekiq_middleware'
|
||||||
|
|
||||||
|
SIDEKIQ_WILL_PROCESSES_JOBS_FILE = Rails.root.join('tmp', 'sidekiq_process_has_started_and_will_begin_processing_jobs').freeze
|
||||||
|
|
||||||
Sidekiq.configure_server do |config|
|
Sidekiq.configure_server do |config|
|
||||||
config.redis = REDIS_SIDEKIQ_PARAMS
|
config.redis = REDIS_SIDEKIQ_PARAMS
|
||||||
|
|
||||||
|
# This is used in Kubernetes setups, to signal that the Sidekiq process has started and will begin processing jobs
|
||||||
|
# This comes from https://github.com/sidekiq/sidekiq/wiki/Kubernetes#sidekiq
|
||||||
|
config.on(:startup) do
|
||||||
|
FileUtils.touch(SIDEKIQ_WILL_PROCESSES_JOBS_FILE)
|
||||||
|
end
|
||||||
|
|
||||||
|
config.on(:shutdown) do
|
||||||
|
FileUtils.rm_f(SIDEKIQ_WILL_PROCESSES_JOBS_FILE)
|
||||||
|
end
|
||||||
|
|
||||||
config.server_middleware do |chain|
|
config.server_middleware do |chain|
|
||||||
chain.add Mastodon::SidekiqMiddleware
|
chain.add Mastodon::SidekiqMiddleware
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,12 +64,16 @@ Rails.application.routes.draw do
|
||||||
tokens: 'oauth/tokens'
|
tokens: 'oauth/tokens'
|
||||||
end
|
end
|
||||||
|
|
||||||
get '.well-known/oauth-authorization-server', to: 'well_known/oauth_metadata#show', as: :oauth_metadata, defaults: { format: 'json' }
|
scope path: '.well-known' do
|
||||||
get '.well-known/host-meta', to: 'well_known/host_meta#show', as: :host_meta, defaults: { format: 'xml' }
|
scope module: :well_known do
|
||||||
get '.well-known/nodeinfo', to: 'well_known/node_info#index', as: :nodeinfo, defaults: { format: 'json' }
|
get 'oauth-authorization-server', to: 'oauth_metadata#show', as: :oauth_metadata, defaults: { format: 'json' }
|
||||||
get '.well-known/webfinger', to: 'well_known/webfinger#show', as: :webfinger
|
get 'host-meta', to: 'host_meta#show', as: :host_meta, defaults: { format: 'xml' }
|
||||||
get '.well-known/change-password', to: redirect('/auth/edit')
|
get 'nodeinfo', to: 'node_info#index', as: :nodeinfo, defaults: { format: 'json' }
|
||||||
get '.well-known/proxy', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }
|
get 'webfinger', to: 'webfinger#show', as: :webfinger
|
||||||
|
end
|
||||||
|
get 'change-password', to: redirect('/auth/edit'), as: nil
|
||||||
|
get 'proxy', to: redirect { |_, request| "/authorize_interaction?#{request.params.to_query}" }, as: nil
|
||||||
|
end
|
||||||
|
|
||||||
get '/nodeinfo/2.0', to: 'well_known/node_info#show', as: :nodeinfo_schema
|
get '/nodeinfo/2.0', to: 'well_known/node_info#show', as: :nodeinfo_schema
|
||||||
|
|
||||||
|
@ -95,7 +99,7 @@ Rails.application.routes.draw do
|
||||||
|
|
||||||
namespace :auth do
|
namespace :auth do
|
||||||
resource :setup, only: [:show, :update], controller: :setup
|
resource :setup, only: [:show, :update], controller: :setup
|
||||||
resource :challenge, only: [:create], controller: :challenges
|
resource :challenge, only: [:create]
|
||||||
get 'sessions/security_key_options', to: 'sessions#webauthn_options'
|
get 'sessions/security_key_options', to: 'sessions#webauthn_options'
|
||||||
post 'captcha_confirmation', to: 'confirmations#confirm_captcha', as: :captcha_confirmation
|
post 'captcha_confirmation', to: 'confirmations#confirm_captcha', as: :captcha_confirmation
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,9 +26,9 @@ namespace :settings do
|
||||||
resources :follows, only: :index, controller: :following_accounts
|
resources :follows, only: :index, controller: :following_accounts
|
||||||
resources :blocks, only: :index, controller: :blocked_accounts
|
resources :blocks, only: :index, controller: :blocked_accounts
|
||||||
resources :mutes, only: :index, controller: :muted_accounts
|
resources :mutes, only: :index, controller: :muted_accounts
|
||||||
resources :lists, only: :index, controller: :lists
|
resources :lists, only: :index
|
||||||
resources :domain_blocks, only: :index, controller: :blocked_domains
|
resources :domain_blocks, only: :index, controller: :blocked_domains
|
||||||
resources :bookmarks, only: :index, controller: :bookmarks
|
resources :bookmarks, only: :index
|
||||||
end
|
end
|
||||||
|
|
||||||
resources :two_factor_authentication_methods, only: [:index] do
|
resources :two_factor_authentication_methods, only: [:index] do
|
||||||
|
|
18
spec/fixtures/requests/long_canonical_url.txt
vendored
Normal file
18
spec/fixtures/requests/long_canonical_url.txt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
server: nginx
|
||||||
|
date: Thu, 13 Jun 2024 14:33:13 GMT
|
||||||
|
content-type: text/html; charset=utf-8
|
||||||
|
content-length: 3225
|
||||||
|
accept-ranges: bytes
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="canonical" href="https://example.com/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa">
|
||||||
|
<title>Very long canonical URL</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>We have very long URLs</h2>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -10,9 +10,10 @@ RSpec.describe 'API V1 Polls Votes' do
|
||||||
|
|
||||||
describe 'POST /api/v1/polls/:poll_id/votes' do
|
describe 'POST /api/v1/polls/:poll_id/votes' do
|
||||||
let(:poll) { Fabricate(:poll) }
|
let(:poll) { Fabricate(:poll) }
|
||||||
|
let(:params) { { choices: %w(1) } }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
post "/api/v1/polls/#{poll.id}/votes", params: { choices: %w(1) }, headers: headers
|
post "/api/v1/polls/#{poll.id}/votes", params: params, headers: headers
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'creates a vote', :aggregate_failures do
|
it 'creates a vote', :aggregate_failures do
|
||||||
|
@ -24,6 +25,14 @@ RSpec.describe 'API V1 Polls Votes' do
|
||||||
expect(poll.reload.cached_tallies).to eq [0, 1]
|
expect(poll.reload.cached_tallies).to eq [0, 1]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the required choices param is not provided' do
|
||||||
|
let(:params) { {} }
|
||||||
|
|
||||||
|
it 'returns http bad request' do
|
||||||
|
expect(response).to have_http_status(400)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def vote
|
def vote
|
||||||
|
|
|
@ -31,6 +31,7 @@ RSpec.describe FetchLinkCardService do
|
||||||
stub_request(:get, 'http://example.com/latin1_posing_as_utf8_recoverable').to_return(request_fixture('latin1_posing_as_utf8_recoverable.txt'))
|
stub_request(:get, 'http://example.com/latin1_posing_as_utf8_recoverable').to_return(request_fixture('latin1_posing_as_utf8_recoverable.txt'))
|
||||||
stub_request(:get, 'http://example.com/aergerliche-umlaute').to_return(request_fixture('redirect_with_utf8_url.txt'))
|
stub_request(:get, 'http://example.com/aergerliche-umlaute').to_return(request_fixture('redirect_with_utf8_url.txt'))
|
||||||
stub_request(:get, 'http://example.com/page_without_title').to_return(request_fixture('page_without_title.txt'))
|
stub_request(:get, 'http://example.com/page_without_title').to_return(request_fixture('page_without_title.txt'))
|
||||||
|
stub_request(:get, 'http://example.com/long_canonical_url').to_return(request_fixture('long_canonical_url.txt'))
|
||||||
|
|
||||||
Rails.cache.write('oembed_endpoint:example.com', oembed_cache) if oembed_cache
|
Rails.cache.write('oembed_endpoint:example.com', oembed_cache) if oembed_cache
|
||||||
|
|
||||||
|
@ -233,19 +234,6 @@ RSpec.describe FetchLinkCardService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with an URL too long for PostgreSQL unique indexes' do
|
|
||||||
let(:url) { "http://example.com/#{'a' * 2674}" }
|
|
||||||
let(:status) { Fabricate(:status, text: url) }
|
|
||||||
|
|
||||||
it 'does not fetch the URL' do
|
|
||||||
expect(a_request(:get, url)).to_not have_been_made
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'does not create a preview card' do
|
|
||||||
expect(status.preview_card).to be_nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'with a URL of a page with oEmbed support' do
|
context 'with a URL of a page with oEmbed support' do
|
||||||
let(:html) { '<!doctype html><title>Hello world</title><link rel="alternate" type="application/json+oembed" href="http://example.com/oembed?url=http://example.com/html">' }
|
let(:html) { '<!doctype html><title>Hello world</title><link rel="alternate" type="application/json+oembed" href="http://example.com/oembed?url=http://example.com/html">' }
|
||||||
let(:status) { Fabricate(:status, text: 'http://example.com/html') }
|
let(:status) { Fabricate(:status, text: 'http://example.com/html') }
|
||||||
|
@ -296,6 +284,14 @@ RSpec.describe FetchLinkCardService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with a URL of a page that includes a canonical URL too long for PostgreSQL unique indexes' do
|
||||||
|
let(:status) { Fabricate(:status, text: 'test http://example.com/long_canonical_url') }
|
||||||
|
|
||||||
|
it 'does not create a preview card' do
|
||||||
|
expect(status.preview_card).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with a remote status' do
|
context 'with a remote status' do
|
||||||
|
|
|
@ -9033,8 +9033,8 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"glob@npm:^10.2.2, glob@npm:^10.2.6, glob@npm:^10.3.10":
|
"glob@npm:^10.2.2, glob@npm:^10.2.6, glob@npm:^10.3.10":
|
||||||
version: 10.4.3
|
version: 10.4.5
|
||||||
resolution: "glob@npm:10.4.3"
|
resolution: "glob@npm:10.4.5"
|
||||||
dependencies:
|
dependencies:
|
||||||
foreground-child: "npm:^3.1.0"
|
foreground-child: "npm:^3.1.0"
|
||||||
jackspeak: "npm:^3.1.2"
|
jackspeak: "npm:^3.1.2"
|
||||||
|
@ -9044,7 +9044,7 @@ __metadata:
|
||||||
path-scurry: "npm:^1.11.1"
|
path-scurry: "npm:^1.11.1"
|
||||||
bin:
|
bin:
|
||||||
glob: dist/esm/bin.mjs
|
glob: dist/esm/bin.mjs
|
||||||
checksum: 10c0/bea148e5dae96c17e2764f4764c72376a6ab7072b27a21e861ae4af6f97f3e810d79d67f64de52f63ce1d7fdb73b7306f61c65b48d0f61ca7c8647ce8acaf9a7
|
checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue