Merge remote-tracking branch 'parent/main' into kbtopic-remove-quote
This commit is contained in:
commit
80542ea172
76 changed files with 658 additions and 390 deletions
|
@ -1,6 +1,6 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.75.2.
|
||||
# using RuboCop version 1.75.3.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -79,7 +79,7 @@ gem 'rails-i18n', '~> 8.0'
|
|||
gem 'redcarpet', '~> 3.6'
|
||||
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'redis-namespace', '~> 1.10'
|
||||
gem 'rqrcode', '~> 2.2'
|
||||
gem 'rqrcode', '~> 3.0'
|
||||
gem 'ruby-progressbar', '~> 1.13'
|
||||
gem 'sanitize', '~> 7.0'
|
||||
gem 'scenic', '~> 1.7'
|
||||
|
|
14
Gemfile.lock
14
Gemfile.lock
|
@ -160,7 +160,7 @@ GEM
|
|||
cocoon (1.2.15)
|
||||
color_diff (0.1)
|
||||
concurrent-ruby (1.3.5)
|
||||
connection_pool (2.5.1)
|
||||
connection_pool (2.5.2)
|
||||
cose (1.3.1)
|
||||
cbor (~> 0.5.9)
|
||||
openssl-signature_algorithm (~> 1.0)
|
||||
|
@ -711,10 +711,10 @@ GEM
|
|||
rotp (6.3.0)
|
||||
rouge (4.5.1)
|
||||
rpam2 (4.0.2)
|
||||
rqrcode (2.2.0)
|
||||
rqrcode (3.0.0)
|
||||
chunky_png (~> 1.0)
|
||||
rqrcode_core (~> 1.0)
|
||||
rqrcode_core (1.2.0)
|
||||
rqrcode_core (~> 2.0)
|
||||
rqrcode_core (2.0.0)
|
||||
rspec (3.13.0)
|
||||
rspec-core (~> 3.13.0)
|
||||
rspec-expectations (~> 3.13.0)
|
||||
|
@ -743,7 +743,7 @@ GEM
|
|||
rspec-mocks (~> 3.0)
|
||||
sidekiq (>= 5, < 9)
|
||||
rspec-support (3.13.2)
|
||||
rubocop (1.75.2)
|
||||
rubocop (1.75.3)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (~> 3.17.0.2)
|
||||
lint_roller (~> 1.1.0)
|
||||
|
@ -773,7 +773,7 @@ GEM
|
|||
rack (>= 1.1)
|
||||
rubocop (>= 1.75.0, < 2.0)
|
||||
rubocop-ast (>= 1.38.0, < 2.0)
|
||||
rubocop-rspec (3.5.0)
|
||||
rubocop-rspec (3.6.0)
|
||||
lint_roller (~> 1.1)
|
||||
rubocop (~> 1.72, >= 1.72.1)
|
||||
rubocop-rspec_rails (2.31.0)
|
||||
|
@ -1043,7 +1043,7 @@ DEPENDENCIES
|
|||
redcarpet (~> 3.6)
|
||||
redis (~> 4.5)
|
||||
redis-namespace (~> 1.10)
|
||||
rqrcode (~> 2.2)
|
||||
rqrcode (~> 3.0)
|
||||
rspec-github (~> 3.0)
|
||||
rspec-rails (~> 7.0)
|
||||
rspec-sidekiq (~> 5.0)
|
||||
|
|
|
@ -72,6 +72,13 @@ class Api::BaseController < ApplicationController
|
|||
end
|
||||
end
|
||||
|
||||
# Redefine `require_functional!` to properly output JSON instead of HTML redirects
|
||||
def require_functional!
|
||||
return if current_user.functional?
|
||||
|
||||
require_user!
|
||||
end
|
||||
|
||||
def render_empty
|
||||
render json: {}, status: 200
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ class Api::V1::FeaturedTagsController < Api::BaseController
|
|||
end
|
||||
|
||||
def destroy
|
||||
RemoveFeaturedTagWorker.perform_async(current_account.id, @featured_tag.id)
|
||||
RemoveFeaturedTagService.new.call(current_account, @featured_tag)
|
||||
render_empty
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::TagsController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, except: :show
|
||||
before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, only: [:follow, :unfollow]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:feature, :unfeature]
|
||||
before_action :require_user!, except: :show
|
||||
before_action :set_or_create_tag
|
||||
|
||||
|
@ -23,6 +24,16 @@ class Api::V1::TagsController < Api::BaseController
|
|||
render json: @tag, serializer: REST::TagSerializer
|
||||
end
|
||||
|
||||
def feature
|
||||
CreateFeaturedTagService.new.call(current_account, @tag)
|
||||
render json: @tag, serializer: REST::TagSerializer
|
||||
end
|
||||
|
||||
def unfeature
|
||||
RemoveFeaturedTagService.new.call(current_account, @tag)
|
||||
render json: @tag, serializer: REST::TagSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_or_create_tag
|
||||
|
|
|
@ -72,10 +72,24 @@ class ApplicationController < ActionController::Base
|
|||
def require_functional!
|
||||
return if current_user.functional?
|
||||
|
||||
if current_user.confirmed?
|
||||
redirect_to edit_user_registration_path
|
||||
else
|
||||
redirect_to auth_setup_path
|
||||
respond_to do |format|
|
||||
format.any do
|
||||
if current_user.confirmed?
|
||||
redirect_to edit_user_registration_path
|
||||
else
|
||||
redirect_to auth_setup_path
|
||||
end
|
||||
end
|
||||
|
||||
format.json do
|
||||
if !current_user.confirmed?
|
||||
render json: { error: 'Your login is missing a confirmed e-mail address' }, status: 403
|
||||
elsif !current_user.approved?
|
||||
render json: { error: 'Your login is currently pending approval' }, status: 403
|
||||
elsif !current_user.functional?
|
||||
render json: { error: 'Your login is currently disabled' }, status: 403
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ module Localized
|
|||
def requested_locale
|
||||
requested_locale_name = available_locale_or_nil(params[:lang])
|
||||
requested_locale_name ||= available_locale_or_nil(current_user.locale) if respond_to?(:user_signed_in?) && user_signed_in?
|
||||
requested_locale_name ||= http_accept_language if ENV['DEFAULT_LOCALE'].blank?
|
||||
requested_locale_name ||= http_accept_language unless ENV['FORCE_DEFAULT_LOCALE'] == 'true'
|
||||
requested_locale_name
|
||||
end
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ class Settings::FeaturedTagsController < Settings::BaseController
|
|||
end
|
||||
|
||||
def create
|
||||
@featured_tag = CreateFeaturedTagService.new.call(current_account, featured_tag_params[:name], force: false)
|
||||
@featured_tag = CreateFeaturedTagService.new.call(current_account, featured_tag_params[:name], raise_error: false)
|
||||
|
||||
if @featured_tag.valid?
|
||||
redirect_to settings_featured_tags_path
|
||||
|
|
|
@ -4,9 +4,12 @@ import axios from 'axios';
|
|||
import ready from '../mastodon/ready';
|
||||
|
||||
async function checkConfirmation() {
|
||||
const response = await axios.get('/api/v1/emails/check_confirmation');
|
||||
const response = await axios.get('/api/v1/emails/check_confirmation', {
|
||||
headers: { Accept: 'application/json' },
|
||||
withCredentials: true,
|
||||
});
|
||||
|
||||
if (response.data) {
|
||||
if (response.status === 200 && response.data === true) {
|
||||
window.location.href = '/start';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="79" height="79" viewBox="0 0 79 75"><symbol id="logo-symbol-icon"><path d="M74.7135 16.6043C73.6199 8.54587 66.5351 2.19527 58.1366 0.964691C56.7196 0.756754 51.351 0 38.9148 0H38.822C26.3824 0 23.7135 0.756754 22.2966 0.964691C14.1319 2.16118 6.67571 7.86752 4.86669 16.0214C3.99657 20.0369 3.90371 24.4888 4.06535 28.5726C4.29578 34.4289 4.34049 40.275 4.877 46.1075C5.24791 49.9817 5.89495 53.8251 6.81328 57.6088C8.53288 64.5968 15.4938 70.4122 22.3138 72.7848C29.6155 75.259 37.468 75.6697 44.9919 73.971C45.8196 73.7801 46.6381 73.5586 47.4475 73.3063C49.2737 72.7302 51.4164 72.086 52.9915 70.9542C53.0131 70.9384 53.0308 70.9178 53.0433 70.8942C53.0558 70.8706 53.0628 70.8445 53.0637 70.8179V65.1661C53.0634 65.1412 53.0574 65.1167 53.0462 65.0944C53.035 65.0721 53.0189 65.0525 52.9992 65.0371C52.9794 65.0218 52.9564 65.011 52.9318 65.0056C52.9073 65.0002 52.8819 65.0003 52.8574 65.0059C48.0369 66.1472 43.0971 66.7193 38.141 66.7103C29.6118 66.7103 27.3178 62.6981 26.6609 61.0278C26.1329 59.5842 25.7976 58.0784 25.6636 56.5486C25.6622 56.5229 25.667 56.4973 25.6775 56.4738C25.688 56.4502 25.7039 56.4295 25.724 56.4132C25.7441 56.397 25.7678 56.3856 25.7931 56.3801C25.8185 56.3746 25.8448 56.3751 25.8699 56.3816C30.6101 57.5151 35.4693 58.0873 40.3455 58.086C41.5183 58.086 42.6876 58.086 43.8604 58.0553C48.7647 57.919 53.9339 57.6701 58.7591 56.7361C58.8794 56.7123 58.9998 56.6918 59.103 56.6611C66.7139 55.2124 73.9569 50.665 74.6929 39.1501C74.7204 38.6967 74.7892 34.4016 74.7892 33.9312C74.7926 32.3325 75.3085 22.5901 74.7135 16.6043ZM62.9996 45.3371H54.9966V25.9069C54.9966 21.8163 53.277 19.7302 49.7793 19.7302C45.9343 19.7302 44.0083 22.1981 44.0083 27.0727V37.7082H36.0534V27.0727C36.0534 22.1981 34.124 19.7302 30.279 19.7302C26.8019 19.7302 25.0651 21.8163 25.0617 25.9069V45.3371H17.0656V25.3172C17.0656 21.2266 18.1191 17.9769 20.2262 15.568C22.3998 13.1648 25.2509 11.9308 28.7898 11.9308C32.8859 11.9308 35.9812 13.492 38.0447 16.6111L40.036 19.9245L42.0308 16.6111C44.0943 13.492 47.1896 11.9308 51.2788 11.9308C54.8143 11.9308 57.6654 13.1648 59.8459 15.568C61.9529 17.9746 63.0065 21.2243 63.0065 25.3172L62.9996 45.3371Z" fill="currentColor"/></symbol><use xlink:href="#logo-symbol-icon"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="79" height="79" viewBox="0 0 79 75"><symbol id="logo-symbol-icon"><path d="M63 45.3v-20c0-4.1-1-7.3-3.2-9.7-2.1-2.4-5-3.7-8.5-3.7-4.1 0-7.2 1.6-9.3 4.7l-2 3.3-2-3.3c-2-3.1-5.1-4.7-9.2-4.7-3.5 0-6.4 1.3-8.6 3.7-2.1 2.4-3.1 5.6-3.1 9.7v20h8V25.9c0-4.1 1.7-6.2 5.2-6.2 3.8 0 5.8 2.5 5.8 7.4V37.7H44V27.1c0-4.9 1.9-7.4 5.8-7.4 3.5 0 5.2 2.1 5.2 6.2V45.3h8ZM74.7 16.6c.6 6 .1 15.7.1 17.3 0 .5-.1 4.8-.1 5.3-.7 11.5-8 16-15.6 17.5-.1 0-.2 0-.3 0-4.9 1-10 1.2-14.9 1.4-1.2 0-2.4 0-3.6 0-4.8 0-9.7-.6-14.4-1.7-.1 0-.1 0-.1 0s-.1 0-.1 0 0 .1 0 .1 0 0 0 0c.1 1.6.4 3.1 1 4.5.6 1.7 2.9 5.7 11.4 5.7 5 0 9.9-.6 14.8-1.7 0 0 0 0 0 0 .1 0 .1 0 .1 0 0 .1 0 .1 0 .1.1 0 .1 0 .1.1v5.6s0 .1-.1.1c0 0 0 0 0 .1-1.6 1.1-3.7 1.7-5.6 2.3-.8.3-1.6.5-2.4.7-7.5 1.7-15.4 1.3-22.7-1.2-6.8-2.4-13.8-8.2-15.5-15.2-.9-3.8-1.6-7.6-1.9-11.5-.6-5.8-.6-11.7-.8-17.5C3.9 24.5 4 20 4.9 16 6.7 7.9 14.1 2.2 22.3 1c1.4-.2 4.1-1 16.5-1h.1C51.4 0 56.7.8 58.1 1c8.4 1.2 15.5 7.5 16.6 15.6Z" fill="currentColor"/></symbol><use xlink:href="#logo-symbol-icon"/></svg>
|
||||
|
||||
|
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -412,14 +412,7 @@ class Status extends ImmutablePureComponent {
|
|||
|
||||
let visibilityName = status.get('limited_scope') || status.get('visibility_ex') || status.get('visibility');
|
||||
|
||||
if (featured) {
|
||||
prepend = (
|
||||
<div className='status__prepend'>
|
||||
<div className='status__prepend__icon'><Icon id='thumb-tack' icon={PushPinIcon} /></div>
|
||||
<FormattedMessage id='status.pinned' defaultMessage='Pinned post' />
|
||||
</div>
|
||||
);
|
||||
} else if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
||||
if (status.get('reblog', null) !== null && typeof status.get('reblog') === 'object') {
|
||||
const display_name_html = { __html: status.getIn(['account', 'display_name_html']) };
|
||||
|
||||
prepend = (
|
||||
|
|
|
@ -292,7 +292,7 @@
|
|||
"column.local": "Local",
|
||||
"column.mutes": "Muted users",
|
||||
"column.notifications": "Notifications",
|
||||
"column.pins": "Pinned posts",
|
||||
"column.pins": "Featured posts",
|
||||
"column.public": "Federated timeline",
|
||||
"column.reaction_deck": "Reaction deck",
|
||||
"column_back_button.label": "Back",
|
||||
|
@ -623,7 +623,7 @@
|
|||
"keyboard_shortcuts.my_profile": "Open your profile",
|
||||
"keyboard_shortcuts.notifications": "Open notifications column",
|
||||
"keyboard_shortcuts.open_media": "Open media",
|
||||
"keyboard_shortcuts.pinned": "Open pinned posts list",
|
||||
"keyboard_shortcuts.pinned": "Open featured posts list",
|
||||
"keyboard_shortcuts.profile": "Open author's profile",
|
||||
"keyboard_shortcuts.reply": "Reply to post",
|
||||
"keyboard_shortcuts.requests": "Open follow requests list",
|
||||
|
@ -718,7 +718,7 @@
|
|||
"navigation_bar.mutes": "Muted users",
|
||||
"navigation_bar.opened_in_classic_interface": "Posts, accounts, and other specific pages are opened by default in the classic web interface.",
|
||||
"navigation_bar.personal": "Personal",
|
||||
"navigation_bar.pins": "Pinned posts",
|
||||
"navigation_bar.pins": "Featured posts",
|
||||
"navigation_bar.preferences": "Preferences",
|
||||
"navigation_bar.public_timeline": "Federated timeline",
|
||||
"navigation_bar.reaction_deck": "Reaction deck",
|
||||
|
@ -1069,8 +1069,7 @@
|
|||
"status.mute": "Mute @{name}",
|
||||
"status.mute_conversation": "Mute conversation",
|
||||
"status.open": "Expand this post",
|
||||
"status.pin": "Pin on profile",
|
||||
"status.pinned": "Pinned post",
|
||||
"status.pin": "Feature on profile",
|
||||
"status.read_more": "Read more",
|
||||
"status.reblog": "Boost",
|
||||
"status.reblog_private": "Boost with original visibility",
|
||||
|
@ -1098,7 +1097,7 @@
|
|||
"status.translated_from_with": "Translated from {lang} using {provider}",
|
||||
"status.uncached_media_warning": "Preview not available",
|
||||
"status.unmute_conversation": "Unmute conversation",
|
||||
"status.unpin": "Unpin from profile",
|
||||
"status.unpin": "Don't feature on profile",
|
||||
"subscribed_languages.lead": "Only posts in selected languages will appear on your home and list timelines after the change. Select none to receive posts in all languages.",
|
||||
"subscribed_languages.save": "Save changes",
|
||||
"subscribed_languages.target": "Change subscribed languages for {target}",
|
||||
|
|
|
@ -19,13 +19,16 @@
|
|||
"account.block_domain": "Blokir domain {domain}",
|
||||
"account.block_short": "Blokir",
|
||||
"account.blocked": "Terblokir",
|
||||
"account.blocking": "Memblokir",
|
||||
"account.cancel_follow_request": "Batalkan permintaan ikut",
|
||||
"account.copy": "Salin tautan ke profil",
|
||||
"account.direct": "Sebut secara pribadi @{name}",
|
||||
"account.disable_notifications": "Berhenti memberitahu saya ketika @{name} memposting",
|
||||
"account.domain_blocking": "Memblokir domain",
|
||||
"account.edit_profile": "Ubah profil",
|
||||
"account.enable_notifications": "Beritahu saya saat @{name} memposting",
|
||||
"account.endorse": "Tampilkan di profil",
|
||||
"account.featured": "",
|
||||
"account.featured_tags.last_status_at": "Kiriman terakhir pada {date}",
|
||||
"account.featured_tags.last_status_never": "Tidak ada kiriman",
|
||||
"account.follow": "Ikuti",
|
||||
|
@ -36,6 +39,7 @@
|
|||
"account.following": "Mengikuti",
|
||||
"account.following_counter": "{count, plural, other {{counter} following}}",
|
||||
"account.follows.empty": "Pengguna ini belum mengikuti siapa pun.",
|
||||
"account.follows_you": "Mengikuti Anda",
|
||||
"account.go_to_profile": "Buka profil",
|
||||
"account.hide_reblogs": "Sembunyikan boosts dari @{name}",
|
||||
"account.in_memoriam": "Mengenang.",
|
||||
|
|
|
@ -19,10 +19,12 @@
|
|||
"account.block_domain": "{domain} 도메인 차단",
|
||||
"account.block_short": "차단",
|
||||
"account.blocked": "차단함",
|
||||
"account.blocking": "차단함",
|
||||
"account.cancel_follow_request": "팔로우 취소",
|
||||
"account.copy": "프로필 링크 복사",
|
||||
"account.direct": "@{name} 님에게 개인적으로 멘션",
|
||||
"account.disable_notifications": "@{name} 의 게시물 알림 끄기",
|
||||
"account.domain_blocking": "도메인 차단함",
|
||||
"account.edit_profile": "프로필 편집",
|
||||
"account.enable_notifications": "@{name} 의 게시물 알림 켜기",
|
||||
"account.endorse": "프로필에 추천하기",
|
||||
|
@ -39,6 +41,7 @@
|
|||
"account.following": "팔로잉",
|
||||
"account.following_counter": "{count, plural, other {팔로잉 {counter}명}}",
|
||||
"account.follows.empty": "이 사용자는 아직 아무도 팔로우하고 있지 않습니다.",
|
||||
"account.follows_you": "나를 팔로우",
|
||||
"account.go_to_profile": "프로필로 이동",
|
||||
"account.hide_reblogs": "@{name}의 부스트를 숨기기",
|
||||
"account.in_memoriam": "고인의 계정입니다.",
|
||||
|
@ -53,13 +56,17 @@
|
|||
"account.mute_notifications_short": "알림 뮤트",
|
||||
"account.mute_short": "뮤트",
|
||||
"account.muted": "뮤트됨",
|
||||
"account.muting": "뮤트함",
|
||||
"account.mutual": "서로 팔로우",
|
||||
"account.no_bio": "제공된 설명이 없습니다.",
|
||||
"account.open_original_page": "원본 페이지 열기",
|
||||
"account.posts": "게시물",
|
||||
"account.posts_with_replies": "게시물과 답장",
|
||||
"account.remove_from_followers": "팔로워에서 {name} 제거",
|
||||
"account.report": "@{name} 신고",
|
||||
"account.requested": "승인 대기 중. 클릭해서 취소하기",
|
||||
"account.requested_follow": "{name} 님이 팔로우 요청을 보냈습니다",
|
||||
"account.requests_to_follow_you": "팔로우 요청",
|
||||
"account.share": "@{name}의 프로필 공유",
|
||||
"account.show_reblogs": "@{name}의 부스트 보기",
|
||||
"account.statuses_counter": "{count, plural, other {게시물 {counter}개}}",
|
||||
|
@ -227,6 +234,9 @@
|
|||
"confirmations.redraft.confirm": "삭제하고 다시 쓰기",
|
||||
"confirmations.redraft.message": "정말로 이 게시물을 삭제하고 다시 쓰시겠습니까? 해당 게시물에 대한 부스트와 좋아요를 잃게 되고 원본에 대한 답장은 연결 되지 않습니다.",
|
||||
"confirmations.redraft.title": "삭제하고 다시 작성할까요?",
|
||||
"confirmations.remove_from_followers.confirm": "팔로워 제거",
|
||||
"confirmations.remove_from_followers.message": "{name} 님이 나를 팔로우하지 않게 됩니다. 계속할까요?",
|
||||
"confirmations.remove_from_followers.title": "팔로워를 제거할까요?",
|
||||
"confirmations.reply.confirm": "답글",
|
||||
"confirmations.reply.message": "지금 답장하면 작성 중인 메시지를 덮어쓰게 됩니다. 정말 진행합니까?",
|
||||
"confirmations.reply.title": "게시물을 덮어쓸까요?",
|
||||
|
@ -294,6 +304,9 @@
|
|||
"emoji_button.search_results": "검색 결과",
|
||||
"emoji_button.symbols": "기호",
|
||||
"emoji_button.travel": "여행과 장소",
|
||||
"empty_column.account_featured.me": "아직 아무 것도 추천하지 않았습니다. 게시물, 자주 사용하는 해시태그, 친구의 계정까지 내 계정에서 추천할 수 있다는 것을 알고 계신가요?",
|
||||
"empty_column.account_featured.other": "{acct} 님은 아직 아무 것도 추천하지 않았습니다. 게시물, 자주 사용하는 해시태그, 친구의 계정까지 내 계정에서 추천할 수 있다는 것을 알고 계신가요?",
|
||||
"empty_column.account_featured_other.unknown": "이 계정은 아직 아무 것도 추천하지 않았습니다.",
|
||||
"empty_column.account_hides_collections": "이 사용자는 이 정보를 사용할 수 없도록 설정했습니다",
|
||||
"empty_column.account_suspended": "계정 정지됨",
|
||||
"empty_column.account_timeline": "이곳에는 게시물이 없습니다!",
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
"about.domain_blocks.preamble": "Mastodon parasti ļauj apskatīt saturu un mijiedarboties ar lietotājiem no jebkura cita fediversa servera. Šie ir izņēmumi, kas veikti tieši šajā serverī.",
|
||||
"about.domain_blocks.silenced.explanation": "Parasti tu neredzēsi profilus un saturu no šī servera, ja vien tu nepārprotami izvēlēsies to pārskatīt vai sekot.",
|
||||
"about.domain_blocks.silenced.title": "Ierobežotie",
|
||||
"about.domain_blocks.suspended.explanation": "Nekādi dati no šī servera netiks apstrādāti, uzglabāti vai apmainīti, padarot neiespējamu mijiedarbību vai saziņu ar lietotājiem no šī servera.",
|
||||
"about.domain_blocks.suspended.explanation": "Nekādi dati no šī servera netiks apstrādāti, uzglabāti vai apmainīti, padarot neiespējamu jebkādu mijiedarbību vai saziņu ar šī servera lietotājiem.",
|
||||
"about.domain_blocks.suspended.title": "Apturētie",
|
||||
"about.not_available": "Šī informācija nav padarīta pieejama šajā serverī.",
|
||||
"about.powered_by": "Decentralizētu sociālo tīklu nodrošina {mastodon}",
|
||||
"about.powered_by": "Decentralizētu sabiedrisko tīklu darbina {mastodon}",
|
||||
"about.rules": "Servera noteikumi",
|
||||
"account.account_note_header": "Personīga piezīme",
|
||||
"account.add_or_remove_from_list": "Pievienot vai Noņemt no sarakstiem",
|
||||
|
@ -22,12 +22,14 @@
|
|||
"account.cancel_follow_request": "Atsaukt sekošanas pieprasījumu",
|
||||
"account.copy": "Ievietot saiti uz profilu starpliktuvē",
|
||||
"account.direct": "Pieminēt @{name} privāti",
|
||||
"account.disable_notifications": "Pārtraukt man paziņot, kad @{name} publicē ierakstu",
|
||||
"account.disable_notifications": "Pārtraukt man paziņot, kad @{name} izveido ierakstu",
|
||||
"account.edit_profile": "Labot profilu",
|
||||
"account.enable_notifications": "Paziņot man, kad @{name} publicē ierakstu",
|
||||
"account.enable_notifications": "Paziņot man, kad @{name} izveido ierakstu",
|
||||
"account.endorse": "Izcelts profilā",
|
||||
"account.featured_tags.last_status_at": "Beidzamā ziņa {date}",
|
||||
"account.featured_tags.last_status_never": "Ierakstu nav",
|
||||
"account.featured.hashtags": "Tēmturi",
|
||||
"account.featured.posts": "Ieraksti",
|
||||
"account.featured_tags.last_status_at": "Pēdējais ieraksts {date}",
|
||||
"account.featured_tags.last_status_never": "Nav ierakstu",
|
||||
"account.follow": "Sekot",
|
||||
"account.follow_back": "Sekot atpakaļ",
|
||||
"account.followers": "Sekotāji",
|
||||
|
@ -36,6 +38,7 @@
|
|||
"account.following": "Seko",
|
||||
"account.following_counter": "{count, plural, one {seko {counter}} other {seko {counter}}}",
|
||||
"account.follows.empty": "Šis lietotājs pagaidām nevienam neseko.",
|
||||
"account.follows_you": "Seko tev",
|
||||
"account.go_to_profile": "Doties uz profilu",
|
||||
"account.hide_reblogs": "Paslēpt @{name} pastiprinātos ierakstus",
|
||||
"account.in_memoriam": "Piemiņai.",
|
||||
|
@ -47,17 +50,19 @@
|
|||
"account.mention": "Pieminēt @{name}",
|
||||
"account.moved_to": "{name} norādīja, ka viņu jaunais konts tagad ir:",
|
||||
"account.mute": "Apklusināt @{name}",
|
||||
"account.mute_notifications_short": "Izslēgt paziņojumu skaņu",
|
||||
"account.mute_notifications_short": "Apklusināt paziņojumus",
|
||||
"account.mute_short": "Apklusināt",
|
||||
"account.muted": "Apklusināts",
|
||||
"account.mutual": "Jūs sekojat viens otram",
|
||||
"account.no_bio": "Apraksts nav sniegts.",
|
||||
"account.open_original_page": "Atvērt pirmavota lapu",
|
||||
"account.posts": "Ieraksti",
|
||||
"account.posts_with_replies": "Ieraksti un atbildes",
|
||||
"account.remove_from_followers": "Dzēst sekotāju {name}",
|
||||
"account.report": "Sūdzēties par @{name}",
|
||||
"account.report": "Ziņot par @{name}",
|
||||
"account.requested": "Gaida apstiprinājumu. Nospied, lai atceltu sekošanas pieparasījumu",
|
||||
"account.requested_follow": "{name} nosūtīja Tev sekošanas pieprasījumu",
|
||||
"account.requests_to_follow_you": "Sekošanas pieprasījumi",
|
||||
"account.share": "Dalīties ar @{name} profilu",
|
||||
"account.show_reblogs": "Parādīt @{name} pastiprinātos ierakstus",
|
||||
"account.statuses_counter": "{count, plural, zero {{counter} ierakstu} one {{counter} ieraksts} other {{counter} ieraksti}}",
|
||||
|
@ -67,7 +72,7 @@
|
|||
"account.unendorse": "Neizcelt profilā",
|
||||
"account.unfollow": "Pārstāt sekot",
|
||||
"account.unmute": "Noņemt apklusinājumu @{name}",
|
||||
"account.unmute_notifications_short": "Ieslēgt paziņojumu skaņu",
|
||||
"account.unmute_notifications_short": "Atcelet paziņojumu apklusināšanu",
|
||||
"account.unmute_short": "Noņemt apklusinājumu",
|
||||
"account_note.placeholder": "Noklikšķini, lai pievienotu piezīmi",
|
||||
"admin.dashboard.daily_retention": "Lietotāju saglabāšanas rādītājs dienā pēc reģistrēšanās",
|
||||
|
@ -91,12 +96,13 @@
|
|||
"alt_text_modal.describe_for_people_with_visual_impairments": "Aprakstīt šo cilvēkiem ar redzes traucējumiem…",
|
||||
"alt_text_modal.done": "Gatavs",
|
||||
"announcement.announcement": "Paziņojums",
|
||||
"annual_report.summary.archetype.lurker": "Glūņa",
|
||||
"annual_report.summary.archetype.oracle": "Orākuls",
|
||||
"annual_report.summary.archetype.replier": "Sabiedriskais tauriņš",
|
||||
"annual_report.summary.followers.followers": "sekotāji",
|
||||
"annual_report.summary.followers.total": "pavisam {count}",
|
||||
"annual_report.summary.here_it_is": "Šeit ir {year}. gada pārskats:",
|
||||
"annual_report.summary.highlighted_post.by_favourites": "izlasēs visvairāk ievietotais ieraksts",
|
||||
"annual_report.summary.highlighted_post.by_favourites": "izlasēm visvairāk pievienotais ieraksts",
|
||||
"annual_report.summary.highlighted_post.by_reblogs": "vispastiprinātākais ieraksts",
|
||||
"annual_report.summary.highlighted_post.by_replies": "ieraksts ar vislielāko atbilžu skaitu",
|
||||
"annual_report.summary.highlighted_post.possessive": "{name}",
|
||||
|
@ -109,16 +115,17 @@
|
|||
"annual_report.summary.thanks": "Paldies, ka esi daļa no Mastodon!",
|
||||
"attachments_list.unprocessed": "(neapstrādāti)",
|
||||
"audio.hide": "Slēpt audio",
|
||||
"block_modal.remote_users_caveat": "Mēs vaicāsim serverim {domain} ņemt vērā Tavu lēmumu. Tomēr atbilstība nav nodrošināta, jo atsevišķi serveri var apstrādāt bloķēšanu citādi. Publiski ieraksti joprojām var būt redzami lietotājiem, kuri nav pieteikušies.",
|
||||
"block_modal.remote_users_caveat": "Mēs vaicāsim serverim {domain} ņemt vērā Tavu lēmumu. Tomēr atbilstība nav nodrošināta, jo atsevišķi serveri liegšanu var apstrādāt citādi. Publiski ieraksti joprojām var būt redzami lietotājiem, kuri nav pieteikušies.",
|
||||
"block_modal.show_less": "Rādīt mazāk",
|
||||
"block_modal.show_more": "Parādīt mazāk",
|
||||
"block_modal.they_cant_mention": "Nevar Tevi pieminēt vai sekot Tev.",
|
||||
"block_modal.they_cant_see_posts": "Nevar redzēt Tavus ierakstus, un Tu neredzēsi lietotāja.",
|
||||
"block_modal.they_cant_see_posts": "Lietotajs nevarēs redzēt Tavus ierakstus, un Tu neredzēsi lietotāja.",
|
||||
"block_modal.title": "Bloķēt lietotāju?",
|
||||
"block_modal.you_wont_see_mentions": "Tu neredzēsi ierakstus, kuros ir minēts šis lietotājs.",
|
||||
"boost_modal.combo": "Nospied {combo}, lai nākamreiz šo izlaistu",
|
||||
"boost_modal.reblog": "Pastiprināt ierakstu?",
|
||||
"boost_modal.undo_reblog": "Atcelt ieraksta pastiprināšanu?",
|
||||
"bundle_column_error.copy_stacktrace": "Kopēt kļūdu ziņojumu",
|
||||
"bundle_column_error.copy_stacktrace": "Ievietot kļūdu ziņojumu starpliktuvē",
|
||||
"bundle_column_error.error.body": "Pieprasīto lapu nevarēja atveidot. Tas varētu būt saistīts ar kļūdu mūsu kodā, vai tā ir pārlūkprogrammas saderības problēma.",
|
||||
"bundle_column_error.error.title": "Ak vai!",
|
||||
"bundle_column_error.network.body": "Mēģinot ielādēt šo lapu, radās kļūda. Tas varētu būt saistīts ar īslaicīgu interneta savienojuma vai šī servera problēmu.",
|
||||
|
@ -167,9 +174,9 @@
|
|||
"community.column_settings.remote_only": "Tikai attālinātie",
|
||||
"compose.language.change": "Mainīt valodu",
|
||||
"compose.language.search": "Meklēt valodas...",
|
||||
"compose.published.body": "Ieraksts izveidots.",
|
||||
"compose.published.body": "Ieraksts pievienots.",
|
||||
"compose.published.open": "Atvērt",
|
||||
"compose.saved.body": "Ziņa saglabāta.",
|
||||
"compose.saved.body": "Ieraksts saglabāts.",
|
||||
"compose_form.direct_message_warning_learn_more": "Uzzināt vairāk",
|
||||
"compose_form.encryption_warning": "Mastodon ieraksti nav pilnībā šifrēti. Nedalies ar jebkādu jūtīgu informāciju caur Mastodon!",
|
||||
"compose_form.hashtag_warning": "Šis ieraksts netiks uzrādīts nevienā tēmturī, jo tas nav redzams visiem. Tikai visiem redzamos ierakstus var meklēt pēc tēmtura.",
|
||||
|
@ -193,7 +200,7 @@
|
|||
"confirmation_modal.cancel": "Atcelt",
|
||||
"confirmations.block.confirm": "Bloķēt",
|
||||
"confirmations.delete.confirm": "Dzēst",
|
||||
"confirmations.delete.message": "Vai tiešām vēlies dzēst šo ierakstu?",
|
||||
"confirmations.delete.message": "Vai tiešām izdzēst šo ierakstu?",
|
||||
"confirmations.delete.title": "Izdzēst ierakstu?",
|
||||
"confirmations.delete_list.confirm": "Dzēst",
|
||||
"confirmations.delete_list.message": "Vai tiešām neatgriezeniski izdzēst šo sarakstu?",
|
||||
|
@ -206,14 +213,15 @@
|
|||
"confirmations.follow_to_list.confirm": "Sekot un pievienot sarakstam",
|
||||
"confirmations.follow_to_list.message": "Ir jāseko {name}, lai pievienotu sarakstam.",
|
||||
"confirmations.follow_to_list.title": "Sekot lietotājam?",
|
||||
"confirmations.logout.confirm": "Iziet",
|
||||
"confirmations.logout.message": "Vai tiešām vēlies izrakstīties?",
|
||||
"confirmations.logout.confirm": "Atteikties",
|
||||
"confirmations.logout.message": "Vai tiešām atteikties?",
|
||||
"confirmations.logout.title": "Atteikties?",
|
||||
"confirmations.missing_alt_text.message": "Tavs ieraksts satur informācijas nesējus bez paskaidrojošā teksta. Aprakstu pievienošana palīdz padarīt saturu pieejamāku vairāk cilvēku.",
|
||||
"confirmations.missing_alt_text.secondary": "Vienalga iesūtīt",
|
||||
"confirmations.mute.confirm": "Apklusināt",
|
||||
"confirmations.redraft.confirm": "Dzēst un pārrakstīt",
|
||||
"confirmations.redraft.message": "Vai tiešām vēlies izdzēst šo ierakstu un veidot jaunu tā uzmetumu? Pievienošana izlasēs un pastiprinājumi tiks zaudēti, un sākotnējā ieraksta atbildes paliks bez saiknes ar to.",
|
||||
"confirmations.redraft.title": "Dzēst un rakstīt vēlreiz?",
|
||||
"confirmations.redraft.title": "Izdzēst un rakstīt ierakstu no jauna?",
|
||||
"confirmations.remove_from_followers.confirm": "Dzēst sekotāju",
|
||||
"confirmations.remove_from_followers.message": "{name} pārstās sekot jums. Vai tiešām vēlaties turpināt?",
|
||||
"confirmations.remove_from_followers.title": "Vai dzēst sekotāju?",
|
||||
|
@ -241,14 +249,23 @@
|
|||
"disabled_account_banner.text": "Tavs konts {disabledAccount} pašlaik ir atspējots.",
|
||||
"dismissable_banner.community_timeline": "Šie ir jaunākie publiskie ieraksti no cilvēkiem, kuru konti ir mitināti {domain}.",
|
||||
"dismissable_banner.dismiss": "Atcelt",
|
||||
"dismissable_banner.explore_links": "Šie jaunumi šodien Fediversā tiek visvairāk kopīgoti. Jaunākas ziņas, kuras pievienoši vairāki dažādi cilvēki, tiek novietotas augstāk.",
|
||||
"dismissable_banner.public_timeline": "Šie ir jaunākie Fediverse lietotāju publiskie ieraksti, kuriem {domain} seko cilvēki.",
|
||||
"domain_block_modal.block": "Bloķēt serveri",
|
||||
"domain_block_modal.block_account_instead": "Tā vietā liegt @{name}",
|
||||
"domain_block_modal.they_cant_follow": "Neviens šajā serverī nevar Tev sekot.",
|
||||
"domain_block_modal.they_wont_know": "Viņi nezinās, ka tikuši bloķēti.",
|
||||
"domain_block_modal.title": "Bloķēt domēnu?",
|
||||
"domain_pill.activitypub_lets_connect": "Tas ļauj savienoties un mijiedarboties ar cilvēkiem ne tikai no Mastodon, bet arī starp dažādām sabiedriskajām lietotnēm.",
|
||||
"domain_pill.activitypub_like_language": "ActivityPub ir kā valoda, kurā Mastodon sazināš ar citiem sabiedriskajiem tīkliem.",
|
||||
"domain_pill.server": "Serveris",
|
||||
"domain_pill.their_handle": "Turis:",
|
||||
"domain_pill.username": "Lietotājvārds",
|
||||
"embed.instructions": "Iestrādā šo ziņu savā mājaslapā, kopējot zemāk redzamo kodu.",
|
||||
"domain_pill.whats_in_a_handle": "Kas ir turī?",
|
||||
"domain_pill.who_they_are": "Tā kā turi norāda, kas kāds ir un kur viņi ir atrodami, Tu vari mijiedarboties ar cilvēkiem viscaur sabiedriskajā tīklā no <button>ar ActivityPub darbinātām platformām</button>.",
|
||||
"domain_pill.who_you_are": "Tā kā Tavs turis norāda, kas Tu esi un kur atrodies, cilvēki var mijiedarboties ar Tevi viscaur sabiedriskajā tīklā no <button>ar ActivityPub darbinātām platformām</button>.",
|
||||
"domain_pill.your_handle": "Tavs turis:",
|
||||
"embed.instructions": "Iekļauj šo ierakstu savā tīmekļvietnē, ievietojot zemāk redzamo kodu starpliktuvē!",
|
||||
"embed.preview": "Tas izskatīsies šādi:",
|
||||
"emoji_button.activity": "Aktivitāte",
|
||||
"emoji_button.clear": "Notīrīt",
|
||||
|
@ -267,20 +284,20 @@
|
|||
"emoji_button.travel": "Ceļošana un vietas",
|
||||
"empty_column.account_hides_collections": "Šis lietotājs ir izvēlējies nedarīt šo informāciju pieejamu",
|
||||
"empty_column.account_suspended": "Konta darbība ir apturēta",
|
||||
"empty_column.account_timeline": "Šeit ziņojumu nav!",
|
||||
"empty_column.account_timeline": "Šeit nav ierakstu.",
|
||||
"empty_column.account_unavailable": "Profils nav pieejams",
|
||||
"empty_column.blocks": "Pašreiz tu neesi nevienu bloķējis.",
|
||||
"empty_column.bookmarked_statuses": "Pašlaik Tev nav neviena grāmatzīmēs pievienota ieraksta. Kad tādu pievienosi, tas parādīsies šeit.",
|
||||
"empty_column.community": "Vietējā laika līnija ir tukša. Uzraksti kaut ko publiski, lai viss notiktu!",
|
||||
"empty_column.community": "Vietējā laika līnija ir tukša. Uzraksti kaut ko publiski, lai iekustinātu visu!",
|
||||
"empty_column.direct": "Tev vēl nav privātu pieminēšanu. Kad Tu nosūtīsi vai saņemsi kādu, tā pārādīsies šeit.",
|
||||
"empty_column.domain_blocks": "Vēl nav neviena bloķēta domēna.",
|
||||
"empty_column.explore_statuses": "Pašlaik nav nekā aktuāla. Ieskaties šeit vēlāk!",
|
||||
"empty_column.favourited_statuses": "Tev vēl nav iecienītāko ierakstu. Kad pievienosi kādu izlasei, tas tiks parādīts šeit.",
|
||||
"empty_column.favourites": "Šo ziņu neviens vēl nav pievienojis izlasei. Kad kāds to izdarīs, tas parādīsies šeit.",
|
||||
"empty_column.favourited_statuses": "Tev vēl nav izlasei pievienotu ierakstu. Kad pievienosi kādu, tas tiks parādīts šeit.",
|
||||
"empty_column.favourites": "Šo ierakstu vēl neviens nav pievienojis izlasei. Kad kāds to izdarīs, šeit parādīsies ieraksti.",
|
||||
"empty_column.follow_requests": "Šobrīd Tev nav sekošanas pieprasījumu. Kad saņemsi kādu, tas parādīsies šeit.",
|
||||
"empty_column.followed_tags": "Tu vēl neseko nevienam tēmturim. Kad to izdarīsi, tie tiks parādīti šeit.",
|
||||
"empty_column.hashtag": "Ar šo tēmturi nekas nav atrodams.",
|
||||
"empty_column.home": "Tava mājas laikjosla ir tukša. Seko vairāk cilvēkiem, lai to piepildītu!",
|
||||
"empty_column.home": "Tava mājas laika līnija ir tukša. Seko vairāk cilvēkiem, lai to piepildītu!",
|
||||
"empty_column.list": "Pagaidām šajā sarakstā nekā nav. Kad šī saraksta dalībnieki ievietos jaunus ierakstus, tie parādīsies šeit.",
|
||||
"empty_column.mutes": "Neviens lietotājs vēl nav apklusināts.",
|
||||
"empty_column.notifications": "Tev vēl nav paziņojumu. Kad citi cilvēki ar Tevi mijiedarbosies, Tu to redzēsi šeit.",
|
||||
|
@ -303,15 +320,15 @@
|
|||
"filter_modal.added.review_and_configure": "Lai pārskatītu un tālāk konfigurētu šo filtru kategoriju, dodies uz {settings_link}.",
|
||||
"filter_modal.added.review_and_configure_title": "Filtra iestatījumi",
|
||||
"filter_modal.added.settings_link": "iestatījumu lapu",
|
||||
"filter_modal.added.short_explanation": "Šī ziņa ir pievienota šai filtra kategorijai: {title}.",
|
||||
"filter_modal.added.short_explanation": "Šis ieraksts tika pievienots šai atlasīšanas kategorijai: {title}.",
|
||||
"filter_modal.added.title": "Filtrs pievienots!",
|
||||
"filter_modal.select_filter.context_mismatch": "neattiecas uz šo kontekstu",
|
||||
"filter_modal.select_filter.expired": "beidzies",
|
||||
"filter_modal.select_filter.prompt_new": "Jauna kategorija: {name}",
|
||||
"filter_modal.select_filter.search": "Meklēt vai izveidot",
|
||||
"filter_modal.select_filter.subtitle": "Izmanto esošu kategoriju vai izveido jaunu",
|
||||
"filter_modal.select_filter.title": "Filtrēt šo ziņu",
|
||||
"filter_modal.title.status": "Filtrēt ziņu",
|
||||
"filter_modal.select_filter.title": "Atlasīt šo ierakstu",
|
||||
"filter_modal.title.status": "Atlasīt ziņu",
|
||||
"filtered_notifications_banner.title": "Filtrētie paziņojumi",
|
||||
"firehose.all": "Visi",
|
||||
"firehose.local": "Šis serveris",
|
||||
|
@ -368,12 +385,21 @@
|
|||
"home.pending_critical_update.title": "Ir pieejams būtisks drošības atjauninājums.",
|
||||
"home.show_announcements": "Rādīt paziņojumus",
|
||||
"ignore_notifications_modal.ignore": "Neņemt vērā paziņojumus",
|
||||
"ignore_notifications_modal.not_following_title": "Neņemt vērā paziņojumus no cilvēkiem, kuriem neseko?",
|
||||
"interaction_modal.action.favourite": "Lai turpinātu, nepieciešams pievienot sava konta izlasei.",
|
||||
"interaction_modal.action.follow": "Lai turpinātu, nepieciešams sekot no sava konta.",
|
||||
"interaction_modal.action.reblog": "Lai turpinātu, nepieciešams pastiprināt no sava konta.",
|
||||
"interaction_modal.action.reply": "Lai turpinātu, nepieciešams atbildēt no sava konta.",
|
||||
"interaction_modal.action.vote": "Lai turpinātu, nepieciešams balsot no sava konta.",
|
||||
"interaction_modal.go": "Aiziet",
|
||||
"interaction_modal.no_account_yet": "Vēl nav konta?",
|
||||
"interaction_modal.on_another_server": "Citā serverī",
|
||||
"interaction_modal.on_this_server": "Šajā serverī",
|
||||
"interaction_modal.title.favourite": "Pievienot {name} ziņu izlasei",
|
||||
"interaction_modal.title.favourite": "Pievienot {name} ierakstu izlasei",
|
||||
"interaction_modal.title.follow": "Sekot {name}",
|
||||
"interaction_modal.title.reblog": "Pastiprināt {name} ierakstu",
|
||||
"interaction_modal.title.reply": "Atbildēt uz {name} ziņu",
|
||||
"interaction_modal.title.reply": "Atbildēt uz {name} ierakstu",
|
||||
"interaction_modal.username_prompt": "Piem., {example}",
|
||||
"intervals.full.days": "{number, plural, one {# diena} other {# dienas}}",
|
||||
"intervals.full.hours": "{number, plural, one {# stunda} other {# stundas}}",
|
||||
"intervals.full.minutes": "{number, plural, one {# minūte} other {# minūtes}}",
|
||||
|
@ -385,8 +411,8 @@
|
|||
"keyboard_shortcuts.description": "Apraksts",
|
||||
"keyboard_shortcuts.direct": "lai atvērtu privāto pieminējumu sleju",
|
||||
"keyboard_shortcuts.down": "Pārvietoties lejup sarakstā",
|
||||
"keyboard_shortcuts.enter": "Atvērt ziņu",
|
||||
"keyboard_shortcuts.favourite": "Pievienot izlasei",
|
||||
"keyboard_shortcuts.enter": "Atvērt ierakstu",
|
||||
"keyboard_shortcuts.favourite": "Pievienot ierakstu izlasei",
|
||||
"keyboard_shortcuts.favourites": "Atvērt izlašu sarakstu",
|
||||
"keyboard_shortcuts.federated": "Atvērt apvienoto laika līniju",
|
||||
"keyboard_shortcuts.heading": "Īsinājumtaustiņi",
|
||||
|
@ -399,7 +425,7 @@
|
|||
"keyboard_shortcuts.my_profile": "Atvērt savu profilu",
|
||||
"keyboard_shortcuts.notifications": "Atvērt paziņojumu kolonnu",
|
||||
"keyboard_shortcuts.open_media": "Atvērt multividi",
|
||||
"keyboard_shortcuts.pinned": "Atvērt piesprausto ziņu sarakstu",
|
||||
"keyboard_shortcuts.pinned": "Atvērt piesprausto ierakstu sarakstu",
|
||||
"keyboard_shortcuts.profile": "Atvērt autora profilu",
|
||||
"keyboard_shortcuts.reply": "Atbildēt",
|
||||
"keyboard_shortcuts.requests": "Atvērt sekošanas pieprasījumu sarakstu",
|
||||
|
@ -408,7 +434,7 @@
|
|||
"keyboard_shortcuts.start": "Atvērt kolonnu “Darba sākšana”",
|
||||
"keyboard_shortcuts.toggle_hidden": "Rādīt/slēpt tekstu aiz satura brīdinājuma",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "Rādīt/slēpt multividi",
|
||||
"keyboard_shortcuts.toot": "Sākt jaunu ziņu",
|
||||
"keyboard_shortcuts.toot": "Uzsākt jaunu ierakstu",
|
||||
"keyboard_shortcuts.unfocus": "Atfokusēt veidojamā teksta/meklēšanas lauku",
|
||||
"keyboard_shortcuts.up": "Pārvietoties augšup sarakstā",
|
||||
"lightbox.close": "Aizvērt",
|
||||
|
@ -444,7 +470,7 @@
|
|||
"navigation_bar.blocks": "Bloķētie lietotāji",
|
||||
"navigation_bar.bookmarks": "Grāmatzīmes",
|
||||
"navigation_bar.community_timeline": "Vietējā laika līnija",
|
||||
"navigation_bar.compose": "Veidot jaunu ziņu",
|
||||
"navigation_bar.compose": "Izveidot jaunu ierakstu",
|
||||
"navigation_bar.direct": "Privātas pieminēšanas",
|
||||
"navigation_bar.discover": "Atklāt",
|
||||
"navigation_bar.domain_blocks": "Bloķētie domēni",
|
||||
|
@ -460,15 +486,17 @@
|
|||
"navigation_bar.mutes": "Apklusinātie lietotāji",
|
||||
"navigation_bar.opened_in_classic_interface": "Ieraksti, konti un citas noteiktas lapas pēc noklusējuma tiek atvērtas klasiskajā tīmekļa saskarnē.",
|
||||
"navigation_bar.personal": "Personīgie",
|
||||
"navigation_bar.pins": "Piespraustās ziņas",
|
||||
"navigation_bar.pins": "Piespraustie ieraksti",
|
||||
"navigation_bar.preferences": "Iestatījumi",
|
||||
"navigation_bar.public_timeline": "Apvienotā laika līnija",
|
||||
"navigation_bar.search": "Meklēt",
|
||||
"navigation_bar.security": "Drošība",
|
||||
"not_signed_in_indicator.not_signed_in": "Ir jāpiesakās, lai piekļūtu šim resursam.",
|
||||
"notification.admin.report": "{name} ziņoja par {target}",
|
||||
"notification.admin.report_account": "{name} ziņoja par {count, plural, one {# ierakstu} other {# ierakstiem}} no {target} ar iemeslu: {category}",
|
||||
"notification.admin.report_statuses": "{name} ziņoja par {target} ar iemeslu: {category}",
|
||||
"notification.admin.sign_up": "{name} pierakstījās",
|
||||
"notification.favourite": "{name} pievienoja tavu ziņu izlasei",
|
||||
"notification.favourite": "{name} pievienoja izlasei Tavu ierakstu",
|
||||
"notification.follow": "{name} uzsāka Tev sekot",
|
||||
"notification.follow_request": "{name} nosūtīja Tev sekošanas pieprasījumu",
|
||||
"notification.moderation-warning.learn_more": "Uzzināt vairāk",
|
||||
|
@ -484,7 +512,7 @@
|
|||
"notification.reblog": "{name} pastiprināja Tavu ierakstu",
|
||||
"notification.relationships_severance_event": "Zaudēti savienojumi ar {name}",
|
||||
"notification.relationships_severance_event.learn_more": "Uzzināt vairāk",
|
||||
"notification.status": "{name} tikko publicēja",
|
||||
"notification.status": "{name} tikko pievienoja ierakstu",
|
||||
"notification.update": "{name} laboja ierakstu",
|
||||
"notification_requests.accept": "Pieņemt",
|
||||
"notification_requests.dismiss": "Noraidīt",
|
||||
|
@ -586,15 +614,15 @@
|
|||
"reply_indicator.cancel": "Atcelt",
|
||||
"reply_indicator.poll": "Aptauja",
|
||||
"report.block": "Bloķēt",
|
||||
"report.block_explanation": "Tu neredzēsi viņu ierakstus. Viņi nevarēs redzēt Tavus ierakstus vai sekot tev. Viņi varēs saprast, ka ir bloķēti.",
|
||||
"report.block_explanation": "Tu neredzēsi viņu ierakstus. Viņi nevarēs redzēt Tavus ierakstus vai sekot tev. Viņi varēs saprast, ka ir liegti.",
|
||||
"report.categories.legal": "Tiesisks",
|
||||
"report.categories.other": "Citi",
|
||||
"report.categories.spam": "Spams",
|
||||
"report.categories.spam": "Mēstule",
|
||||
"report.categories.violation": "Saturs pārkāpj vienu vai vairākus servera noteikumus",
|
||||
"report.category.subtitle": "Izvēlieties labāko atbilstību",
|
||||
"report.category.title": "Pastāsti mums, kas notiek ar šo {type}",
|
||||
"report.category.title_account": "profilu",
|
||||
"report.category.title_status": "ziņu",
|
||||
"report.category.title_status": "ierakstu",
|
||||
"report.close": "Darīts",
|
||||
"report.comment.title": "Vai, tavuprāt, mums vēl būtu kas jāzina?",
|
||||
"report.forward": "Pārsūtīt {target}",
|
||||
|
@ -609,7 +637,7 @@
|
|||
"report.reasons.legal_description": "Tu uzskati, ka tas pārkāpj tavus vai servera valsts likumus",
|
||||
"report.reasons.other": "Tas ir kaut kas cits",
|
||||
"report.reasons.other_description": "Šī sūdzība neatbilst pārējām kategorijām",
|
||||
"report.reasons.spam": "Tas ir spams",
|
||||
"report.reasons.spam": "Tā ir mēstule",
|
||||
"report.reasons.spam_description": "Ļaunprātīgas saites, viltus iesaistīšana vai atkārtotas atbildes",
|
||||
"report.reasons.violation": "Tas pārkāpj servera noteikumus",
|
||||
"report.reasons.violation_description": "Tu zini, ka tas pārkāpj īpašus noteikumus",
|
||||
|
@ -621,15 +649,19 @@
|
|||
"report.target": "Ziņošana par: {target}",
|
||||
"report.thanks.take_action": "Šeit ir iespējas, lai pārvaldītu Mastodon redzamo saturu:",
|
||||
"report.thanks.take_action_actionable": "Kamēr mēs to izskatām, tu vari veikt darbības pret @{name}:",
|
||||
"report.thanks.title": "Vai nevēlies to redzēt?",
|
||||
"report.thanks.title": "Nevēlies to redzēt?",
|
||||
"report.thanks.title_actionable": "Paldies, ka ziņoji, mēs to izskatīsim.",
|
||||
"report.unfollow": "Pārtraukt sekot @{name}",
|
||||
"report.unfollow_explanation": "Tu seko šim kontam. Lai vairs neredzētu tā ierakstus savā mājas plūsmā, pārtrauc sekot tam!",
|
||||
"report_notification.attached_statuses": "Pievienoti {count, plural,one {{count} sūtījums} other {{count} sūtījumi}}",
|
||||
"report_notification.attached_statuses": "{count, plural, zero {Pievienoti {count} ierakstu} one {Pievienots {count} ieraksts} other {Pievienoti {count} ieraksti}}",
|
||||
"report_notification.categories.legal": "Tiesisks",
|
||||
"report_notification.categories.legal_sentence": "nelikumīgs saturs",
|
||||
"report_notification.categories.other": "Cita",
|
||||
"report_notification.categories.spam": "Spams",
|
||||
"report_notification.categories.other_sentence": "cits",
|
||||
"report_notification.categories.spam": "Mēstule",
|
||||
"report_notification.categories.spam_sentence": "mēstule",
|
||||
"report_notification.categories.violation": "Noteikumu pārkāpums",
|
||||
"report_notification.categories.violation_sentence": "noteikumu pārkāpums",
|
||||
"report_notification.open": "Atvērt ziņojumu",
|
||||
"search.no_recent_searches": "Nav nesen veiktu meklējumu",
|
||||
"search.placeholder": "Meklēšana",
|
||||
|
@ -657,6 +689,7 @@
|
|||
"server_banner.administered_by": "Pārvalda:",
|
||||
"server_banner.server_stats": "Servera statistika:",
|
||||
"sign_in_banner.create_account": "Izveidot kontu",
|
||||
"sign_in_banner.follow_anyone": "Seko ikvienam Fediversā un redzi visu pievienošanas secībā! Nekādu algoritmu, reklāmu vai klikšķēsmu.",
|
||||
"sign_in_banner.sign_in": "Pieteikties",
|
||||
"sign_in_banner.sso_redirect": "Piesakies vai Reģistrējies",
|
||||
"status.admin_account": "Atvērt @{name} satura pārraudzības saskarni",
|
||||
|
@ -665,7 +698,7 @@
|
|||
"status.block": "Bloķēt @{name}",
|
||||
"status.bookmark": "Grāmatzīme",
|
||||
"status.cancel_reblog_private": "Nepastiprināt",
|
||||
"status.cannot_reblog": "Šo ziņu nevar izcelt",
|
||||
"status.cannot_reblog": "Šo ierakstu nevar pastiprināt",
|
||||
"status.continued_thread": "Turpināts pavediens",
|
||||
"status.copy": "Ievietot ieraksta saiti starpliktuvē",
|
||||
"status.delete": "Dzēst",
|
||||
|
@ -676,8 +709,8 @@
|
|||
"status.edited": "Pēdējoreiz labots {date}",
|
||||
"status.edited_x_times": "Labots {count, plural, zero {{count} reižu} one {{count} reizi} other {{count} reizes}}",
|
||||
"status.favourite": "Izlasē",
|
||||
"status.favourites": "{count, plural, zero {izlasēs} one {izlasē} other {izlasēs}}",
|
||||
"status.filter": "Filtrē šo ziņu",
|
||||
"status.favourites": "{count, plural, one {izlasē} other {izlasēs}}",
|
||||
"status.filter": "Atlasīt šo ierakstu",
|
||||
"status.history.created": "{name} izveidoja {date}",
|
||||
"status.history.edited": "{name} laboja {date}",
|
||||
"status.load_more": "Ielādēt vairāk",
|
||||
|
@ -688,7 +721,7 @@
|
|||
"status.more": "Vairāk",
|
||||
"status.mute": "Apklusināt @{name}",
|
||||
"status.mute_conversation": "Apklusināt sarunu",
|
||||
"status.open": "Paplašināt šo ziņu",
|
||||
"status.open": "Izvērst šo ierakstu",
|
||||
"status.pin": "Piespraust profilam",
|
||||
"status.pinned": "Piesprausts ieraksts",
|
||||
"status.read_more": "Lasīt vairāk",
|
||||
|
@ -696,7 +729,7 @@
|
|||
"status.reblog_private": "Pastiprināt ar sākotnējo redzamību",
|
||||
"status.reblogged_by": "{name} pastiprināja",
|
||||
"status.reblogs": "{count, plural, zero {pastiprinājumu} one {pastiprinājums} other {pastiprinājumi}}",
|
||||
"status.reblogs.empty": "Neviens šo ierakstu vēl nav pastiprinājis. Kad būs, tie parādīsies šeit.",
|
||||
"status.reblogs.empty": "Neviens vēl nav pastiprinājis šo ierakstu. Kad kāds to izdarīs, šeit tiks parādīti lietotāji.",
|
||||
"status.redraft": "Dzēst un pārrakstīt",
|
||||
"status.remove_bookmark": "Noņemt grāmatzīmi",
|
||||
"status.replied_to": "Atbildēja {name}",
|
||||
|
@ -708,13 +741,13 @@
|
|||
"status.show_less_all": "Rādīt mazāk visiem",
|
||||
"status.show_more_all": "Rādīt vairāk visiem",
|
||||
"status.show_original": "Rādīt pirmavotu",
|
||||
"status.title.with_attachments": "{user} publicējis {attachmentCount, plural, one {pielikumu} other {{attachmentCount} pielikumus}}",
|
||||
"status.title.with_attachments": "{user} pievienoja {attachmentCount, plural, zero {{attachmentCount} pielikumu} one {{attachmentCount} pielikumu} other {{attachmentCount} pielikumus}}",
|
||||
"status.translate": "Tulkot",
|
||||
"status.translated_from_with": "Tulkots no {lang} izmantojot {provider}",
|
||||
"status.uncached_media_warning": "Priekšskatījums nav pieejams",
|
||||
"status.unmute_conversation": "Noņemt sarunas apklusinājumu",
|
||||
"status.unpin": "Noņemt profila piespraudumu",
|
||||
"subscribed_languages.lead": "Pēc izmaiņu veikšanas Tavā mājas un sarakstu laika līnijā tiks rādīti tikai tie ieraksti atlasītajās valodās. Neatlasīt nevienu, lai saņemtu ierakstus visās valodās.",
|
||||
"subscribed_languages.lead": "Pēc izmaiņu veikšanas Tavā mājas un sarakstu laika līnijā tiks rādīti tikai ieraksti atlasītajās valodās. Neatlasīt nevienu, lai saņemtu ierakstus visās valodās.",
|
||||
"subscribed_languages.save": "Saglabāt izmaiņas",
|
||||
"subscribed_languages.target": "Mainīt abonētās valodas priekš {target}",
|
||||
"tabs_bar.home": "Sākums",
|
||||
|
|
|
@ -98,8 +98,8 @@
|
|||
"alt_text_modal.add_text_from_image": "Добавить текст из изображения",
|
||||
"alt_text_modal.cancel": "Отмена",
|
||||
"alt_text_modal.change_thumbnail": "Изменить обложку",
|
||||
"alt_text_modal.describe_for_people_with_hearing_impairments": "Опишите то, что слышите, для людей с нарушениями слуха…",
|
||||
"alt_text_modal.describe_for_people_with_visual_impairments": "Опишите то, что видите, для людей с нарушениями зрения…",
|
||||
"alt_text_modal.describe_for_people_with_hearing_impairments": "Добавьте описание для людей с нарушениями слуха…",
|
||||
"alt_text_modal.describe_for_people_with_visual_impairments": "Добавьте описание для людей с нарушениями зрения…",
|
||||
"alt_text_modal.done": "Готово",
|
||||
"announcement.announcement": "Объявление",
|
||||
"annual_report.summary.archetype.booster": "Репостер",
|
||||
|
@ -456,36 +456,36 @@
|
|||
"intervals.full.hours": "{number, plural, one {# час} few {# часа} other {# часов}}",
|
||||
"intervals.full.minutes": "{number, plural, one {# минута} few {# минуты} other {# минут}}",
|
||||
"keyboard_shortcuts.back": "перейти назад",
|
||||
"keyboard_shortcuts.blocked": "чтобы открыть список заблокированных",
|
||||
"keyboard_shortcuts.blocked": "открыть список заблокированных",
|
||||
"keyboard_shortcuts.boost": "продвинуть пост",
|
||||
"keyboard_shortcuts.column": "фокус на одном из столбцов",
|
||||
"keyboard_shortcuts.compose": "фокус на поле ввода",
|
||||
"keyboard_shortcuts.description": "Описание",
|
||||
"keyboard_shortcuts.direct": "чтобы открыть столбец личных упоминаний",
|
||||
"keyboard_shortcuts.direct": "перейти к личным упоминаниям",
|
||||
"keyboard_shortcuts.down": "вниз по списку",
|
||||
"keyboard_shortcuts.enter": "открыть пост",
|
||||
"keyboard_shortcuts.favourite": "добавить пост в избранное",
|
||||
"keyboard_shortcuts.favourites": "открыть «Избранные»",
|
||||
"keyboard_shortcuts.favourites": "перейти к избранным постам",
|
||||
"keyboard_shortcuts.federated": "перейти к глобальной ленте",
|
||||
"keyboard_shortcuts.heading": "Сочетания клавиш",
|
||||
"keyboard_shortcuts.home": "перейти к домашней ленте",
|
||||
"keyboard_shortcuts.hotkey": "Гор. клавиша",
|
||||
"keyboard_shortcuts.legend": "показать это окно",
|
||||
"keyboard_shortcuts.hotkey": "Горячая клавиша",
|
||||
"keyboard_shortcuts.legend": "показать эту справку",
|
||||
"keyboard_shortcuts.local": "перейти к локальной ленте",
|
||||
"keyboard_shortcuts.mention": "упомянуть автора поста",
|
||||
"keyboard_shortcuts.muted": "открыть список игнорируемых",
|
||||
"keyboard_shortcuts.my_profile": "перейти к своему профилю",
|
||||
"keyboard_shortcuts.notifications": "перейти к уведомлениям",
|
||||
"keyboard_shortcuts.open_media": "открыть вложение",
|
||||
"keyboard_shortcuts.open_media": "открыть медиа",
|
||||
"keyboard_shortcuts.pinned": "перейти к закреплённым постам",
|
||||
"keyboard_shortcuts.profile": "перейти к профилю автора",
|
||||
"keyboard_shortcuts.reply": "ответить",
|
||||
"keyboard_shortcuts.requests": "перейти к запросам на подписку",
|
||||
"keyboard_shortcuts.search": "перейти к поиску",
|
||||
"keyboard_shortcuts.spoilers": "показать/скрыть поле предупреждения о содержании",
|
||||
"keyboard_shortcuts.start": "перейти к разделу \"добро пожаловать\"",
|
||||
"keyboard_shortcuts.start": "перейти к разделу «Добро пожаловать»",
|
||||
"keyboard_shortcuts.toggle_hidden": "показать/скрыть текст за предупреждением",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "показать/скрыть медиафайлы",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "показать/скрыть медиа",
|
||||
"keyboard_shortcuts.toot": "начать писать новый пост",
|
||||
"keyboard_shortcuts.translate": "перевести пост",
|
||||
"keyboard_shortcuts.unfocus": "убрать фокус с поля ввода/поиска",
|
||||
|
|
|
@ -38,6 +38,11 @@ class Admin::SystemCheck::ElasticsearchCheck < Admin::SystemCheck::BaseCheck
|
|||
:elasticsearch_index_mismatch,
|
||||
mismatched_indexes.join(' ')
|
||||
)
|
||||
elsif !specifications_match?
|
||||
Admin::SystemCheck::Message.new(
|
||||
:elasticsearch_analysis_mismatch,
|
||||
mismatched_specifications_indexes.join(' ')
|
||||
)
|
||||
elsif cluster_health['status'] == 'red'
|
||||
Admin::SystemCheck::Message.new(:elasticsearch_health_red)
|
||||
elsif cluster_health['number_of_nodes'] < 2 && es_preset != 'single_node_cluster'
|
||||
|
@ -111,10 +116,20 @@ class Admin::SystemCheck::ElasticsearchCheck < Admin::SystemCheck::BaseCheck
|
|||
end
|
||||
end
|
||||
|
||||
def mismatched_specifications_indexes
|
||||
@mismatched_specifications_indexes ||= INDEXES.filter_map do |klass|
|
||||
klass.base_name if klass.specification.changed?
|
||||
end
|
||||
end
|
||||
|
||||
def indexes_match?
|
||||
mismatched_indexes.empty?
|
||||
end
|
||||
|
||||
def specifications_match?
|
||||
mismatched_specifications_indexes.empty?
|
||||
end
|
||||
|
||||
def es_preset
|
||||
ENV.fetch('ES_PRESET', 'single_node_cluster')
|
||||
end
|
||||
|
|
|
@ -18,17 +18,17 @@ class FeaturedTag < ApplicationRecord
|
|||
belongs_to :account, inverse_of: :featured_tags
|
||||
belongs_to :tag, inverse_of: :featured_tags, optional: true # Set after validation
|
||||
|
||||
validates :name, presence: true, format: { with: Tag::HASHTAG_NAME_RE }, on: :create
|
||||
validates :name, presence: true, on: :create, if: -> { tag_id.nil? }
|
||||
validates :name, format: { with: Tag::HASHTAG_NAME_RE }, on: :create, allow_blank: true
|
||||
validates :tag_id, uniqueness: { scope: :account_id }
|
||||
|
||||
validate :validate_tag_uniqueness, on: :create
|
||||
validate :validate_featured_tags_limit, on: :create
|
||||
|
||||
normalizes :name, with: ->(name) { name.strip.delete_prefix('#') }
|
||||
|
||||
before_create :set_tag
|
||||
before_create :reset_data
|
||||
before_validation :set_tag
|
||||
|
||||
scope :by_name, ->(name) { joins(:tag).where(tag: { name: HashtagNormalizer.new.normalize(name) }) }
|
||||
before_create :reset_data
|
||||
|
||||
LIMIT = 10
|
||||
|
||||
|
@ -59,7 +59,11 @@ class FeaturedTag < ApplicationRecord
|
|||
private
|
||||
|
||||
def set_tag
|
||||
self.tag = Tag.find_or_create_by_names(name)&.first
|
||||
if tag.nil?
|
||||
self.tag = Tag.find_or_create_by_names(name)&.first
|
||||
elsif tag&.new_record?
|
||||
tag.save
|
||||
end
|
||||
end
|
||||
|
||||
def reset_data
|
||||
|
@ -73,14 +77,6 @@ class FeaturedTag < ApplicationRecord
|
|||
errors.add(:base, I18n.t('featured_tags.errors.limit')) if account.featured_tags.count >= LIMIT
|
||||
end
|
||||
|
||||
def validate_tag_uniqueness
|
||||
errors.add(:name, :taken) if tag_already_featured_for_account?
|
||||
end
|
||||
|
||||
def tag_already_featured_for_account?
|
||||
FeaturedTag.by_name(name).exists?(account_id: account_id)
|
||||
end
|
||||
|
||||
def visible_tagged_account_statuses
|
||||
account.statuses.distributable_visibility.tagged_with(tag)
|
||||
end
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TagRelationshipsPresenter
|
||||
attr_reader :following_map
|
||||
attr_reader :following_map, :featuring_map
|
||||
|
||||
def initialize(tags, current_account_id = nil, **options)
|
||||
@following_map = if current_account_id.nil?
|
||||
{}
|
||||
else
|
||||
TagFollow.select(:tag_id).where(tag_id: tags.map(&:id), account_id: current_account_id).each_with_object({}) { |f, h| h[f.tag_id] = true }.merge(options[:following_map] || {})
|
||||
end
|
||||
if current_account_id.nil?
|
||||
@following_map = {}
|
||||
@featuring_map = {}
|
||||
else
|
||||
@following_map = TagFollow.select(:tag_id).where(tag_id: tags.map(&:id), account_id: current_account_id).each_with_object({}) { |f, h| h[f.tag_id] = true }.merge(options[:following_map] || {})
|
||||
@featuring_map = FeaturedTag.select(:tag_id).where(tag_id: tags.map(&:id), account_id: current_account_id).each_with_object({}) { |f, h| h[f.tag_id] = true }.merge(options[:featuring_map] || {})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -75,7 +75,7 @@ class OEmbedSerializer < ActiveModel::Serializer
|
|||
<<~HTML.squish
|
||||
<blockquote class="mastodon-embed" data-embed-url="#{embed_short_account_status_url(object.account, object)}" style="#{INLINE_STYLES[:blockquote]}">
|
||||
<a href="#{short_account_status_url(object.account, object)}" target="_blank" style="#{INLINE_STYLES[:status_link]}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 79 75"><path d="M74.7135 16.6043C73.6199 8.54587 66.5351 2.19527 58.1366 0.964691C56.7196 0.756754 51.351 0 38.9148 0H38.822C26.3824 0 23.7135 0.756754 22.2966 0.964691C14.1319 2.16118 6.67571 7.86752 4.86669 16.0214C3.99657 20.0369 3.90371 24.4888 4.06535 28.5726C4.29578 34.4289 4.34049 40.275 4.877 46.1075C5.24791 49.9817 5.89495 53.8251 6.81328 57.6088C8.53288 64.5968 15.4938 70.4122 22.3138 72.7848C29.6155 75.259 37.468 75.6697 44.9919 73.971C45.8196 73.7801 46.6381 73.5586 47.4475 73.3063C49.2737 72.7302 51.4164 72.086 52.9915 70.9542C53.0131 70.9384 53.0308 70.9178 53.0433 70.8942C53.0558 70.8706 53.0628 70.8445 53.0637 70.8179V65.1661C53.0634 65.1412 53.0574 65.1167 53.0462 65.0944C53.035 65.0721 53.0189 65.0525 52.9992 65.0371C52.9794 65.0218 52.9564 65.011 52.9318 65.0056C52.9073 65.0002 52.8819 65.0003 52.8574 65.0059C48.0369 66.1472 43.0971 66.7193 38.141 66.7103C29.6118 66.7103 27.3178 62.6981 26.6609 61.0278C26.1329 59.5842 25.7976 58.0784 25.6636 56.5486C25.6622 56.5229 25.667 56.4973 25.6775 56.4738C25.688 56.4502 25.7039 56.4295 25.724 56.4132C25.7441 56.397 25.7678 56.3856 25.7931 56.3801C25.8185 56.3746 25.8448 56.3751 25.8699 56.3816C30.6101 57.5151 35.4693 58.0873 40.3455 58.086C41.5183 58.086 42.6876 58.086 43.8604 58.0553C48.7647 57.919 53.9339 57.6701 58.7591 56.7361C58.8794 56.7123 58.9998 56.6918 59.103 56.6611C66.7139 55.2124 73.9569 50.665 74.6929 39.1501C74.7204 38.6967 74.7892 34.4016 74.7892 33.9312C74.7926 32.3325 75.3085 22.5901 74.7135 16.6043ZM62.9996 45.3371H54.9966V25.9069C54.9966 21.8163 53.277 19.7302 49.7793 19.7302C45.9343 19.7302 44.0083 22.1981 44.0083 27.0727V37.7082H36.0534V27.0727C36.0534 22.1981 34.124 19.7302 30.279 19.7302C26.8019 19.7302 25.0651 21.8163 25.0617 25.9069V45.3371H17.0656V25.3172C17.0656 21.2266 18.1191 17.9769 20.2262 15.568C22.3998 13.1648 25.2509 11.9308 28.7898 11.9308C32.8859 11.9308 35.9812 13.492 38.0447 16.6111L40.036 19.9245L42.0308 16.6111C44.0943 13.492 47.1896 11.9308 51.2788 11.9308C54.8143 11.9308 57.6654 13.1648 59.8459 15.568C61.9529 17.9746 63.0065 21.2243 63.0065 25.3172L62.9996 45.3371Z" fill="currentColor"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 79 75"><path d="M63 45.3v-20c0-4.1-1-7.3-3.2-9.7-2.1-2.4-5-3.7-8.5-3.7-4.1 0-7.2 1.6-9.3 4.7l-2 3.3-2-3.3c-2-3.1-5.1-4.7-9.2-4.7-3.5 0-6.4 1.3-8.6 3.7-2.1 2.4-3.1 5.6-3.1 9.7v20h8V25.9c0-4.1 1.7-6.2 5.2-6.2 3.8 0 5.8 2.5 5.8 7.4V37.7H44V27.1c0-4.9 1.9-7.4 5.8-7.4 3.5 0 5.2 2.1 5.2 6.2V45.3h8ZM74.7 16.6c.6 6 .1 15.7.1 17.3 0 .5-.1 4.8-.1 5.3-.7 11.5-8 16-15.6 17.5-.1 0-.2 0-.3 0-4.9 1-10 1.2-14.9 1.4-1.2 0-2.4 0-3.6 0-4.8 0-9.7-.6-14.4-1.7-.1 0-.1 0-.1 0s-.1 0-.1 0 0 .1 0 .1 0 0 0 0c.1 1.6.4 3.1 1 4.5.6 1.7 2.9 5.7 11.4 5.7 5 0 9.9-.6 14.8-1.7 0 0 0 0 0 0 .1 0 .1 0 .1 0 0 .1 0 .1 0 .1.1 0 .1 0 .1.1v5.6s0 .1-.1.1c0 0 0 0 0 .1-1.6 1.1-3.7 1.7-5.6 2.3-.8.3-1.6.5-2.4.7-7.5 1.7-15.4 1.3-22.7-1.2-6.8-2.4-13.8-8.2-15.5-15.2-.9-3.8-1.6-7.6-1.9-11.5-.6-5.8-.6-11.7-.8-17.5C3.9 24.5 4 20 4.9 16 6.7 7.9 14.1 2.2 22.3 1c1.4-.2 4.1-1 16.5-1h.1C51.4 0 56.7.8 58.1 1c8.4 1.2 15.5 7.5 16.6 15.6Z" fill="currentColor"/></svg>
|
||||
<div style="#{INLINE_STYLES[:div_account]}">Post by @#{object.account.pretty_acct}@#{provider_name}</div>
|
||||
<div style="#{INLINE_STYLES[:div_view]}">View on Mastodon</div>
|
||||
</a>
|
||||
|
|
|
@ -6,6 +6,7 @@ class REST::TagSerializer < ActiveModel::Serializer
|
|||
attributes :id, :name, :url, :history
|
||||
|
||||
attribute :following, if: :current_user?
|
||||
attribute :featuring, if: :current_user?
|
||||
|
||||
def id
|
||||
object.id.to_s
|
||||
|
@ -27,6 +28,14 @@ class REST::TagSerializer < ActiveModel::Serializer
|
|||
end
|
||||
end
|
||||
|
||||
def featuring
|
||||
if instance_options && instance_options[:relationships]
|
||||
instance_options[:relationships].featuring_map[object.id] || false
|
||||
else
|
||||
FeaturedTag.exists?(tag_id: object.id, account_id: current_user.account_id)
|
||||
end
|
||||
end
|
||||
|
||||
def current_user?
|
||||
!current_user.nil?
|
||||
end
|
||||
|
|
|
@ -142,11 +142,37 @@ class AccountSearchService < BaseService
|
|||
|
||||
def core_query
|
||||
{
|
||||
multi_match: {
|
||||
query: @query,
|
||||
type: 'best_fields',
|
||||
fields: %w(username^2 display_name^2 text text.*),
|
||||
operator: 'and',
|
||||
dis_max: {
|
||||
queries: [
|
||||
{
|
||||
match: {
|
||||
username: {
|
||||
query: @query,
|
||||
analyzer: 'word_join_analyzer',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
match: {
|
||||
display_name: {
|
||||
query: @query,
|
||||
analyzer: 'word_join_analyzer',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
multi_match: {
|
||||
query: @query,
|
||||
type: 'best_fields',
|
||||
fields: %w(text text.*),
|
||||
operator: 'and',
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
tie_breaker: 0.5,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
|
|
@ -3,18 +3,24 @@
|
|||
class CreateFeaturedTagService < BaseService
|
||||
include Payloadable
|
||||
|
||||
def call(account, name, force: true)
|
||||
def call(account, name_or_tag, raise_error: true)
|
||||
raise ArgumentError unless account.local?
|
||||
|
||||
@account = account
|
||||
|
||||
FeaturedTag.create!(account: account, name: name).tap do |featured_tag|
|
||||
ActivityPub::AccountRawDistributionWorker.perform_async(build_json(featured_tag), account.id) if @account.local?
|
||||
end
|
||||
rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid => e
|
||||
if force && e.is_a(ActiveRecord::RecordNotUnique)
|
||||
FeaturedTag.by_name(name).find_by!(account: account)
|
||||
else
|
||||
account.featured_tags.new(name: name)
|
||||
@featured_tag = begin
|
||||
if name_or_tag.is_a?(Tag)
|
||||
account.featured_tags.find_or_initialize_by(tag: name_or_tag)
|
||||
else
|
||||
account.featured_tags.find_or_initialize_by(name: name_or_tag)
|
||||
end
|
||||
end
|
||||
|
||||
create_method = raise_error ? :save! : :save
|
||||
|
||||
ActivityPub::AccountRawDistributionWorker.perform_async(build_json(@featured_tag), @account.id) if @featured_tag.new_record? && @featured_tag.public_send(create_method)
|
||||
|
||||
@featured_tag
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -3,11 +3,24 @@
|
|||
class RemoveFeaturedTagService < BaseService
|
||||
include Payloadable
|
||||
|
||||
def call(account, featured_tag)
|
||||
def call(account, featured_tag_or_tag)
|
||||
raise ArgumentError unless account.local?
|
||||
|
||||
@account = account
|
||||
|
||||
featured_tag.destroy!
|
||||
ActivityPub::AccountRawDistributionWorker.perform_async(build_json(featured_tag), account.id) if @account.local?
|
||||
@featured_tag = begin
|
||||
if featured_tag_or_tag.is_a?(FeaturedTag)
|
||||
featured_tag_or_tag
|
||||
elsif featured_tag_or_tag.is_a?(Tag)
|
||||
FeaturedTag.find_by(account: account, tag: featured_tag_or_tag)
|
||||
end
|
||||
end
|
||||
|
||||
return if @featured_tag.nil?
|
||||
|
||||
@featured_tag.destroy!
|
||||
|
||||
ActivityPub::AccountRawDistributionWorker.perform_async(build_json(@featured_tag), account.id) if @account.local?
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# This is a configuration file for environments that use Japanese and Sudachi plug-ins.
|
||||
# To use this file, copy it to the Mastodon root directory and rename the file to ".elasticsearch.yml".
|
||||
|
||||
version: 1
|
||||
version: 2
|
||||
|
||||
accounts:
|
||||
filter:
|
||||
|
@ -14,6 +14,10 @@ accounts:
|
|||
english_possessive_stemmer:
|
||||
type: stemmer
|
||||
language: possessive_english
|
||||
word_joiner:
|
||||
type: shingle
|
||||
output_unigrams: true
|
||||
token_separator: ''
|
||||
my_posfilter:
|
||||
type: sudachi_part_of_speech
|
||||
stoptags:
|
||||
|
@ -45,6 +49,14 @@ accounts:
|
|||
- lowercase
|
||||
- asciifolding
|
||||
- cjk_width
|
||||
word_join_analyzer:
|
||||
type: custom
|
||||
tokenizer: standard
|
||||
filter:
|
||||
- lowercase
|
||||
- asciifolding
|
||||
- cjk_width
|
||||
- word_joiner
|
||||
edge_ngram:
|
||||
tokenizer: edge_ngram
|
||||
filter:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# The standard ElasticSearch settings described in the original Mastodon code are stored.
|
||||
# This configuration file is overridden by creating a ".elasticsearch.yml" file in the Mastodon root directory.
|
||||
|
||||
version: 1
|
||||
version: 2
|
||||
|
||||
accounts:
|
||||
filter:
|
||||
|
@ -14,6 +14,10 @@ accounts:
|
|||
english_possessive_stemmer:
|
||||
type: stemmer
|
||||
language: possessive_english
|
||||
word_joiner:
|
||||
type: shingle
|
||||
output_unigrams: true
|
||||
token_separator: ''
|
||||
|
||||
analyzer:
|
||||
natural:
|
||||
|
@ -32,6 +36,14 @@ accounts:
|
|||
- lowercase
|
||||
- asciifolding
|
||||
- cjk_width
|
||||
word_join_analyzer:
|
||||
type: custom
|
||||
tokenizer: standard
|
||||
filter:
|
||||
- lowercase
|
||||
- asciifolding
|
||||
- cjk_width
|
||||
- word_joiner
|
||||
edge_ngram:
|
||||
tokenizer: edge_ngram
|
||||
filter:
|
||||
|
|
|
@ -1167,6 +1167,8 @@ en:
|
|||
system_checks:
|
||||
database_schema_check:
|
||||
message_html: There are pending database migrations. Please run them to ensure the application behaves as expected
|
||||
elasticsearch_analysis_index_mismatch:
|
||||
message_html: Elasticsearch index analyzer settings are outdated. Please run <code>tootctl search deploy --only-mapping --only=%{value}</code>
|
||||
elasticsearch_health_red:
|
||||
message_html: Elasticsearch cluster is unhealthy (red status), search features are unavailable
|
||||
elasticsearch_health_yellow:
|
||||
|
|
|
@ -325,6 +325,7 @@ ru:
|
|||
create: Создать объявление
|
||||
title: Новое объявление
|
||||
preview:
|
||||
disclaimer: Так как пользователи не могут отказаться от получения уведомлений по электронной почте, их следует использовать только для действительно важных объявлений, например, чтобы сообщить об утечке персональных данных или о закрытии сервера.
|
||||
explanation_html: 'Сообщение будет отравлено <strong>%{display_count} пользователям</strong>. В теле письма будет указан следующий текст:'
|
||||
title: Предпросмотр объявления по электронной почте
|
||||
publish: Опубликовать
|
||||
|
@ -509,6 +510,7 @@ ru:
|
|||
save: Сохранить
|
||||
sign_in:
|
||||
status: Пост
|
||||
title: FASP
|
||||
follow_recommendations:
|
||||
description_html: "<strong>Следуйте рекомендациям, чтобы помочь новым пользователям быстро находить интересный контент</strong>. Если пользователь не взаимодействовал с другими в достаточной степени, чтобы сформировать персонализированные рекомендации, вместо этого рекомендуется использовать эти учетные записи. Они пересчитываются на ежедневной основе на основе комбинации аккаунтов с наибольшим количеством недавних взаимодействий и наибольшим количеством местных подписчиков для данного языка."
|
||||
language: Для языка
|
||||
|
@ -1620,13 +1622,6 @@ ru:
|
|||
action: Да, отписаться
|
||||
complete: Подписка отменена
|
||||
confirmation_html: Вы точно желаете отписаться от всех уведомления типа «%{type}», доставляемых из сервера Mastodon %{domain} на ваш адрес электронной почты %{email}? Вы всегда сможете подписаться снова в <a href="%{settings_path}">настройках e-mail уведомлений</a>.
|
||||
emails:
|
||||
notification_emails:
|
||||
favourite: любимые электронные письма с уведомлениями
|
||||
follow: Следить за электронными сообщениями
|
||||
follow_request: Письма с просьбой о помощи
|
||||
mention: Упоминание электронных писем с уведомлениями
|
||||
reblog: Уведомления по электронной почте
|
||||
resubscribe_html: Если вы отписались от рассылки по ошибке, вы можете повторно подписаться на рассылку в настройках <a href="%{settings_path}">настроек почтовых уведомлений</a>.
|
||||
success_html: Вы больше не будете получать %{type} для Mastodon на %{domain} на вашу электронную почту %{email}.
|
||||
title: Отписаться
|
||||
|
@ -1710,7 +1705,6 @@ ru:
|
|||
update:
|
||||
subject: "%{name} изменил(а) пост"
|
||||
notifications:
|
||||
administration_emails: Уведомления администратора по электронной почте
|
||||
email_events: События для уведомлений по электронной почте
|
||||
email_events_hint: 'Выберите события, для которых вы хотели бы получать уведомления:'
|
||||
number:
|
||||
|
|
|
@ -231,6 +231,8 @@ namespace :api, format: false do
|
|||
member do
|
||||
post :follow
|
||||
post :unfollow
|
||||
post :feature
|
||||
post :unfeature
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ module Mastodon
|
|||
|
||||
def api_versions
|
||||
{
|
||||
mastodon: 5,
|
||||
mastodon: 6,
|
||||
kmyblue: KMYBLUE_API_VERSION,
|
||||
}
|
||||
end
|
||||
|
|
|
@ -23,7 +23,7 @@ RSpec.describe ApplicationController do
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples 'respond_with_error' do |code|
|
||||
shared_examples 'error response' do |code|
|
||||
it "returns http #{code} for http and renders template" do
|
||||
subject
|
||||
|
||||
|
@ -51,7 +51,7 @@ RSpec.describe ApplicationController do
|
|||
post 'success'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 422
|
||||
it_behaves_like 'error response', 422
|
||||
end
|
||||
|
||||
describe 'helper_method :current_account' do
|
||||
|
@ -123,7 +123,7 @@ RSpec.describe ApplicationController do
|
|||
get 'routing_error'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 404
|
||||
it_behaves_like 'error response', 404
|
||||
end
|
||||
|
||||
context 'with ActiveRecord::RecordNotFound' do
|
||||
|
@ -132,7 +132,7 @@ RSpec.describe ApplicationController do
|
|||
get 'record_not_found'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 404
|
||||
it_behaves_like 'error response', 404
|
||||
end
|
||||
|
||||
context 'with ActionController::InvalidAuthenticityToken' do
|
||||
|
@ -141,7 +141,7 @@ RSpec.describe ApplicationController do
|
|||
get 'invalid_authenticity_token'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 422
|
||||
it_behaves_like 'error response', 422
|
||||
end
|
||||
|
||||
describe 'before_action :check_suspension' do
|
||||
|
@ -186,7 +186,7 @@ RSpec.describe ApplicationController do
|
|||
get 'route_forbidden'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 403
|
||||
it_behaves_like 'error response', 403
|
||||
end
|
||||
|
||||
describe 'not_found' do
|
||||
|
@ -201,7 +201,7 @@ RSpec.describe ApplicationController do
|
|||
get 'route_not_found'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 404
|
||||
it_behaves_like 'error response', 404
|
||||
end
|
||||
|
||||
describe 'gone' do
|
||||
|
@ -216,7 +216,7 @@ RSpec.describe ApplicationController do
|
|||
get 'route_gone'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 410
|
||||
it_behaves_like 'error response', 410
|
||||
end
|
||||
|
||||
describe 'unprocessable_entity' do
|
||||
|
@ -231,6 +231,6 @@ RSpec.describe ApplicationController do
|
|||
get 'route_unprocessable_entity'
|
||||
end
|
||||
|
||||
include_examples 'respond_with_error', 422
|
||||
it_behaves_like 'error response', 422
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rails_helper'
|
|||
RSpec.describe Auth::RegistrationsController do
|
||||
render_views
|
||||
|
||||
shared_examples 'checks for enabled registrations' do |path|
|
||||
shared_examples 'registration mode based responses' do |path|
|
||||
context 'when in single user mode and open for registration' do
|
||||
before do
|
||||
Setting.registrations_mode = 'open'
|
||||
|
@ -156,7 +156,7 @@ RSpec.describe Auth::RegistrationsController do
|
|||
end
|
||||
end
|
||||
|
||||
include_examples 'checks for enabled registrations', :new
|
||||
it_behaves_like 'registration mode based responses', :new
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
|
@ -542,7 +542,8 @@ RSpec.describe Auth::RegistrationsController do
|
|||
it_behaves_like 'registration with time', 'only secondary time range is set', 0, 0, 9, 12, true
|
||||
end
|
||||
|
||||
include_examples 'checks for enabled registrations', :create
|
||||
it_behaves_like 'checks for enabled registrations', :create
|
||||
it_behaves_like 'registration mode based responses', :create
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
|
|
|
@ -59,10 +59,10 @@ RSpec.describe Localized do
|
|||
sign_in(user)
|
||||
end
|
||||
|
||||
include_examples 'default locale'
|
||||
it_behaves_like 'default locale'
|
||||
end
|
||||
|
||||
context 'with a user who has not signed in' do
|
||||
include_examples 'default locale'
|
||||
it_behaves_like 'default locale'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ RSpec.describe RelationshipsController do
|
|||
describe 'PATCH #update' do
|
||||
let(:alice) { Fabricate(:account, username: 'alice', domain: 'example.com') }
|
||||
|
||||
shared_examples 'redirects back to followers page' do
|
||||
shared_examples 'general behavior for followed user' do
|
||||
it 'redirects back to followers page' do
|
||||
alice.follow!(user.account)
|
||||
|
||||
|
@ -49,7 +49,7 @@ RSpec.describe RelationshipsController do
|
|||
context 'when select parameter is not provided' do
|
||||
subject { patch :update }
|
||||
|
||||
include_examples 'redirects back to followers page'
|
||||
it_behaves_like 'general behavior for followed user'
|
||||
end
|
||||
|
||||
context 'when select parameter is provided' do
|
||||
|
@ -83,7 +83,7 @@ RSpec.describe RelationshipsController do
|
|||
end
|
||||
end
|
||||
|
||||
include_examples 'redirects back to followers page'
|
||||
it_behaves_like 'general behavior for followed user'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -162,7 +162,7 @@ RSpec.describe Settings::ImportsController do
|
|||
]
|
||||
end
|
||||
|
||||
include_examples 'export failed rows', "Account address,Show boosts,Notify on new posts,Languages\nfoo@bar,true,false,\nuser@bar,false,true,\"fr, de\"\n"
|
||||
it_behaves_like 'export failed rows', "Account address,Show boosts,Notify on new posts,Languages\nfoo@bar,true,false,\nuser@bar,false,true,\"fr, de\"\n"
|
||||
end
|
||||
|
||||
context 'with blocks' do
|
||||
|
@ -175,7 +175,7 @@ RSpec.describe Settings::ImportsController do
|
|||
]
|
||||
end
|
||||
|
||||
include_examples 'export failed rows', "foo@bar\nuser@bar\n"
|
||||
it_behaves_like 'export failed rows', "foo@bar\nuser@bar\n"
|
||||
end
|
||||
|
||||
context 'with mutes' do
|
||||
|
@ -188,7 +188,7 @@ RSpec.describe Settings::ImportsController do
|
|||
]
|
||||
end
|
||||
|
||||
include_examples 'export failed rows', "Account address,Hide notifications\nfoo@bar,true\nuser@bar,false\n"
|
||||
it_behaves_like 'export failed rows', "Account address,Hide notifications\nfoo@bar,true\nuser@bar,false\n"
|
||||
end
|
||||
|
||||
context 'with domain blocks' do
|
||||
|
@ -201,7 +201,7 @@ RSpec.describe Settings::ImportsController do
|
|||
]
|
||||
end
|
||||
|
||||
include_examples 'export failed rows', "bad.domain\nevil.domain\n"
|
||||
it_behaves_like 'export failed rows', "bad.domain\nevil.domain\n"
|
||||
end
|
||||
|
||||
context 'with bookmarks' do
|
||||
|
@ -214,7 +214,7 @@ RSpec.describe Settings::ImportsController do
|
|||
]
|
||||
end
|
||||
|
||||
include_examples 'export failed rows', "https://foo.com/1\nhttps://foo.com/2\n"
|
||||
it_behaves_like 'export failed rows', "https://foo.com/1\nhttps://foo.com/2\n"
|
||||
end
|
||||
|
||||
context 'with lists' do
|
||||
|
@ -227,7 +227,7 @@ RSpec.describe Settings::ImportsController do
|
|||
]
|
||||
end
|
||||
|
||||
include_examples 'export failed rows', "Amigos,user@example.com\nFrenemies,user@org.org\n"
|
||||
it_behaves_like 'export failed rows', "Amigos,user@example.com\nFrenemies,user@org.org\n"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do
|
|||
get :new, session: { challenge_passed_at: Time.now.utc, new_otp_secret: 'thisisasecretforthespecofnewview' }
|
||||
end
|
||||
|
||||
include_examples 'renders expected page'
|
||||
it_behaves_like 'renders expected page'
|
||||
end
|
||||
|
||||
it 'redirects if a new otp_secret has not been set in the session' do
|
||||
|
@ -94,7 +94,7 @@ RSpec.describe Settings::TwoFactorAuthentication::ConfirmationsController do
|
|||
.to include(I18n.t('otp_authentication.wrong_code'))
|
||||
end
|
||||
|
||||
include_examples 'renders expected page'
|
||||
it_behaves_like 'renders expected page'
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -12,7 +12,7 @@ RSpec.describe CacheBuster do
|
|||
let(:purge_url) { 'https://example.com/test_purge' }
|
||||
|
||||
describe '#bust' do
|
||||
shared_examples 'makes_request' do
|
||||
shared_examples 'cache busting request' do
|
||||
it 'makes an HTTP purging request' do
|
||||
method = http_method&.to_sym || :get
|
||||
stub_request(method, purge_url).to_return(status: 200)
|
||||
|
@ -28,28 +28,28 @@ RSpec.describe CacheBuster do
|
|||
end
|
||||
|
||||
context 'when using default options' do
|
||||
include_examples 'makes_request'
|
||||
it_behaves_like 'cache busting request'
|
||||
end
|
||||
|
||||
context 'when specifying a secret header' do
|
||||
let(:secret_header) { 'X-Purge-Secret' }
|
||||
let(:secret) { SecureRandom.hex(20) }
|
||||
|
||||
include_examples 'makes_request'
|
||||
it_behaves_like 'cache busting request'
|
||||
end
|
||||
|
||||
context 'when specifying a PURGE method' do
|
||||
let(:http_method) { 'purge' }
|
||||
|
||||
context 'when not using headers' do
|
||||
include_examples 'makes_request'
|
||||
it_behaves_like 'cache busting request'
|
||||
end
|
||||
|
||||
context 'when specifying a secret header' do
|
||||
let(:secret_header) { 'X-Purge-Secret' }
|
||||
let(:secret) { SecureRandom.hex(20) }
|
||||
|
||||
include_examples 'makes_request'
|
||||
it_behaves_like 'cache busting request'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -44,14 +44,14 @@ RSpec.describe Fasp::Request do
|
|||
end
|
||||
|
||||
describe '#get' do
|
||||
include_examples 'a provider request', :get
|
||||
it_behaves_like 'a provider request', :get
|
||||
end
|
||||
|
||||
describe '#post' do
|
||||
include_examples 'a provider request', :post
|
||||
it_behaves_like 'a provider request', :post
|
||||
end
|
||||
|
||||
describe '#delete' do
|
||||
include_examples 'a provider request', :delete
|
||||
it_behaves_like 'a provider request', :delete
|
||||
end
|
||||
end
|
||||
|
|
|
@ -118,7 +118,7 @@ RSpec.describe LinkDetailsExtractor do
|
|||
</html>
|
||||
HTML
|
||||
|
||||
include_examples 'structured data'
|
||||
it_behaves_like 'structured data'
|
||||
end
|
||||
|
||||
context 'with the first tag is invalid JSON' do
|
||||
|
@ -136,7 +136,7 @@ RSpec.describe LinkDetailsExtractor do
|
|||
</html>
|
||||
HTML
|
||||
|
||||
include_examples 'structured data'
|
||||
it_behaves_like 'structured data'
|
||||
end
|
||||
|
||||
context 'with the first tag is null' do
|
||||
|
@ -154,7 +154,7 @@ RSpec.describe LinkDetailsExtractor do
|
|||
</html>
|
||||
HTML
|
||||
|
||||
include_examples 'structured data'
|
||||
it_behaves_like 'structured data'
|
||||
end
|
||||
|
||||
context 'with preceding block of unsupported LD+JSON' do
|
||||
|
@ -194,7 +194,7 @@ RSpec.describe LinkDetailsExtractor do
|
|||
</html>
|
||||
HTML
|
||||
|
||||
include_examples 'structured data'
|
||||
it_behaves_like 'structured data'
|
||||
end
|
||||
|
||||
context 'with unsupported in same block LD+JSON' do
|
||||
|
@ -218,7 +218,7 @@ RSpec.describe LinkDetailsExtractor do
|
|||
</html>
|
||||
HTML
|
||||
|
||||
include_examples 'structured data'
|
||||
it_behaves_like 'structured data'
|
||||
end
|
||||
|
||||
context 'with author names as array' do
|
||||
|
|
|
@ -56,7 +56,7 @@ RSpec.describe Mastodon::CLI::IpBlocks do
|
|||
end
|
||||
|
||||
context 'with valid IP addresses' do
|
||||
include_examples 'ip address blocking'
|
||||
it_behaves_like 'ip address blocking'
|
||||
end
|
||||
|
||||
context 'when a specified IP address is already blocked' do
|
||||
|
@ -84,7 +84,7 @@ RSpec.describe Mastodon::CLI::IpBlocks do
|
|||
.to('sign_up_requires_approval')
|
||||
end
|
||||
|
||||
include_examples 'ip address blocking'
|
||||
it_behaves_like 'ip address blocking'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -101,25 +101,25 @@ RSpec.describe Mastodon::CLI::IpBlocks do
|
|||
context 'with --comment option' do
|
||||
let(:options) { { severity: 'no_access', comment: 'Spam' } }
|
||||
|
||||
include_examples 'ip address blocking'
|
||||
it_behaves_like 'ip address blocking'
|
||||
end
|
||||
|
||||
context 'with --duration option' do
|
||||
let(:options) { { severity: 'no_access', duration: 10.days } }
|
||||
|
||||
include_examples 'ip address blocking'
|
||||
it_behaves_like 'ip address blocking'
|
||||
end
|
||||
|
||||
context 'with "sign_up_requires_approval" severity' do
|
||||
let(:options) { { severity: 'sign_up_requires_approval' } }
|
||||
|
||||
include_examples 'ip address blocking'
|
||||
it_behaves_like 'ip address blocking'
|
||||
end
|
||||
|
||||
context 'with "sign_up_block" severity' do
|
||||
let(:options) { { severity: 'sign_up_block' } }
|
||||
|
||||
include_examples 'ip address blocking'
|
||||
it_behaves_like 'ip address blocking'
|
||||
end
|
||||
|
||||
context 'when a specified IP address fails to be blocked' do
|
||||
|
|
|
@ -207,18 +207,18 @@ RSpec.describe Mastodon::RedisConfiguration do
|
|||
end
|
||||
end
|
||||
|
||||
include_examples 'setting a different driver'
|
||||
include_examples 'setting a namespace'
|
||||
include_examples 'sentinel support'
|
||||
it_behaves_like 'setting a different driver'
|
||||
it_behaves_like 'setting a namespace'
|
||||
it_behaves_like 'sentinel support'
|
||||
end
|
||||
|
||||
describe '#sidekiq' do
|
||||
subject { redis_environment.sidekiq }
|
||||
|
||||
include_examples 'secondary configuration', 'SIDEKIQ'
|
||||
include_examples 'setting a different driver'
|
||||
include_examples 'setting a namespace'
|
||||
include_examples 'sentinel support', 'SIDEKIQ'
|
||||
it_behaves_like 'secondary configuration', 'SIDEKIQ'
|
||||
it_behaves_like 'setting a different driver'
|
||||
it_behaves_like 'setting a namespace'
|
||||
it_behaves_like 'sentinel support', 'SIDEKIQ'
|
||||
end
|
||||
|
||||
describe '#cache' do
|
||||
|
@ -256,8 +256,8 @@ RSpec.describe Mastodon::RedisConfiguration do
|
|||
end
|
||||
end
|
||||
|
||||
include_examples 'secondary configuration', 'CACHE'
|
||||
include_examples 'setting a different driver'
|
||||
include_examples 'sentinel support', 'CACHE'
|
||||
it_behaves_like 'secondary configuration', 'CACHE'
|
||||
it_behaves_like 'setting a different driver'
|
||||
it_behaves_like 'sentinel support', 'CACHE'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ RSpec.describe NotificationMailer do
|
|||
let(:notification) { Notification.create!(account: receiver.account, activity: mention) }
|
||||
let(:mail) { prepared_mailer_for(receiver.account).mention }
|
||||
|
||||
include_examples 'localized subject', 'notification_mailer.mention.subject', name: 'bob'
|
||||
it_behaves_like 'localized subject', 'notification_mailer.mention.subject', name: 'bob'
|
||||
|
||||
it 'renders the email' do
|
||||
expect(mail)
|
||||
|
@ -47,8 +47,8 @@ RSpec.describe NotificationMailer do
|
|||
.and have_standard_headers('mention').for(receiver)
|
||||
end
|
||||
|
||||
include_examples 'delivery to non functional user'
|
||||
include_examples 'delivery without status'
|
||||
it_behaves_like 'delivery to non functional user'
|
||||
it_behaves_like 'delivery without status'
|
||||
end
|
||||
|
||||
describe 'follow' do
|
||||
|
@ -56,7 +56,7 @@ RSpec.describe NotificationMailer do
|
|||
let(:notification) { Notification.create!(account: receiver.account, activity: follow) }
|
||||
let(:mail) { prepared_mailer_for(receiver.account).follow }
|
||||
|
||||
include_examples 'localized subject', 'notification_mailer.follow.subject', name: 'bob'
|
||||
it_behaves_like 'localized subject', 'notification_mailer.follow.subject', name: 'bob'
|
||||
|
||||
it 'renders the email' do
|
||||
expect(mail)
|
||||
|
@ -66,7 +66,7 @@ RSpec.describe NotificationMailer do
|
|||
.and have_standard_headers('follow').for(receiver)
|
||||
end
|
||||
|
||||
include_examples 'delivery to non functional user'
|
||||
it_behaves_like 'delivery to non functional user'
|
||||
end
|
||||
|
||||
describe 'favourite' do
|
||||
|
@ -74,7 +74,7 @@ RSpec.describe NotificationMailer do
|
|||
let(:notification) { Notification.create!(account: receiver.account, activity: favourite) }
|
||||
let(:mail) { prepared_mailer_for(own_status.account).favourite }
|
||||
|
||||
include_examples 'localized subject', 'notification_mailer.favourite.subject', name: 'bob'
|
||||
it_behaves_like 'localized subject', 'notification_mailer.favourite.subject', name: 'bob'
|
||||
|
||||
it 'renders the email' do
|
||||
expect(mail)
|
||||
|
@ -86,8 +86,8 @@ RSpec.describe NotificationMailer do
|
|||
.and have_standard_headers('favourite').for(receiver)
|
||||
end
|
||||
|
||||
include_examples 'delivery to non functional user'
|
||||
include_examples 'delivery without status'
|
||||
it_behaves_like 'delivery to non functional user'
|
||||
it_behaves_like 'delivery without status'
|
||||
end
|
||||
|
||||
describe 'reblog' do
|
||||
|
@ -95,7 +95,7 @@ RSpec.describe NotificationMailer do
|
|||
let(:notification) { Notification.create!(account: receiver.account, activity: reblog) }
|
||||
let(:mail) { prepared_mailer_for(own_status.account).reblog }
|
||||
|
||||
include_examples 'localized subject', 'notification_mailer.reblog.subject', name: 'bob'
|
||||
it_behaves_like 'localized subject', 'notification_mailer.reblog.subject', name: 'bob'
|
||||
|
||||
it 'renders the email' do
|
||||
expect(mail)
|
||||
|
@ -107,8 +107,8 @@ RSpec.describe NotificationMailer do
|
|||
.and have_standard_headers('reblog').for(receiver)
|
||||
end
|
||||
|
||||
include_examples 'delivery to non functional user'
|
||||
include_examples 'delivery without status'
|
||||
it_behaves_like 'delivery to non functional user'
|
||||
it_behaves_like 'delivery without status'
|
||||
end
|
||||
|
||||
describe 'follow_request' do
|
||||
|
@ -116,7 +116,7 @@ RSpec.describe NotificationMailer do
|
|||
let(:notification) { Notification.create!(account: receiver.account, activity: follow_request) }
|
||||
let(:mail) { prepared_mailer_for(receiver.account).follow_request }
|
||||
|
||||
include_examples 'localized subject', 'notification_mailer.follow_request.subject', name: 'bob'
|
||||
it_behaves_like 'localized subject', 'notification_mailer.follow_request.subject', name: 'bob'
|
||||
|
||||
it 'renders the email' do
|
||||
expect(mail)
|
||||
|
@ -126,7 +126,7 @@ RSpec.describe NotificationMailer do
|
|||
.and have_standard_headers('follow_request').for(receiver)
|
||||
end
|
||||
|
||||
include_examples 'delivery to non functional user'
|
||||
it_behaves_like 'delivery to non functional user'
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -29,10 +29,10 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(Rails.configuration.x.local_domain))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.confirmation_instructions.subject',
|
||||
instance: Rails.configuration.x.local_domain
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'localized subject',
|
||||
'devise.mailer.confirmation_instructions.subject',
|
||||
instance: Rails.configuration.x.local_domain
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#reconfirmation_instructions' do
|
||||
|
@ -48,10 +48,10 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(Rails.configuration.x.local_domain))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.confirmation_instructions.subject',
|
||||
instance: Rails.configuration.x.local_domain
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'localized subject',
|
||||
'devise.mailer.confirmation_instructions.subject',
|
||||
instance: Rails.configuration.x.local_domain
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#reset_password_instructions' do
|
||||
|
@ -66,9 +66,9 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text('spec'))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.reset_password_instructions.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'localized subject',
|
||||
'devise.mailer.reset_password_instructions.subject'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#password_change' do
|
||||
|
@ -82,9 +82,9 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.password_change.title')))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.password_change.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'localized subject',
|
||||
'devise.mailer.password_change.subject'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#email_changed' do
|
||||
|
@ -98,9 +98,9 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.email_changed.title')))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.email_changed.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'localized subject',
|
||||
'devise.mailer.email_changed.subject'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#warning' do
|
||||
|
@ -129,9 +129,9 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.webauthn_credential.deleted.title')))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'devise.mailer.webauthn_credential.deleted.subject'
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'localized subject',
|
||||
'devise.mailer.webauthn_credential.deleted.subject'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#suspicious_sign_in' do
|
||||
|
@ -148,8 +148,8 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('user_mailer.suspicious_sign_in.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'user_mailer.suspicious_sign_in.subject'
|
||||
it_behaves_like 'localized subject',
|
||||
'user_mailer.suspicious_sign_in.subject'
|
||||
end
|
||||
|
||||
describe '#failed_2fa' do
|
||||
|
@ -166,8 +166,8 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('user_mailer.failed_2fa.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'localized subject',
|
||||
'user_mailer.failed_2fa.subject'
|
||||
it_behaves_like 'localized subject',
|
||||
'user_mailer.failed_2fa.subject'
|
||||
end
|
||||
|
||||
describe '#appeal_approved' do
|
||||
|
@ -204,7 +204,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.two_factor_enabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#two_factor_disabled' do
|
||||
|
@ -217,7 +217,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.two_factor_disabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#webauthn_enabled' do
|
||||
|
@ -230,7 +230,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.webauthn_enabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#webauthn_disabled' do
|
||||
|
@ -243,7 +243,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.webauthn_disabled.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#two_factor_recovery_codes_changed' do
|
||||
|
@ -256,7 +256,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.two_factor_recovery_codes_changed.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#webauthn_credential_added' do
|
||||
|
@ -270,7 +270,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('devise.mailer.webauthn_credential.added.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#welcome' do
|
||||
|
@ -289,7 +289,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('user_mailer.welcome.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#backup_ready' do
|
||||
|
@ -303,7 +303,7 @@ RSpec.describe UserMailer do
|
|||
.and(have_body_text(I18n.t('user_mailer.backup_ready.explanation')))
|
||||
end
|
||||
|
||||
include_examples 'delivery to memorialized user'
|
||||
it_behaves_like 'delivery to memorialized user'
|
||||
end
|
||||
|
||||
describe '#terms_of_service_changed' do
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Account do
|
||||
include_examples 'Account::Search'
|
||||
include_examples 'Reviewable'
|
||||
it_behaves_like 'Account::Search'
|
||||
it_behaves_like 'Reviewable'
|
||||
|
||||
context 'with an account record' do
|
||||
subject { Fabricate(:account) }
|
||||
|
@ -992,8 +992,8 @@ RSpec.describe Account do
|
|||
end
|
||||
end
|
||||
|
||||
include_examples 'AccountAvatar', :account
|
||||
include_examples 'AccountHeader', :account
|
||||
it_behaves_like 'AccountAvatar', :account
|
||||
it_behaves_like 'AccountHeader', :account
|
||||
|
||||
describe '#increment_count!' do
|
||||
subject { Fabricate(:account) }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe CustomFilter do
|
||||
include_examples 'Expireable'
|
||||
it_behaves_like 'Expireable'
|
||||
|
||||
describe 'Validations' do
|
||||
it { is_expected.to validate_presence_of(:title) }
|
||||
|
|
|
@ -17,7 +17,7 @@ RSpec.describe FeaturedTag do
|
|||
|
||||
let(:account) { Fabricate :account }
|
||||
|
||||
it { is_expected.to_not allow_value('Test').for(:name) }
|
||||
it { is_expected.to_not allow_value('Test').for(:name).against(:tag_id) }
|
||||
|
||||
context 'when account has hit limit' do
|
||||
before { stub_const 'FeaturedTag::LIMIT', 1 }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Invite do
|
||||
include_examples 'Expireable'
|
||||
it_behaves_like 'Expireable'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:user).inverse_of(:invites) }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe IpBlock do
|
||||
include_examples 'Expireable'
|
||||
it_behaves_like 'Expireable'
|
||||
|
||||
describe 'Validations' do
|
||||
subject { Fabricate.build :ip_block }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe LoginActivity do
|
||||
include_examples 'BrowserDetection'
|
||||
it_behaves_like 'BrowserDetection'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:user).required }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Mute do
|
||||
include_examples 'Expireable'
|
||||
it_behaves_like 'Expireable'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:account).required }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Poll do
|
||||
include_examples 'Expireable'
|
||||
it_behaves_like 'Expireable'
|
||||
|
||||
describe '#reset_votes!' do
|
||||
let(:poll) { Fabricate :poll, cached_tallies: [2, 3], votes_count: 5, voters_count: 5 }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe PreviewCardProvider do
|
||||
include_examples 'Reviewable'
|
||||
it_behaves_like 'Reviewable'
|
||||
|
||||
describe 'scopes' do
|
||||
let(:trendable_and_reviewed) { Fabricate(:preview_card_provider, trendable: true, reviewed_at: 5.days.ago) }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe PreviewCardTrend do
|
||||
include_examples 'RankedTrend'
|
||||
it_behaves_like 'RankedTrend'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:preview_card).required }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe SessionActivation do
|
||||
include_examples 'BrowserDetection'
|
||||
it_behaves_like 'BrowserDetection'
|
||||
|
||||
describe '.active?' do
|
||||
subject { described_class.active?(id) }
|
||||
|
|
|
@ -9,7 +9,7 @@ RSpec.describe Status do
|
|||
let(:bob) { Fabricate(:account, username: 'bob') }
|
||||
let(:other) { Fabricate(:status, account: bob, text: 'Skulls for the skull god! The enemy\'s gates are sideways!') }
|
||||
|
||||
include_examples 'Status::Visibility'
|
||||
it_behaves_like 'Status::Visibility'
|
||||
|
||||
describe '#local?' do
|
||||
it 'returns true when no remote URI is set' do
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe StatusTrend do
|
||||
include_examples 'RankedTrend'
|
||||
it_behaves_like 'RankedTrend'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:account).required }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Tag do
|
||||
include_examples 'Reviewable'
|
||||
it_behaves_like 'Reviewable'
|
||||
|
||||
describe 'Validations' do
|
||||
describe 'name' do
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe TagTrend do
|
||||
include_examples 'RankedTrend'
|
||||
it_behaves_like 'RankedTrend'
|
||||
|
||||
describe 'Associations' do
|
||||
it { is_expected.to belong_to(:tag).required }
|
||||
|
|
|
@ -25,10 +25,10 @@ RSpec.describe Admin::Fasp::ProviderPolicy, type: :policy do
|
|||
end
|
||||
|
||||
permissions :index?, :create? do
|
||||
include_examples 'admin only', Fasp::Provider
|
||||
it_behaves_like 'admin only', Fasp::Provider
|
||||
end
|
||||
|
||||
permissions :show?, :create?, :update?, :destroy? do
|
||||
include_examples 'admin only', :fasp_provider
|
||||
it_behaves_like 'admin only', :fasp_provider
|
||||
end
|
||||
end
|
||||
|
|
|
@ -127,10 +127,10 @@ RSpec.describe 'FeaturedTags' do
|
|||
FeaturedTag.create(name: params[:name], account: user.account)
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
it 'returns http success' do
|
||||
post '/api/v1/featured_tags', headers: headers, params: params
|
||||
|
||||
expect(response).to have_http_status(422)
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
|
|
|
@ -161,4 +161,116 @@ RSpec.describe 'Tags' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/tags/:id/feature' do
|
||||
subject do
|
||||
post "/api/v1/tags/#{name}/feature", headers: headers
|
||||
end
|
||||
|
||||
let!(:tag) { Fabricate(:tag) }
|
||||
let(:name) { tag.name }
|
||||
let(:scopes) { 'write:accounts' }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
context 'when the tag exists' do
|
||||
it 'creates featured tag', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
expect(FeaturedTag.where(tag: tag, account: user.account)).to exist
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the tag does not exist' do
|
||||
let(:name) { 'hoge' }
|
||||
|
||||
it 'creates a new tag with the specified name', :aggregate_failures 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(FeaturedTag.where(tag: Tag.find_by(name: name), account: user.account)).to exist
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the tag name is invalid' do
|
||||
let(:name) { 'tag-name' }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the Authorization header is missing' do
|
||||
let(:headers) { {} }
|
||||
let(:name) { 'unauthorized' }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #unfeature' do
|
||||
subject do
|
||||
post "/api/v1/tags/#{name}/unfeature", headers: headers
|
||||
end
|
||||
|
||||
let(:name) { tag.name }
|
||||
let!(:tag) { Fabricate(:tag, name: 'foo') }
|
||||
let(:scopes) { 'write:accounts' }
|
||||
|
||||
before do
|
||||
Fabricate(:featured_tag, account: user.account, tag: tag)
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
it 'removes the featured tag', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
expect(FeaturedTag.where(tag: tag, account: user.account)).to_not exist
|
||||
end
|
||||
|
||||
context 'when the tag name is invalid' do
|
||||
let(:name) { 'tag-name' }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the Authorization header is missing' do
|
||||
let(:headers) { {} }
|
||||
let(:name) { 'unauthorized' }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
expect(response.content_type)
|
||||
.to start_with('application/json')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,7 +29,7 @@ RSpec.describe 'Managing OAuth Tokens' do
|
|||
access_grant.plaintext_token
|
||||
end
|
||||
|
||||
shared_examples 'returns originally requested scopes' do
|
||||
shared_examples 'original scope request preservation' do
|
||||
it 'returns all scopes requested for the given code' do
|
||||
subject
|
||||
|
||||
|
@ -41,26 +41,26 @@ RSpec.describe 'Managing OAuth Tokens' do
|
|||
context 'with no scopes specified' do
|
||||
let(:scope) { nil }
|
||||
|
||||
include_examples 'returns originally requested scopes'
|
||||
it_behaves_like 'original scope request preservation'
|
||||
end
|
||||
|
||||
context 'with scopes specified' do
|
||||
context 'when the scopes were requested for this code' do
|
||||
let(:scope) { 'write' }
|
||||
|
||||
include_examples 'returns originally requested scopes'
|
||||
it_behaves_like 'original scope request preservation'
|
||||
end
|
||||
|
||||
context 'when the scope was not requested for the code' do
|
||||
let(:scope) { 'follow' }
|
||||
|
||||
include_examples 'returns originally requested scopes'
|
||||
it_behaves_like 'original scope request preservation'
|
||||
end
|
||||
|
||||
context 'when the scope does not belong to the application' do
|
||||
let(:scope) { 'push' }
|
||||
|
||||
include_examples 'returns originally requested scopes'
|
||||
it_behaves_like 'original scope request preservation'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -130,14 +130,14 @@ RSpec.describe 'OmniAuth callbacks' do
|
|||
end
|
||||
|
||||
describe '#openid_connect', if: ENV['OIDC_ENABLED'] == 'true' && ENV['OIDC_SCOPE'].present? do
|
||||
include_examples 'omniauth provider callbacks', :openid_connect
|
||||
it_behaves_like 'omniauth provider callbacks', :openid_connect
|
||||
end
|
||||
|
||||
describe '#cas', if: ENV['CAS_ENABLED'] == 'true' do
|
||||
include_examples 'omniauth provider callbacks', :cas
|
||||
it_behaves_like 'omniauth provider callbacks', :cas
|
||||
end
|
||||
|
||||
describe '#saml', if: ENV['SAML_ENABLED'] == 'true' do
|
||||
include_examples 'omniauth provider callbacks', :saml
|
||||
it_behaves_like 'omniauth provider callbacks', :saml
|
||||
end
|
||||
end
|
||||
|
|
|
@ -70,7 +70,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
|
|||
expect(account.domain).to eq 'example.com'
|
||||
end
|
||||
|
||||
include_examples 'sets profile data'
|
||||
it_behaves_like 'sets profile data'
|
||||
end
|
||||
|
||||
context 'when WebFinger presents different domain than URI' do
|
||||
|
@ -94,7 +94,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do
|
|||
expect(account.domain).to eq 'iscool.af'
|
||||
end
|
||||
|
||||
include_examples 'sets profile data'
|
||||
it_behaves_like 'sets profile data'
|
||||
end
|
||||
|
||||
context 'when WebFinger returns a different URI' do
|
||||
|
|
|
@ -70,7 +70,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
|||
expect(account.domain).to eq 'example.com'
|
||||
end
|
||||
|
||||
include_examples 'sets profile data'
|
||||
it_behaves_like 'sets profile data'
|
||||
end
|
||||
|
||||
context 'when WebFinger presents different domain than URI' do
|
||||
|
@ -94,7 +94,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
|||
expect(account.domain).to eq 'iscool.af'
|
||||
end
|
||||
|
||||
include_examples 'sets profile data'
|
||||
it_behaves_like 'sets profile data'
|
||||
end
|
||||
|
||||
context 'when WebFinger returns a different URI' do
|
||||
|
|
|
@ -115,7 +115,7 @@ RSpec.describe BulkImportRowService do
|
|||
account.follow!(target_account)
|
||||
end
|
||||
|
||||
include_examples 'row import success and list addition'
|
||||
it_behaves_like 'row import success and list addition'
|
||||
end
|
||||
|
||||
context 'when the user already requested to follow the target account' do
|
||||
|
@ -123,17 +123,17 @@ RSpec.describe BulkImportRowService do
|
|||
account.request_follow!(target_account)
|
||||
end
|
||||
|
||||
include_examples 'row import success and list addition'
|
||||
it_behaves_like 'row import success and list addition'
|
||||
end
|
||||
|
||||
context 'when the target account is neither followed nor requested' do
|
||||
include_examples 'row import success and list addition'
|
||||
it_behaves_like 'row import success and list addition'
|
||||
end
|
||||
|
||||
context 'when the target account is the user themself' do
|
||||
let(:target_account) { account }
|
||||
|
||||
include_examples 'row import success and list addition'
|
||||
it_behaves_like 'row import success and list addition'
|
||||
end
|
||||
|
||||
def add_target_account_to_list
|
||||
|
@ -153,7 +153,7 @@ RSpec.describe BulkImportRowService do
|
|||
end
|
||||
|
||||
context 'when the list does not exist yet' do
|
||||
include_examples 'common behavior'
|
||||
it_behaves_like 'common behavior'
|
||||
end
|
||||
|
||||
context 'when the list exists' do
|
||||
|
@ -161,7 +161,7 @@ RSpec.describe BulkImportRowService do
|
|||
Fabricate(:list, account: account, title: list_name)
|
||||
end
|
||||
|
||||
include_examples 'common behavior'
|
||||
it_behaves_like 'common behavior'
|
||||
|
||||
it 'does not create a new list' do
|
||||
account.follow!(target_account)
|
||||
|
|
|
@ -20,11 +20,9 @@ RSpec.describe CreateFeaturedTagService do
|
|||
context 'with a remote account' do
|
||||
let(:account) { Fabricate(:account, domain: 'host.example') }
|
||||
|
||||
it 'creates a new featured tag and does not distributes' do
|
||||
it 'raises argument error' do
|
||||
expect { subject.call(account, tag) }
|
||||
.to change(FeaturedTag, :count).by(1)
|
||||
expect(ActivityPub::AccountRawDistributionWorker)
|
||||
.to_not have_enqueued_sidekiq_job(any_args)
|
||||
.to raise_error ArgumentError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -128,7 +128,7 @@ RSpec.describe DeleteAccountService do
|
|||
let!(:remote_alice) { Fabricate(:account, inbox_url: 'https://alice.com/inbox', domain: 'alice.com', protocol: :activitypub) }
|
||||
let!(:remote_bob) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', domain: 'bob.com', protocol: :activitypub) }
|
||||
|
||||
include_examples 'common behavior' do
|
||||
it_behaves_like 'common behavior' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:local_follower) { Fabricate(:account) }
|
||||
|
||||
|
@ -145,7 +145,7 @@ RSpec.describe DeleteAccountService do
|
|||
stub_request(:post, account.inbox_url).to_return(status: 201)
|
||||
end
|
||||
|
||||
include_examples 'common behavior' do
|
||||
it_behaves_like 'common behavior' do
|
||||
let(:account) { Fabricate(:account, inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') }
|
||||
let(:local_follower) { Fabricate(:account) }
|
||||
|
||||
|
|
|
@ -23,13 +23,9 @@ RSpec.describe RemoveFeaturedTagService do
|
|||
context 'when called by a non local account' do
|
||||
let(:account) { Fabricate(:account, domain: 'host.example') }
|
||||
|
||||
it 'destroys the featured tag and does not send a distribution' do
|
||||
subject.call(account, featured_tag)
|
||||
|
||||
expect { featured_tag.reload }
|
||||
.to raise_error(ActiveRecord::RecordNotFound)
|
||||
expect(ActivityPub::AccountRawDistributionWorker)
|
||||
.to_not have_enqueued_sidekiq_job(any_args)
|
||||
it 'raises argument error' do
|
||||
expect { subject.call(account, featured_tag) }
|
||||
.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,7 +46,7 @@ RSpec.describe SuspendAccountService do
|
|||
json['type'] == 'Update' && json['actor'] == actor_id && json['object']['id'] == actor_id && json['object']['suspended']
|
||||
end
|
||||
|
||||
include_examples 'common behavior' do
|
||||
it_behaves_like 'common behavior' do
|
||||
let!(:account) { Fabricate(:account) }
|
||||
let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub, domain: 'alice.com') }
|
||||
let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') }
|
||||
|
@ -72,7 +72,7 @@ RSpec.describe SuspendAccountService do
|
|||
json['type'] == 'Reject' && json['actor'] == ActivityPub::TagManager.instance.uri_for(followee) && json['object']['actor'] == account.uri
|
||||
end
|
||||
|
||||
include_examples 'common behavior' do
|
||||
it_behaves_like 'common behavior' do
|
||||
let!(:account) { Fabricate(:account, domain: 'bob.com', uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
|
||||
let!(:local_followee) { Fabricate(:account) }
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UnsuspendAccountService do
|
||||
shared_context 'with common context' do
|
||||
shared_context 'when account is unsuspended' do
|
||||
subject { described_class.new.call(account) }
|
||||
|
||||
let!(:local_follower) { Fabricate(:user, current_sign_in_at: 1.hour.ago).account }
|
||||
|
@ -31,12 +31,13 @@ RSpec.describe UnsuspendAccountService do
|
|||
stub_request(:post, 'https://bob.com/inbox').to_return(status: 201)
|
||||
end
|
||||
|
||||
let!(:account) { Fabricate(:account) }
|
||||
|
||||
it 'does not change the “suspended” flag' do
|
||||
expect { subject }.to_not change(account, :suspended?)
|
||||
end
|
||||
|
||||
include_examples 'with common context' do
|
||||
let!(:account) { Fabricate(:account) }
|
||||
include_context 'when account is unsuspended' do
|
||||
let!(:remote_follower) { Fabricate(:account, uri: 'https://alice.com', inbox_url: 'https://alice.com/inbox', protocol: :activitypub, domain: 'alice.com') }
|
||||
let!(:remote_reporter) { Fabricate(:account, uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub, domain: 'bob.com') }
|
||||
|
||||
|
@ -65,8 +66,8 @@ RSpec.describe UnsuspendAccountService do
|
|||
end
|
||||
|
||||
describe 'unsuspending a remote account' do
|
||||
include_examples 'with common context' do
|
||||
let!(:account) { Fabricate(:account, domain: 'bob.com', uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
|
||||
include_context 'when account is unsuspended' do
|
||||
let!(:account) { Fabricate(:account, domain: 'bob.com', uri: 'https://bob.com', inbox_url: 'https://bob.com/inbox', protocol: :activitypub) }
|
||||
let!(:resolve_account_service) { instance_double(ResolveAccountService) }
|
||||
|
||||
before do
|
||||
|
|
|
@ -8,95 +8,82 @@ RSpec.describe Import::RowWorker do
|
|||
let(:row) { Fabricate(:bulk_import_row, bulk_import: import) }
|
||||
|
||||
describe '#perform' do
|
||||
before do
|
||||
allow(BulkImportRowService).to receive(:new).and_return(service_double)
|
||||
before { allow(BulkImportRowService).to receive(:new).and_return(service_double) }
|
||||
|
||||
shared_context 'when service succeeds' do
|
||||
let(:service_double) { instance_double(BulkImportRowService, call: true) }
|
||||
end
|
||||
|
||||
shared_context 'when service fails' do
|
||||
let(:service_double) { instance_double(BulkImportRowService, call: false) }
|
||||
end
|
||||
|
||||
shared_context 'when service errors' do
|
||||
let(:service_double) { instance_double(BulkImportRowService) }
|
||||
before { allow(service_double).to receive(:call).and_raise('dummy error') }
|
||||
end
|
||||
|
||||
shared_examples 'clean failure' do
|
||||
let(:service_double) { instance_double(BulkImportRowService, call: false) }
|
||||
|
||||
it 'calls BulkImportRowService' do
|
||||
subject.perform(row.id)
|
||||
expect(service_double).to have_received(:call).with(row)
|
||||
end
|
||||
|
||||
it 'increases the number of processed items' do
|
||||
expect { subject.perform(row.id) }.to(change { import.reload.processed_items }.by(+1))
|
||||
end
|
||||
|
||||
it 'does not increase the number of imported items' do
|
||||
expect { subject.perform(row.id) }.to_not(change { import.reload.imported_items })
|
||||
end
|
||||
|
||||
it 'does not delete the row' do
|
||||
subject.perform(row.id)
|
||||
expect(BulkImportRow.exists?(row.id)).to be true
|
||||
it 'calls service, increases processed items, preserves imported items, and keeps row' do
|
||||
expect { subject.perform(row.id) }
|
||||
.to change { import.reload.processed_items }.by(+1)
|
||||
.and not_change { import.reload.imported_items }
|
||||
.and(not_change { BulkImportRow.exists?(row.id) }.from(true))
|
||||
expect(service_double)
|
||||
.to have_received(:call).with(row)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'unclean failure' do
|
||||
let(:service_double) { instance_double(BulkImportRowService) }
|
||||
|
||||
before do
|
||||
allow(service_double).to receive(:call) do
|
||||
raise 'dummy error'
|
||||
end
|
||||
end
|
||||
|
||||
it 'raises an error and does not change processed items count' do
|
||||
expect { subject.perform(row.id) }.to raise_error(StandardError, 'dummy error').and(not_change { import.reload.processed_items })
|
||||
end
|
||||
|
||||
it 'does not delete the row' do
|
||||
expect { subject.perform(row.id) }.to raise_error(StandardError, 'dummy error').and(not_change { BulkImportRow.exists?(row.id) })
|
||||
it 'raises an error, preserves processed items, and keeps row' do
|
||||
expect { subject.perform(row.id) }
|
||||
.to raise_error(StandardError, 'dummy error')
|
||||
.and(not_change { import.reload.processed_items })
|
||||
.and(not_change { BulkImportRow.exists?(row.id) }.from(true))
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'clean success' do
|
||||
let(:service_double) { instance_double(BulkImportRowService, call: true) }
|
||||
|
||||
it 'calls BulkImportRowService' do
|
||||
subject.perform(row.id)
|
||||
it 'calls service, increases processed items, increases imported items, and deletes row' do
|
||||
expect { subject.perform(row.id) }
|
||||
.to change { import.reload.processed_items }.by(+1)
|
||||
.and change { import.reload.imported_items }.by(+1)
|
||||
.and(change { BulkImportRow.exists?(row.id) }.from(true).to(false))
|
||||
expect(service_double).to have_received(:call).with(row)
|
||||
end
|
||||
|
||||
it 'increases the number of processed items' do
|
||||
expect { subject.perform(row.id) }.to(change { import.reload.processed_items }.by(+1))
|
||||
end
|
||||
|
||||
it 'increases the number of imported items' do
|
||||
expect { subject.perform(row.id) }.to(change { import.reload.imported_items }.by(+1))
|
||||
end
|
||||
|
||||
it 'deletes the row' do
|
||||
expect { subject.perform(row.id) }.to change { BulkImportRow.exists?(row.id) }.from(true).to(false)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are multiple rows to process' do
|
||||
let(:import) { Fabricate(:bulk_import, total_items: 2, processed_items: 0, imported_items: 0, state: :in_progress) }
|
||||
|
||||
context 'with a clean failure' do
|
||||
include_examples 'clean failure'
|
||||
include_context 'when service fails'
|
||||
it_behaves_like 'clean failure'
|
||||
|
||||
it 'does not mark the import as finished' do
|
||||
expect { subject.perform(row.id) }.to_not(change { import.reload.state.to_sym })
|
||||
expect { subject.perform(row.id) }
|
||||
.to_not(change { import.reload.state.to_sym })
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an unclean failure' do
|
||||
include_examples 'unclean failure'
|
||||
include_context 'when service errors'
|
||||
it_behaves_like 'unclean failure'
|
||||
|
||||
it 'does not mark the import as finished' do
|
||||
expect { subject.perform(row.id) }.to raise_error(StandardError).and(not_change { import.reload.state.to_sym })
|
||||
expect { subject.perform(row.id) }
|
||||
.to raise_error(StandardError)
|
||||
.and(not_change { import.reload.state.to_sym })
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a clean success' do
|
||||
include_examples 'clean success'
|
||||
include_context 'when service succeeds'
|
||||
it_behaves_like 'clean success'
|
||||
|
||||
it 'does not mark the import as finished' do
|
||||
expect { subject.perform(row.id) }.to_not(change { import.reload.state.to_sym })
|
||||
expect { subject.perform(row.id) }
|
||||
.to_not(change { import.reload.state.to_sym })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -105,21 +92,28 @@ RSpec.describe Import::RowWorker do
|
|||
let(:import) { Fabricate(:bulk_import, total_items: 2, processed_items: 1, imported_items: 0, state: :in_progress) }
|
||||
|
||||
context 'with a clean failure' do
|
||||
include_examples 'clean failure'
|
||||
include_context 'when service fails'
|
||||
it_behaves_like 'clean failure'
|
||||
|
||||
it 'marks the import as finished' do
|
||||
expect { subject.perform(row.id) }.to change { import.reload.state.to_sym }.from(:in_progress).to(:finished)
|
||||
expect { subject.perform(row.id) }
|
||||
.to change { import.reload.state.to_sym }.from(:in_progress).to(:finished)
|
||||
end
|
||||
end
|
||||
|
||||
# NOTE: sidekiq retry logic may be a bit too difficult to test, so leaving this blind spot for now
|
||||
it_behaves_like 'unclean failure'
|
||||
context 'with an unclean failure' do
|
||||
# NOTE: sidekiq retry logic may be a bit too difficult to test, so leaving this blind spot for now
|
||||
include_context 'when service errors'
|
||||
it_behaves_like 'unclean failure'
|
||||
end
|
||||
|
||||
context 'with a clean success' do
|
||||
include_examples 'clean success'
|
||||
include_context 'when service succeeds'
|
||||
it_behaves_like 'clean success'
|
||||
|
||||
it 'marks the import as finished' do
|
||||
expect { subject.perform(row.id) }.to change { import.reload.state.to_sym }.from(:in_progress).to(:finished)
|
||||
expect { subject.perform(row.id) }
|
||||
.to change { import.reload.state.to_sym }.from(:in_progress).to(:finished)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -113,27 +113,27 @@ RSpec.describe MoveWorker do
|
|||
end
|
||||
|
||||
shared_examples 'common tests' do
|
||||
include_examples 'user note handling'
|
||||
include_examples 'block and mute handling'
|
||||
include_examples 'followers count handling'
|
||||
include_examples 'lists handling'
|
||||
it_behaves_like 'user note handling'
|
||||
it_behaves_like 'block and mute handling'
|
||||
it_behaves_like 'followers count handling'
|
||||
it_behaves_like 'lists handling'
|
||||
|
||||
context 'when a local user already follows both source and target' do
|
||||
before do
|
||||
local_follower.request_follow!(target_account)
|
||||
end
|
||||
|
||||
include_examples 'user note handling'
|
||||
include_examples 'block and mute handling'
|
||||
include_examples 'followers count handling'
|
||||
include_examples 'lists handling'
|
||||
it_behaves_like 'user note handling'
|
||||
it_behaves_like 'block and mute handling'
|
||||
it_behaves_like 'followers count handling'
|
||||
it_behaves_like 'lists handling'
|
||||
|
||||
context 'when the local user already has the target in a list' do
|
||||
before do
|
||||
list.accounts << target_account
|
||||
end
|
||||
|
||||
include_examples 'lists handling'
|
||||
it_behaves_like 'lists handling'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -142,17 +142,17 @@ RSpec.describe MoveWorker do
|
|||
local_follower.follow!(target_account)
|
||||
end
|
||||
|
||||
include_examples 'user note handling'
|
||||
include_examples 'block and mute handling'
|
||||
include_examples 'followers count handling'
|
||||
include_examples 'lists handling'
|
||||
it_behaves_like 'user note handling'
|
||||
it_behaves_like 'block and mute handling'
|
||||
it_behaves_like 'followers count handling'
|
||||
it_behaves_like 'lists handling'
|
||||
|
||||
context 'when the local user already has the target in a list' do
|
||||
before do
|
||||
list.accounts << target_account
|
||||
end
|
||||
|
||||
include_examples 'lists handling'
|
||||
it_behaves_like 'lists handling'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -164,7 +164,7 @@ RSpec.describe MoveWorker do
|
|||
expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, false)
|
||||
end
|
||||
|
||||
include_examples 'common tests'
|
||||
it_behaves_like 'common tests'
|
||||
end
|
||||
|
||||
context 'when target account is local' do
|
||||
|
@ -175,7 +175,7 @@ RSpec.describe MoveWorker do
|
|||
expect(UnfollowFollowWorker).to have_enqueued_sidekiq_job(local_follower.id, source_account.id, target_account.id, true)
|
||||
end
|
||||
|
||||
include_examples 'common tests'
|
||||
it_behaves_like 'common tests'
|
||||
end
|
||||
|
||||
context 'when both target and source accounts are local' do
|
||||
|
@ -187,7 +187,7 @@ RSpec.describe MoveWorker do
|
|||
expect(local_follower.following?(target_account)).to be true
|
||||
end
|
||||
|
||||
include_examples 'common tests'
|
||||
it_behaves_like 'common tests'
|
||||
|
||||
it 'does not allow the moved account to follow themselves' do
|
||||
source_account.follow!(target_account)
|
||||
|
|
|
@ -108,7 +108,7 @@ RSpec.describe Scheduler::AccountsStatusesCleanupScheduler do
|
|||
|
||||
context 'when the budget is lower than the number of toots to delete' do
|
||||
it 'deletes the appropriate statuses' do
|
||||
expect(Status.count).to be > (subject.compute_budget) # Data check
|
||||
expect(Status.count).to be > subject.compute_budget # Data check
|
||||
|
||||
expect { subject.perform }
|
||||
.to change(Status, :count).by(-subject.compute_budget) # Cleanable statuses
|
||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -13432,9 +13432,9 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"pg-connection-string@npm:^2.6.0":
|
||||
version: 2.8.1
|
||||
resolution: "pg-connection-string@npm:2.8.1"
|
||||
checksum: 10c0/87cb519d97a5bdc756f71a6b051eea4d4887e2e102bc694ecda935fe636a037666a0444729b08c7a26c2e9e4b052b2b366af58492ccc49704bacd6876f946ce8
|
||||
version: 2.8.5
|
||||
resolution: "pg-connection-string@npm:2.8.5"
|
||||
checksum: 10c0/5f65afc9dfc99ecf1583a1699c97511f3d505659c9c6a91db8cd0ffe862caa29060722712a034abd6da493356567261febf18b3a6ef223d0a219f0d50d959b97
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -13469,9 +13469,9 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"pg-protocol@npm:*":
|
||||
version: 1.9.0
|
||||
resolution: "pg-protocol@npm:1.9.0"
|
||||
checksum: 10c0/c37e61d7fafa97f22eabf12de69863f42fdabb3671df9cc2623bd0ffd6bdedc212e7e8460ad2c721c8a08d8477b4f128a923bf2381905d68a23a532ec7517c77
|
||||
version: 1.9.5
|
||||
resolution: "pg-protocol@npm:1.9.5"
|
||||
checksum: 10c0/5cb3444cf973adadd22ee9ea26bb1674f0d980ef8f9c66d426bbe67fc9cb5f0ca4a204bf7e432b3ab2ab59ac8227f4b18ab3b2e64eaed537e037e916991c7319
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue