Merge remote-tracking branch 'parent/main' into kb_development

This commit is contained in:
KMY 2023-12-09 10:04:10 +09:00
commit f20cb3fd59
60 changed files with 1036 additions and 695 deletions

View file

@ -120,7 +120,6 @@ module.exports = defineConfig({
'react/jsx-uses-react': 'off', // not needed with new JSX transform 'react/jsx-uses-react': 'off', // not needed with new JSX transform
'react/jsx-wrap-multilines': 'error', 'react/jsx-wrap-multilines': 'error',
'react/no-deprecated': 'off', 'react/no-deprecated': 'off',
'react/no-unknown-property': 'off',
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform 'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
'react/self-closing-comp': 'error', 'react/self-closing-comp': 'error',

View file

@ -50,7 +50,6 @@
matchManagers: ['bundler'], matchManagers: ['bundler'],
matchPackageNames: [ matchPackageNames: [
'rack', // Needs to be synced with Rails version 'rack', // Needs to be synced with Rails version
'sprockets', // Requires manual upgrade https://github.com/rails/sprockets/blob/master/UPGRADING.md#guide-to-upgrading-from-sprockets-3x-to-4x
'strong_migrations', // Requires manual upgrade 'strong_migrations', // Requires manual upgrade
'sidekiq', // Requires manual upgrade 'sidekiq', // Requires manual upgrade
'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version 'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version

View file

@ -5,7 +5,7 @@ ruby '>= 3.0.0'
gem 'puma', '~> 6.3' gem 'puma', '~> 6.3'
gem 'rails', '~> 7.1.1' gem 'rails', '~> 7.1.1'
gem 'sprockets', '~> 3.7.2' gem 'propshaft'
gem 'thor', '~> 1.2' gem 'thor', '~> 1.2'
gem 'rack', '~> 2.2.7' gem 'rack', '~> 2.2.7'
@ -89,7 +89,6 @@ gem 'sidekiq-unique-jobs', '~> 7.1'
gem 'sidekiq-bulk', '~> 0.2.0' gem 'sidekiq-bulk', '~> 0.2.0'
gem 'simple-navigation', '~> 4.4' gem 'simple-navigation', '~> 4.4'
gem 'simple_form', '~> 5.2' gem 'simple_form', '~> 5.2'
gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie'
gem 'stoplight', '~> 3.0.1' gem 'stoplight', '~> 3.0.1'
gem 'strong_migrations', '1.6.4' gem 'strong_migrations', '1.6.4'
gem 'tty-prompt', '~> 0.23', require: false gem 'tty-prompt', '~> 0.23', require: false

View file

@ -197,7 +197,7 @@ GEM
activesupport activesupport
cbor (0.5.9.6) cbor (0.5.9.6)
charlock_holmes (0.7.7) charlock_holmes (0.7.7)
chewy (7.3.4) chewy (7.3.5)
activesupport (>= 5.2) activesupport (>= 5.2)
elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch (>= 7.12.0, < 7.14.0)
elasticsearch-dsl elasticsearch-dsl
@ -377,7 +377,7 @@ GEM
terminal-table (>= 1.5.1) terminal-table (>= 1.5.1)
idn-ruby (0.1.5) idn-ruby (0.1.5)
io-console (0.6.0) io-console (0.6.0)
irb (1.10.0) irb (1.10.1)
rdoc rdoc
reline (>= 0.3.8) reline (>= 0.3.8)
jmespath (1.6.2) jmespath (1.6.2)
@ -484,7 +484,8 @@ GEM
nokogiri (1.15.5) nokogiri (1.15.5)
mini_portile2 (~> 2.8.2) mini_portile2 (~> 2.8.2)
racc (~> 1.4) racc (~> 1.4)
oj (3.16.1) oj (3.16.2)
bigdecimal (~> 3.1)
omniauth (2.1.1) omniauth (2.1.1)
hashie (>= 3.4.6) hashie (>= 3.4.6)
rack (>= 2.2.3) rack (>= 2.2.3)
@ -534,6 +535,11 @@ GEM
net-smtp net-smtp
premailer (~> 1.7, >= 1.7.9) premailer (~> 1.7, >= 1.7.9)
private_address_check (0.5.0) private_address_check (0.5.0)
propshaft (0.8.0)
actionpack (>= 7.0.0)
activesupport (>= 7.0.0)
rack
railties (>= 7.0.0)
psych (5.1.1.1) psych (5.1.1.1)
stringio stringio
public_suffix (5.0.4) public_suffix (5.0.4)
@ -608,7 +614,7 @@ GEM
link_header (~> 0.0, >= 0.0.8) link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.6.1) rdf-normalize (0.6.1)
rdf (~> 3.2) rdf (~> 3.2)
rdoc (6.6.0) rdoc (6.6.1)
psych (>= 4.0.0) psych (>= 4.0.0)
redcarpet (3.6.0) redcarpet (3.6.0)
redis (4.8.1) redis (4.8.1)
@ -704,7 +710,7 @@ GEM
scenic (1.7.0) scenic (1.7.0)
activerecord (>= 4.0.0) activerecord (>= 4.0.0)
railties (>= 4.0.0) railties (>= 4.0.0)
selenium-webdriver (4.15.0) selenium-webdriver (4.16.0)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0) rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0) websocket (~> 1.0)
@ -738,13 +744,6 @@ GEM
simplecov-lcov (0.8.0) simplecov-lcov (0.8.0)
simplecov_json_formatter (0.1.4) simplecov_json_formatter (0.1.4)
smart_properties (1.17.0) smart_properties (1.17.0)
sprockets (3.7.2)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.4.2)
actionpack (>= 5.2)
activesupport (>= 5.2)
sprockets (>= 3.0.0)
stackprof (0.2.25) stackprof (0.2.25)
statsd-ruby (1.5.0) statsd-ruby (1.5.0)
stoplight (3.0.2) stoplight (3.0.2)
@ -913,6 +912,7 @@ DEPENDENCIES
posix-spawn posix-spawn
premailer-rails premailer-rails
private_address_check (~> 0.5) private_address_check (~> 0.5)
propshaft
public_suffix (~> 5.0) public_suffix (~> 5.0)
puma (~> 6.3) puma (~> 6.3)
pundit (~> 2.3) pundit (~> 2.3)
@ -952,8 +952,6 @@ DEPENDENCIES
simple_form (~> 5.2) simple_form (~> 5.2)
simplecov (~> 0.22) simplecov (~> 0.22)
simplecov-lcov (~> 0.8) simplecov-lcov (~> 0.8)
sprockets (~> 3.7.2)
sprockets-rails (~> 3.4)
stackprof stackprof
stoplight (~> 3.0.1) stoplight (~> 3.0.1)
strong_migrations (= 1.6.4) strong_migrations (= 1.6.4)

View file

@ -299,9 +299,9 @@ class LoginForm extends React.PureComponent {
onFocus={this.handleFocus} onFocus={this.handleFocus}
onBlur={this.handleBlur} onBlur={this.handleBlur}
onKeyDown={this.handleKeyDown} onKeyDown={this.handleKeyDown}
autocomplete='off' autoComplete='off'
autocapitalize='off' autoCapitalize='off'
spellcheck='false' spellCheck='false'
/> />
<Button onClick={this.handleSubmit} disabled={isSubmitting || error}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button> <Button onClick={this.handleSubmit} disabled={isSubmitting || error}><FormattedMessage id='interaction_modal.login.action' defaultMessage='Take me home' /></Button>

View file

@ -99,7 +99,7 @@ class NavigationPanel extends Component {
</div> </div>
{banner && {banner &&
<div class='navigation-panel__banner'> <div className='navigation-panel__banner'>
{banner} {banner}
</div> </div>
} }

View file

@ -612,7 +612,6 @@ class Video extends PureComponent {
aria-label={alt} aria-label={alt}
title={alt} title={alt}
lang={lang} lang={lang}
volume={volume}
onClick={this.togglePlay} onClick={this.togglePlay}
onKeyDown={this.handleVideoKeyDown} onKeyDown={this.handleVideoKeyDown}
onPlay={this.handlePlay} onPlay={this.handlePlay}

View file

@ -702,7 +702,7 @@
"timeline_hint.resources.followers": "Les abonnés", "timeline_hint.resources.followers": "Les abonnés",
"timeline_hint.resources.follows": "Les abonnements", "timeline_hint.resources.follows": "Les abonnements",
"timeline_hint.resources.statuses": "Messages plus anciens", "timeline_hint.resources.statuses": "Messages plus anciens",
"trends.counter_by_accounts": "{count, plural, one {{counter} personne} other {{counter} personnes}} au cours {days, plural, one {des dernières 24h} other {des {days} derniers jours}}", "trends.counter_by_accounts": "{count, plural, one {{counter} pers.} other {{counter} pers.}} sur {days, plural, one {les dernières 24h} other {les {days} derniers jours}}",
"trends.trending_now": "Tendance en ce moment", "trends.trending_now": "Tendance en ce moment",
"ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.", "ui.beforeunload": "Votre brouillon sera perdu si vous quittez Mastodon.",
"units.short.billion": "{count}Md", "units.short.billion": "{count}Md",

View file

@ -13,7 +13,7 @@
"about.rules": "Kiszolgáló szabályai", "about.rules": "Kiszolgáló szabályai",
"account.account_note_header": "Feljegyzés", "account.account_note_header": "Feljegyzés",
"account.add_or_remove_from_list": "Hozzáadás vagy eltávolítás a listákról", "account.add_or_remove_from_list": "Hozzáadás vagy eltávolítás a listákról",
"account.badges.bot": "Bot", "account.badges.bot": "Automatizált",
"account.badges.group": "Csoport", "account.badges.group": "Csoport",
"account.block": "@{name} letiltása", "account.block": "@{name} letiltása",
"account.block_domain": "Domain blokkolása: {domain}", "account.block_domain": "Domain blokkolása: {domain}",
@ -63,8 +63,8 @@
"account.share": "@{name} profiljának megosztása", "account.share": "@{name} profiljának megosztása",
"account.show_reblogs": "@{name} megtolásainak mutatása", "account.show_reblogs": "@{name} megtolásainak mutatása",
"account.statuses_counter": "{count, plural, one {{counter} Bejegyzés} other {{counter} Bejegyzés}}", "account.statuses_counter": "{count, plural, one {{counter} Bejegyzés} other {{counter} Bejegyzés}}",
"account.unblock": "@{name} tiltásának feloldása", "account.unblock": "@{name} letiltásának feloldása",
"account.unblock_domain": "{domain} domain tiltás feloldása", "account.unblock_domain": "{domain} domain tiltásának feloldása",
"account.unblock_short": "Tiltás feloldása", "account.unblock_short": "Tiltás feloldása",
"account.unendorse": "Ne jelenjen meg a profilodon", "account.unendorse": "Ne jelenjen meg a profilodon",
"account.unfollow": "Követés megszüntetése", "account.unfollow": "Követés megszüntetése",
@ -138,21 +138,21 @@
"compose.language.search": "Nyelv keresése...", "compose.language.search": "Nyelv keresése...",
"compose.published.body": "A bejegyzés publikálásra került.", "compose.published.body": "A bejegyzés publikálásra került.",
"compose.published.open": "Megnyitás", "compose.published.open": "Megnyitás",
"compose.saved.body": "A bejegyzés mentésre került.", "compose.saved.body": "A bejegyzés mentve.",
"compose_form.direct_message_warning_learn_more": "Tudj meg többet", "compose_form.direct_message_warning_learn_more": "Tudj meg többet",
"compose_form.encryption_warning": "A bejegyzések Mastodonon nem használnak végpontok közötti titkosítást. Ne ossz meg semmilyen érzékeny információt Mastodonon.", "compose_form.encryption_warning": "A bejegyzések a Mastodonon nem használnak végpontok közti titkosítást. Ne ossz meg semmilyen érzékeny információt a Mastodonon.",
"compose_form.hashtag_warning": "Ez a bejegyzésed nem fog megjelenni semmilyen hashtag alatt, mivel nem nyilvános. Csak a nyilvános bejegyzések kereshetők hashtaggel.", "compose_form.hashtag_warning": "Ez a bejegyzésed nem fog megjelenni semmilyen hashtag alatt, mivel nem nyilvános. Csak a nyilvános bejegyzések kereshetők hashtaggel.",
"compose_form.lock_disclaimer": "A fiókod nincs {locked}. Bárki követni tud, hogy megtekintse a kizárólag követőknek szánt bejegyzéseket.", "compose_form.lock_disclaimer": "A fiókod nincs {locked}. Bárki követni tud, hogy megtekintse a kizárólag követőknek szánt bejegyzéseket.",
"compose_form.lock_disclaimer.lock": "lezárva", "compose_form.lock_disclaimer.lock": "zárolva",
"compose_form.placeholder": "Mi jár a fejedben?", "compose_form.placeholder": "Mi jár a fejedben?",
"compose_form.poll.add_option": "Lehetőség hozzáadása", "compose_form.poll.add_option": "Lehetőség hozzáadása",
"compose_form.poll.duration": "Szavazás időtartama", "compose_form.poll.duration": "Szavazás időtartama",
"compose_form.poll.option_placeholder": "{number}. lehetőség", "compose_form.poll.option_placeholder": "{number}. lehetőség",
"compose_form.poll.remove_option": "Lehetőség törlése", "compose_form.poll.remove_option": "Lehetőség eltávolítása",
"compose_form.poll.switch_to_multiple": "Szavazás megváltoztatása több választásosra", "compose_form.poll.switch_to_multiple": "Szavazás megváltoztatása több választásosra",
"compose_form.poll.switch_to_single": "Szavazás megváltoztatása egyetlen választásosra", "compose_form.poll.switch_to_single": "Szavazás megváltoztatása egyetlen választásosra",
"compose_form.publish": "Közzététel", "compose_form.publish": "Közzététel",
"compose_form.publish_form": "Közzététel", "compose_form.publish_form": "Új bejegyzés",
"compose_form.publish_loud": "{publish}!", "compose_form.publish_loud": "{publish}!",
"compose_form.save_changes": "Módosítások mentése", "compose_form.save_changes": "Módosítások mentése",
"compose_form.sensitive.hide": "{count, plural, one {Média kényesnek jelölése} other {Média kényesnek jelölése}}", "compose_form.sensitive.hide": "{count, plural, one {Média kényesnek jelölése} other {Média kényesnek jelölése}}",
@ -195,13 +195,13 @@
"copy_icon_button.copied": "A szöveg a vágólapra másolva", "copy_icon_button.copied": "A szöveg a vágólapra másolva",
"copypaste.copied": "Másolva", "copypaste.copied": "Másolva",
"copypaste.copy_to_clipboard": "Másolás vágólapra", "copypaste.copy_to_clipboard": "Másolás vágólapra",
"directory.federated": "Az ismert fediverzumból", "directory.federated": "Az ismert födiverzumból",
"directory.local": "Csak {domain} tartományból", "directory.local": "Csak {domain} tartományból",
"directory.new_arrivals": "Új csatlakozók", "directory.new_arrivals": "Új csatlakozók",
"directory.recently_active": "Nemrég aktív", "directory.recently_active": "Nemrég aktív",
"disabled_account_banner.account_settings": "Fiókbeállítások", "disabled_account_banner.account_settings": "Fiókbeállítások",
"disabled_account_banner.text": "A(z) {disabledAccount} fiókod jelenleg le van tiltva.", "disabled_account_banner.text": "A(z) {disabledAccount} fiókod jelenleg le van tiltva.",
"dismissable_banner.community_timeline": "Ezek a legfrissebb nyilvános bejegyzések, amelyeket {domain} tartományban levő kiszolgáló fiókjait használó emberek tettek közzé.", "dismissable_banner.community_timeline": "Ezek a legfrissebb nyilvános bejegyzések, amelyeket a(z) {domain} kiszolgáló fiókjait használó emberek tették közzé.",
"dismissable_banner.dismiss": "Elvetés", "dismissable_banner.dismiss": "Elvetés",
"dismissable_banner.explore_links": "Jelenleg ezekről a hírekről beszélgetnek az ezen és a központosítás nélküli hálózat többi kiszolgálóján lévő emberek.", "dismissable_banner.explore_links": "Jelenleg ezekről a hírekről beszélgetnek az ezen és a központosítás nélküli hálózat többi kiszolgálóján lévő emberek.",
"dismissable_banner.explore_statuses": "Ezek jelenleg népszerűvé váló bejegyzések a háló különböző szegleteiből. Az újabb vagy több megtolással rendelkező bejegyzéseket, illetve a kedvencnek jelöléssel rendelkezőeket rangsoroljuk előrébb.", "dismissable_banner.explore_statuses": "Ezek jelenleg népszerűvé váló bejegyzések a háló különböző szegleteiből. Az újabb vagy több megtolással rendelkező bejegyzéseket, illetve a kedvencnek jelöléssel rendelkezőeket rangsoroljuk előrébb.",
@ -216,14 +216,14 @@
"emoji_button.food": "Étel és Ital", "emoji_button.food": "Étel és Ital",
"emoji_button.label": "Emodzsi beszúrása", "emoji_button.label": "Emodzsi beszúrása",
"emoji_button.nature": "Természet", "emoji_button.nature": "Természet",
"emoji_button.not_found": "Nincsenek emodzsik!! (╯°□°)╯︵ ┻━┻", "emoji_button.not_found": "Nem találhatók emodzsik",
"emoji_button.objects": "Tárgyak", "emoji_button.objects": "Tárgyak",
"emoji_button.people": "Emberek", "emoji_button.people": "Emberek",
"emoji_button.recent": "Gyakran használt", "emoji_button.recent": "Gyakran használt",
"emoji_button.search": "Keresés...", "emoji_button.search": "Keresés...",
"emoji_button.search_results": "Keresési találatok", "emoji_button.search_results": "Keresési találatok",
"emoji_button.symbols": "Szimbólumok", "emoji_button.symbols": "Szimbólumok",
"emoji_button.travel": "Utazás és Helyek", "emoji_button.travel": "Utazás és helyek",
"empty_column.account_hides_collections": "Ez a felhasználó úgy döntött, hogy nem teszi elérhetővé ezt az információt.", "empty_column.account_hides_collections": "Ez a felhasználó úgy döntött, hogy nem teszi elérhetővé ezt az információt.",
"empty_column.account_suspended": "Fiók felfüggesztve", "empty_column.account_suspended": "Fiók felfüggesztve",
"empty_column.account_timeline": "Itt nincs bejegyzés!", "empty_column.account_timeline": "Itt nincs bejegyzés!",
@ -245,7 +245,7 @@
"empty_column.mutes": "Még egy felhasználót sem némítottál le.", "empty_column.mutes": "Még egy felhasználót sem némítottál le.",
"empty_column.notifications": "Jelenleg még nincsenek értesítéseid. Ha mások kapcsolatba lépnek veled, ezek itt lesznek láthatóak.", "empty_column.notifications": "Jelenleg még nincsenek értesítéseid. Ha mások kapcsolatba lépnek veled, ezek itt lesznek láthatóak.",
"empty_column.public": "Jelenleg itt nincs semmi! Írj valamit nyilvánosan vagy kövess más kiszolgálón levő felhasználókat, hogy megtöltsd.", "empty_column.public": "Jelenleg itt nincs semmi! Írj valamit nyilvánosan vagy kövess más kiszolgálón levő felhasználókat, hogy megtöltsd.",
"error.unexpected_crash.explanation": "Egy hiba vagy böngésző inkompatibilitás miatt ez az oldal nem jeleníthető meg rendesen.", "error.unexpected_crash.explanation": "Egy kód- vagy böngészőkompatibilitási hiba miatt ez az oldal nem jeleníthető meg helyesen.",
"error.unexpected_crash.explanation_addons": "Ezt az oldalt nem lehet helyesen megjeleníteni. Ezt a hibát valószínűleg egy böngésző kiegészítő vagy egy automatikus fordító okozza.", "error.unexpected_crash.explanation_addons": "Ezt az oldalt nem lehet helyesen megjeleníteni. Ezt a hibát valószínűleg egy böngésző kiegészítő vagy egy automatikus fordító okozza.",
"error.unexpected_crash.next_steps": "Próbáld frissíteni az oldalt. Ha ez nem segít, egy másik böngészőn vagy appon keresztül még mindig használhatod a Mastodont.", "error.unexpected_crash.next_steps": "Próbáld frissíteni az oldalt. Ha ez nem segít, egy másik böngészőn vagy appon keresztül még mindig használhatod a Mastodont.",
"error.unexpected_crash.next_steps_addons": "Próbáld letiltani őket és frissíteni az oldalt. Ha ez nem segít, egy másik böngészőn vagy appon keresztül még mindig használhatod a Mastodont.", "error.unexpected_crash.next_steps_addons": "Próbáld letiltani őket és frissíteni az oldalt. Ha ez nem segít, egy másik böngészőn vagy appon keresztül még mindig használhatod a Mastodont.",
@ -278,13 +278,13 @@
"firehose.remote": "Egyéb kiszolgálók", "firehose.remote": "Egyéb kiszolgálók",
"follow_request.authorize": "Hitelesítés", "follow_request.authorize": "Hitelesítés",
"follow_request.reject": "Elutasítás", "follow_request.reject": "Elutasítás",
"follow_requests.unlocked_explanation": "Bár a fiókod nincs zárolva, a(z) {domain} csapata úgy gondolta, hogy talán kézzel szeretnéd ellenőrizni a fiók követési kéréseit.", "follow_requests.unlocked_explanation": "Bár a fiókod nincs zárolva, a(z) {domain} csapata úgy gondolta, hogy talán kézzel szeretnéd ellenőrizni ezen fiókok követési kéréseit.",
"followed_tags": "Követett hashtagek", "followed_tags": "Követett hashtagek",
"footer.about": "Névjegy", "footer.about": "Névjegy",
"footer.directory": "Profiltár", "footer.directory": "Profiltár",
"footer.get_app": "Alkalmazás beszerzése", "footer.get_app": "Alkalmazás beszerzése",
"footer.invite": "Emberek meghívása", "footer.invite": "Emberek meghívása",
"footer.keyboard_shortcuts": "Billentyűparancsok", "footer.keyboard_shortcuts": "Gyorsbillentyűk",
"footer.privacy_policy": "Adatvédelmi szabályzat", "footer.privacy_policy": "Adatvédelmi szabályzat",
"footer.source_code": "Forráskód megtekintése", "footer.source_code": "Forráskód megtekintése",
"footer.status": "Állapot", "footer.status": "Állapot",
@ -347,13 +347,13 @@
"keyboard_shortcuts.favourite": "Bejegyzés kedvencnek jelölése", "keyboard_shortcuts.favourite": "Bejegyzés kedvencnek jelölése",
"keyboard_shortcuts.favourites": "Kedvencek lista megnyitása", "keyboard_shortcuts.favourites": "Kedvencek lista megnyitása",
"keyboard_shortcuts.federated": "Föderációs idővonal megnyitása", "keyboard_shortcuts.federated": "Föderációs idővonal megnyitása",
"keyboard_shortcuts.heading": "Billentyűparancsok", "keyboard_shortcuts.heading": "Gyorsbillentyűk",
"keyboard_shortcuts.home": "Saját idővonal megnyitása", "keyboard_shortcuts.home": "Saját idővonal megnyitása",
"keyboard_shortcuts.hotkey": "Gyorsbillentyű", "keyboard_shortcuts.hotkey": "Gyorsbillentyű",
"keyboard_shortcuts.legend": "jelmagyarázat megjelenítése", "keyboard_shortcuts.legend": "jelmagyarázat megjelenítése",
"keyboard_shortcuts.local": "helyi idővonal megnyitása", "keyboard_shortcuts.local": "Helyi idővonal megnyitása",
"keyboard_shortcuts.mention": "Szerző megemlítése", "keyboard_shortcuts.mention": "Szerző megemlítése",
"keyboard_shortcuts.muted": "némított felhasználók listájának megnyitása", "keyboard_shortcuts.muted": "Némított felhasználók listájának megnyitása",
"keyboard_shortcuts.my_profile": "Saját profil megnyitása", "keyboard_shortcuts.my_profile": "Saját profil megnyitása",
"keyboard_shortcuts.notifications": "Értesítések oszlop megnyitása", "keyboard_shortcuts.notifications": "Értesítések oszlop megnyitása",
"keyboard_shortcuts.open_media": "Média megnyitása", "keyboard_shortcuts.open_media": "Média megnyitása",
@ -389,7 +389,7 @@
"lists.replies_policy.list": "A lista tagjai", "lists.replies_policy.list": "A lista tagjai",
"lists.replies_policy.none": "Senki", "lists.replies_policy.none": "Senki",
"lists.replies_policy.title": "Nekik mutassuk a válaszokat:", "lists.replies_policy.title": "Nekik mutassuk a válaszokat:",
"lists.search": "Keresés a követett személyek között", "lists.search": "Keresés a követett emberek között",
"lists.subheading": "Saját listák", "lists.subheading": "Saját listák",
"load_pending": "{count, plural, one {# új elem} other {# új elem}}", "load_pending": "{count, plural, one {# új elem} other {# új elem}}",
"loading_indicator.label": "Betöltés…", "loading_indicator.label": "Betöltés…",
@ -399,7 +399,7 @@
"mute_modal.hide_notifications": "Rejtsük el a felhasználótól származó értesítéseket?", "mute_modal.hide_notifications": "Rejtsük el a felhasználótól származó értesítéseket?",
"mute_modal.indefinite": "Határozatlan", "mute_modal.indefinite": "Határozatlan",
"navigation_bar.about": "Névjegy", "navigation_bar.about": "Névjegy",
"navigation_bar.advanced_interface": "Haladó webes felület engedélyezése", "navigation_bar.advanced_interface": "Megnyitás a speciális webes felületben",
"navigation_bar.blocks": "Letiltott felhasználók", "navigation_bar.blocks": "Letiltott felhasználók",
"navigation_bar.bookmarks": "Könyvjelzők", "navigation_bar.bookmarks": "Könyvjelzők",
"navigation_bar.community_timeline": "Helyi idővonal", "navigation_bar.community_timeline": "Helyi idővonal",
@ -411,9 +411,9 @@
"navigation_bar.explore": "Felfedezés", "navigation_bar.explore": "Felfedezés",
"navigation_bar.favourites": "Kedvencek", "navigation_bar.favourites": "Kedvencek",
"navigation_bar.filters": "Némított szavak", "navigation_bar.filters": "Némított szavak",
"navigation_bar.follow_requests": "Követési kérelmek", "navigation_bar.follow_requests": "Követési kérések",
"navigation_bar.followed_tags": "Követett hashtagek", "navigation_bar.followed_tags": "Követett hashtagek",
"navigation_bar.follows_and_followers": "Követettek és követők", "navigation_bar.follows_and_followers": "Követések és követők",
"navigation_bar.lists": "Listák", "navigation_bar.lists": "Listák",
"navigation_bar.logout": "Kijelentkezés", "navigation_bar.logout": "Kijelentkezés",
"navigation_bar.mutes": "Némított felhasználók", "navigation_bar.mutes": "Némított felhasználók",
@ -449,7 +449,7 @@
"notifications.column_settings.follow_request": "Új követési kérelmek:", "notifications.column_settings.follow_request": "Új követési kérelmek:",
"notifications.column_settings.mention": "Megemlítések:", "notifications.column_settings.mention": "Megemlítések:",
"notifications.column_settings.poll": "Szavazási eredmények:", "notifications.column_settings.poll": "Szavazási eredmények:",
"notifications.column_settings.push": "Push értesítések", "notifications.column_settings.push": "Leküldéses értesítések",
"notifications.column_settings.reblog": "Megtolások:", "notifications.column_settings.reblog": "Megtolások:",
"notifications.column_settings.show": "Megjelenítés az oszlopban", "notifications.column_settings.show": "Megjelenítés az oszlopban",
"notifications.column_settings.sound": "Hang lejátszása", "notifications.column_settings.sound": "Hang lejátszása",
@ -479,8 +479,8 @@
"onboarding.actions.go_to_home": "Ugrás a saját hírfolyamra", "onboarding.actions.go_to_home": "Ugrás a saját hírfolyamra",
"onboarding.compose.template": "Üdvözlet, #Mastodon!", "onboarding.compose.template": "Üdvözlet, #Mastodon!",
"onboarding.follows.empty": "Sajnos jelenleg nem jeleníthető meg eredmény. Kipróbálhatod a keresést vagy böngészheted a felfedező oldalon a követni kívánt személyeket, vagy próbáld meg később.", "onboarding.follows.empty": "Sajnos jelenleg nem jeleníthető meg eredmény. Kipróbálhatod a keresést vagy böngészheted a felfedező oldalon a követni kívánt személyeket, vagy próbáld meg később.",
"onboarding.follows.lead": "A saját hírfolyamod az elsődleges tapasztalás a Mastodonon. Minél több embert követsz, annál aktívabb és érdekesebb a dolog. Az induláshoz itt van néhány javaslat:", "onboarding.follows.lead": "A kezdőlapod a Mastodon használatának elsődleges módja. Minél több embert követsz, annál aktívabbak és érdekesebbek lesznek a dolgok. Az induláshoz itt van néhány javaslat:",
"onboarding.follows.title": "Népszerű a Mastodonon", "onboarding.follows.title": "Szabd személyre a kezdőlapodat",
"onboarding.profile.discoverable": "Saját profil beállítása felfedezhetőként", "onboarding.profile.discoverable": "Saját profil beállítása felfedezhetőként",
"onboarding.profile.discoverable_hint": "A Mastodonon a felfedezhetőség választása esetén a saját bejegyzéseid megjelenhetnek a keresési eredmények és a felkapott tartalmak között, valamint a profilod a hozzád hasonló érdeklődési körrel rendelkező embereknél is ajánlásra kerülhet.", "onboarding.profile.discoverable_hint": "A Mastodonon a felfedezhetőség választása esetén a saját bejegyzéseid megjelenhetnek a keresési eredmények és a felkapott tartalmak között, valamint a profilod a hozzád hasonló érdeklődési körrel rendelkező embereknél is ajánlásra kerülhet.",
"onboarding.profile.display_name": "Megjelenített név", "onboarding.profile.display_name": "Megjelenített név",
@ -499,14 +499,14 @@
"onboarding.start.lead": "Az új Mastodon-fiók használatra kész. Így hozhatod ki belőle a legtöbbet:", "onboarding.start.lead": "Az új Mastodon-fiók használatra kész. Így hozhatod ki belőle a legtöbbet:",
"onboarding.start.skip": "Szeretnél előreugrani?", "onboarding.start.skip": "Szeretnél előreugrani?",
"onboarding.start.title": "Ez sikerült!", "onboarding.start.title": "Ez sikerült!",
"onboarding.steps.follow_people.body": "Te állítod össze a saját hírfolyamodat. Töltsd meg érdekes emberekkel.", "onboarding.steps.follow_people.body": "A Mastodon az érdekes emberek követéséről szól.",
"onboarding.steps.follow_people.title": "{count, plural, one {egy ember} other {# ember}} követése", "onboarding.steps.follow_people.title": "{count, plural, one {egy ember} other {# ember}} követése",
"onboarding.steps.publish_status.body": "Üdvözöljük a világot.", "onboarding.steps.publish_status.body": "Üdvözöljük a világot.",
"onboarding.steps.publish_status.title": "Az első bejegyzés létrehozása", "onboarding.steps.publish_status.title": "Az első bejegyzés létrehozása",
"onboarding.steps.setup_profile.body": "Mások nagyobb valószínűséggel lépnek kapcsolatba veled egy kitöltött profil esetén.", "onboarding.steps.setup_profile.body": "Mások nagyobb valószínűséggel lépnek kapcsolatba veled egy kitöltött profil esetén.",
"onboarding.steps.setup_profile.title": "Profilod testreszabása", "onboarding.steps.setup_profile.title": "Profilod testreszabása",
"onboarding.steps.share_profile.body": "Tudasd az ismerőseiddel, hogyan találhatnak meg a Mastodonon!", "onboarding.steps.share_profile.body": "Tudasd az ismerőseiddel, hogyan találhatnak meg a Mastodonon",
"onboarding.steps.share_profile.title": "Profilod megosztása", "onboarding.steps.share_profile.title": "Oszd meg a Mastodon profilodat",
"onboarding.tips.2fa": "<strong>Tudtad?</strong> A fiókod biztonságossá teheted, ha a fiók beállításaiban beállítod a kétlépcsős hitelesítést. Bármilyen választott TOTP alkalmazással működik, nincs szükség telefonszámra!", "onboarding.tips.2fa": "<strong>Tudtad?</strong> A fiókod biztonságossá teheted, ha a fiók beállításaiban beállítod a kétlépcsős hitelesítést. Bármilyen választott TOTP alkalmazással működik, nincs szükség telefonszámra!",
"onboarding.tips.accounts_from_other_servers": "<strong>Tudtad?</strong> Mivel a Mastodon decentralizált, egyes profilok, amelyekkel találkozol, más kiszolgálókon lesznek tárolva. És mégis zökkenőmentesen kommunikálhatsz velük! A kiszolgáló a felhasználónevük második felében található!", "onboarding.tips.accounts_from_other_servers": "<strong>Tudtad?</strong> Mivel a Mastodon decentralizált, egyes profilok, amelyekkel találkozol, más kiszolgálókon lesznek tárolva. És mégis zökkenőmentesen kommunikálhatsz velük! A kiszolgáló a felhasználónevük második felében található!",
"onboarding.tips.migration": "<strong>Tudtad?</strong> Ha úgy érzed, hogy a {domain} már nem jó kiszolgáló a számodra, átköltözhetsz egy másik Mastodon kiszolgálóra anélkül, hogy elveszítenéd a követőidet. Akár saját kiszolgálót is üzemeltethetsz!", "onboarding.tips.migration": "<strong>Tudtad?</strong> Ha úgy érzed, hogy a {domain} már nem jó kiszolgáló a számodra, átköltözhetsz egy másik Mastodon kiszolgálóra anélkül, hogy elveszítenéd a követőidet. Akár saját kiszolgálót is üzemeltethetsz!",
@ -720,7 +720,7 @@
"upload_form.undo": "Törlés", "upload_form.undo": "Törlés",
"upload_form.video_description": "Leírás siket, hallássérült, vak vagy gyengénlátó emberek számára", "upload_form.video_description": "Leírás siket, hallássérült, vak vagy gyengénlátó emberek számára",
"upload_modal.analyzing_picture": "Kép elemzése…", "upload_modal.analyzing_picture": "Kép elemzése…",
"upload_modal.apply": "Alkalmazás", "upload_modal.apply": "Alkalmaz",
"upload_modal.applying": "Alkalmazás…", "upload_modal.applying": "Alkalmazás…",
"upload_modal.choose_image": "Kép kiválasztása", "upload_modal.choose_image": "Kép kiválasztása",
"upload_modal.description_placeholder": "A gyors, barna róka átugrik a lusta kutya fölött", "upload_modal.description_placeholder": "A gyors, barna róka átugrik a lusta kutya fölött",

View file

@ -40,7 +40,7 @@
"account.follows.empty": "Šis (-i) naudotojas (-a) dar nieko neseka.", "account.follows.empty": "Šis (-i) naudotojas (-a) dar nieko neseka.",
"account.follows_you": "Seka tave", "account.follows_you": "Seka tave",
"account.go_to_profile": "Eiti į profilį", "account.go_to_profile": "Eiti į profilį",
"account.hide_reblogs": "Slėpti \"boosts\" iš @{name}", "account.hide_reblogs": "Slėpti pakėlimus iš @{name}",
"account.in_memoriam": "Atminimui.", "account.in_memoriam": "Atminimui.",
"account.joined_short": "Prisijungė", "account.joined_short": "Prisijungė",
"account.languages": "Keisti prenumeruojamas kalbas", "account.languages": "Keisti prenumeruojamas kalbas",
@ -49,19 +49,19 @@
"account.media": "Medija", "account.media": "Medija",
"account.mention": "Paminėti @{name}", "account.mention": "Paminėti @{name}",
"account.moved_to": "{name} nurodė, kad dabar jų nauja paskyra yra:", "account.moved_to": "{name} nurodė, kad dabar jų nauja paskyra yra:",
"account.mute": "tildyti @{name}", "account.mute": "Nutildyti @{name}",
"account.mute_notifications_short": "Nutildyti pranešimus", "account.mute_notifications_short": "Nutildyti pranešimus",
"account.mute_short": "Nutildyti", "account.mute_short": "Nutildyti",
"account.muted": "tildytas", "account.muted": "Nutildytas",
"account.no_bio": "Nėra pateikto aprašymo.", "account.no_bio": "Nėra pateikto aprašymo.",
"account.open_original_page": "Atidaryti originalinį tinklalapį", "account.open_original_page": "Atidaryti originalinį puslapį",
"account.posts": "Įrašai", "account.posts": "Įrašai",
"account.posts_with_replies": "Įrašai ir atsakymai", "account.posts_with_replies": "Įrašai ir atsakymai",
"account.report": "Pranešti @{name}", "account.report": "Pranešti @{name}",
"account.requested": "Laukiama patvirtinimo. Spausk, kad atšaukti sekimo užklausą.", "account.requested": "Laukiama patvirtinimo. Spausk, kad atšaukti sekimo užklausą",
"account.requested_follow": "{name} paprašė tave sekti", "account.requested_follow": "{name} paprašė tave sekti",
"account.share": "Bendrinti @{name} profilį", "account.share": "Bendrinti @{name} profilį",
"account.show_reblogs": "Rodyti \"boosts\" iš @{name}", "account.show_reblogs": "Rodyti pakėlimus iš @{name}",
"account.statuses_counter": "{count, plural, one {{counter} įrašas} few {{counter} įrašai} many {{counter} įrašo} other {{counter} įrašų}}", "account.statuses_counter": "{count, plural, one {{counter} įrašas} few {{counter} įrašai} many {{counter} įrašo} other {{counter} įrašų}}",
"account.unblock": "Atblokuoti @{name}", "account.unblock": "Atblokuoti @{name}",
"account.unblock_domain": "Atblokuoti domeną {domain}", "account.unblock_domain": "Atblokuoti domeną {domain}",
@ -73,7 +73,7 @@
"account.unmute_short": "Atitildyti", "account.unmute_short": "Atitildyti",
"account_note.placeholder": "Spausk norėdamas (-a) pridėti pastabą", "account_note.placeholder": "Spausk norėdamas (-a) pridėti pastabą",
"admin.dashboard.daily_retention": "Vartotojų išbuvimo rodiklis pagal dieną po registracijos", "admin.dashboard.daily_retention": "Vartotojų išbuvimo rodiklis pagal dieną po registracijos",
"admin.dashboard.monthly_retention": "Vartotojų išbuvimo rodiklis pagal mėnesį po registracijos", "admin.dashboard.monthly_retention": "Naudotojų išlaikymo rodiklis pagal mėnesį po registracijos",
"admin.dashboard.retention.average": "Vidurkis", "admin.dashboard.retention.average": "Vidurkis",
"admin.dashboard.retention.cohort": "Registravimo mėnuo", "admin.dashboard.retention.cohort": "Registravimo mėnuo",
"admin.dashboard.retention.cohort_size": "Nauji naudotojai", "admin.dashboard.retention.cohort_size": "Nauji naudotojai",
@ -117,9 +117,9 @@
"column.favourites": "Mėgstamiausi", "column.favourites": "Mėgstamiausi",
"column.firehose": "Tiesioginiai padavimai", "column.firehose": "Tiesioginiai padavimai",
"column.follow_requests": "Sekti prašymus", "column.follow_requests": "Sekti prašymus",
"column.home": "Pradžia", "column.home": "Pagrindinis",
"column.lists": "Sąrašai", "column.lists": "Sąrašai",
"column.mutes": "tildyti naudotojai", "column.mutes": "Nutildyti naudotojai",
"column.notifications": "Pranešimai", "column.notifications": "Pranešimai",
"column.pins": "Prisegti įrašai", "column.pins": "Prisegti įrašai",
"column.public": "Federacinė laiko skalė", "column.public": "Federacinė laiko skalė",
@ -141,13 +141,13 @@
"compose.saved.body": "Įrašas išsaugotas.", "compose.saved.body": "Įrašas išsaugotas.",
"compose_form.direct_message_warning_learn_more": "Sužinoti daugiau", "compose_form.direct_message_warning_learn_more": "Sužinoti daugiau",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.hashtag_warning": "Šis įrašas nebus įtraukta į jokį saitažodį, nes ji nėra vieša. Tik viešų įrašų galima ieškoti pagal saitažodį.",
"compose_form.lock_disclaimer": "Jūsų paskyra nėra {locked}. Kiekvienas gali jus sekti ir peržiūrėti tik sekėjams skirtus įrašus.", "compose_form.lock_disclaimer": "Tavo paskyra nėra {locked}. Bet kas gali sekti tave ir peržiūrėti tik sekėjams skirtus įrašus.",
"compose_form.lock_disclaimer.lock": "užrakinta", "compose_form.lock_disclaimer.lock": "užrakinta",
"compose_form.placeholder": "Kas tavo mintyse?", "compose_form.placeholder": "Kas tavo mintyse?",
"compose_form.poll.add_option": "Pridėti pasirinkimą", "compose_form.poll.add_option": "Pridėti pasirinkimą",
"compose_form.poll.duration": "Apklausos trukmė", "compose_form.poll.duration": "Apklausos trukmė",
"compose_form.poll.option_placeholder": "Pasirinkimas {number}", "compose_form.poll.option_placeholder": "{number} pasirinkimas",
"compose_form.poll.remove_option": "Pašalinti šį pasirinkimą", "compose_form.poll.remove_option": "Pašalinti šį pasirinkimą",
"compose_form.poll.switch_to_multiple": "Keisti apklausą, kad būtų galima pasirinkti kelis pasirinkimus", "compose_form.poll.switch_to_multiple": "Keisti apklausą, kad būtų galima pasirinkti kelis pasirinkimus",
"compose_form.poll.switch_to_single": "Pakeisti apklausą, kad būtų galima pasirinkti vieną variantą", "compose_form.poll.switch_to_single": "Pakeisti apklausą, kad būtų galima pasirinkti vieną variantą",
@ -528,6 +528,8 @@
"search_results.hashtags": "Saitažodžiai", "search_results.hashtags": "Saitažodžiai",
"search_results.nothing_found": "Nepavyko rasti nieko pagal šiuos paieškos terminus.", "search_results.nothing_found": "Nepavyko rasti nieko pagal šiuos paieškos terminus.",
"search_results.statuses": "Toots", "search_results.statuses": "Toots",
"server_banner.about_active_users": "Žmonės, kurie naudojosi šiuo serveriu per pastarąsias 30 dienų (mėnesio aktyvūs naudotojai)",
"server_banner.active_users": "aktyvūs naudotojai",
"sign_in_banner.sign_in": "Prisijungimas", "sign_in_banner.sign_in": "Prisijungimas",
"sign_in_banner.text": "Prisijunk, kad galėtum sekti profilius arba saitažodžius, mėgsti, bendrinti ir atsakyti į įrašus. Taip pat gali bendrauti iš savo paskyros kitame serveryje.", "sign_in_banner.text": "Prisijunk, kad galėtum sekti profilius arba saitažodžius, mėgsti, bendrinti ir atsakyti į įrašus. Taip pat gali bendrauti iš savo paskyros kitame serveryje.",
"status.admin_status": "Open this status in the moderation interface", "status.admin_status": "Open this status in the moderation interface",

View file

@ -21,6 +21,7 @@
"account.blocked": "ဘလော့ထားသည်", "account.blocked": "ဘလော့ထားသည်",
"account.browse_more_on_origin_server": "မူရင်းပရိုဖိုင်တွင် ပိုမိုကြည့်ရှုပါ။", "account.browse_more_on_origin_server": "မူရင်းပရိုဖိုင်တွင် ပိုမိုကြည့်ရှုပါ။",
"account.cancel_follow_request": "စောင့်ကြည့်မှု ပယ်ဖျက်ခြင်း", "account.cancel_follow_request": "စောင့်ကြည့်မှု ပယ်ဖျက်ခြင်း",
"account.copy": "လင့်ခ်ကို ပရိုဖိုင်သို့ ကူးယူပါ",
"account.direct": "@{name} သီးသန့် သိရှိနိုင်အောင် မန်းရှင်းခေါ်မည်", "account.direct": "@{name} သီးသန့် သိရှိနိုင်အောင် မန်းရှင်းခေါ်မည်",
"account.disable_notifications": "@{name} ပို့စ်တင်သည့်အခါ ကျွန်ုပ်ထံ အသိပေးခြင်း မပြုလုပ်ရန်။", "account.disable_notifications": "@{name} ပို့စ်တင်သည့်အခါ ကျွန်ုပ်ထံ အသိပေးခြင်း မပြုလုပ်ရန်။",
"account.domain_blocked": "ဒိုမိန်း ပိတ်ပင်ထားခဲ့သည်", "account.domain_blocked": "ဒိုမိန်း ပိတ်ပင်ထားခဲ့သည်",
@ -191,6 +192,7 @@
"conversation.mark_as_read": "ဖတ်ပြီးသားအဖြစ်မှတ်ထားပါ", "conversation.mark_as_read": "ဖတ်ပြီးသားအဖြစ်မှတ်ထားပါ",
"conversation.open": "Conversation ကိုကြည့်မည်", "conversation.open": "Conversation ကိုကြည့်မည်",
"conversation.with": "{အမည်များ} ဖြင့်", "conversation.with": "{အမည်များ} ဖြင့်",
"copy_icon_button.copied": "ကလစ်ဘုတ်သို့ ကူးပါ",
"copypaste.copied": "ကူယူပြီးပါပြီ", "copypaste.copied": "ကူယူပြီးပါပြီ",
"copypaste.copy_to_clipboard": "ကလစ်ဘုတ်သို့ ကူးပါ", "copypaste.copy_to_clipboard": "ကလစ်ဘုတ်သို့ ကူးပါ",
"directory.federated": "သင် သိသော ဖက်ဒီမှ", "directory.federated": "သင် သိသော ဖက်ဒီမှ",
@ -389,6 +391,7 @@
"lists.search": "မိမိဖောလိုးထားသူများမှရှာဖွေမည်", "lists.search": "မိမိဖောလိုးထားသူများမှရှာဖွေမည်",
"lists.subheading": "သင့်၏စာရင်းများ", "lists.subheading": "သင့်၏စာရင်းများ",
"load_pending": "{count, plural, one {# new item} other {# new items}}", "load_pending": "{count, plural, one {# new item} other {# new items}}",
"loading_indicator.label": "လုပ်ဆောင်နေသည်…",
"media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}", "media_gallery.toggle_visible": "{number, plural, one {Hide image} other {Hide images}}",
"moved_to_account_banner.text": "{movedToAccount} အကောင့်သို့ပြောင်းလဲထားသဖြင့် {disabledAccount} အကောင့်မှာပိတ်ထားသည်", "moved_to_account_banner.text": "{movedToAccount} အကောင့်သို့ပြောင်းလဲထားသဖြင့် {disabledAccount} အကောင့်မှာပိတ်ထားသည်",
"mute_modal.duration": "ကြာချိန်", "mute_modal.duration": "ကြာချိန်",
@ -477,6 +480,13 @@
"onboarding.follows.empty": "ယခုအချိန် မည်သည့်ရလဒ်ကိုမျှ မပြသနိုင်ပါ။ လူများကိုစောင့်ကြည့်ရန်အတွက် Explore စာမျက်နှာကို အသုံးပြု၍ စမ်းကြည့်နိုင်သည် သို့မဟုတ် နောက်မှ ထပ်စမ်းကြည့်ပါ။", "onboarding.follows.empty": "ယခုအချိန် မည်သည့်ရလဒ်ကိုမျှ မပြသနိုင်ပါ။ လူများကိုစောင့်ကြည့်ရန်အတွက် Explore စာမျက်နှာကို အသုံးပြု၍ စမ်းကြည့်နိုင်သည် သို့မဟုတ် နောက်မှ ထပ်စမ်းကြည့်ပါ။",
"onboarding.follows.lead": "သင့်ကိုယ်ပိုင်ပို့စ်များ တင်နိုင်သည်။ သင်စောင့်ကြည့်သူ များလေလေ၊ စိတ်ဝင်စားစရာကောင်းသောပို့စ်များ တွေ့ရလေဖြစ်သည်။ ဤပရိုဖိုင်များမှာ ကောင်းမွန်သောအစပြုမှုတစ်ခုဖြစ်ပြီး ၎င်းတို့ကိုစောင့်ကြည့်ခြင်းမှလည်း အချိန်မရွေး ပယ်ဖျက်နိုင်ပါသည်။", "onboarding.follows.lead": "သင့်ကိုယ်ပိုင်ပို့စ်များ တင်နိုင်သည်။ သင်စောင့်ကြည့်သူ များလေလေ၊ စိတ်ဝင်စားစရာကောင်းသောပို့စ်များ တွေ့ရလေဖြစ်သည်။ ဤပရိုဖိုင်များမှာ ကောင်းမွန်သောအစပြုမှုတစ်ခုဖြစ်ပြီး ၎င်းတို့ကိုစောင့်ကြည့်ခြင်းမှလည်း အချိန်မရွေး ပယ်ဖျက်နိုင်ပါသည်။",
"onboarding.follows.title": "Mastodon တွင် ရေပန်းစားခြင်း", "onboarding.follows.title": "Mastodon တွင် ရေပန်းစားခြင်း",
"onboarding.profile.discoverable": "ပရိုဖိုင် ရှာဖွေနိုင်ပါမည်",
"onboarding.profile.display_name": "ဖော်ပြမည့်အမည်",
"onboarding.profile.display_name_hint": "သင့်အမည်အပြည့်အစုံ သို့မဟုတ် သင့်အမည်ပြောင်။",
"onboarding.profile.note": "ကိုယ်ရေးအကျဉ်း",
"onboarding.profile.save_and_continue": "သိမ်းပြီး ဆက်လုပ်ပါ",
"onboarding.profile.title": "ပရိုဖိုင်စနစ် ထည့်သွင်းခြင်း",
"onboarding.profile.upload_avatar": "ပရိုဖိုင်ပုံ အပ်လုဒ်လုပ်ပါ",
"onboarding.share.lead": "Mastodon တွင် သင့်အား မည်သို့ရှာတွေ့နိုင်သည်ကို အသိပေးပါ။", "onboarding.share.lead": "Mastodon တွင် သင့်အား မည်သို့ရှာတွေ့နိုင်သည်ကို အသိပေးပါ။",
"onboarding.share.message": "Mastodon ရှိ ကျွန်ုပ်၏အမည်မှာ {username} ဖြစ်သည်။ ကျွန်ုပ်ကို {url} တွင် စောင့်ကြည့်နိုင်ပါသည်", "onboarding.share.message": "Mastodon ရှိ ကျွန်ုပ်၏အမည်မှာ {username} ဖြစ်သည်။ ကျွန်ုပ်ကို {url} တွင် စောင့်ကြည့်နိုင်ပါသည်",
"onboarding.share.next_steps": "ဖြစ်နိုင်ချေရှိသော နောက်အဆင့်များ -", "onboarding.share.next_steps": "ဖြစ်နိုင်ချေရှိသော နောက်အဆင့်များ -",
@ -520,6 +530,7 @@
"privacy.unlisted.short": "စာရင်းမသွင်းထားပါ", "privacy.unlisted.short": "စာရင်းမသွင်းထားပါ",
"privacy_policy.last_updated": "နောက်ဆုံး ပြင်ဆင်ခဲ့သည့်ရက်စွဲ {date}", "privacy_policy.last_updated": "နောက်ဆုံး ပြင်ဆင်ခဲ့သည့်ရက်စွဲ {date}",
"privacy_policy.title": "ကိုယ်ရေးအချက်အလက်မူဝါဒ", "privacy_policy.title": "ကိုယ်ရေးအချက်အလက်မူဝါဒ",
"recommended": "အကြံပြုသည်",
"refresh": "ပြန်လည်စတင်ပါ", "refresh": "ပြန်လည်စတင်ပါ",
"regeneration_indicator.label": "လုပ်ဆောင်နေသည်…", "regeneration_indicator.label": "လုပ်ဆောင်နေသည်…",
"regeneration_indicator.sublabel": "သင့်ပင်မစာမျက်နှာကို ပြင်ဆင်နေပါသည်။", "regeneration_indicator.sublabel": "သင့်ပင်မစာမျက်နှာကို ပြင်ဆင်နေပါသည်။",
@ -590,6 +601,7 @@
"search.quick_action.status_search": "{x} နှင့် ကိုက်ညီသော ပို့စ်များ", "search.quick_action.status_search": "{x} နှင့် ကိုက်ညီသော ပို့စ်များ",
"search.search_or_paste": "URL ရိုက်ထည့်ပါ သို့မဟုတ် ရှာဖွေပါ", "search.search_or_paste": "URL ရိုက်ထည့်ပါ သို့မဟုတ် ရှာဖွေပါ",
"search_popout.full_text_search_disabled_message": "{domain} တွင် မရနိုင်ပါ။", "search_popout.full_text_search_disabled_message": "{domain} တွင် မရနိုင်ပါ။",
"search_popout.full_text_search_logged_out_message": "အကောင့်ဝင်ထားမှသာ ရနိုင်သည်။",
"search_popout.language_code": "ISO ဘာသာစကားကုဒ်", "search_popout.language_code": "ISO ဘာသာစကားကုဒ်",
"search_popout.options": "ရွေးချယ်ထားသည်များ ရှာဖွေရန်", "search_popout.options": "ရွေးချယ်ထားသည်များ ရှာဖွေရန်",
"search_popout.quick_actions": "အမြန်လုပ်ဆောင်မှုများ", "search_popout.quick_actions": "အမြန်လုပ်ဆောင်မှုများ",

View file

@ -7,7 +7,7 @@
"about.domain_blocks.silenced.explanation": "Normalmente não verá perfis e conteúdo deste servidor, a menos que os procure explicitamente ou opte por os seguir.", "about.domain_blocks.silenced.explanation": "Normalmente não verá perfis e conteúdo deste servidor, a menos que os procure explicitamente ou opte por os seguir.",
"about.domain_blocks.silenced.title": "Limitados", "about.domain_blocks.silenced.title": "Limitados",
"about.domain_blocks.suspended.explanation": "Nenhum dado deste servidor será processado, armazenado ou trocado, impossibilitando qualquer interação ou comunicação com os utilizadores dessas instâncias.", "about.domain_blocks.suspended.explanation": "Nenhum dado deste servidor será processado, armazenado ou trocado, impossibilitando qualquer interação ou comunicação com os utilizadores dessas instâncias.",
"about.domain_blocks.suspended.title": "Supensos", "about.domain_blocks.suspended.title": "Suspensos",
"about.not_available": "Esta informação não foi disponibilizada neste servidor.", "about.not_available": "Esta informação não foi disponibilizada neste servidor.",
"about.powered_by": "Rede social descentralizada baseada no {mastodon}", "about.powered_by": "Rede social descentralizada baseada no {mastodon}",
"about.rules": "Regras do servidor", "about.rules": "Regras do servidor",

View file

@ -4,7 +4,8 @@ class AttachmentBatch
# Maximum amount of objects you can delete in an S3 API call. It's # Maximum amount of objects you can delete in an S3 API call. It's
# important to remember that this does not correspond to the number # important to remember that this does not correspond to the number
# of records in the batch, since records can have multiple attachments # of records in the batch, since records can have multiple attachments
LIMIT = 1_000 LIMIT = ENV.fetch('S3_BATCH_DELETE_LIMIT', 1000).to_i
MAX_RETRY = ENV.fetch('S3_BATCH_DELETE_RETRY', 3).to_i
# Attributes generated and maintained by Paperclip (not all of them # Attributes generated and maintained by Paperclip (not all of them
# are always used on every class, however) # are always used on every class, however)
@ -95,6 +96,7 @@ class AttachmentBatch
# objects can be processed at once, so we have to potentially # objects can be processed at once, so we have to potentially
# separate them into multiple calls. # separate them into multiple calls.
retries = 0
keys.each_slice(LIMIT) do |keys_slice| keys.each_slice(LIMIT) do |keys_slice|
logger.debug { "Deleting #{keys_slice.size} objects" } logger.debug { "Deleting #{keys_slice.size} objects" }
@ -102,6 +104,17 @@ class AttachmentBatch
objects: keys_slice.map { |key| { key: key } }, objects: keys_slice.map { |key| { key: key } },
quiet: true, quiet: true,
}) })
rescue => e
retries += 1
if retries < MAX_RETRY
logger.debug "Retry #{retries}/#{MAX_RETRY} after #{e.message}"
sleep 2**retries
retry
else
logger.error "Batch deletion from S3 failed after #{e.message}"
raise e
end
end end
end end

View file

@ -37,6 +37,7 @@ class LinkDetailsExtractor
def language def language
lang = json['inLanguage'] lang = json['inLanguage']
lang = lang.first if lang.is_a?(Array)
lang.is_a?(Hash) ? (lang['alternateName'] || lang['name']) : lang lang.is_a?(Hash) ? (lang['alternateName'] || lang['name']) : lang
end end

View file

@ -9,9 +9,7 @@
# url :string # url :string
# #
class PreviewCardsStatus < ApplicationRecord class PreviewCardsStatus < ApplicationRecord
# Composite primary keys are not properly supported in Rails. However, self.primary_key = [:preview_card_id, :status_id]
# we shouldn't need this anyway...
self.primary_key = nil
belongs_to :preview_card belongs_to :preview_card
belongs_to :status belongs_to :status

View file

@ -108,8 +108,7 @@ class Status < ApplicationRecord
has_and_belongs_to_many :tags has_and_belongs_to_many :tags
# Because of a composite primary key, the `dependent` option cannot be used on this association has_one :preview_cards_status, inverse_of: :status, dependent: :delete
has_one :preview_cards_status, inverse_of: :status # rubocop:disable Rails/HasManyOrHasOneDependent
has_one :notification, as: :activity, dependent: :destroy has_one :notification, as: :activity, dependent: :destroy
has_one :status_stat, inverse_of: :status, dependent: nil has_one :status_stat, inverse_of: :status, dependent: nil
@ -178,7 +177,6 @@ class Status < ApplicationRecord
# The `prepend: true` option below ensures this runs before # The `prepend: true` option below ensures this runs before
# the `dependent: destroy` callbacks remove relevant records # the `dependent: destroy` callbacks remove relevant records
before_destroy :unlink_from_conversations!, prepend: true before_destroy :unlink_from_conversations!, prepend: true
before_destroy :reset_preview_card!
cache_associated :application, cache_associated :application,
:media_attachments, :media_attachments,

View file

@ -14,7 +14,6 @@ require 'active_job/railtie'
# require 'action_mailbox/engine' # require 'action_mailbox/engine'
# require 'action_text/engine' # require 'action_text/engine'
# require 'rails/test_unit/railtie' # require 'rails/test_unit/railtie'
require 'sprockets/railtie'
# Used to be implicitly required in action_mailbox/engine # Used to be implicitly required in action_mailbox/engine
require 'mail' require 'mail'

View file

@ -71,17 +71,6 @@ Rails.application.configure do
# Highlight code that enqueued background job in logs. # Highlight code that enqueued background job in logs.
config.active_job.verbose_enqueue_logs = true config.active_job.verbose_enqueue_logs = true
# Debug mode disables concatenation and preprocessing of assets.
config.assets.debug = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Adds additional error checking when serving assets at runtime.
# Checks for improperly declared sprockets dependencies.
# Raises helpful error messages.
config.assets.raise_runtime_errors = true
# Raises error for missing translations. # Raises error for missing translations.
# config.i18n.raise_on_missing_translations = true # config.i18n.raise_on_missing_translations = true

View file

@ -1,16 +0,0 @@
# frozen_string_literal: true
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
Rails.application.config.assets.initialize_on_precompile = true

View file

@ -20,7 +20,7 @@ hu:
attributes: attributes:
username: username:
invalid: csak betűket, számokat vagy alávonást tartalmazhat invalid: csak betűket, számokat vagy alávonást tartalmazhat
reserved: fenntartott reserved: foglalt
admin/webhook: admin/webhook:
attributes: attributes:
url: url:

View file

@ -44,7 +44,7 @@ hu:
action: Jelszó módosítása action: Jelszó módosítása
explanation: A fiókodhoz tartozó jelszó módosítását kezdeményezted. explanation: A fiókodhoz tartozó jelszó módosítását kezdeményezted.
extra: Amennyiben nem te kezdeményezted a módosítást, kérjük tekintsd ezt az emailt tárgytalannak. A jelszavad változatlan marad mindaddig, amíg újat nem hozol létre a fenti linkre kattintva. extra: Amennyiben nem te kezdeményezted a módosítást, kérjük tekintsd ezt az emailt tárgytalannak. A jelszavad változatlan marad mindaddig, amíg újat nem hozol létre a fenti linkre kattintva.
subject: 'Mastodon: Jelszó visszaállítási lépések' subject: 'Mastodon: Jelszóvisszaállítási utasítások'
title: Jelszó visszaállítása title: Jelszó visszaállítása
two_factor_disabled: two_factor_disabled:
explanation: A fiókod kétlépcsős hitelesítését kikapcsoltuk. A bejelentkezés mostantól csak az e-mail cím és a jelszó használatával lesz lehetséges. explanation: A fiókod kétlépcsős hitelesítését kikapcsoltuk. A bejelentkezés mostantól csak az e-mail cím és a jelszó használatával lesz lehetséges.
@ -52,14 +52,14 @@ hu:
title: Kétlépcsős hitelesítés kikapcsolva title: Kétlépcsős hitelesítés kikapcsolva
two_factor_enabled: two_factor_enabled:
explanation: A kétlépcsős hitelesítést engedélyeztük a fiókodban. A bejelentkezéshez a párosított TOTP alkalmazás által generált tokenre lesz szükség. explanation: A kétlépcsős hitelesítést engedélyeztük a fiókodban. A bejelentkezéshez a párosított TOTP alkalmazás által generált tokenre lesz szükség.
subject: Kétlépcsős azonosítás engedélyezve subject: 'Mastodon: Kétlépcsős azonosítás engedélyezve'
title: Kétlépcsős hitelesítés engedélyezve title: Kétlépcsős hitelesítés engedélyezve
two_factor_recovery_codes_changed: two_factor_recovery_codes_changed:
explanation: A korábbi helyreállítási kódok letiltásra és újragenerálásra kerültek. explanation: A korábbi helyreállítási kódok letiltásra és újragenerálásra kerültek.
subject: Kétlépcsős helyreállítási kódok újra létrejöttek subject: 'Mastodon: Kétlépcsős helyreállítási kódok újból előállítva'
title: A kétlépcsős kódok megváltoztak title: A kétlépcsős kódok megváltoztak
unlock_instructions: unlock_instructions:
subject: 'Mastodon: Feloldási lépések' subject: 'Mastodon: Feloldási utasítások'
webauthn_credential: webauthn_credential:
added: added:
explanation: A következő biztonsági kulcsot hozzáadtuk a fiókodhoz explanation: A következő biztonsági kulcsot hozzáadtuk a fiókodhoz

View file

@ -4,7 +4,7 @@ hu:
about_mastodon_html: 'A jövő közösségi hálózata: Hirdetések és céges megfigyelés nélkül, etikus dizájnnal és decentralizációval! Legyél a saját adataid ura a Mastodonnal!' about_mastodon_html: 'A jövő közösségi hálózata: Hirdetések és céges megfigyelés nélkül, etikus dizájnnal és decentralizációval! Legyél a saját adataid ura a Mastodonnal!'
contact_missing: Nincs megadva contact_missing: Nincs megadva
contact_unavailable: N/A contact_unavailable: N/A
hosted_on: "%{domain} Mastodon szerver" hosted_on: "%{domain} Mastodon-kiszolgáló"
title: Névjegy title: Névjegy
accounts: accounts:
follow: Követés follow: Követés
@ -747,7 +747,7 @@ hu:
desc_html: Ez hCaptcha-ból származó külső scripteket használ, mely biztonsági vagy adatvédelmi résnek bizonyulhat. Ezen kívül ez <strong>a regisztrációs folyamatot jelentősen megnehezítheti bizonyos (kifejezetten különleges szükségletű) emberek számára</strong>. Emiatt fontold meg más módszerek, mint pl. jóváhagyás-alapú vagy meghívásalapú regisztráció használatát. desc_html: Ez hCaptcha-ból származó külső scripteket használ, mely biztonsági vagy adatvédelmi résnek bizonyulhat. Ezen kívül ez <strong>a regisztrációs folyamatot jelentősen megnehezítheti bizonyos (kifejezetten különleges szükségletű) emberek számára</strong>. Emiatt fontold meg más módszerek, mint pl. jóváhagyás-alapú vagy meghívásalapú regisztráció használatát.
title: Az új felhasználóknak egy CAPTCHA-t kell megoldaniuk, hogy megerősítsék a fiókjuk regisztrációját title: Az új felhasználóknak egy CAPTCHA-t kell megoldaniuk, hogy megerősítsék a fiókjuk regisztrációját
content_retention: content_retention:
preamble: Felhasználók által generált tartalom Mastodonon való tárolásának szabályozása. preamble: A felhasználók által előállított tartalom Mastodonon való tárolásának szabályozása.
title: Tartalom megtartása title: Tartalom megtartása
default_noindex: default_noindex:
desc_html: Azokat a felhasználókat érinti, akik nem módosították ezt a beállítást desc_html: Azokat a felhasználókat érinti, akik nem módosították ezt a beállítást
@ -1007,8 +1007,8 @@ hu:
hint_html: Ha másik fiókról kívánsz átlépni erre a fiókra, itt létrehozhatsz egy aliast, amelyre szükség van, mielőtt folytathatod a követők áthelyezését a régi fiókból erre. Ez az áthelyezés önmagában <strong>ártalmatlan és visszafordítható</strong> folyamat. <strong>A fiók áttelepítése a régi fiókból indul el. </strong> hint_html: Ha másik fiókról kívánsz átlépni erre a fiókra, itt létrehozhatsz egy aliast, amelyre szükség van, mielőtt folytathatod a követők áthelyezését a régi fiókból erre. Ez az áthelyezés önmagában <strong>ártalmatlan és visszafordítható</strong> folyamat. <strong>A fiók áttelepítése a régi fiókból indul el. </strong>
remove: Alias szétkapcsolása remove: Alias szétkapcsolása
appearance: appearance:
advanced_web_interface: Haladó webes felület advanced_web_interface: Speciális webes felület
advanced_web_interface_hint: 'Ha szeretnéd, a teljes képernyőszélességet felhasználhatod. A haladó webes felülettel különböző oszlopokat állíthatsz be, hogy egyszerre annyi infót láthass, amennyit csak akarsz: Saját idővonal, értesítések, föderációs idővonal, bármennyi lista vagy hashtag.' advanced_web_interface_hint: 'Ha szeretnéd, a képernyő teljes szélességét kihasználhatod. A speciális webes felülettel különböző oszlopokat állíthatsz be, hogy egyszerre annyi információt láthass, amennyit csak akarsz: Kezdőoldal, értesítések, föderációs idővonal, bármennyi lista vagy hashtag.'
animations_and_accessibility: Animáció és akadálymentesítés animations_and_accessibility: Animáció és akadálymentesítés
confirmation_dialogs: Megerősítő párbeszédablakok confirmation_dialogs: Megerősítő párbeszédablakok
discovery: Felfedezés discovery: Felfedezés
@ -1052,7 +1052,7 @@ hu:
delete_account: Felhasználói fiók törlése delete_account: Felhasználói fiók törlése
delete_account_html: Felhasználói fiókod törléséhez <a href="%{path}">kattints ide</a>. A rendszer újbóli megerősítést fog kérni. delete_account_html: Felhasználói fiókod törléséhez <a href="%{path}">kattints ide</a>. A rendszer újbóli megerősítést fog kérni.
description: description:
prefix_invited_by_user: "@%{name} meghív téged, hogy csatlakozz ehhez a Mastodon kiszolgálóhoz." prefix_invited_by_user: "@%{name} meghív téged, hogy csatlakozz ehhez a Mastodon-kiszolgálóhoz."
prefix_sign_up: Regisztrláj még ma a Mastodonra! prefix_sign_up: Regisztrláj még ma a Mastodonra!
suffix: Egy fiókkal követhetsz másokat, bejegyzéseket tehetsz közzé, eszmét cserélhetsz más Mastodon szerverek felhasználóival! suffix: Egy fiókkal követhetsz másokat, bejegyzéseket tehetsz közzé, eszmét cserélhetsz más Mastodon szerverek felhasználóival!
didnt_get_confirmation: Nem kaptál visszaigazoló hivatkozást? didnt_get_confirmation: Nem kaptál visszaigazoló hivatkozást?
@ -1101,7 +1101,7 @@ hu:
title: 'Bejelentkezés ide: %{domain}' title: 'Bejelentkezés ide: %{domain}'
sign_up: sign_up:
manual_review: A(z) %{domain} regisztrációi a moderátorok kézi felülvizsgálatán mennek át. Hogy segítsd a regisztráció feldolgozását, írj röviden magadról, és hogy miért szeretnél fiókot a(z) %{domain} oldalon. manual_review: A(z) %{domain} regisztrációi a moderátorok kézi felülvizsgálatán mennek át. Hogy segítsd a regisztráció feldolgozását, írj röviden magadról, és hogy miért szeretnél fiókot a(z) %{domain} oldalon.
preamble: Egy fiókkal ezen a Mastodon kiszolgálón követhetsz bárkit a hálózaton, függetlenül attól, hogy az illető fiókja melyik kiszolgálón található. preamble: Egy fiókkal ezen a Mastodon-kiszolgálón követhetsz bárkit a hálózaton, függetlenül attól, hogy az illető fiókja melyik kiszolgálón található.
title: Állítsuk be a fiókod a %{domain} kiszolgálón. title: Állítsuk be a fiókod a %{domain} kiszolgálón.
status: status:
account_status: Fiók állapota account_status: Fiók állapota
@ -1234,7 +1234,7 @@ hu:
filters: filters:
contexts: contexts:
account: Profil account: Profil
home: Saját idővonal home: Kezdőlap és listák
notifications: Értesítések notifications: Értesítések
public: Nyilvános idővonalak public: Nyilvános idővonalak
thread: Beszélgetések thread: Beszélgetések
@ -1245,7 +1245,7 @@ hu:
statuses_hint_html: Ez a szűrő egyedi bejegyzések kiválasztására vonatkozik, függetlenül attól, hogy megfelelnek-e a lenti kulcsszavaknak. <a href="%{path}">Engedélyezze vagy távolítsa el a bejegyzéseket a szűrőből</a>. statuses_hint_html: Ez a szűrő egyedi bejegyzések kiválasztására vonatkozik, függetlenül attól, hogy megfelelnek-e a lenti kulcsszavaknak. <a href="%{path}">Engedélyezze vagy távolítsa el a bejegyzéseket a szűrőből</a>.
title: Szűrő szerkesztése title: Szűrő szerkesztése
errors: errors:
deprecated_api_multiple_keywords: Ezek a paraméterek nem módosíthatóak az alkalmazásból, mert több mint egy szűrőkulcsszóra is hatással vannak. Használd az alkalmazás vagy a webes felület újabb verzióját. deprecated_api_multiple_keywords: Ezek a paraméterek nem módosíthatók az alkalmazásból, mert egynél több szűrőkulcsszóra is hatással vannak. Használd az alkalmazás vagy a webes felület újabb verzióját.
invalid_context: A megadott kontextus hamis vagy hiányzik invalid_context: A megadott kontextus hamis vagy hiányzik
index: index:
contexts: 'Szűrés helye: %{contexts}' contexts: 'Szűrés helye: %{contexts}'
@ -1396,7 +1396,7 @@ hu:
unsubscribe: unsubscribe:
action: Igen, leiratkozás action: Igen, leiratkozás
complete: Leiratkozva complete: Leiratkozva
confirmation_html: Biztos vagy benne, hogy le szeretnél iratkozni arról, hogy %{type} típusú üzeneteket kapj a %{domain} Mastodon kiszolgálón a %{email} címedre? Bármikor újra feliratkozhatsz az <a href="%{settings_path}">email értesítések beállításainál</a>. confirmation_html: 'Biztos, hogy leiratkozol arról, hogy %{type} típusú üzeneteket kapj a %{domain} Mastodon-kiszolgálótól erre a címedre: %{email}? Bármikor újra feliratkozhatsz az <a href="%{settings_path}">e-mail-értesítések beállításánál</a>.'
emails: emails:
notification_emails: notification_emails:
favourite: kedvencnek jelölésről email értesítő favourite: kedvencnek jelölésről email értesítő
@ -1405,7 +1405,7 @@ hu:
mention: megemlítésről email értesítő mention: megemlítésről email értesítő
reblog: megtolásról email értesítő reblog: megtolásról email értesítő
resubscribe_html: Ha tévedésből iratkoztál le, újra feliratkozhatsz az <a href="%{settings_path}">email értesítések beállításainál</a>. resubscribe_html: Ha tévedésből iratkoztál le, újra feliratkozhatsz az <a href="%{settings_path}">email értesítések beállításainál</a>.
success_html: Mostantól nem kapsz %{type} típusú üzeneket a %{domain} Mastodon kiszolgálón a %{email} címedre. success_html: 'Mostantól nem kapsz %{type} típusú üzeneket a(z) %{domain} Mastodon-kiszolgálón erre a címedre: %{email}.'
title: Leiratkozás title: Leiratkozás
media_attachments: media_attachments:
validations: validations:
@ -1743,9 +1743,9 @@ hu:
tags: tags:
does_not_match_previous_name: nem illeszkedik az előző névvel does_not_match_previous_name: nem illeszkedik az előző névvel
themes: themes:
contrast: Mastodon (Nagy kontrasztú) contrast: Mastodon (nagy kontrasztú)
default: Mastodon (Sötét) default: Mastodon (sötét)
mastodon-light: Mastodon (Világos) mastodon-light: Mastodon (világos)
time: time:
formats: formats:
default: "%Y. %b %d., %H:%M" default: "%Y. %b %d., %H:%M"
@ -1782,7 +1782,7 @@ hu:
subject: A %{date}-i fellebbezésedet visszautasították subject: A %{date}-i fellebbezésedet visszautasították
title: Fellebbezés visszautasítva title: Fellebbezés visszautasítva
backup_ready: backup_ready:
explanation: A Mastodon fiókod teljes mentését kérted. A mentés kész ás letölthető! explanation: A Mastodon-fiókod teljes mentését kérted. A mentés elkészült, és letölthető.
subject: Az adataidról készült archív letöltésre kész subject: Az adataidról készült archív letöltésre kész
title: Archiválás title: Archiválás
suspicious_sign_in: suspicious_sign_in:

View file

@ -1324,6 +1324,7 @@ my:
'86400': ရက် '86400': ရက်
expires_in_prompt: ဘယ်တော့မှ expires_in_prompt: ဘယ်တော့မှ
generate: ဖိတ်ကြားချက်လင့်ခ် ဖန်တီးပါ generate: ဖိတ်ကြားချက်လင့်ခ် ဖန်တီးပါ
invalid: ဤဖိတ်ကြားချက်မှာ မမှန်ကန်ပါ
invited_by: သင့်ကို ဖိတ်ခေါ်ထားသည် - invited_by: သင့်ကို ဖိတ်ခေါ်ထားသည် -
max_uses: max_uses:
other: "%{count} အသုံးပြုမှုများ" other: "%{count} အသုံးပြုမှုများ"

View file

@ -81,8 +81,8 @@ hu:
bootstrap_timeline_accounts: Ezek a fiókok ki lesznek tűzve az új felhasználók követési javaslatainak élére. bootstrap_timeline_accounts: Ezek a fiókok ki lesznek tűzve az új felhasználók követési javaslatainak élére.
closed_registrations_message: Akkor jelenik meg, amikor a regisztráció le van zárva closed_registrations_message: Akkor jelenik meg, amikor a regisztráció le van zárva
content_cache_retention_period: A más kiszolgálókról származó bejegyzések megadott számú nap után törölve lesznek, ha pozitív értékre van állítva. Ez lehet, hogy nem fordítható vissza. content_cache_retention_period: A más kiszolgálókról származó bejegyzések megadott számú nap után törölve lesznek, ha pozitív értékre van állítva. Ez lehet, hogy nem fordítható vissza.
custom_css: A Mastodon webes verziójában használhatsz egyedi stílusokat. custom_css: A Mastodon webes verziójában használhatsz egyéni stílusokat.
mascot: Felülvágja a haladó webes felületen található illusztrációt. mascot: Felülbírálja a speciális webes felületen található illusztrációt.
media_cache_retention_period: A letöltött médiafájlok megadott számú nap után törölve lesznek, ha pozitív értékre van állítva, és igény szerint újból le lesznek töltve. media_cache_retention_period: A letöltött médiafájlok megadott számú nap után törölve lesznek, ha pozitív értékre van állítva, és igény szerint újból le lesznek töltve.
peers_api_enabled: Azon domainek listája, melyekkel ez a kiszolgáló találkozott a fediverzumban. Nem csatolunk adatot arról, hogy föderált kapcsolatban vagy-e az adott kiszolgálóval, csak arról, hogy a kiszolgálód tud a másikról. Ezt olyan szolgáltatások használják, melyek általában a föderációról készítenek statisztikákat. peers_api_enabled: Azon domainek listája, melyekkel ez a kiszolgáló találkozott a fediverzumban. Nem csatolunk adatot arról, hogy föderált kapcsolatban vagy-e az adott kiszolgálóval, csak arról, hogy a kiszolgálód tud a másikról. Ezt olyan szolgáltatások használják, melyek általában a föderációról készítenek statisztikákat.
profile_directory: A profilok jegyzéke minden olyan felhasználót felsorol, akik engedélyezték a felfedezhetőségüket. profile_directory: A profilok jegyzéke minden olyan felhasználót felsorol, akik engedélyezték a felfedezhetőségüket.
@ -103,7 +103,7 @@ hu:
form_challenge: form_challenge:
current_password: Beléptél egy biztonsági térben current_password: Beléptél egy biztonsági térben
imports: imports:
data: Egy másik Mastodon kiszolgálóról exportált CSV-fájl data: Egy másik Mastodon-kiszolgálóról exportált CSV-fájl
invite_request: invite_request:
text: Ez segít nekünk átnézni a jelentkezésedet text: Ez segít nekünk átnézni a jelentkezésedet
ip_block: ip_block:
@ -199,7 +199,7 @@ hu:
otp_attempt: Kétlépcsős azonosító kód otp_attempt: Kétlépcsős azonosító kód
password: Jelszó password: Jelszó
phrase: Kulcsszó vagy kifejezés phrase: Kulcsszó vagy kifejezés
setting_advanced_layout: Haladó webes felület engedélyezése setting_advanced_layout: Speciális webes felület engedélyezése
setting_aggregate_reblogs: Megtolások csoportosítása az idővonalakon setting_aggregate_reblogs: Megtolások csoportosítása az idővonalakon
setting_always_send_emails: E-mail értesítések küldése mindig setting_always_send_emails: E-mail értesítések küldése mindig
setting_auto_play_gif: GIF-ek automatikus lejátszása setting_auto_play_gif: GIF-ek automatikus lejátszása

View file

@ -43,7 +43,7 @@ hy:
setting_display_media_hide_all: Երբեք մեդիա ցոյց չտալ setting_display_media_hide_all: Երբեք մեդիա ցոյց չտալ
setting_display_media_show_all: Մեդիա միշտ ցոյց տալ setting_display_media_show_all: Մեդիա միշտ ցոյց տալ
setting_use_blurhash: Կտորները հիմնուում են թաքցուած վիզուալի վրայ՝ խամրեցնելով դետալները setting_use_blurhash: Կտորները հիմնուում են թաքցուած վիզուալի վրայ՝ խամրեցնելով դետալները
setting_use_pending_items: Թաքցնել հոսքի թարմացումները կտտոի ետեւում՝ աւտօմատ թարմացուող հոսքի փոխարէն setting_use_pending_items: Թաքցնել հոսքի թարմացումները կոճակի ետեւում՝ աւտօմատ թարմացուող հոսքի փոխարէն
username: Միայն լատինատառեր, թուեր եւ տակի գծիկ username: Միայն լատինատառեր, թուեր եւ տակի գծիկ
whole_word: Եթէ բանալի բառը կամ արտայայտութիւնը պարունակում է միայն այբբենական նիշեր եւ թուեր, ապա այն կիրառուելու է ամբողջ բառի հետ համընկնելու դէպքում միայն whole_word: Եթէ բանալի բառը կամ արտայայտութիւնը պարունակում է միայն այբբենական նիշեր եւ թուեր, ապա այն կիրառուելու է ամբողջ բառի հետ համընկնելու դէպքում միայն
domain_allow: domain_allow:

View file

@ -63,6 +63,8 @@ lt:
setting_use_pending_items: Slėpti laiko skalės naujienas po paspaudimo, vietoj automatinio kanalo slinkimo setting_use_pending_items: Slėpti laiko skalės naujienas po paspaudimo, vietoj automatinio kanalo slinkimo
username: Gali naudoti raides, skaičius ir pabraukimus username: Gali naudoti raides, skaičius ir pabraukimus
whole_word: Kai raktažodis ar frazė yra tik raidinis ir skaitmeninis, jis bus taikomas tik tada, jei atitiks visą žodį whole_word: Kai raktažodis ar frazė yra tik raidinis ir skaitmeninis, jis bus taikomas tik tada, jei atitiks visą žodį
email_domain_block:
with_dns_records: Bus bandoma išspręsti nurodyto domeno DNS įrašus, o rezultatai taip pat bus blokuojami
featured_tag: featured_tag:
name: 'Štai keletas pastaruoju metu dažniausiai saitažodžių, kurių tu naudojai:' name: 'Štai keletas pastaruoju metu dažniausiai saitažodžių, kurių tu naudojai:'
filters: filters:
@ -77,15 +79,98 @@ lt:
site_contact_email: Kaip žmonės gali su tavimi susisiekti teisiniais ar pagalbos užklausimais. site_contact_email: Kaip žmonės gali su tavimi susisiekti teisiniais ar pagalbos užklausimais.
site_contact_username: Kaip žmonės gali tave pasiekti Mastodon. site_contact_username: Kaip žmonės gali tave pasiekti Mastodon.
site_extended_description: Bet kokia papildoma informacija, kuri gali būti naudinga lankytojams ir naudotojams. Gali būti struktūrizuota naudojant Markdown sintaksę. site_extended_description: Bet kokia papildoma informacija, kuri gali būti naudinga lankytojams ir naudotojams. Gali būti struktūrizuota naudojant Markdown sintaksę.
thumbnail: Maždaug 2:1 dydžio vaizdas, rodomas šalia tavo serverio informacijos.
timeline_preview: Atsijungę lankytojai galės naršyti naujausius viešus įrašus, esančius serveryje.
trends: Trendai rodo, kurios įrašai, saitažodžiai ir naujienų istorijos tavo serveryje sulaukia didžiausio susidomėjimo. trends: Trendai rodo, kurios įrašai, saitažodžiai ir naujienų istorijos tavo serveryje sulaukia didžiausio susidomėjimo.
sessions: sessions:
otp: 'Įvesk telefono programėlėje sugeneruotą dviejų tapatybės kodą arba naudok vieną iš atkūrimo kodų:' otp: 'Įvesk telefono programėlėje sugeneruotą dviejų tapatybės kodą arba naudok vieną iš atkūrimo kodų:'
webauthn: Jei tai USB raktas, būtinai jį įkišk ir, jei reikia, paspausk. webauthn: Jei tai USB raktas, būtinai jį įkišk ir, jei reikia, paspausk.
settings: settings:
indexable: Tavo profilio puslapis gali būti rodomas paieškos rezultatuose Google, Bing ir kituose. indexable: Tavo profilio puslapis gali būti rodomas paieškos rezultatuose Google, Bing ir kituose.
user:
chosen_languages: Kai pažymėta, viešose laiko skalėse bus rodomi tik įrašai pasirinktomis kalbomis
role: Vaidmuo valdo, kokius leidimus naudotojas (-a) turi
labels: labels:
account:
indexable: Įtraukti viešus įrašus į paieškos rezultatus
show_collections: Rodyti sekimus ir sekėjus profilyje
unlocked: Automatiškai priimti naujus sekėjus
account_warning_preset:
title: Pavadinimas
admin_account_action:
include_statuses: Įtraukti praneštus įrašus į el. laišką
defaults:
avatar: Profilio nuotrauka
bot: Tai automatinė paskyra
chosen_languages: Filtruoti kalbas
display_name: Rodomas vardas
email: El. pašto adresas
expires_in: Nustoja galioti po
fields: Papildomi laukai
irreversible: Mesti vietoj slėpti
locale: Sąsajos kalba
max_uses: Maksimalus naudojimo skaičius
new_password: Naujas slaptažodis
note: Biografija
password: Slaptažodis
phrase: Raktažodis arba frazė
setting_auto_play_gif: Automatiškai leisti animuotų GIF
setting_boost_modal: Rodyti patvirtinimo dialogą prieš pakėliant įrašą
setting_default_language: Skelbimo kalba
setting_default_privacy: Skelbimo privatumas
setting_default_sensitive: Visada žymėti mediją kaip jautrią
setting_delete_modal: Rodyti patvirtinimo dialogą prieš ištrinant įrašą
setting_display_media: Medijos rodymas
setting_display_media_hide_all: Slėpti viską
setting_display_media_show_all: Rodyti viską
setting_expand_spoilers: Visada išplėsti įrašus, pažymėtus turinio įspėjimais
setting_hide_network: Slėpti savo socialinę diagramą
setting_system_font_ui: Naudoti numatytąjį sistemos šriftą
setting_theme: Svetainės tema
setting_use_pending_items: Lėtas režimas
title: Pavadinimas
type: Importo tipas
username: Naudotojo vardas
username_or_email: Naudotojo vardas arba el. paštas
whole_word: Visas žodis
email_domain_block:
with_dns_records: Įtraukti MX įrašus ir domeno IP adresus
featured_tag: featured_tag:
name: Saitažodis name: Saitažodis
filters:
actions:
hide: Slėpti visiškai
warn: Slėpti su įspėjimu
form_admin_settings:
activity_api_enabled: Skelbti suvestinį statistiką apie naudotojų veiklą per API
bootstrap_timeline_accounts: Visada rekomenduoti šias paskyras naujiems naudotojams
content_cache_retention_period: Turinio talpyklos išlaikymo laikotarpis
custom_css: Pasirinktinis CSS
mascot: Pasirinktinis talismanas (pasenęs)
registrations_mode: Kas gali užsiregistruoti
show_domain_blocks_rationale: Rodyti, kodėl domenai buvo užblokuoti
site_extended_description: Išplėstas aprašymas
site_short_description: Serverio aprašymas
site_terms: Privatumo politika
site_title: Serverio pavadinimas
theme: Numatytoji tema
thumbnail: Serverio miniatūra
invite_request:
text: Kodėl nori prisijungti?
notification_emails:
favourite: Kažkas pamėgo tavo įrašą
follow: Kažkas seka tave
follow_request: Kažkas paprašė sekti tave
mention: Kažkas paminėjo tave
pending_account: Reikia peržiūros naujam paskyrui
reblog: Kažkas pakėlė tavo įrašą
software_updates:
label: Yra nauja Mastodon versija
patch: Pranešti apie klaidų ištaisymo atnaujinimus
rule:
text: Taisyklė
settings:
show_application: Rodyti, iš kurios programėles išsiuntei įrašą
tag: tag:
listable: Leisti šį saitažodį rodyti paieškose ir pasiūlymuose listable: Leisti šį saitažodį rodyti paieškose ir pasiūlymuose
name: Saitažodis name: Saitažodis
@ -93,11 +178,15 @@ lt:
usable: Leisti įrašams naudoti šį saitažodį usable: Leisti įrašams naudoti šį saitažodį
user: user:
role: Vaidmuo role: Vaidmuo
time_zone: Laiko juosta
user_role: user_role:
color: Ženklelio spalva
highlighted: Rodyti vaidmenį kaip ženklelį naudotojo profiliuose
name: Pavadinimas
permissions_as_keys: Leidimai permissions_as_keys: Leidimai
position: Prioritetas position: Prioritetas
webhook: webhook:
events: Įgalinti įvykiai events: Įjungti įvykiai
template: Naudingosios apkrovos šablonas template: Naudingosios apkrovos šablonas
url: Galutinio taško URL url: Galutinio taško URL
'no': Ne 'no': Ne

View file

@ -472,15 +472,13 @@ module Mastodon::CLI
end end
total = 0 total = 0
total += Account.where(id: ::Follow.where(account: account).select(:target_account_id)).count if options[:follows] total += account.following.reorder(nil).count if options[:follows]
total += Account.where(id: ::Follow.where(target_account: account).select(:account_id)).count if options[:followers] total += account.followers.reorder(nil).count if options[:followers]
progress = create_progress_bar(total) progress = create_progress_bar(total)
processed = 0 processed = 0
if options[:follows] if options[:follows]
scope = Account.where(id: ::Follow.where(account: account).select(:target_account_id)) account.following.reorder(nil).find_each do |target_account|
scope.find_each do |target_account|
UnfollowService.new.call(account, target_account) UnfollowService.new.call(account, target_account)
rescue => e rescue => e
progress.log pastel.red("Error processing #{target_account.id}: #{e}") progress.log pastel.red("Error processing #{target_account.id}: #{e}")
@ -493,9 +491,7 @@ module Mastodon::CLI
end end
if options[:followers] if options[:followers]
scope = Account.where(id: ::Follow.where(target_account: account).select(:account_id)) account.followers.reorder(nil).find_each do |target_account|
scope.find_each do |target_account|
UnfollowService.new.call(target_account, account) UnfollowService.new.call(target_account, account)
rescue => e rescue => e
progress.log pastel.red("Error processing #{target_account.id}: #{e}") progress.log pastel.red("Error processing #{target_account.id}: #{e}")

View file

@ -97,6 +97,8 @@ module Mastodon::CLI
say("Removed #{custom_emojis_count} custom emojis#{dry_run_mode_suffix}", :green) say("Removed #{custom_emojis_count} custom emojis#{dry_run_mode_suffix}", :green)
end end
CRAWL_SLEEP_TIME = 20
option :concurrency, type: :numeric, default: 50, aliases: [:c] option :concurrency, type: :numeric, default: 50, aliases: [:c]
option :format, type: :string, default: 'summary', aliases: [:f] option :format, type: :string, default: 'summary', aliases: [:f]
option :exclude_suspended, type: :boolean, default: false, aliases: [:x] option :exclude_suspended, type: :boolean, default: false, aliases: [:x]
@ -168,8 +170,8 @@ module Mastodon::CLI
pool.post(domain, &work_unit) pool.post(domain, &work_unit)
end end
sleep 20 sleep CRAWL_SLEEP_TIME
sleep 20 until pool.queue_length.zero? sleep CRAWL_SLEEP_TIME until pool.queue_length.zero?
pool.shutdown pool.shutdown
pool.wait_for_termination(20) pool.wait_for_termination(20)

View file

@ -346,7 +346,7 @@ module Mastodon::CLI
remove_index_if_exists!(:announcement_reactions, 'index_announcement_reactions_on_account_id_and_announcement_id') remove_index_if_exists!(:announcement_reactions, 'index_announcement_reactions_on_account_id_and_announcement_id')
say 'Removing duplicate account identity proofs…' say 'Removing duplicate announcement reactions…'
ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM announcement_reactions GROUP BY account_id, announcement_id, name HAVING count(*) > 1").each do |row| ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM announcement_reactions GROUP BY account_id, announcement_id, name HAVING count(*) > 1").each do |row|
AnnouncementReaction.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) AnnouncementReaction.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy)
end end
@ -431,7 +431,7 @@ module Mastodon::CLI
def deduplicate_domain_blocks! def deduplicate_domain_blocks!
remove_index_if_exists!(:domain_blocks, 'index_domain_blocks_on_domain') remove_index_if_exists!(:domain_blocks, 'index_domain_blocks_on_domain')
say 'Deduplicating domain_allows…' say 'Deduplicating domain_blocks…'
ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM domain_blocks GROUP BY domain HAVING count(*) > 1").each do |row| ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM domain_blocks GROUP BY domain HAVING count(*) > 1").each do |row|
domain_blocks = DomainBlock.where(id: row['ids'].split(',')).by_severity.reverse.to_a domain_blocks = DomainBlock.where(id: row['ids'].split(',')).by_severity.reverse.to_a
@ -462,7 +462,7 @@ module Mastodon::CLI
UnavailableDomain.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy) UnavailableDomain.where(id: row['ids'].split(',')).sort_by(&:id).reverse.drop(1).each(&:destroy)
end end
say 'Restoring domain_allows indexes…' say 'Restoring unavailable_domains indexes…'
ActiveRecord::Base.connection.add_index :unavailable_domains, ['domain'], name: 'index_unavailable_domains_on_domain', unique: true ActiveRecord::Base.connection.add_index :unavailable_domains, ['domain'], name: 'index_unavailable_domains_on_domain', unique: true
end end

View file

@ -120,7 +120,7 @@ module Mastodon::CLI
say('Beginning removal of now-orphaned media attachments to free up disk space...') say('Beginning removal of now-orphaned media attachments to free up disk space...')
scope = MediaAttachment.reorder(nil).unattached.where('created_at < ?', options[:days].pred.days.ago) scope = MediaAttachment.unattached.where('created_at < ?', options[:days].pred.days.ago)
processed = 0 processed = 0
removed = 0 removed = 0
progress = create_progress_bar(scope.count) progress = create_progress_bar(scope.count)

View file

@ -198,7 +198,7 @@
"eslint-plugin-jsx-a11y": "~6.8.0", "eslint-plugin-jsx-a11y": "~6.8.0",
"eslint-plugin-prettier": "^5.0.0", "eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-promise": "~6.1.1", "eslint-plugin-promise": "~6.1.1",
"eslint-plugin-react": "~7.33.0", "eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.3", "husky": "^8.0.3",
"jest": "^29.5.0", "jest": "^29.5.0",

BIN
spec/fixtures/files/elite-assets.tar.gz vendored Normal file

Binary file not shown.

View file

@ -12,7 +12,7 @@ describe PostDeploymentMigrationGenerator, type: :generator do
include FileUtils include FileUtils
tests described_class tests described_class
destination File.expand_path('../../tmp', __dir__) destination Rails.root.join('tmp', 'generator-test')
before { prepare_destination } before { prepare_destination }
after { rm_rf(destination_root) } after { rm_rf(destination_root) }

View file

@ -29,15 +29,25 @@ describe ApplicationHelper do
describe 'body_classes' do describe 'body_classes' do
context 'with a body class string from a controller' do context 'with a body class string from a controller' do
before do before { helper.extend controller_helpers }
without_partial_double_verification do
allow(helper).to receive_messages(body_class_string: 'modal-layout compose-standalone', current_theme: 'default', current_account: Fabricate(:account))
end
end
it 'uses the controller body classes in the result' do it 'uses the controller body classes in the result' do
expect(helper.body_classes).to match(/modal-layout compose-standalone/) expect(helper.body_classes).to match(/modal-layout compose-standalone/)
end end
private
def controller_helpers
Module.new do
def body_class_string = 'modal-layout compose-standalone'
def current_account
@current_account ||= Fabricate(:account)
end
def current_theme = 'default'
end
end
end end
end end
@ -122,9 +132,7 @@ describe ApplicationHelper do
describe 'available_sign_up_path' do describe 'available_sign_up_path' do
context 'when registrations are closed' do context 'when registrations are closed' do
before do before do
without_partial_double_verification do allow(Setting).to receive(:[]).with('registrations_mode').and_return 'none'
allow(Setting).to receive(:registrations_mode).and_return('none')
end
end end
it 'redirects to joinmastodon site' do it 'redirects to joinmastodon site' do

View file

@ -23,13 +23,20 @@ RSpec.describe HomeHelper do
context 'with a valid account' do context 'with a valid account' do
let(:account) { Fabricate(:account) } let(:account) { Fabricate(:account) }
before { helper.extend controller_helpers }
it 'returns a link to the account' do it 'returns a link to the account' do
without_partial_double_verification do
allow(helper).to receive_messages(current_account: account, prefers_autoplay?: false)
result = helper.account_link_to(account) result = helper.account_link_to(account)
expect(result).to match "@#{account.acct}" expect(result).to match "@#{account.acct}"
end end
private
def controller_helpers
Module.new do
def current_account = Account.last
end
end end
end end
end end

View file

@ -3,16 +3,12 @@
require 'rails_helper' require 'rails_helper'
describe MediaComponentHelper do describe MediaComponentHelper do
before { helper.extend controller_helpers }
describe 'render_video_component' do describe 'render_video_component' do
let(:media) { Fabricate(:media_attachment, type: :video, status: Fabricate(:status)) } let(:media) { Fabricate(:media_attachment, type: :video, status: Fabricate(:status)) }
let(:result) { helper.render_video_component(media.status) } let(:result) { helper.render_video_component(media.status) }
before do
without_partial_double_verification do
allow(helper).to receive(:current_account).and_return(media.account)
end
end
it 'renders a react component for the video' do it 'renders a react component for the video' do
expect(parsed_html.div['data-component']).to eq('Video') expect(parsed_html.div['data-component']).to eq('Video')
end end
@ -22,12 +18,6 @@ describe MediaComponentHelper do
let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) } let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) }
let(:result) { helper.render_audio_component(media.status) } let(:result) { helper.render_audio_component(media.status) }
before do
without_partial_double_verification do
allow(helper).to receive(:current_account).and_return(media.account)
end
end
it 'renders a react component for the audio' do it 'renders a react component for the audio' do
expect(parsed_html.div['data-component']).to eq('Audio') expect(parsed_html.div['data-component']).to eq('Audio')
end end
@ -37,12 +27,6 @@ describe MediaComponentHelper do
let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) } let(:media) { Fabricate(:media_attachment, type: :audio, status: Fabricate(:status)) }
let(:result) { helper.render_media_gallery_component(media.status) } let(:result) { helper.render_media_gallery_component(media.status) }
before do
without_partial_double_verification do
allow(helper).to receive(:current_account).and_return(media.account)
end
end
it 'renders a react component for the media gallery' do it 'renders a react component for the media gallery' do
expect(parsed_html.div['data-component']).to eq('MediaGallery') expect(parsed_html.div['data-component']).to eq('MediaGallery')
end end
@ -54,10 +38,6 @@ describe MediaComponentHelper do
before do before do
PreviewCardsStatus.create(status: status, preview_card: Fabricate(:preview_card)) PreviewCardsStatus.create(status: status, preview_card: Fabricate(:preview_card))
without_partial_double_verification do
allow(helper).to receive(:current_account).and_return(status.account)
end
end end
it 'returns the correct react component markup' do it 'returns the correct react component markup' do
@ -69,12 +49,6 @@ describe MediaComponentHelper do
let(:status) { Fabricate(:status, poll: Fabricate(:poll)) } let(:status) { Fabricate(:status, poll: Fabricate(:poll)) }
let(:result) { helper.render_poll_component(status) } let(:result) { helper.render_poll_component(status) }
before do
without_partial_double_verification do
allow(helper).to receive(:current_account).and_return(status.account)
end
end
it 'returns the correct react component markup' do it 'returns the correct react component markup' do
expect(parsed_html.div['data-component']).to eq('Poll') expect(parsed_html.div['data-component']).to eq('Poll')
end end
@ -85,4 +59,10 @@ describe MediaComponentHelper do
def parsed_html def parsed_html
Nokogiri::Slop(result) Nokogiri::Slop(result)
end end
def controller_helpers
Module.new do
def current_account = Account.last
end
end
end end

File diff suppressed because it is too large Load diff

View file

@ -4,22 +4,29 @@ require 'rails_helper'
require 'mastodon/cli/cache' require 'mastodon/cli/cache'
describe Mastodon::CLI::Cache do describe Mastodon::CLI::Cache do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#clear' do describe '#clear' do
let(:action) { :clear }
before { allow(Rails.cache).to receive(:clear) } before { allow(Rails.cache).to receive(:clear) }
it 'clears the Rails cache' do it 'clears the Rails cache' do
expect { cli.invoke(:clear) }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
expect(Rails.cache).to have_received(:clear) expect(Rails.cache).to have_received(:clear)
end end
end end
describe '#recount' do describe '#recount' do
let(:action) { :recount }
context 'with the `accounts` argument' do context 'with the `accounts` argument' do
let(:arguments) { ['accounts'] } let(:arguments) { ['accounts'] }
let(:account_stat) { Fabricate(:account_stat) } let(:account_stat) { Fabricate(:account_stat) }
@ -29,9 +36,8 @@ describe Mastodon::CLI::Cache do
end end
it 're-calculates account records in the cache' do it 're-calculates account records in the cache' do
expect { cli.invoke(:recount, arguments) }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
expect(account_stat.reload.statuses_count).to be_zero expect(account_stat.reload.statuses_count).to be_zero
end end
@ -46,9 +52,8 @@ describe Mastodon::CLI::Cache do
end end
it 're-calculates account records in the cache' do it 're-calculates account records in the cache' do
expect { cli.invoke(:recount, arguments) }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
expect(status_stat.reload.replies_count).to be_zero expect(status_stat.reload.replies_count).to be_zero
end end
@ -58,9 +63,9 @@ describe Mastodon::CLI::Cache do
let(:arguments) { ['other-type'] } let(:arguments) { ['other-type'] }
it 'Exits with an error message' do it 'Exits with an error message' do
expect { cli.invoke(:recount, arguments) }.to output( expect { subject }
a_string_including('Unknown') .to output_results('Unknown')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
end end

View file

@ -4,42 +4,45 @@ require 'rails_helper'
require 'mastodon/cli/canonical_email_blocks' require 'mastodon/cli/canonical_email_blocks'
describe Mastodon::CLI::CanonicalEmailBlocks do describe Mastodon::CLI::CanonicalEmailBlocks do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#find' do describe '#find' do
let(:action) { :find }
let(:arguments) { ['user@example.com'] } let(:arguments) { ['user@example.com'] }
context 'when a block is present' do context 'when a block is present' do
before { Fabricate(:canonical_email_block, email: 'user@example.com') } before { Fabricate(:canonical_email_block, email: 'user@example.com') }
it 'announces the presence of the block' do it 'announces the presence of the block' do
expect { cli.invoke(:find, arguments) }.to output( expect { subject }
a_string_including('user@example.com is blocked') .to output_results('user@example.com is blocked')
).to_stdout
end end
end end
context 'when a block is not present' do context 'when a block is not present' do
it 'announces the absence of the block' do it 'announces the absence of the block' do
expect { cli.invoke(:find, arguments) }.to output( expect { subject }
a_string_including('user@example.com is not blocked') .to output_results('user@example.com is not blocked')
).to_stdout
end end
end end
end end
describe '#remove' do describe '#remove' do
let(:action) { :remove }
let(:arguments) { ['user@example.com'] } let(:arguments) { ['user@example.com'] }
context 'when a block is present' do context 'when a block is present' do
before { Fabricate(:canonical_email_block, email: 'user@example.com') } before { Fabricate(:canonical_email_block, email: 'user@example.com') }
it 'removes the block' do it 'removes the block' do
expect { cli.invoke(:remove, arguments) }.to output( expect { subject }
a_string_including('Unblocked user@example.com') .to output_results('Unblocked user@example.com')
).to_stdout
expect(CanonicalEmailBlock.matching_email('user@example.com')).to be_empty expect(CanonicalEmailBlock.matching_email('user@example.com')).to be_empty
end end
@ -47,9 +50,8 @@ describe Mastodon::CLI::CanonicalEmailBlocks do
context 'when a block is not present' do context 'when a block is not present' do
it 'announces the absence of the block' do it 'announces the absence of the block' do
expect { cli.invoke(:remove, arguments) }.to output( expect { subject }
a_string_including('user@example.com is not blocked') .to output_results('user@example.com is not blocked')
).to_stdout
end end
end end
end end

View file

@ -4,22 +4,75 @@ require 'rails_helper'
require 'mastodon/cli/domains' require 'mastodon/cli/domains'
describe Mastodon::CLI::Domains do describe Mastodon::CLI::Domains do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#purge' do describe '#purge' do
let(:action) { :purge }
context 'with accounts from the domain' do context 'with accounts from the domain' do
let(:options) { {} }
let(:domain) { 'host.example' } let(:domain) { 'host.example' }
let!(:account) { Fabricate(:account, domain: domain) } let!(:account) { Fabricate(:account, domain: domain) }
let(:arguments) { [domain] }
it 'removes the account' do it 'removes the account' do
expect { cli.invoke(:purge, [domain], options) }.to output( expect { subject }
a_string_including('Removed 1 accounts') .to output_results('Removed 1 accounts')
).to_stdout
expect { account.reload }.to raise_error(ActiveRecord::RecordNotFound) expect { account.reload }.to raise_error(ActiveRecord::RecordNotFound)
end end
end end
end end
describe '#crawl' do
let(:action) { :crawl }
context 'with accounts from the domain' do
let(:domain) { 'host.example' }
before do
Fabricate(:account, domain: domain)
stub_request(:get, 'https://host.example/api/v1/instance').to_return(status: 200, body: {}.to_json)
stub_request(:get, 'https://host.example/api/v1/instance/peers').to_return(status: 200, body: {}.to_json)
stub_request(:get, 'https://host.example/api/v1/instance/activity').to_return(status: 200, body: {}.to_json)
stub_const('Mastodon::CLI::Domains::CRAWL_SLEEP_TIME', 0)
end
context 'with --format of summary' do
let(:options) { { format: 'summary' } }
it 'crawls the domains and summarizes results' do
expect { subject }
.to output_results('Visited 1 domains, 0 failed')
end
end
context 'with --format of domains' do
let(:options) { { format: 'domains' } }
it 'crawls the domains and summarizes results' do
expect { subject }
.to output_results(domain)
end
end
context 'with --format of json' do
let(:options) { { format: 'json' } }
it 'crawls the domains and summarizes results' do
expect { subject }
.to output_results(json_summary)
end
def json_summary
Oj.dump('host.example': { activity: {} })
end
end
end
end
end end

View file

@ -4,96 +4,99 @@ require 'rails_helper'
require 'mastodon/cli/email_domain_blocks' require 'mastodon/cli/email_domain_blocks'
describe Mastodon::CLI::EmailDomainBlocks do describe Mastodon::CLI::EmailDomainBlocks do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#list' do describe '#list' do
let(:action) { :list }
context 'with email domain block records' do context 'with email domain block records' do
let!(:parent_block) { Fabricate(:email_domain_block) } let!(:parent_block) { Fabricate(:email_domain_block) }
let!(:child_block) { Fabricate(:email_domain_block, parent: parent_block) } let!(:child_block) { Fabricate(:email_domain_block, parent: parent_block) }
let(:options) { {} }
it 'lists the blocks' do it 'lists the blocks' do
expect { cli.invoke(:list, [], options) }.to output( expect { subject }
a_string_including(parent_block.domain) .to output_results(
.and(a_string_including(child_block.domain)) parent_block.domain,
).to_stdout child_block.domain
)
end end
end end
end end
describe '#add' do describe '#add' do
context 'without any options' do let(:action) { :add }
let(:options) { {} }
context 'without any options' do
it 'warns about usage and exits' do it 'warns about usage and exits' do
expect { cli.invoke(:add, [], options) }.to output( expect { subject }
a_string_including('No domain(s) given') .to output_results('No domain(s) given')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
context 'when blocks exist' do context 'when blocks exist' do
let(:options) { {} } let(:options) { {} }
let(:domain) { 'host.example' } let(:domain) { 'host.example' }
let(:arguments) { [domain] }
before { Fabricate(:email_domain_block, domain: domain) } before { Fabricate(:email_domain_block, domain: domain) }
it 'does not add a new block' do it 'does not add a new block' do
expect { cli.invoke(:add, [domain], options) }.to output( expect { subject }
a_string_including('is already blocked') .to output_results('is already blocked')
).to_stdout
.and(not_change(EmailDomainBlock, :count)) .and(not_change(EmailDomainBlock, :count))
end end
end end
context 'when no blocks exist' do context 'when no blocks exist' do
let(:options) { {} }
let(:domain) { 'host.example' } let(:domain) { 'host.example' }
let(:arguments) { [domain] }
it 'adds a new block' do it 'adds a new block' do
expect { cli.invoke(:add, [domain], options) }.to output( expect { subject }
a_string_including('Added 1') .to output_results('Added 1')
).to_stdout
.and(change(EmailDomainBlock, :count).by(1)) .and(change(EmailDomainBlock, :count).by(1))
end end
end end
end end
describe '#remove' do describe '#remove' do
context 'without any options' do let(:action) { :remove }
let(:options) { {} }
context 'without any options' do
it 'warns about usage and exits' do it 'warns about usage and exits' do
expect { cli.invoke(:remove, [], options) }.to output( expect { subject }
a_string_including('No domain(s) given') .to output_results('No domain(s) given')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
context 'when blocks exist' do context 'when blocks exist' do
let(:options) { {} }
let(:domain) { 'host.example' } let(:domain) { 'host.example' }
let(:arguments) { [domain] }
before { Fabricate(:email_domain_block, domain: domain) } before { Fabricate(:email_domain_block, domain: domain) }
it 'removes the block' do it 'removes the block' do
expect { cli.invoke(:remove, [domain], options) }.to output( expect { subject }
a_string_including('Removed 1') .to output_results('Removed 1')
).to_stdout
.and(change(EmailDomainBlock, :count).by(-1)) .and(change(EmailDomainBlock, :count).by(-1))
end end
end end
context 'when no blocks exist' do context 'when no blocks exist' do
let(:options) { {} }
let(:domain) { 'host.example' } let(:domain) { 'host.example' }
let(:arguments) { [domain] }
it 'does not remove a block' do it 'does not remove a block' do
expect { cli.invoke(:remove, [domain], options) }.to output( expect { subject }
a_string_including('is not yet blocked') .to output_results('is not yet blocked')
).to_stdout
.and(not_change(EmailDomainBlock, :count)) .and(not_change(EmailDomainBlock, :count))
end end
end end

View file

@ -4,5 +4,61 @@ require 'rails_helper'
require 'mastodon/cli/emoji' require 'mastodon/cli/emoji'
describe Mastodon::CLI::Emoji do describe Mastodon::CLI::Emoji do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#purge' do
let(:action) { :purge }
context 'with existing custom emoji' do
before { Fabricate(:custom_emoji) }
it 'reports a successful purge' do
expect { subject }
.to output_results('OK')
end
end
end
describe '#import' do
context 'with existing custom emoji' do
let(:import_path) { Rails.root.join('spec', 'fixtures', 'files', 'elite-assets.tar.gz') }
let(:action) { :import }
let(:arguments) { [import_path] }
it 'reports about imported emoji' do
expect { subject }
.to output_results('Imported 1')
.and change(CustomEmoji, :count).by(1)
end
end
end
describe '#export' do
context 'with existing custom emoji' do
before do
FileUtils.rm_rf(export_path.dirname)
FileUtils.mkdir_p(export_path.dirname)
Fabricate(:custom_emoji)
end
after { FileUtils.rm_rf(export_path.dirname) }
let(:export_path) { Rails.root.join('tmp', 'cli-tests', 'export.tar.gz') }
let(:arguments) { [export_path.dirname.to_s] }
let(:action) { :export }
it 'reports about exported emoji' do
expect { subject }
.to output_results('Exported 1')
.and change { File.exist?(export_path) }.from(false).to(true)
end
end
end
end end

View file

@ -4,20 +4,25 @@ require 'rails_helper'
require 'mastodon/cli/feeds' require 'mastodon/cli/feeds'
describe Mastodon::CLI::Feeds do describe Mastodon::CLI::Feeds do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#build' do describe '#build' do
let(:action) { :build }
before { Fabricate(:account) } before { Fabricate(:account) }
context 'with --all option' do context 'with --all option' do
let(:options) { { all: true } } let(:options) { { all: true } }
it 'regenerates feeds for all accounts' do it 'regenerates feeds for all accounts' do
expect { cli.invoke(:build, [], options) }.to output( expect { subject }
a_string_including('Regenerated feeds') .to output_results('Regenerated feeds')
).to_stdout
end end
end end
@ -27,9 +32,8 @@ describe Mastodon::CLI::Feeds do
let(:arguments) { ['alice'] } let(:arguments) { ['alice'] }
it 'regenerates feeds for the account' do it 'regenerates feeds for the account' do
expect { cli.invoke(:build, arguments) }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
end end
end end
@ -37,22 +41,23 @@ describe Mastodon::CLI::Feeds do
let(:arguments) { ['invalid-username'] } let(:arguments) { ['invalid-username'] }
it 'displays an error and exits' do it 'displays an error and exits' do
expect { cli.invoke(:build, arguments) }.to output( expect { subject }
a_string_including('No such account') .to output_results('No such account')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
end end
describe '#clear' do describe '#clear' do
let(:action) { :clear }
before do before do
allow(redis).to receive(:del).with(key_namespace) allow(redis).to receive(:del).with(key_namespace)
end end
it 'clears the redis `feed:*` namespace' do it 'clears the redis `feed:*` namespace' do
expect { cli.invoke(:clear) }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
expect(redis).to have_received(:del).with(key_namespace).once expect(redis).to have_received(:del).with(key_namespace).once
end end

View file

@ -4,11 +4,16 @@ require 'rails_helper'
require 'mastodon/cli/ip_blocks' require 'mastodon/cli/ip_blocks'
describe Mastodon::CLI::IpBlocks do describe Mastodon::CLI::IpBlocks do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#add' do describe '#add' do
let(:action) { :add }
let(:ip_list) do let(:ip_list) do
[ [
'192.0.2.1', '192.0.2.1',
@ -25,10 +30,11 @@ describe Mastodon::CLI::IpBlocks do
] ]
end end
let(:options) { { severity: 'no_access' } } let(:options) { { severity: 'no_access' } }
let(:arguments) { ip_list }
shared_examples 'ip address blocking' do shared_examples 'ip address blocking' do
it 'blocks all specified IP addresses' do it 'blocks all specified IP addresses' do
cli.invoke(:add, ip_list, options) subject
blocked_ip_addresses = IpBlock.where(ip: ip_list).pluck(:ip) blocked_ip_addresses = IpBlock.where(ip: ip_list).pluck(:ip)
expected_ip_addresses = ip_list.map { |ip| IPAddr.new(ip) } expected_ip_addresses = ip_list.map { |ip| IPAddr.new(ip) }
@ -37,7 +43,7 @@ describe Mastodon::CLI::IpBlocks do
end end
it 'sets the severity for all blocked IP addresses' do it 'sets the severity for all blocked IP addresses' do
cli.invoke(:add, ip_list, options) subject
blocked_ips_severity = IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity]) blocked_ips_severity = IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity])
@ -45,9 +51,8 @@ describe Mastodon::CLI::IpBlocks do
end end
it 'displays a success message with a summary' do it 'displays a success message with a summary' do
expect { cli.invoke(:add, ip_list, options) }.to output( expect { subject }
a_string_including("Added #{ip_list.size}, skipped 0, failed 0") .to output_results("Added #{ip_list.size}, skipped 0, failed 0")
).to_stdout
end end
end end
@ -57,19 +62,19 @@ describe Mastodon::CLI::IpBlocks do
context 'when a specified IP address is already blocked' do context 'when a specified IP address is already blocked' do
let!(:blocked_ip) { IpBlock.create(ip: ip_list.last, severity: options[:severity]) } let!(:blocked_ip) { IpBlock.create(ip: ip_list.last, severity: options[:severity]) }
let(:arguments) { ip_list }
it 'skips the already blocked IP address' do it 'skips the already blocked IP address' do
allow(IpBlock).to receive(:new).and_call_original allow(IpBlock).to receive(:new).and_call_original
cli.invoke(:add, ip_list, options) subject
expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last) expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last)
end end
it 'displays the correct summary' do it 'displays the correct summary' do
expect { cli.invoke(:add, ip_list, options) }.to output( expect { subject }
a_string_including("#{ip_list.last} is already blocked\nAdded #{ip_list.size - 1}, skipped 1, failed 0") .to output_results("#{ip_list.last} is already blocked\nAdded #{ip_list.size - 1}, skipped 1, failed 0")
).to_stdout
end end
context 'with --force option' do context 'with --force option' do
@ -77,7 +82,7 @@ describe Mastodon::CLI::IpBlocks do
let(:options) { { severity: 'sign_up_requires_approval', force: true } } let(:options) { { severity: 'sign_up_requires_approval', force: true } }
it 'overwrites the existing IP block record' do it 'overwrites the existing IP block record' do
expect { cli.invoke(:add, ip_list, options) } expect { subject }
.to change { blocked_ip.reload.severity } .to change { blocked_ip.reload.severity }
.from('no_access') .from('no_access')
.to('sign_up_requires_approval') .to('sign_up_requires_approval')
@ -89,11 +94,11 @@ describe Mastodon::CLI::IpBlocks do
context 'when a specified IP address is invalid' do context 'when a specified IP address is invalid' do
let(:ip_list) { ['320.15.175.0', '9.5.105.255', '0.0.0.0'] } let(:ip_list) { ['320.15.175.0', '9.5.105.255', '0.0.0.0'] }
let(:arguments) { ip_list }
it 'displays the correct summary' do it 'displays the correct summary' do
expect { cli.invoke(:add, ip_list, options) }.to output( expect { subject }
a_string_including("#{ip_list.first} is invalid\nAdded #{ip_list.size - 1}, skipped 0, failed 1") .to output_results("#{ip_list.first} is invalid\nAdded #{ip_list.size - 1}, skipped 0, failed 1")
).to_stdout
end end
end end
@ -124,6 +129,7 @@ describe Mastodon::CLI::IpBlocks do
context 'when a specified IP address fails to be blocked' do context 'when a specified IP address fails to be blocked' do
let(:ip_address) { '127.0.0.1' } let(:ip_address) { '127.0.0.1' }
let(:ip_block) { instance_double(IpBlock, ip: ip_address, save: false) } let(:ip_block) { instance_double(IpBlock, ip: ip_address, save: false) }
let(:arguments) { [ip_address] }
before do before do
allow(IpBlock).to receive(:new).and_return(ip_block) allow(IpBlock).to receive(:new).and_return(ip_block)
@ -132,24 +138,25 @@ describe Mastodon::CLI::IpBlocks do
end end
it 'displays an error message' do it 'displays an error message' do
expect { cli.invoke(:add, [ip_address], options) } expect { subject }
.to output( .to output_results("#{ip_address} could not be saved")
a_string_including("#{ip_address} could not be saved")
).to_stdout
end end
end end
context 'when no IP address is provided' do context 'when no IP address is provided' do
let(:arguments) { [] }
it 'exits with an error message' do it 'exits with an error message' do
expect { cli.add }.to output( expect { subject }
a_string_including('No IP(s) given') .to output_results('No IP(s) given')
).to_stdout
.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
end end
describe '#remove' do describe '#remove' do
let(:action) { :remove }
context 'when removing exact matches' do context 'when removing exact matches' do
let(:ip_list) do let(:ip_list) do
[ [
@ -166,21 +173,21 @@ describe Mastodon::CLI::IpBlocks do
'::/128', '::/128',
] ]
end end
let(:arguments) { ip_list }
before do before do
ip_list.each { |ip| IpBlock.create(ip: ip, severity: :no_access) } ip_list.each { |ip| IpBlock.create(ip: ip, severity: :no_access) }
end end
it 'removes exact IP blocks' do it 'removes exact IP blocks' do
cli.invoke(:remove, ip_list) subject
expect(IpBlock.where(ip: ip_list)).to_not exist expect(IpBlock.where(ip: ip_list)).to_not exist
end end
it 'displays success message with a summary' do it 'displays success message with a summary' do
expect { cli.invoke(:remove, ip_list) }.to output( expect { subject }
a_string_including("Removed #{ip_list.size}, skipped 0") .to output_results("Removed #{ip_list.size}, skipped 0")
).to_stdout
end end
end end
@ -192,13 +199,13 @@ describe Mastodon::CLI::IpBlocks do
let(:options) { { force: true } } let(:options) { { force: true } }
it 'removes blocks for IP ranges that cover given IP(s)' do it 'removes blocks for IP ranges that cover given IP(s)' do
cli.invoke(:remove, arguments, options) subject
expect(IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id])).to_not exist expect(IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id])).to_not exist
end end
it 'does not remove other IP ranges' do it 'does not remove other IP ranges' do
cli.invoke(:remove, arguments, options) subject
expect(IpBlock.where(id: third_ip_range_block.id)).to exist expect(IpBlock.where(id: third_ip_range_block.id)).to exist
end end
@ -206,47 +213,46 @@ describe Mastodon::CLI::IpBlocks do
context 'when a specified IP address is not blocked' do context 'when a specified IP address is not blocked' do
let(:unblocked_ip) { '192.0.2.1' } let(:unblocked_ip) { '192.0.2.1' }
let(:arguments) { [unblocked_ip] }
it 'skips the IP address' do it 'skips the IP address' do
expect { cli.invoke(:remove, [unblocked_ip]) }.to output( expect { subject }
a_string_including("#{unblocked_ip} is not yet blocked") .to output_results("#{unblocked_ip} is not yet blocked")
).to_stdout
end end
it 'displays the summary correctly' do it 'displays the summary correctly' do
expect { cli.invoke(:remove, [unblocked_ip]) }.to output( expect { subject }
a_string_including('Removed 0, skipped 1') .to output_results('Removed 0, skipped 1')
).to_stdout
end end
end end
context 'when a specified IP address is invalid' do context 'when a specified IP address is invalid' do
let(:invalid_ip) { '320.15.175.0' } let(:invalid_ip) { '320.15.175.0' }
let(:arguments) { [invalid_ip] }
it 'skips the invalid IP address' do it 'skips the invalid IP address' do
expect { cli.invoke(:remove, [invalid_ip]) }.to output( expect { subject }
a_string_including("#{invalid_ip} is invalid") .to output_results("#{invalid_ip} is invalid")
).to_stdout
end end
it 'displays the summary correctly' do it 'displays the summary correctly' do
expect { cli.invoke(:remove, [invalid_ip]) }.to output( expect { subject }
a_string_including('Removed 0, skipped 1') .to output_results('Removed 0, skipped 1')
).to_stdout
end end
end end
context 'when no IP address is provided' do context 'when no IP address is provided' do
it 'exits with an error message' do it 'exits with an error message' do
expect { cli.remove }.to output( expect { subject }
a_string_including('No IP(s) given') .to output_results('No IP(s) given')
).to_stdout
.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
end end
describe '#export' do describe '#export' do
let(:action) { :export }
let(:first_ip_range_block) { IpBlock.create(ip: '192.168.0.0/24', severity: :no_access) } let(:first_ip_range_block) { IpBlock.create(ip: '192.168.0.0/24', severity: :no_access) }
let(:second_ip_range_block) { IpBlock.create(ip: '10.0.0.0/16', severity: :no_access) } let(:second_ip_range_block) { IpBlock.create(ip: '10.0.0.0/16', severity: :no_access) }
let(:third_ip_range_block) { IpBlock.create(ip: '127.0.0.1', severity: :sign_up_block) } let(:third_ip_range_block) { IpBlock.create(ip: '127.0.0.1', severity: :sign_up_block) }
@ -255,15 +261,13 @@ describe Mastodon::CLI::IpBlocks do
let(:options) { { format: 'plain' } } let(:options) { { format: 'plain' } }
it 'exports blocked IPs with "no_access" severity in plain format' do it 'exports blocked IPs with "no_access" severity in plain format' do
expect { cli.invoke(:export, nil, options) }.to output( expect { subject }
a_string_including("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}") .to output_results("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
).to_stdout
end end
it 'does not export bloked IPs with different severities' do it 'does not export bloked IPs with different severities' do
expect { cli.invoke(:export, nil, options) }.to_not output( expect { subject }
a_string_including("#{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}") .to_not output_results("#{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}")
).to_stdout
end end
end end
@ -271,23 +275,20 @@ describe Mastodon::CLI::IpBlocks do
let(:options) { { format: 'nginx' } } let(:options) { { format: 'nginx' } }
it 'exports blocked IPs with "no_access" severity in plain format' do it 'exports blocked IPs with "no_access" severity in plain format' do
expect { cli.invoke(:export, nil, options) }.to output( expect { subject }
a_string_including("deny #{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};\ndeny #{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix};") .to output_results("deny #{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};\ndeny #{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix};")
).to_stdout
end end
it 'does not export bloked IPs with different severities' do it 'does not export bloked IPs with different severities' do
expect { cli.invoke(:export, nil, options) }.to_not output( expect { subject }
a_string_including("deny #{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};") .to_not output_results("deny #{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};")
).to_stdout
end end
end end
context 'when --format option is not provided' do context 'when --format option is not provided' do
it 'exports blocked IPs in plain format by default' do it 'exports blocked IPs in plain format by default' do
expect { cli.export }.to output( expect { subject }
a_string_including("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}") .to output_results("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}")
).to_stdout
end end
end end
end end

View file

@ -4,13 +4,20 @@ require 'rails_helper'
require 'mastodon/cli/main' require 'mastodon/cli/main'
describe Mastodon::CLI::Main do describe Mastodon::CLI::Main do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe 'version' do describe '#version' do
let(:action) { :version }
it 'returns the Mastodon version' do it 'returns the Mastodon version' do
expect { described_class.new.invoke(:version) }.to output( expect { subject }
a_string_including(Mastodon::Version.to_s) .to output_results(Mastodon::Version.to_s)
).to_stdout
end end
end end
end end

View file

@ -4,20 +4,26 @@ require 'rails_helper'
require 'mastodon/cli/maintenance' require 'mastodon/cli/maintenance'
describe Mastodon::CLI::Maintenance do describe Mastodon::CLI::Maintenance do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#fix_duplicates' do describe '#fix_duplicates' do
let(:action) { :fix_duplicates }
context 'when the database version is too old' do context 'when the database version is too old' do
before do before do
allow(ActiveRecord::Migrator).to receive(:current_version).and_return(2000_01_01_000000) # Earlier than minimum allow(ActiveRecord::Migrator).to receive(:current_version).and_return(2000_01_01_000000) # Earlier than minimum
end end
it 'Exits with error message' do it 'Exits with error message' do
expect { cli.invoke :fix_duplicates }.to output( expect { subject }
a_string_including('is too old') .to output_results('is too old')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
@ -28,9 +34,9 @@ describe Mastodon::CLI::Maintenance do
end end
it 'Exits with error message' do it 'Exits with error message' do
expect { cli.invoke :fix_duplicates }.to output( expect { subject }
a_string_including('more recent') .to output_results('more recent')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
@ -41,9 +47,9 @@ describe Mastodon::CLI::Maintenance do
end end
it 'Exits with error message' do it 'Exits with error message' do
expect { cli.invoke :fix_duplicates }.to output( expect { subject }
a_string_including('Sidekiq is running') .to output_results('Sidekiq is running')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
end end

View file

@ -4,18 +4,24 @@ require 'rails_helper'
require 'mastodon/cli/media' require 'mastodon/cli/media'
describe Mastodon::CLI::Media do describe Mastodon::CLI::Media do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#remove' do describe '#remove' do
let(:action) { :remove }
context 'with --prune-profiles and --remove-headers' do context 'with --prune-profiles and --remove-headers' do
let(:options) { { prune_profiles: true, remove_headers: true } } let(:options) { { prune_profiles: true, remove_headers: true } }
it 'warns about usage and exits' do it 'warns about usage and exits' do
expect { cli.invoke(:remove, [], options) }.to output( expect { subject }
a_string_including('--prune-profiles and --remove-headers should not be specified simultaneously') .to output_results('--prune-profiles and --remove-headers should not be specified simultaneously')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
@ -23,9 +29,9 @@ describe Mastodon::CLI::Media do
let(:options) { { include_follows: true } } let(:options) { { include_follows: true } }
it 'warns about usage and exits' do it 'warns about usage and exits' do
expect { cli.invoke(:remove, [], options) }.to output( expect { subject }
a_string_including('--include-follows can only be used with --prune-profiles or --remove-headers') .to output_results('--include-follows can only be used with --prune-profiles or --remove-headers')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
@ -38,9 +44,8 @@ describe Mastodon::CLI::Media do
let(:options) { { prune_profiles: true } } let(:options) { { prune_profiles: true } }
it 'removes account avatars' do it 'removes account avatars' do
expect { cli.invoke(:remove, [], options) }.to output( expect { subject }
a_string_including('Visited 1') .to output_results('Visited 1')
).to_stdout
expect(account.reload.avatar).to be_blank expect(account.reload.avatar).to be_blank
end end
@ -50,9 +55,8 @@ describe Mastodon::CLI::Media do
let(:options) { { remove_headers: true } } let(:options) { { remove_headers: true } }
it 'removes account header' do it 'removes account header' do
expect { cli.invoke(:remove, [], options) }.to output( expect { subject }
a_string_including('Visited 1') .to output_results('Visited 1')
).to_stdout
expect(account.reload.header).to be_blank expect(account.reload.header).to be_blank
end end
@ -64,9 +68,8 @@ describe Mastodon::CLI::Media do
context 'without options' do context 'without options' do
it 'removes account avatars' do it 'removes account avatars' do
expect { cli.invoke(:remove) }.to output( expect { subject }
a_string_including('Removed 1') .to output_results('Removed 1')
).to_stdout
expect(media_attachment.reload.file).to be_blank expect(media_attachment.reload.file).to be_blank
expect(media_attachment.reload.thumbnail).to be_blank expect(media_attachment.reload.thumbnail).to be_blank
@ -76,25 +79,50 @@ describe Mastodon::CLI::Media do
end end
describe '#usage' do describe '#usage' do
context 'without options' do let(:action) { :usage }
let(:options) { {} }
context 'without options' do
it 'reports about storage size' do it 'reports about storage size' do
expect { cli.invoke(:usage, [], options) }.to output( expect { subject }
a_string_including('0 Bytes') .to output_results('0 Bytes')
).to_stdout end
end
end
describe '#lookup' do
let(:action) { :lookup }
let(:arguments) { [url] }
context 'with valid url not connected to a record' do
let(:url) { 'https://example.host/assets/1' }
it 'warns about url and exits' do
expect { subject }
.to output_results('Not a media URL')
.and raise_error(SystemExit)
end
end
context 'with a valid media url' do
let(:status) { Fabricate(:status) }
let(:media_attachment) { Fabricate(:media_attachment, status: status) }
let(:url) { media_attachment.file.url(:original) }
it 'displays the url of a connected status' do
expect { subject }
.to output_results(status.id.to_s)
end end
end end
end end
describe '#refresh' do describe '#refresh' do
context 'without any options' do let(:action) { :refresh }
let(:options) { {} }
context 'without any options' do
it 'warns about usage and exits' do it 'warns about usage and exits' do
expect { cli.invoke(:refresh, [], options) }.to output( expect { subject }
a_string_including('Specify the source') .to output_results('Specify the source')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
@ -108,9 +136,8 @@ describe Mastodon::CLI::Media do
let(:status) { Fabricate(:status) } let(:status) { Fabricate(:status) }
it 'redownloads the attachment file' do it 'redownloads the attachment file' do
expect { cli.invoke(:refresh, [], options) }.to output( expect { subject }
a_string_including('Downloaded 1 media') .to output_results('Downloaded 1 media')
).to_stdout
end end
end end
@ -119,9 +146,9 @@ describe Mastodon::CLI::Media do
let(:options) { { account: 'not-real-user@example.host' } } let(:options) { { account: 'not-real-user@example.host' } }
it 'warns about usage and exits' do it 'warns about usage and exits' do
expect { cli.invoke(:refresh, [], options) }.to output( expect { subject }
a_string_including('No such account') .to output_results('No such account')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
@ -135,9 +162,8 @@ describe Mastodon::CLI::Media do
let(:account) { Fabricate(:account) } let(:account) { Fabricate(:account) }
it 'redownloads the attachment file' do it 'redownloads the attachment file' do
expect { cli.invoke(:refresh, [], options) }.to output( expect { subject }
a_string_including('Downloaded 1 media') .to output_results('Downloaded 1 media')
).to_stdout
end end
end end
end end
@ -153,9 +179,8 @@ describe Mastodon::CLI::Media do
let(:account) { Fabricate(:account, domain: domain) } let(:account) { Fabricate(:account, domain: domain) }
it 'redownloads the attachment file' do it 'redownloads the attachment file' do
expect { cli.invoke(:refresh, [], options) }.to output( expect { subject }
a_string_including('Downloaded 1 media') .to output_results('Downloaded 1 media')
).to_stdout
end end
end end
end end

View file

@ -4,11 +4,17 @@ require 'rails_helper'
require 'mastodon/cli/preview_cards' require 'mastodon/cli/preview_cards'
describe Mastodon::CLI::PreviewCards do describe Mastodon::CLI::PreviewCards do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#remove' do describe '#remove' do
let(:action) { :remove }
context 'with relevant preview cards' do context 'with relevant preview cards' do
before do before do
Fabricate(:preview_card, updated_at: 10.years.ago, type: :link) Fabricate(:preview_card, updated_at: 10.years.ago, type: :link)
@ -18,10 +24,11 @@ describe Mastodon::CLI::PreviewCards do
context 'with no arguments' do context 'with no arguments' do
it 'deletes thumbnails for local preview cards' do it 'deletes thumbnails for local preview cards' do
expect { cli.invoke(:remove) }.to output( expect { subject }
a_string_including('Removed 2 preview cards') .to output_results(
.and(a_string_including('approx. 119 KB')) 'Removed 2 preview cards',
).to_stdout 'approx. 119 KB'
)
end end
end end
@ -29,10 +36,11 @@ describe Mastodon::CLI::PreviewCards do
let(:options) { { link: true } } let(:options) { { link: true } }
it 'deletes thumbnails for local preview cards' do it 'deletes thumbnails for local preview cards' do
expect { cli.invoke(:remove, [], options) }.to output( expect { subject }
a_string_including('Removed 1 link-type preview cards') .to output_results(
.and(a_string_including('approx. 59.6 KB')) 'Removed 1 link-type preview cards',
).to_stdout 'approx. 59.6 KB'
)
end end
end end
@ -40,10 +48,11 @@ describe Mastodon::CLI::PreviewCards do
let(:options) { { days: 365 } } let(:options) { { days: 365 } }
it 'deletes thumbnails for local preview cards' do it 'deletes thumbnails for local preview cards' do
expect { cli.invoke(:remove, [], options) }.to output( expect { subject }
a_string_including('Removed 1 preview cards') .to output_results(
.and(a_string_including('approx. 59.6 KB')) 'Removed 1 preview cards',
).to_stdout 'approx. 59.6 KB'
)
end end
end end
end end

View file

@ -4,5 +4,79 @@ require 'rails_helper'
require 'mastodon/cli/search' require 'mastodon/cli/search'
describe Mastodon::CLI::Search do describe Mastodon::CLI::Search do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#deploy' do
let(:action) { :deploy }
context 'with concurrency out of range' do
let(:options) { { concurrency: -100 } }
it 'Exits with error message' do
expect { subject }
.to output_results('this concurrency setting')
.and raise_error(SystemExit)
end
end
context 'with batch size out of range' do
let(:options) { { batch_size: -100_000 } }
it 'Exits with error message' do
expect { subject }
.to output_results('this batch_size setting')
.and raise_error(SystemExit)
end
end
context 'without options' do
before { stub_search_indexes }
let(:indexed_count) { 1 }
let(:deleted_count) { 2 }
it 'reports about storage size' do
expect { subject }
.to output_results(
"Indexed #{described_class::INDICES.size * indexed_count} records",
"de-indexed #{described_class::INDICES.size * deleted_count}"
)
end
end
def stub_search_indexes
described_class::INDICES.each do |index|
allow(index)
.to receive_messages(
specification: instance_double(Chewy::Index::Specification, changed?: true, lock!: nil),
purge: nil
)
importer_double = importer_double_for(index)
allow(importer_double).to receive(:on_progress).and_yield([indexed_count, deleted_count])
allow("Importer::#{index}Importer".constantize)
.to receive(:new)
.and_return(importer_double)
end
end
def importer_double_for(index)
instance_double(
"Importer::#{index}Importer".constantize,
clean_up!: nil,
estimate!: 100,
import!: nil,
on_failure: nil,
# on_progress: nil,
optimize_for_import!: nil,
optimize_for_search!: nil
)
end
end
end end

View file

@ -7,59 +7,64 @@ describe Mastodon::CLI::Settings do
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe 'subcommand "registrations"' do describe 'subcommand "registrations"' do
subject { cli.invoke(action, arguments, options) }
let(:cli) { Mastodon::CLI::Registrations.new } let(:cli) { Mastodon::CLI::Registrations.new }
let(:arguments) { [] }
let(:options) { {} }
before do before do
Setting.registrations_mode = nil Setting.registrations_mode = nil
end end
describe '#open' do describe '#open' do
let(:action) { :open }
it 'changes "registrations_mode" to "open"' do it 'changes "registrations_mode" to "open"' do
expect { cli.open }.to change(Setting, :registrations_mode).from(nil).to('open') expect { subject }.to change(Setting, :registrations_mode).from(nil).to('open')
end end
it 'displays success message' do it 'displays success message' do
expect { cli.open }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
end end
end end
describe '#approved' do describe '#approved' do
let(:action) { :approved }
it 'changes "registrations_mode" to "approved"' do it 'changes "registrations_mode" to "approved"' do
expect { cli.approved }.to change(Setting, :registrations_mode).from(nil).to('approved') expect { subject }.to change(Setting, :registrations_mode).from(nil).to('approved')
end end
it 'displays success message' do it 'displays success message' do
expect { cli.approved }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
end end
context 'with --require-reason' do context 'with --require-reason' do
before do let(:options) { { require_reason: true } }
cli.options = { require_reason: true }
end
it 'changes "registrations_mode" to "approved"' do it 'changes "registrations_mode" to "approved"' do
expect { cli.approved }.to change(Setting, :registrations_mode).from(nil).to('approved') expect { subject }.to change(Setting, :registrations_mode).from(nil).to('approved')
end end
it 'sets "require_invite_text" to "true"' do it 'sets "require_invite_text" to "true"' do
expect { cli.approved }.to change(Setting, :require_invite_text).from(false).to(true) expect { subject }.to change(Setting, :require_invite_text).from(false).to(true)
end end
end end
end end
describe '#close' do describe '#close' do
let(:action) { :close }
it 'changes "registrations_mode" to "none"' do it 'changes "registrations_mode" to "none"' do
expect { cli.close }.to change(Setting, :registrations_mode).from(nil).to('none') expect { subject }.to change(Setting, :registrations_mode).from(nil).to('none')
end end
it 'displays success message' do it 'displays success message' do
expect { cli.close }.to output( expect { subject }
a_string_including('OK') .to output_results('OK')
).to_stdout
end end
end end
end end

View file

@ -4,26 +4,31 @@ require 'rails_helper'
require 'mastodon/cli/statuses' require 'mastodon/cli/statuses'
describe Mastodon::CLI::Statuses do describe Mastodon::CLI::Statuses do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#remove', use_transactional_tests: false do describe '#remove', use_transactional_tests: false do
let(:action) { :remove }
context 'with small batch size' do context 'with small batch size' do
let(:options) { { batch_size: 0 } } let(:options) { { batch_size: 0 } }
it 'exits with error message' do it 'exits with error message' do
expect { cli.invoke :remove, [], options }.to output( expect { subject }
a_string_including('Cannot run') .to output_results('Cannot run')
).to_stdout.and raise_error(SystemExit) .and raise_error(SystemExit)
end end
end end
context 'with default batch size' do context 'with default batch size' do
it 'removes unreferenced statuses' do it 'removes unreferenced statuses' do
expect { cli.invoke :remove }.to output( expect { subject }
a_string_including('Done after') .to output_results('Done after')
).to_stdout
end end
end end
end end

View file

@ -4,23 +4,26 @@ require 'rails_helper'
require 'mastodon/cli/upgrade' require 'mastodon/cli/upgrade'
describe Mastodon::CLI::Upgrade do describe Mastodon::CLI::Upgrade do
subject { cli.invoke(action, arguments, options) }
let(:cli) { described_class.new } let(:cli) { described_class.new }
let(:arguments) { [] }
let(:options) { {} }
it_behaves_like 'CLI Command' it_behaves_like 'CLI Command'
describe '#storage_schema' do describe '#storage_schema' do
context 'with records that dont need upgrading' do let(:action) { :storage_schema }
let(:options) { {} }
context 'with records that dont need upgrading' do
before do before do
Fabricate(:account) Fabricate(:account)
Fabricate(:media_attachment) Fabricate(:media_attachment)
end end
it 'does not upgrade storage for the attachments' do it 'does not upgrade storage for the attachments' do
expect { cli.invoke(:storage_schema, [], options) }.to output( expect { subject }
a_string_including('Upgraded storage schema of 0 records') .to output_results('Upgraded storage schema of 0 records')
).to_stdout
end end
end end
end end

View file

@ -88,6 +88,7 @@ RSpec.configure do |config|
config.include Chewy::Rspec::Helpers config.include Chewy::Rspec::Helpers
config.include Redisable config.include Redisable
config.include SignedRequestHelpers, type: :request config.include SignedRequestHelpers, type: :request
config.include CommandLineHelpers, type: :cli
config.around(:each, use_transactional_tests: false) do |example| config.around(:each, use_transactional_tests: false) do |example|
self.use_transactional_tests = false self.use_transactional_tests = false

View file

@ -2,25 +2,21 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Api::V2::SearchController do describe 'Search API' do
render_views
context 'with token' do context 'with token' do
let(:user) { Fabricate(:user) } let(:user) { Fabricate(:user) }
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:search') } let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
let(:scopes) { 'read:search' }
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
before do describe 'GET /api/v2/search' do
allow(controller).to receive(:doorkeeper_token) { token }
end
describe 'GET #index' do
let!(:bob) { Fabricate(:account, username: 'bob_test') } let!(:bob) { Fabricate(:account, username: 'bob_test') }
let!(:ana) { Fabricate(:account, username: 'ana_test') } let!(:ana) { Fabricate(:account, username: 'ana_test') }
let!(:tom) { Fabricate(:account, username: 'tom_test') } let!(:tom) { Fabricate(:account, username: 'tom_test') }
let(:params) { { q: 'test' } } let(:params) { { q: 'test' } }
it 'returns http success' do it 'returns http success' do
get :index, params: params get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
@ -29,7 +25,7 @@ RSpec.describe Api::V2::SearchController do
let(:params) { { q: 'test', type: 'accounts' } } let(:params) { { q: 'test', type: 'accounts' } }
it 'returns all matching accounts' do it 'returns all matching accounts' do
get :index, params: params get '/api/v2/search', headers: headers, params: params
expect(body_as_json[:accounts].pluck(:id)).to contain_exactly(bob.id.to_s, ana.id.to_s, tom.id.to_s) expect(body_as_json[:accounts].pluck(:id)).to contain_exactly(bob.id.to_s, ana.id.to_s, tom.id.to_s)
end end
@ -38,7 +34,7 @@ RSpec.describe Api::V2::SearchController do
let(:params) { { q: 'test1', resolve: '1' } } let(:params) { { q: 'test1', resolve: '1' } }
it 'returns http unauthorized' do it 'returns http unauthorized' do
get :index, params: params get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
@ -48,7 +44,7 @@ RSpec.describe Api::V2::SearchController do
let(:params) { { q: 'test1', offset: 1 } } let(:params) { { q: 'test1', offset: 1 } }
it 'returns http unauthorized' do it 'returns http unauthorized' do
get :index, params: params get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
end end
@ -62,7 +58,7 @@ RSpec.describe Api::V2::SearchController do
end end
it 'returns only the followed accounts' do it 'returns only the followed accounts' do
get :index, params: params get '/api/v2/search', headers: headers, params: params
expect(body_as_json[:accounts].pluck(:id)).to contain_exactly(ana.id.to_s) expect(body_as_json[:accounts].pluck(:id)).to contain_exactly(ana.id.to_s)
end end
@ -73,7 +69,7 @@ RSpec.describe Api::V2::SearchController do
before { allow(Search).to receive(:new).and_raise(Mastodon::SyntaxError) } before { allow(Search).to receive(:new).and_raise(Mastodon::SyntaxError) }
it 'returns http unprocessable_entity' do it 'returns http unprocessable_entity' do
get :index, params: params get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(422) expect(response).to have_http_status(422)
end end
@ -83,7 +79,7 @@ RSpec.describe Api::V2::SearchController do
before { allow(Search).to receive(:new).and_raise(ActiveRecord::RecordNotFound) } before { allow(Search).to receive(:new).and_raise(ActiveRecord::RecordNotFound) }
it 'returns http not_found' do it 'returns http not_found' do
get :index, params: params get '/api/v2/search', headers: headers, params: params
expect(response).to have_http_status(404) expect(response).to have_http_status(404)
end end
@ -92,11 +88,11 @@ RSpec.describe Api::V2::SearchController do
end end
context 'without token' do context 'without token' do
describe 'GET #index' do describe 'GET /api/v2/search' do
let(:search_params) { nil } let(:search_params) { nil }
before do before do
get :index, params: search_params get '/api/v2/search', params: search_params
end end
context 'without a `q` param' do context 'without a `q` param' do

View file

@ -378,12 +378,10 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
end end
end end
it 'creates at least some accounts' do it 'creates accounts without exceeding rate limit' do
expect { subject }.to change { Account.remote.count }.by_at_least(2) expect { subject }
end .to create_some_remote_accounts
.and create_fewer_than_rate_limit_accounts
it 'creates no more account than the limit allows' do
expect { subject }.to change { Account.remote.count }.by_at_most(5)
end end
end end
@ -445,12 +443,20 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
end end
end end
it 'creates at least some accounts' do it 'creates accounts without exceeding rate limit' do
expect { subject.call('user1', 'foo.test', payload) }.to change { Account.remote.count }.by_at_least(2) expect { subject.call('user1', 'foo.test', payload) }
.to create_some_remote_accounts
.and create_fewer_than_rate_limit_accounts
end
end end
it 'creates no more account than the limit allows' do private
expect { subject.call('user1', 'foo.test', payload) }.to change { Account.remote.count }.by_at_most(5)
def create_some_remote_accounts
change(Account.remote, :count).by_at_least(2)
end end
def create_fewer_than_rate_limit_accounts
change(Account.remote, :count).by_at_most(5)
end end
end end

View file

@ -47,8 +47,15 @@ RSpec.describe DeleteAccountService, type: :service do
let!(:account_note) { Fabricate(:account_note, account: account) } let!(:account_note) { Fabricate(:account_note, account: account) }
it 'deletes associated owned records' do it 'deletes associated owned and target records and target notifications' do
expect { subject }.to change { expect { subject }
.to delete_associated_owned_records
.and delete_associated_target_records
.and delete_associated_target_notifications
end
def delete_associated_owned_records
change do
[ [
account.statuses, account.statuses,
account.media_attachments, account.media_attachments,
@ -61,7 +68,7 @@ RSpec.describe DeleteAccountService, type: :service do
account.polls, account.polls,
account.account_notes, account.account_notes,
].map(&:count) ].map(&:count)
}.from([3, 1, 1, 1, 1, 1, 2, 2, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) end.from([3, 1, 1, 1, 1, 1, 2, 2, 1, 1]).to([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
end end
it 'deletes associated owned record groups' do it 'deletes associated owned record groups' do
@ -82,20 +89,20 @@ RSpec.describe DeleteAccountService, type: :service do
expect { bookmark_category_status.reload }.to raise_error(ActiveRecord::RecordNotFound) expect { bookmark_category_status.reload }.to raise_error(ActiveRecord::RecordNotFound)
end end
it 'deletes associated target records' do def delete_associated_target_records
expect { subject }.to change { change do
[ [
AccountPin.where(target_account: account), AccountPin.where(target_account: account),
].map(&:count) ].map(&:count)
}.from([1]).to([0]) end.from([1]).to([0])
end end
it 'deletes associated target notifications' do def delete_associated_target_notifications
expect { subject }.to change { change do
%w( %w(
poll favourite emoji_reaction status mention follow poll favourite emoji_reaction status mention follow
).map { |type| Notification.where(type: type).count } ).map { |type| Notification.where(type: type).count }
}.from([1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0]) end.from([1, 1, 1, 1, 1, 1]).to([0, 0, 0, 0, 0, 0])
end end
end end

View file

@ -18,14 +18,15 @@ RSpec.describe SuspendAccountService, type: :service do
account.suspend! account.suspend!
end end
it "unmerges from local followers' feeds" do it 'unmerges from feeds of local followers and preserves suspended flag' do
subject expect { subject }
.to_not change_suspended_flag
expect(FeedManager.instance).to have_received(:unmerge_from_home).with(account, local_follower) expect(FeedManager.instance).to have_received(:unmerge_from_home).with(account, local_follower)
expect(FeedManager.instance).to have_received(:unmerge_from_list).with(account, list) expect(FeedManager.instance).to have_received(:unmerge_from_list).with(account, list)
end end
it 'does not change the “suspended” flag' do def change_suspended_flag
expect { subject }.to_not change(account, :suspended?) change(account, :suspended?)
end end
end end

View file

@ -45,14 +45,19 @@ RSpec.describe UnsuspendAccountService, type: :service do
remote_follower.follow!(account) remote_follower.follow!(account)
end end
it "merges back into local followers' feeds" do it 'merges back into feeds of local followers and sends update' do
subject subject
expect_feeds_merged
expect_updates_sent
end
def expect_feeds_merged
expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list) expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list)
end end
it 'sends an update actor to followers and reporters' do def expect_updates_sent
subject
expect(a_request(:post, remote_follower.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once expect(a_request(:post, remote_follower.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
expect(a_request(:post, remote_reporter.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once expect(a_request(:post, remote_reporter.inbox_url).with { |req| match_update_actor_request(req, account) }).to have_been_made.once
end end
@ -73,19 +78,20 @@ RSpec.describe UnsuspendAccountService, type: :service do
allow(resolve_account_service).to receive(:call).with(account).and_return(account) allow(resolve_account_service).to receive(:call).with(account).and_return(account)
end end
it 're-fetches the account' do it 're-fetches the account, merges feeds, and preserves suspended' do
subject expect { subject }
.to_not change_suspended_flag
expect_feeds_merged
expect(resolve_account_service).to have_received(:call).with(account) expect(resolve_account_service).to have_received(:call).with(account)
end end
it "merges back into local followers' feeds" do def expect_feeds_merged
subject
expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list) expect(FeedManager.instance).to have_received(:merge_into_list).with(account, list)
end end
it 'does not change the “suspended” flag' do def change_suspended_flag
expect { subject }.to_not change(account, :suspended?) change(account, :suspended?)
end end
end end
@ -97,19 +103,20 @@ RSpec.describe UnsuspendAccountService, type: :service do
end end
end end
it 're-fetches the account' do it 're-fetches the account, does not merge feeds, marks suspended' do
subject expect { subject }
.to change_suspended_to_true
expect(resolve_account_service).to have_received(:call).with(account) expect(resolve_account_service).to have_received(:call).with(account)
expect_feeds_not_merged
end end
it "does not merge back into local followers' feeds" do def expect_feeds_not_merged
subject
expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list) expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list)
end end
it 'marks account as suspended' do def change_suspended_to_true
expect { subject }.to change(account, :suspended?).from(false).to(true) change(account, :suspended?).from(false).to(true)
end end
end end
@ -118,13 +125,14 @@ RSpec.describe UnsuspendAccountService, type: :service do
allow(resolve_account_service).to receive(:call).with(account).and_return(nil) allow(resolve_account_service).to receive(:call).with(account).and_return(nil)
end end
it 're-fetches the account' do it 're-fetches the account and does not merge feeds' do
subject subject
expect(resolve_account_service).to have_received(:call).with(account) expect(resolve_account_service).to have_received(:call).with(account)
expect_feeds_not_merged
end end
it "does not merge back into local followers' feeds" do def expect_feeds_not_merged
subject
expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower) expect(FeedManager.instance).to_not have_received(:merge_into_home).with(account, local_follower)
expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list) expect(FeedManager.instance).to_not have_received(:merge_into_list).with(account, list)
end end

View file

@ -0,0 +1,9 @@
# frozen_string_literal: true
module CommandLineHelpers
def output_results(*args)
output(
include(*args)
).to_stdout
end
end

View file

@ -2390,7 +2390,7 @@ __metadata:
eslint-plugin-jsx-a11y: "npm:~6.8.0" eslint-plugin-jsx-a11y: "npm:~6.8.0"
eslint-plugin-prettier: "npm:^5.0.0" eslint-plugin-prettier: "npm:^5.0.0"
eslint-plugin-promise: "npm:~6.1.1" eslint-plugin-promise: "npm:~6.1.1"
eslint-plugin-react: "npm:~7.33.0" eslint-plugin-react: "npm:^7.33.2"
eslint-plugin-react-hooks: "npm:^4.6.0" eslint-plugin-react-hooks: "npm:^4.6.0"
file-loader: "npm:^6.2.0" file-loader: "npm:^6.2.0"
font-awesome: "npm:^4.7.0" font-awesome: "npm:^4.7.0"
@ -5979,9 +5979,9 @@ __metadata:
linkType: hard linkType: hard
"core-js@npm:^3.30.2": "core-js@npm:^3.30.2":
version: 3.33.3 version: 3.34.0
resolution: "core-js@npm:3.33.3" resolution: "core-js@npm:3.34.0"
checksum: 08abdc9470c8228b9d09f61e62ab312738681202c4c34e9638889125b304b235f34c4fe22e9d41c20906ac0fcc807dca57c5ff7d6b90021bf64e8fe23461d9ab checksum: 408a77898abe03bf3e5dec2a451c36f4745081cca9022f8bdf9b817d57bb6d3a534d555f47a4b95e1daa5e21dbc79122eac2402e25720d425f5925127e55dcd8
languageName: node languageName: node
linkType: hard linkType: hard
@ -7529,7 +7529,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-plugin-react@npm:~7.33.0": "eslint-plugin-react@npm:^7.33.2":
version: 7.33.2 version: 7.33.2
resolution: "eslint-plugin-react@npm:7.33.2" resolution: "eslint-plugin-react@npm:7.33.2"
dependencies: dependencies:
@ -14698,8 +14698,8 @@ __metadata:
linkType: hard linkType: hard
"sass-loader@npm:^10.2.0": "sass-loader@npm:^10.2.0":
version: 10.4.1 version: 10.5.0
resolution: "sass-loader@npm:10.4.1" resolution: "sass-loader@npm:10.5.0"
dependencies: dependencies:
klona: "npm:^2.0.4" klona: "npm:^2.0.4"
loader-utils: "npm:^2.0.0" loader-utils: "npm:^2.0.0"
@ -14708,7 +14708,7 @@ __metadata:
semver: "npm:^7.3.2" semver: "npm:^7.3.2"
peerDependencies: peerDependencies:
fibers: ">= 3.1.0" fibers: ">= 3.1.0"
node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 node-sass: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0
sass: ^1.3.0 sass: ^1.3.0
webpack: ^4.36.0 || ^5.0.0 webpack: ^4.36.0 || ^5.0.0
peerDependenciesMeta: peerDependenciesMeta:
@ -14718,7 +14718,7 @@ __metadata:
optional: true optional: true
sass: sass:
optional: true optional: true
checksum: bf04a440fe471928f3cf884bc12c6b70bc391795b35510b1b9021e8a2cca3b8f966aef9518f4171e87e9cb78193a774f695921e6b61881a1580ae0a3c7b1b5e4 checksum: be5da7784fd21c4f526cc3afaa1a765ba44cdc2f9798ecbac87b296ab44184ac5ba9bbda68a7a86f8cdcb6130acceefeb8912260fca14bdfc97f9dad02658400
languageName: node languageName: node
linkType: hard linkType: hard