Merge remote-tracking branch 'parent/main' into kb-upstream-20231014
This commit is contained in:
commit
60195928e1
76 changed files with 1282 additions and 1205 deletions
|
@ -180,7 +180,6 @@ RSpec/LetSetup:
|
|||
- 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb'
|
||||
- 'spec/controllers/api/v1/admin/accounts_controller_spec.rb'
|
||||
- 'spec/controllers/api/v1/filters_controller_spec.rb'
|
||||
- 'spec/controllers/api/v1/followed_tags_controller_spec.rb'
|
||||
- 'spec/controllers/api/v2/admin/accounts_controller_spec.rb'
|
||||
- 'spec/controllers/api/v2/filters/keywords_controller_spec.rb'
|
||||
- 'spec/controllers/api/v2/filters/statuses_controller_spec.rb'
|
||||
|
|
|
@ -216,11 +216,11 @@ GEM
|
|||
railties (>= 4.1.0)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
devise-two-factor (4.1.0)
|
||||
activesupport (< 7.1)
|
||||
devise-two-factor (4.1.1)
|
||||
activesupport (~> 7.0)
|
||||
attr_encrypted (>= 1.3, < 5, != 2)
|
||||
devise (~> 4.0)
|
||||
railties (< 7.1)
|
||||
railties (~> 7.0)
|
||||
rotp (~> 6.0)
|
||||
devise_pam_authenticatable2 (9.2.0)
|
||||
devise (>= 4.0.0)
|
||||
|
@ -622,7 +622,7 @@ GEM
|
|||
sidekiq (>= 5, < 8)
|
||||
rspec-support (3.12.1)
|
||||
rspec_chunked (0.6)
|
||||
rubocop (1.57.0)
|
||||
rubocop (1.57.1)
|
||||
base64 (~> 0.1.1)
|
||||
json (~> 2.3)
|
||||
language_server-protocol (>= 3.17.0)
|
||||
|
|
|
@ -26,10 +26,10 @@
|
|||
"account.domain_blocked": "Verkkotunnus estetty",
|
||||
"account.edit_profile": "Muokkaa profiilia",
|
||||
"account.enable_notifications": "Ilmoita minulle, kun @{name} julkaisee",
|
||||
"account.endorse": "Suosittele profiilissasi",
|
||||
"account.endorse": "Pidä esillä profiilissa",
|
||||
"account.featured_tags.last_status_at": "Viimeisin julkaisu {date}",
|
||||
"account.featured_tags.last_status_never": "Ei julkaisuja",
|
||||
"account.featured_tags.title": "Käyttäjän {name} esille nostetut aihetunnisteet",
|
||||
"account.featured_tags.title": "Käyttäjän {name} esillä pidettävät aihetunnisteet",
|
||||
"account.follow": "Seuraa",
|
||||
"account.followers": "Seuraajat",
|
||||
"account.followers.empty": "Kukaan ei seuraa tätä käyttäjää vielä.",
|
||||
|
@ -62,10 +62,10 @@
|
|||
"account.share": "Jaa käyttäjän @{name} profiili",
|
||||
"account.show_reblogs": "Näytä käyttäjän @{name} tehostukset",
|
||||
"account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
|
||||
"account.unblock": "Poista esto: @{name}",
|
||||
"account.unblock_domain": "Salli palvelu {domain}",
|
||||
"account.unblock": "Poista käyttäjän @{name} esto",
|
||||
"account.unblock_domain": "Poista verkkotunnuksen {domain} esto",
|
||||
"account.unblock_short": "Poista esto",
|
||||
"account.unendorse": "Poista suosittelu profiilistasi",
|
||||
"account.unendorse": "Älä pidä esillä profiilissa",
|
||||
"account.unfollow": "Lopeta seuraaminen",
|
||||
"account.unmute": "Poista käyttäjän @{name} mykistys",
|
||||
"account.unmute_notifications_short": "Poista ilmoitusten mykistys",
|
||||
|
@ -225,12 +225,12 @@
|
|||
"empty_column.account_suspended": "Tili jäädytetty",
|
||||
"empty_column.account_timeline": "Ei viestejä täällä.",
|
||||
"empty_column.account_unavailable": "Profiilia ei löydy",
|
||||
"empty_column.blocks": "Et ole estänyt käyttäjiä.",
|
||||
"empty_column.blocks": "Et ole vielä estänyt käyttäjiä.",
|
||||
"empty_column.bookmarked_statuses": "Et ole vielä lisännyt julkaisuja kirjanmerkkeihisi. Kun lisäät yhden, se näkyy tässä.",
|
||||
"empty_column.community": "Paikallinen aikajana on tyhjä. Kirjoita jotain julkista, niin homma lähtee käyntiin!",
|
||||
"empty_column.direct": "Yksityisiä mainintoja ei vielä ole. Jos lähetät tai sinulle lähetetään sellaisia, näet ne täällä.",
|
||||
"empty_column.domain_blocks": "Palveluita ei ole vielä estetty.",
|
||||
"empty_column.explore_statuses": "Mikään ei trendaa nyt. Tarkista myöhemmin uudelleen!",
|
||||
"empty_column.domain_blocks": "Verkkotunnuksia ei ole vielä estetty.",
|
||||
"empty_column.explore_statuses": "Mikään ei ole nyt suosittua. Tarkista myöhemmin uudelleen!",
|
||||
"empty_column.favourited_statuses": "Sinulla ei ole vielä yhtään suosikkijulkaisua. Kun lisäät sellaisen, näkyy se tässä.",
|
||||
"empty_column.favourites": "Kukaan ei ole vielä lisännyt tätä julkaisua suosikkeihinsa. Kun joku tekee niin, tulee hän tähän näkyviin.",
|
||||
"empty_column.follow_requests": "Et ole vielä vastaanottanut seuraamispyyntöjä. Saamasi pyynnöt näkyvät täällä.",
|
||||
|
@ -414,7 +414,7 @@
|
|||
"navigation_bar.lists": "Listat",
|
||||
"navigation_bar.logout": "Kirjaudu ulos",
|
||||
"navigation_bar.mutes": "Mykistetyt käyttäjät",
|
||||
"navigation_bar.opened_in_classic_interface": "Julkaisut, profiilit ja tietyt muut sivut avautuvat oletuksena perinteiseen web-käyttöliittymään.",
|
||||
"navigation_bar.opened_in_classic_interface": "Julkaisut, profiilit ja tietyt muut sivut avautuvat oletuksena perinteiseen selainkäyttöliittymään.",
|
||||
"navigation_bar.personal": "Henkilökohtainen",
|
||||
"navigation_bar.pins": "Kiinnitetyt julkaisut",
|
||||
"navigation_bar.preferences": "Asetukset",
|
||||
|
@ -472,7 +472,7 @@
|
|||
"notifications_permission_banner.title": "Älä anna minkään mennä ohi",
|
||||
"onboarding.action.back": "Palaa takaisin",
|
||||
"onboarding.actions.back": "Palaa takaisin",
|
||||
"onboarding.actions.go_to_explore": "Siirry suosituimpien aiheiden syötteeseen",
|
||||
"onboarding.actions.go_to_explore": "Siirry suosittujen aiheiden syötteeseen",
|
||||
"onboarding.actions.go_to_home": "Siirry kotisyötteeseeni",
|
||||
"onboarding.compose.template": "Tervehdys #Mastodon!",
|
||||
"onboarding.follows.empty": "Valitettavasti tuloksia ei voida näyttää juuri nyt. Voit kokeilla hakua tai selata tutustumissivua löytääksesi seurattavaa tai yrittää myöhemmin uudelleen.",
|
||||
|
@ -537,7 +537,7 @@
|
|||
"relative_time.today": "tänään",
|
||||
"reply_indicator.cancel": "Peruuta",
|
||||
"report.block": "Estä",
|
||||
"report.block_explanation": "Et näe hänen viestejään, eikä hän voi nähdä viestejäsi tai seurata sinua. Hän näkevät, että olet estänyt hänet.",
|
||||
"report.block_explanation": "Et näe hänen viestejään, eikä hän voi nähdä viestejäsi tai seurata sinua. Hän näkee, että olet estänyt hänet.",
|
||||
"report.categories.legal": "Lakiasiat",
|
||||
"report.categories.other": "Muu",
|
||||
"report.categories.spam": "Roskaposti",
|
||||
|
@ -694,7 +694,7 @@
|
|||
"units.short.thousand": "{count} t.",
|
||||
"upload_area.title": "Lataa raahaamalla ja pudottamalla tähän",
|
||||
"upload_button.label": "Lisää kuvia, video tai äänitiedosto",
|
||||
"upload_error.limit": "Tiedostolatauksien raja ylitetty.",
|
||||
"upload_error.limit": "Tiedostolatauksien rajoitus ylitetty.",
|
||||
"upload_error.poll": "Tiedoston lataaminen ei ole sallittua äänestyksissä.",
|
||||
"upload_form.audio_description": "Kuvaile sisältöä kuuroille ja kuulorajoitteisille",
|
||||
"upload_form.description": "Kuvaile sisältöä sokeille ja näkörajoitteisille",
|
||||
|
|
|
@ -207,6 +207,7 @@ class FeedManager
|
|||
# also tagged with another followed hashtag or from a followed user
|
||||
scope = from_tag.statuses
|
||||
.where(id: timeline_status_ids)
|
||||
.where.not(account: into_account)
|
||||
.where.not(account: into_account.following)
|
||||
.tagged_with_none(TagFollow.where(account: into_account).pluck(:tag_id))
|
||||
|
||||
|
|
|
@ -16,11 +16,18 @@ class ManifestSerializer < ActiveModel::Serializer
|
|||
512
|
||||
).freeze
|
||||
|
||||
attributes :name, :short_name,
|
||||
attributes :id, :name, :short_name,
|
||||
:icons, :theme_color, :background_color,
|
||||
:display, :start_url, :scope,
|
||||
:share_target, :shortcuts
|
||||
|
||||
def id
|
||||
# This is set to `/home` because that was the old value of `start_url` and
|
||||
# thus the fallback ID computed by Chrome:
|
||||
# https://developer.chrome.com/blog/pwa-manifest-id/
|
||||
'/home'
|
||||
end
|
||||
|
||||
def name
|
||||
object.title
|
||||
end
|
||||
|
@ -53,7 +60,7 @@ class ManifestSerializer < ActiveModel::Serializer
|
|||
end
|
||||
|
||||
def start_url
|
||||
'/home'
|
||||
'/'
|
||||
end
|
||||
|
||||
def scope
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
enabled = ENV['ES_ENABLED'] == 'true'
|
||||
host = ENV.fetch('ES_HOST') { 'localhost' }
|
||||
port = ENV.fetch('ES_PORT') { 9200 }
|
||||
user = ENV.fetch('ES_USER') { nil }
|
||||
password = ENV.fetch('ES_PASS') { nil }
|
||||
fallback_prefix = ENV.fetch('REDIS_NAMESPACE') { nil }
|
||||
user = ENV.fetch('ES_USER', nil).presence
|
||||
password = ENV.fetch('ES_PASS', nil).presence
|
||||
fallback_prefix = ENV.fetch('REDIS_NAMESPACE', nil).presence
|
||||
prefix = ENV.fetch('ES_PREFIX') { fallback_prefix }
|
||||
|
||||
Chewy.settings = {
|
||||
|
|
|
@ -394,7 +394,7 @@ Devise.setup do |config|
|
|||
config.check_at_sign = true
|
||||
config.pam_default_suffix = ENV.fetch('PAM_EMAIL_DOMAIN') { ENV['LOCAL_DOMAIN'] }
|
||||
config.pam_default_service = ENV.fetch('PAM_DEFAULT_SERVICE') { 'rpam' }
|
||||
config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE') { nil }
|
||||
config.pam_controlled_service = ENV.fetch('PAM_CONTROLLED_SERVICE', nil).presence
|
||||
end
|
||||
|
||||
if ENV['LDAP_ENABLED'] == 'true'
|
||||
|
|
|
@ -118,11 +118,11 @@ fi:
|
|||
write: Vain kirjoitusoikeus
|
||||
title:
|
||||
accounts: Tilit
|
||||
admin/accounts: Tilien hallinta
|
||||
admin/accounts: Tilien hallinnointi
|
||||
admin/all: Kaikki hallinnolliset toiminnot
|
||||
admin/reports: Raporttien hallinta
|
||||
admin/reports: Raporttien hallinnointi
|
||||
all: Täysi pääsy Mastodon-tiliisi
|
||||
blocks: Torjutut
|
||||
blocks: Estot
|
||||
bookmarks: Kirjanmerkit
|
||||
conversations: Keskustelut
|
||||
crypto: Päästä päähän -salaus
|
||||
|
|
|
@ -27,10 +27,10 @@ fi:
|
|||
title: Suorita valvontatoimi käyttäjälle %{acct}
|
||||
account_moderation_notes:
|
||||
create: Jätä muistiinpano
|
||||
created_msg: Valvontamerkinnän luonti onnistui!
|
||||
destroyed_msg: Valvontamerkinnän poisto onnistui!
|
||||
created_msg: Valvontamuistiinpanon luonti onnistui!
|
||||
destroyed_msg: Valvontamuistiinpanon poisto onnistui!
|
||||
accounts:
|
||||
add_email_domain_block: Estä sähköpostidomain
|
||||
add_email_domain_block: Estä sähköpostiverkkotunnus
|
||||
approve: Hyväksy
|
||||
approved_msg: Käyttäjän %{username} liittymishakemus hyväksyttiin
|
||||
are_you_sure: Oletko varma?
|
||||
|
@ -95,10 +95,10 @@ fi:
|
|||
silenced: Rajoitettu
|
||||
suspended: Jäädytetty
|
||||
title: Valvonta
|
||||
moderation_notes: Valvontamerkinnät
|
||||
moderation_notes: Valvontamuistiinpanot
|
||||
most_recent_activity: Viimeisin toiminta
|
||||
most_recent_ip: Viimeisin IP
|
||||
no_account_selected: Yhtään tiliä ei muutettu, koska mitään ei valittu
|
||||
no_account_selected: Tilejä ei muutettu, koska yhtään ei ollut valittuna
|
||||
no_limits_imposed: Rajoituksia ei ole asetettu
|
||||
no_role_assigned: Roolia ei ole määritetty
|
||||
not_subscribed: Ei tilaaja
|
||||
|
@ -117,7 +117,7 @@ fi:
|
|||
reject: Hylkää
|
||||
rejected_msg: Käyttäjän %{username} rekisteröitymishakemus hylättiin
|
||||
remote_suspension_irreversible: Tämän tilin tiedot on poistettu peruuttamattomasti.
|
||||
remote_suspension_reversible_hint_html: Tili on jäädytetty heidän palvelimellaan, ja kaikki tiedot poistetaan %{date}. Sitä ennen etäpalvelin voi palauttaa tilin ongelmitta. Jos haluat poistaa kaikki tilin tiedot heti, onnistuu se alta.
|
||||
remote_suspension_reversible_hint_html: Tili on jäädytetty omalla palvelimellaan, ja kaikki tiedot poistetaan %{date}. Sitä ennen etäpalvelin voi palauttaa tilin ongelmitta. Jos haluat poistaa kaikki tilin tiedot heti, onnistuu se alta.
|
||||
remove_avatar: Poista profiilikuva
|
||||
remove_header: Poista otsakekuva
|
||||
removed_avatar_msg: Käyttäjän %{username} avatar-kuva poistettu onnistuneesti
|
||||
|
@ -181,7 +181,7 @@ fi:
|
|||
create_custom_emoji: Luo mukautettu emoji
|
||||
create_domain_allow: Luo verkkotunnuksen salliminen
|
||||
create_domain_block: Luo verkkotunnuksen esto
|
||||
create_email_domain_block: Luo sähköpostin verkkotunnuksen esto
|
||||
create_email_domain_block: Luo sähköpostiverkkotunnuksen esto
|
||||
create_ip_block: Luo IP-sääntö
|
||||
create_unavailable_domain: Luo ei-saatavilla oleva verkkotunnus
|
||||
create_user_role: Luo rooli
|
||||
|
@ -191,7 +191,7 @@ fi:
|
|||
destroy_custom_emoji: Poista mukautettu emoji
|
||||
destroy_domain_allow: Poista verkkotunnuksen salliminen
|
||||
destroy_domain_block: Poista verkkotunnuksen esto
|
||||
destroy_email_domain_block: Poista sähköpostin verkkotunnuksen esto
|
||||
destroy_email_domain_block: Poista sähköpostiverkkotunnuksen esto
|
||||
destroy_instance: Tyhjennä verkkotunnus
|
||||
destroy_ip_block: Poista IP-sääntö
|
||||
destroy_status: Poista julkaisu
|
||||
|
@ -236,21 +236,21 @@ fi:
|
|||
confirm_user_html: "%{name} vahvisti käyttäjän %{target} sähköpostiosoitteen"
|
||||
create_account_warning_html: "%{name} lähetti varoituksen käyttäjälle %{target}"
|
||||
create_announcement_html: "%{name} loi uuden tiedotteen %{target}"
|
||||
create_canonical_email_block_html: "%{name} esti sähköpostin hashilla %{target}"
|
||||
create_canonical_email_block_html: "%{name} esti sähköpostin tiivisteellä %{target}"
|
||||
create_custom_emoji_html: "%{name} lähetti uuden emojin %{target}"
|
||||
create_domain_allow_html: "%{name} salli federoinnin verkkotunnuksen %{target} kanssa"
|
||||
create_domain_block_html: "%{name} esti verkkotunnuksen %{target}"
|
||||
create_email_domain_block_html: "%{name} esti sähköpostin %{target}"
|
||||
create_email_domain_block_html: "%{name} esti sähköpostiverkkotunnuksen %{target}"
|
||||
create_ip_block_html: "%{name} loi IP-säännön %{target}"
|
||||
create_unavailable_domain_html: "%{name} pysäytti toimituksen verkkotunnukseen %{target}"
|
||||
create_user_role_html: "%{name} loi roolin %{target}"
|
||||
demote_user_html: "%{name} alensi käyttäjän %{target}"
|
||||
destroy_announcement_html: "%{name} poisti tiedotteen %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} poisti sähköpostieston hashilla %{target}"
|
||||
destroy_canonical_email_block_html: "%{name} poisti sähköpostin eston tiivisteellä %{target}"
|
||||
destroy_custom_emoji_html: "%{name} poisti emojin %{target}"
|
||||
destroy_domain_allow_html: "%{name} kielsi federoinnin verkkotunnuksen %{target} kanssa"
|
||||
destroy_domain_block_html: "%{name} poisti verkkotunnuksen %{target} eston"
|
||||
destroy_email_domain_block_html: "%{name} poisti sähköpostin verkkotunnuksen %{target} eston"
|
||||
destroy_email_domain_block_html: "%{name} poisti sähköpostiverkkotunnuksen %{target} eston"
|
||||
destroy_instance_html: "%{name} tyhjensi verkkotunnuksen %{target}"
|
||||
destroy_ip_block_html: "%{name} poisti IP-säännön %{target}"
|
||||
destroy_status_html: "%{name} poisti käyttäjän %{target} julkaisun"
|
||||
|
@ -331,7 +331,7 @@ fi:
|
|||
listed: Listalla
|
||||
new:
|
||||
title: Lisää uusi mukautettu emoji
|
||||
no_emoji_selected: Emojeita ei muutettu, koska yhtään ei valittu
|
||||
no_emoji_selected: Emojeita ei muutettu, koska yhtään ei ollut valittuna
|
||||
not_permitted: Sinulla ei ole oikeutta suorittaa tätä toimintoa
|
||||
overwrite: Korvaa
|
||||
shortcode: Lyhennekoodi
|
||||
|
@ -381,7 +381,7 @@ fi:
|
|||
import: Tuo
|
||||
undo: Estä liitto verkkotunnukselle
|
||||
domain_blocks:
|
||||
add_new: Lisää uusi
|
||||
add_new: Lisää uusi verkkotunnuksen esto
|
||||
confirm_suspension:
|
||||
cancel: Peruuta
|
||||
confirm: Jäädytä
|
||||
|
@ -408,7 +408,7 @@ fi:
|
|||
silence: Rajoita
|
||||
suspend: Jäädytä
|
||||
title: Uusi verkkotunnuksen esto
|
||||
no_domain_block_selected: Verkkoalue-estoihin ei tehty muutoksia, koska valintoja ei tehty
|
||||
no_domain_block_selected: Verkkotunnusten estoja ei muutettu, koska yhtään ei ollut valittuna
|
||||
not_permitted: Nykyiset käyttöoikeutesi eivät kata tätä toimintoa
|
||||
obfuscate: Peitä verkkotunnuksen nimi
|
||||
obfuscate_hint: Peitä verkkotunnus osittain luettelossa, jos julkinen verkkotunnusten rajoitusluettelo on käytössä
|
||||
|
@ -420,14 +420,14 @@ fi:
|
|||
reject_media_hint: Poistaa paikallisesti tallennetut mediatiedostot eikä lataa niitä enää jatkossa. Ei merkitystä jäähyn kohdalla
|
||||
reject_reports: Hylkää raportit
|
||||
reject_reports_hint: Ohita kaikki tästä verkkotunnuksesta tulevat raportit. Erottamisen kannalta ei merkitystä
|
||||
undo: Peru
|
||||
undo: Peru verkkotunnuksen esto
|
||||
view: Näytä verkkotunnuksen esto
|
||||
email_domain_blocks:
|
||||
add_new: Lisää uusi
|
||||
attempts_over_week:
|
||||
one: "%{count} yritystä viimeisen viikon aikana"
|
||||
other: "%{count} rekisteröitymisyritystä viimeisen viikon aikana"
|
||||
created_msg: Sähköpostiverkkotunnuksen lisäys estolistalle onnistui
|
||||
created_msg: Sähköpostiverkkotunnus estetty onnistuneesti
|
||||
delete: Poista
|
||||
dns:
|
||||
types:
|
||||
|
@ -436,26 +436,26 @@ fi:
|
|||
new:
|
||||
create: Lisää verkkotunnus
|
||||
resolve: Ratkaise verkkotunnus
|
||||
title: Uusi sähköpostiestolistan merkintä
|
||||
no_email_domain_block_selected: Sähköpostin verkkotunnuksia ei muutettu, koska yhtään ei valittu
|
||||
title: Estä uusi sähköpostiverkkotunnus
|
||||
no_email_domain_block_selected: Sähköpostin verkkotunnuksia ei muutettu, koska yhtään ei ollut valittuna
|
||||
not_permitted: Ei sallittu
|
||||
resolved_dns_records_hint_html: Verkkotunnuksen nimi määräytyy seuraaviin MX-verkkotunnuksiin, jotka ovat viime kädessä vastuussa sähköpostin vastaanottamisesta. MX-verkkotunnuksen estäminen estää kirjautumisen mistä tahansa sähköpostiosoitteesta, joka käyttää samaa MX-verkkotunnusta, vaikka näkyvä verkkotunnuksen nimi olisikin erilainen. <strong>Varo estämästä suuria sähköpostin palveluntarjoajia.</strong>
|
||||
resolved_through_html: Ratkaistu %{domain} kautta
|
||||
title: Sähköpostiestolista
|
||||
title: Estetyt sähköpostiverkkotunnukset
|
||||
export_domain_allows:
|
||||
new:
|
||||
title: Tuo sallitut verkkoalueet
|
||||
title: Tuo sallittuja verkkotunnuksia
|
||||
no_file: Yhtäkään tiedostoa ei ole valittu
|
||||
export_domain_blocks:
|
||||
import:
|
||||
description_html: Olet tuomassa verkkotunnusten estoluetteloa. Tarkista luettelo huolella – etenkin, jos et ole laatinut sitä itse.
|
||||
existing_relationships_warning: Olemassa olevat seuraussuhteet
|
||||
private_comment_description_html: 'Tuodun estolistan alkuperän selvillä pitämiseksi, lisätään tietojen yhteyteen seuraava yksityinen kommentti: <q>%{comment}</q>'
|
||||
private_comment_template: Tuotu lähteestä %{source}, pvm %{date}
|
||||
title: Tuo luettelo verkkoalue-estoista
|
||||
invalid_domain_block: 'Yksi tai useampi verkkotunnuksen lohko ohitettiin seuraavien virheiden vuoksi: %{error}'
|
||||
private_comment_description_html: 'Seurataksesi tuotujen estojen alkuperää lisätään estojen yhteyteen seuraava yksityinen kommentti: <q>%{comment}</q>'
|
||||
private_comment_template: Tuotu lähteestä %{source} %{date}
|
||||
title: Tuo verkkotunnusten estoja
|
||||
invalid_domain_block: 'Yksi tai useampi verkkotunnuksen esto ohitettiin seuraavien virheiden vuoksi: %{error}'
|
||||
new:
|
||||
title: Tuo luettelo verkkoalue-estoista
|
||||
title: Tuo verkkotunnusten estoja
|
||||
no_file: Yhtäkään tiedostoa ei ole valittu
|
||||
follow_recommendations:
|
||||
description_html: "<strong>Seuraamissuositukset auttavat uusia käyttäjiä löytämään nopeasti kiinnostavaa sisältöä</strong>. Kun käyttäjä ei ole ollut tarpeeksi vuorovaikutuksessa muiden kanssa, jotta hänelle olisi muodostunut henkilökohtaisia seuraamissuosituksia, suositellaan niiden sijaan näitä tilejä. Ne lasketaan päivittäin uudelleen yhdistelmästä tilejä, jotka ovat viime aikoina olleet aktiivisimmin sitoutuneita ja joilla on suurimmat paikalliset seuraajamäärät tietyllä kielellä."
|
||||
|
@ -481,9 +481,9 @@ fi:
|
|||
back_to_limited: Rajoitettu
|
||||
back_to_warning: Varoitus
|
||||
by_domain: Verkkotunnus
|
||||
confirm_purge: Oletko varma, että haluat pysyvästi poistaa tiedot tältä verkkotunnukselta?
|
||||
confirm_purge: Haluatko varmasti poistaa pysyvästi tämän verkkotunnuksen tiedot?
|
||||
content_policies:
|
||||
comment: Sisäinen huomautus
|
||||
comment: Sisäinen muistiinpano
|
||||
description_html: Voit määrittää sisältökäytännöt, joita sovelletaan kaikkiin tämän verkkotunnuksen ja sen aliverkkotunnuksien tileihin.
|
||||
limited_federation_mode_description_html: Voit valita sallitaanko federointi tällä verkkotunnuksella.
|
||||
policies:
|
||||
|
@ -527,7 +527,7 @@ fi:
|
|||
purge: Tyhjennä
|
||||
purge_description_html: Jos uskot, että tämä verkkotunnus on offline-tilassa tarkoituksella, voit poistaa kaikki verkkotunnuksen tilitietueet ja niihin liittyvät tiedot tallennustilastasi. Tämä voi kestää jonkin aikaa.
|
||||
title: Federointi
|
||||
total_blocked_by_us: Estetty meidän toimesta
|
||||
total_blocked_by_us: Estämämme
|
||||
total_followed_by_them: Heidän seuraama
|
||||
total_followed_by_us: Meidän seuraama
|
||||
total_reported: Niitä koskevat raportit
|
||||
|
@ -554,7 +554,7 @@ fi:
|
|||
'94670856': 3 vuotta
|
||||
new:
|
||||
title: Luo uusi IP-sääntö
|
||||
no_ip_block_selected: IP-sääntöjä ei muutettu, koska yhtään ei ole valittuna
|
||||
no_ip_block_selected: IP-sääntöjä ei muutettu, koska yhtään ei ollut valittuna
|
||||
title: IP-säännöt
|
||||
relationships:
|
||||
title: "%{acct}n suhteet"
|
||||
|
@ -575,13 +575,13 @@ fi:
|
|||
status: Tila
|
||||
title: Välittäjät
|
||||
report_notes:
|
||||
created_msg: Muistiinpano onnistuneesti lisätty raporttiin!
|
||||
destroyed_msg: Muistiinpano onnistuneesti poistettu raportista!
|
||||
created_msg: Muistiinpano lisätty raporttiin onnistuneesti!
|
||||
destroyed_msg: Muistiinpano poistettu raportista onnistuneesti!
|
||||
reports:
|
||||
account:
|
||||
notes:
|
||||
one: "%{count} ilmoitus"
|
||||
other: "%{count} ilmoitusta"
|
||||
one: "%{count} muistiinpano"
|
||||
other: "%{count} muistiinpanoa"
|
||||
action_log: Tarkastusloki
|
||||
action_taken_by: Toimen tehnyt
|
||||
actions:
|
||||
|
@ -620,8 +620,8 @@ fi:
|
|||
create_and_unresolve: Avaa uudelleen ja lisää muistiinpano
|
||||
delete: Poista
|
||||
placeholder: Kuvaile mitä toimia on tehty tai muita päivityksiä tähän raporttiin…
|
||||
title: Merkinnät
|
||||
notes_description_html: Tarkastele ja jätä merkintöjä muille valvojille ja itsellesi tulevaisuuteen
|
||||
title: Muistiinpanot
|
||||
notes_description_html: Tarkastele ja jätä muistiinpanoja muille valvojille ja itsellesi tulevaisuuteen
|
||||
processed_msg: 'Raportti #%{id} käsitelty'
|
||||
quick_actions_description_html: 'Suorita nopea toiminto tai vieritä alas nähdäksesi raportoitu sisältö:'
|
||||
remote_user_placeholder: etäkäyttäjä instanssista %{instance}
|
||||
|
@ -707,7 +707,7 @@ fi:
|
|||
manage_settings: Hallitse asetuksia
|
||||
manage_settings_description: Sallii käyttäjien muuttaa sivuston asetuksia
|
||||
manage_taxonomies: Hallitse luokittelua
|
||||
manage_taxonomies_description: Sallii käyttäjien tarkistaa nousussa olevan sisällön ja päivittää aihetunnisteiden asetuksia
|
||||
manage_taxonomies_description: Sallii käyttäjien tarkistaa suositun sisällön ja päivittää aihetunnisteiden asetuksia
|
||||
manage_user_access: Hallitse käyttäjäoikeuksia
|
||||
manage_user_access_description: Sallii käyttäjien poistaa muiden käyttäjien kaksivaiheinen todennus käytöstä, vaihtaa heidän sähköpostiosoitteensa ja nollata heidän salasanansa
|
||||
manage_users: Hallitse käyttäjiä
|
||||
|
@ -735,10 +735,10 @@ fi:
|
|||
rules_hint: On olemassa erityinen alue sääntöjä, joita käyttäjien odotetaan noudattavan.
|
||||
title: Tietoja
|
||||
appearance:
|
||||
preamble: Mukauta Mastodonin verkkokäyttöliittymää.
|
||||
preamble: Mukauta Mastodonin selainkäyttöliittymää.
|
||||
title: Ulkoasu
|
||||
branding:
|
||||
preamble: Palvelimesi brändäys erottaa sen muista verkon palvelimista. Nämä tiedot voivat näkyä monissa eri ympäristöissä, kuten Mastodonin verkkokäyttöliittymässä, natiivisovelluksissa, linkkien esikatseluissa muilla sivustoilla, viestintäsovelluksissa ja niin edelleen. Siksi nämä tiedot kannattaa pitää selkeinä, lyhyinä ja ytimekkäinä.
|
||||
preamble: Palvelimesi brändäys erottaa sen muista verkon palvelimista. Nämä tiedot voivat näkyä monissa eri ympäristöissä, kuten Mastodonin selainkäyttöliittymässä, natiivisovelluksissa, linkkien esikatseluissa muilla sivustoilla, viestintäsovelluksissa ja niin edelleen. Siksi nämä tiedot kannattaa pitää selkeinä, lyhyinä ja ytimekkäinä.
|
||||
title: Brändäys
|
||||
captcha_enabled:
|
||||
desc_html: Tämä perustuu ulkoisiin skripteihin hCaptchasta, mikä voi olla turvallisuus- ja yksityisyysongelma. Lisäksi <strong>tämä voi tehdä rekisteröinnin ihmisille huomattavasti (erityisesti vammaisten) helpommaksi</strong>. Harkitse vaihtoehtoisia toimenpiteitä, kuten hyväksymisperusteista tai kutsupohjaista rekisteröintiä.
|
||||
|
@ -807,13 +807,13 @@ fi:
|
|||
media:
|
||||
title: Media
|
||||
metadata: Metadata
|
||||
no_status_selected: Julkaisuja ei muutettu, koska yhtään ei ole valittuna
|
||||
no_status_selected: Julkaisuja ei muutettu, koska yhtään ei ollut valittuna
|
||||
open: Avaa julkaisu
|
||||
original_status: Alkuperäinen julkaisu
|
||||
reblogs: Edelleen jako
|
||||
status_changed: Julkaisua muutettu
|
||||
title: Tilin tilat
|
||||
trending: Nousussa
|
||||
trending: Suosituttua
|
||||
visibility: Näkyvyys
|
||||
with_media: Sisältää mediaa
|
||||
strikes:
|
||||
|
@ -881,9 +881,9 @@ fi:
|
|||
description_html: Nämä ovat linkkejä, joita jaetaan tällä hetkellä paljon tileillä, joilta palvelimesi näkee viestejä. Se voi auttaa käyttäjiäsi saamaan selville, mitä maailmassa tapahtuu. Linkkejä ei näytetä julkisesti, ennen kuin hyväksyt julkaisijan. Voit myös sallia tai hylätä yksittäiset linkit.
|
||||
disallow: Hylkää linkki
|
||||
disallow_provider: Estä julkaisija
|
||||
no_link_selected: Yhtään linkkiä ei muutettu, koska yhtään ei valittu
|
||||
no_link_selected: Linkkejä ei muutettu, koska yhtään ei ollut valittuna
|
||||
publishers:
|
||||
no_publisher_selected: Julkaisijoita ei muutettu, koska yhtään ei valittu
|
||||
no_publisher_selected: Julkaisijoita ei muutettu, koska yhtään ei ollut valittuna
|
||||
shared_by_over_week:
|
||||
one: Yksi henkilö jakanut viimeisen viikon aikana
|
||||
other: Jakanut %{count} henkilöä viimeisen viikon aikana
|
||||
|
@ -904,7 +904,7 @@ fi:
|
|||
description_html: Nämä ovat julkaisuja, joita palvelimesi tietää jaettavan ja lisättävän suosikkeihin paljon tällä hetkellä. Listaus voi auttaa uusia ja palaavia käyttäjiäsi löytämään lisää seurattavia. Julkaisut eivät näy julkisesti ennen kuin hyväksyt niiden julkaisijan ja julkaisija sallii tilinsä ehdottamisen. Voit myös sallia tai hylätä yksittäisiä julkaisuja.
|
||||
disallow: Kiellä julkaisu
|
||||
disallow_account: Estä tekijä
|
||||
no_status_selected: Suosittuja julkaisuja ei muutettu, koska yhtään ei ole valittuna
|
||||
no_status_selected: Suosittuja julkaisuja ei muutettu, koska yhtään ei ollut valittuna
|
||||
not_discoverable: Tekijä ei ole ilmoittanut olevansa löydettävissä
|
||||
shared_by:
|
||||
one: Jaettu tai lisätty suosikkeihin kerran
|
||||
|
@ -920,21 +920,21 @@ fi:
|
|||
tag_uses_measure: käyttökerrat
|
||||
description_html: Nämä ovat aihetunnisteita, jotka näkyvät tällä hetkellä monissa julkaisuissa, jotka palvelimesi näkee. Tämä voi auttaa käyttäjiäsi selvittämään, mistä ihmiset puhuvat eniten tällä hetkellä. Mitään aihetunnisteita ei näytetä julkisesti, ennen kuin hyväksyt ne.
|
||||
listable: Voidaan ehdottaa
|
||||
no_tag_selected: Yhtään tagia ei muutettu, koska yhtään ei valittu
|
||||
no_tag_selected: Tunnisteita ei muutettu, koska yhtään ei ollut valittuna
|
||||
not_listable: Ei tulla ehdottamaan
|
||||
not_trendable: Ei näy trendien alla
|
||||
not_usable: Ei voida käyttää
|
||||
peaked_on_and_decaying: Saavutti huipun %{date}, nyt hiipuu
|
||||
title: Suositut aihetunnisteet
|
||||
trendable: Voi näkyä trendien alla
|
||||
trending_rank: 'Nousussa #%{rank}'
|
||||
trending_rank: 'Suosittua #%{rank}'
|
||||
usable: Voidaan käyttää
|
||||
usage_comparison: Käytetty %{today} kertaa tänään, verrattuna %{yesterday} eiliseen
|
||||
used_by_over_week:
|
||||
one: Yhden henkilön käyttämä viime viikon aikana
|
||||
other: Käyttänyt %{count} henkilöä viimeisen viikon aikana
|
||||
title: Trendit
|
||||
trending: Nousussa
|
||||
trending: Suosittua
|
||||
warning_presets:
|
||||
add_new: Lisää uusi
|
||||
delete: Poista
|
||||
|
@ -994,8 +994,8 @@ fi:
|
|||
new_trending_statuses:
|
||||
title: Suositut julkaisut
|
||||
new_trending_tags:
|
||||
no_approved_tags: Tällä hetkellä ei ole hyväksyttyjä trendikkäitä aihetunnisteita.
|
||||
requirements: 'Mikä tahansa näistä ehdokkaista voisi ylittää #%{rank} hyväksytyn trendikkään aihetunnisteen, joka on tällä hetkellä #%{lowest_tag_name} arvosanalla %{lowest_tag_score}.'
|
||||
no_approved_tags: Tällä hetkellä ei ole hyväksyttyjä suosittuja aihetunnisteita.
|
||||
requirements: 'Mikä tahansa näistä ehdokkaista voisi ylittää #%{rank} hyväksytyn suositun aihetunnisteen, joka on tällä hetkellä #%{lowest_tag_name} %{lowest_tag_score} pisteellä.'
|
||||
title: Suositut aihetunnisteet
|
||||
subject: Uusia trendejä tarkistettavaksi instanssissa %{instance}
|
||||
aliases:
|
||||
|
@ -1007,7 +1007,7 @@ fi:
|
|||
remove: Poista aliaksen linkitys
|
||||
appearance:
|
||||
advanced_web_interface: Edistynyt selainkäyttöliittymä
|
||||
advanced_web_interface_hint: 'Jos haluat hyödyntää näytön koko leveyttä, edistyneen webkäyttöliittymän avulla voit määrittää useita erilaisia sarakkeita, niin näet kerralla niin paljon tietoa kuin haluat: kotisyöte, ilmoitukset, yleinen aikajana, mikä tahansa määrä listoja ja aihetunnisteita.'
|
||||
advanced_web_interface_hint: 'Jos haluat hyödyntää näytön koko leveyttä, edistyneen selainkäyttöliittymän avulla voit määrittää useita erilaisia sarakkeita, niin näet kerralla niin paljon tietoa kuin haluat: kotisyöte, ilmoitukset, yleinen aikajana, mikä tahansa määrä listoja ja aihetunnisteita.'
|
||||
animations_and_accessibility: Animaatiot ja saavutettavuus
|
||||
confirmation_dialogs: Vahvistusvalinnat
|
||||
discovery: Löytäminen
|
||||
|
@ -1219,8 +1219,8 @@ fi:
|
|||
featured_tags:
|
||||
add_new: Lisää uusi
|
||||
errors:
|
||||
limit: Olet jo nostanut esille enimmäismäärän aihetunnisteita
|
||||
hint_html: "<strong>Mitä ovat näkyvillä olevat hashtagit eli aihetunnisteet?</strong> Ne ovat näkyvissä julkisessa profiilissasi ja niiden avulla ihmiset voivat selata julkisia viestejäsi nimenomaan näiden aihetunnisteiden alla. Ne auttavat esimerkiksi luovan työn tai pitkäaikaisten projektien seurannassa."
|
||||
limit: Pidät jo esillä aihetunnisteiden enimmäismäärää
|
||||
hint_html: "<strong>Pidä tärkeimpiä aihetunnisteitasi esillä profiilissasi.</strong> Erinomainen työkalu, jolla pidät kirjaa luovista teoksistasi ja pitkäaikaisista projekteistasi. Esillä pitämäsi aihetunnisteet ovat näyttävällä paikalla profiilissasi ja mahdollistavat nopean pääsyn omiin julkaisuihisi."
|
||||
filters:
|
||||
contexts:
|
||||
account: Profiilit
|
||||
|
@ -1235,7 +1235,7 @@ fi:
|
|||
statuses_hint_html: Tämä suodatin koskee yksittäisten julkaisujen valintaa riippumatta siitä, vastaavatko ne alla olevia avainsanoja. <a href="%{path}">Tarkista tai poista julkaisut suodattimesta</a>.
|
||||
title: Muokkaa suodatinta
|
||||
errors:
|
||||
deprecated_api_multiple_keywords: Näitä parametreja ei voi muuttaa tästä sovelluksesta, koska ne koskevat useampaa kuin yhtä suodattimen avainsanaa. Käytä uudempaa sovellusta tai verkkokäyttöliittymää.
|
||||
deprecated_api_multiple_keywords: Näitä parametreja ei voi muuttaa tästä sovelluksesta, koska ne koskevat useampaa kuin yhtä suodattimen avainsanaa. Käytä uudempaa sovellusta tai selainkäyttöliittymää.
|
||||
invalid_context: Ei sisältöä tai se on virheellinen
|
||||
index:
|
||||
contexts: Suodattimet %{contexts}
|
||||
|
@ -1261,7 +1261,7 @@ fi:
|
|||
batch:
|
||||
remove: Poista suodattimista
|
||||
index:
|
||||
hint: Tämä suodatin koskee yksittäisten julkaisujen valintaa muista kriteereistä riippumatta. Voit lisätä lisää julkaisuja tähän suodattimeen verkkokäyttöliittymästä.
|
||||
hint: Tämä suodatin koskee yksittäisten julkaisujen valintaa muista kriteereistä riippumatta. Voit lisätä lisää julkaisuja tähän suodattimeen selainkäyttöliittymästä.
|
||||
title: Suodatetut julkaisut
|
||||
generic:
|
||||
all: Kaikki
|
||||
|
@ -1290,7 +1290,7 @@ fi:
|
|||
imports:
|
||||
errors:
|
||||
empty: Tyhjä CSV-tiedosto
|
||||
incompatible_type: Yhteensopimaton valitun tuontilajin kanssa
|
||||
incompatible_type: Yhteensopimaton valitun tuontityypin kanssa
|
||||
invalid_csv_file: 'Epäkelpo CSV-tiedosto. Virhe: %{error}'
|
||||
over_rows_processing_limit: sisältää yli %{count} riviä
|
||||
too_large: Tiedosto on liian suuri
|
||||
|
@ -1331,8 +1331,8 @@ fi:
|
|||
bookmarks: Tuodaan kirjanmerkkejä
|
||||
domain_blocking: Tuodaan estettyjä verkkotunnuksia
|
||||
following: Tuodaan seurattuja tilejä
|
||||
lists: Listojen tuonti
|
||||
muting: Tuodaan hiljennettyjä tilejä
|
||||
lists: Tuodaan listoja
|
||||
muting: Tuodaan mykistettyjä tilejä
|
||||
type: Tuonnin tyyppi
|
||||
type_groups:
|
||||
constructive: Seuratut ja kirjanmerkit
|
||||
|
@ -1340,7 +1340,7 @@ fi:
|
|||
types:
|
||||
blocking: Estoluettelo
|
||||
bookmarks: Kirjanmerkit
|
||||
domain_blocking: Verkkotunnuksen estoluettelo
|
||||
domain_blocking: Verkkotunnusten estoluettelo
|
||||
following: Seurattujen luettelo
|
||||
lists: Listat
|
||||
muting: Mykistettyjen luettelo
|
||||
|
@ -1436,7 +1436,7 @@ fi:
|
|||
title: Valvonta
|
||||
move_handler:
|
||||
carry_blocks_over_text: Tämä käyttäjä siirtyi paikasta %{acct}, jonka olit estänyt.
|
||||
carry_mutes_over_text: Tämä käyttäjä siirtyi paikasta %{acct}, jonka mykistit.
|
||||
carry_mutes_over_text: Tämä käyttäjä siirtyi tililtä %{acct}, jonka olet mykistänyt.
|
||||
copy_account_note_text: 'Tämä käyttäjä siirtyi paikasta %{acct}, tässä olivat aiemmat muistiinpanosi niistä:'
|
||||
navigation:
|
||||
toggle_menu: Avaa/sulje valikko
|
||||
|
@ -1625,7 +1625,7 @@ fi:
|
|||
development: Kehitys
|
||||
edit_profile: Muokkaa profiilia
|
||||
export: Vie tietoja
|
||||
featured_tags: Esiteltävät aihetunnisteet
|
||||
featured_tags: Esillä pidettävät aihetunnisteet
|
||||
import: Tuo
|
||||
import_and_export: Tuonti ja vienti
|
||||
migrate: Tilin muutto muualle
|
||||
|
|
|
@ -77,11 +77,11 @@ fi:
|
|||
form_admin_settings:
|
||||
activity_api_enabled: Paikallisesti julkaistujen julkaisujen, aktiivisten käyttäjien ja rekisteröitymisten viikoittainen määrä
|
||||
backups_retention_period: Säilytä luodut arkistot määritetyn määrän päiviä.
|
||||
bootstrap_timeline_accounts: Nämä tilit kiinnitetään uusien käyttäjien suositusten yläpuolelle.
|
||||
bootstrap_timeline_accounts: Nämä tilit kiinnitetään uusien käyttäjien seuraamissuositusten yläpuolelle.
|
||||
closed_registrations_message: Näkyy, kun ilmoittautuminen on suljettu
|
||||
content_cache_retention_period: Viestit muilta palvelimilta poistetaan määritetyn määrän päiviä jälkeen, kun arvo on asetettu positiiviseksi. Tämä voi olla peruuttamatonta.
|
||||
custom_css: Voit käyttää mukautettuja tyylejä Mastodonin verkkoversiossa.
|
||||
mascot: Ohittaa kuvituksen edistyneessä käyttöliittymässä.
|
||||
mascot: Ohittaa kuvituksen edistyneessä selainkäyttöliittymässä.
|
||||
media_cache_retention_period: Ladatut mediatiedostot poistetaan määritetyn määrän päiviä jälkeen, kun arvo on positiivinen ja ladataan uudelleen pyynnöstä.
|
||||
peers_api_enabled: Luettelo verkkotunnuksista, jotka tämä palvelin on kohdannut fediversumissa. Se ei kerro, oletko liitossa tietyn palvelimen kanssa, vaan että palvelimesi on ylipäätään tietoinen siitä. Tätä tietoa käytetään palveluissa, jotka keräävät tilastoja liittoutumisesta yleisellä tasolla.
|
||||
profile_directory: Profiilihakemisto lueteloi kaikki käyttäjät, jotka ovat ilmoittaneet olevansa löydettävissä.
|
||||
|
@ -108,7 +108,7 @@ fi:
|
|||
ip_block:
|
||||
comment: Valinnainen. Muista miksi lisäsit tämän säännön.
|
||||
expires_in: IP-osoitteet ovat rajallinen resurssi, joskus niitä jaetaan ja vaihtavat usein omistajaa. Tästä syystä epämääräisiä IP-lohkoja ei suositella.
|
||||
ip: Kirjoita IPv4- tai IPv6-osoite. Voit estää kokonaisia alueita käyttämällä CIDR-syntaksia. Varo, että et lukitse itseäsi!
|
||||
ip: Kirjoita IPv4- tai IPv6-osoite. Voit estää kokonaisia alueita käyttämällä CIDR-syntaksia. Varo, että et lukitse itseäsi ulos!
|
||||
severities:
|
||||
no_access: Estä pääsy kaikkiin resursseihin
|
||||
sign_up_block: Uudet kirjautumiset eivät ole mahdollisia
|
||||
|
@ -139,7 +139,7 @@ fi:
|
|||
url: Mihin tapahtumat lähetetään
|
||||
labels:
|
||||
account:
|
||||
discoverable: Nosta profiili ja julkaisut esille löytämisalgoritmeissa
|
||||
discoverable: Pidä profiiliasi ja julkaisujasi esillä löytämisalgoritmeissa
|
||||
fields:
|
||||
name: Nimike
|
||||
value: Sisältö
|
||||
|
@ -162,8 +162,8 @@ fi:
|
|||
disable: Poista kirjautuminen käytöstä
|
||||
none: Älä tee mitään
|
||||
sensitive: Arkaluonteinen
|
||||
silence: Hiljennä
|
||||
suspend: Poista käytöstä ja tuhoa käyttäjätunnuksen tiedot peruuttamattomasti
|
||||
silence: Rajoita
|
||||
suspend: Jäädytä
|
||||
warning_preset_id: Käytä varoitusmallia
|
||||
announcement:
|
||||
all_day: Koko päivän kestävä tapahtuma
|
||||
|
@ -224,7 +224,7 @@ fi:
|
|||
severity: Vakavuus
|
||||
sign_in_token_attempt: Turvakoodi
|
||||
title: Nimi
|
||||
type: Tuontilaji
|
||||
type: Tuontityyppi
|
||||
username: Käyttäjänimi
|
||||
username_or_email: Käyttäjänimi tai sähköpostiosoite
|
||||
whole_word: Koko sana
|
||||
|
@ -249,7 +249,7 @@ fi:
|
|||
profile_directory: Ota profiilihakemisto käyttöön
|
||||
registrations_mode: Kuka voi rekisteröityä
|
||||
require_invite_text: Vaadi syy liittyä
|
||||
show_domain_blocks: Näytä domainestot
|
||||
show_domain_blocks: Näytä verkkotunnusten estot
|
||||
show_domain_blocks_rationale: Näytä miksi verkkotunnukset on estetty
|
||||
site_contact_email: Ota yhteyttä sähköpostilla
|
||||
site_contact_username: Yhteyshenkilön käyttäjänimi
|
||||
|
@ -277,7 +277,7 @@ fi:
|
|||
ip: IP-osoite
|
||||
severities:
|
||||
no_access: Estä pääsy
|
||||
sign_up_block: Estä kirjautumiset
|
||||
sign_up_block: Estä rekisteröitymiset
|
||||
sign_up_requires_approval: Rajoita rekisteröitymisiä
|
||||
severity: Sääntö
|
||||
notification_emails:
|
||||
|
|
|
@ -16,37 +16,63 @@ describe Rack::Attack, type: :request do
|
|||
# https://github.com/rack/rack-attack/blob/v6.6.1/lib/rack/attack/cache.rb#L64-L66
|
||||
# So we want to minimize `Time.now.to_i % period`
|
||||
|
||||
travel_to Time.zone.at((Time.now.to_i / period.seconds).to_i * period.seconds)
|
||||
travel_to Time.zone.at(counter_prefix * period.seconds)
|
||||
end
|
||||
|
||||
context 'when the number of requests is lower than the limit' do
|
||||
it 'does not change the request status' do
|
||||
limit.times do
|
||||
request.call
|
||||
expect(response).to_not have_http_status(429)
|
||||
before do
|
||||
below_limit.times { increment_counter }
|
||||
end
|
||||
|
||||
it 'does not change the request status' do
|
||||
expect { request.call }.to change { throttle_count }.by(1)
|
||||
|
||||
expect(response).to_not have_http_status(429)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the number of requests is higher than the limit' do
|
||||
it 'returns http too many requests after limit and returns to normal status after period' do
|
||||
(limit * 2).times do |i|
|
||||
request.call
|
||||
expect(response).to have_http_status(429) if i > limit
|
||||
before do
|
||||
above_limit.times { increment_counter }
|
||||
end
|
||||
|
||||
it 'returns http too many requests after limit and returns to normal status after period' do
|
||||
expect { request.call }.to change { throttle_count }.by(1)
|
||||
expect(response).to have_http_status(429)
|
||||
|
||||
travel period
|
||||
|
||||
request.call
|
||||
expect { request.call }.to change { throttle_count }.by(1)
|
||||
expect(response).to_not have_http_status(429)
|
||||
end
|
||||
end
|
||||
|
||||
def below_limit
|
||||
limit - 1
|
||||
end
|
||||
|
||||
def above_limit
|
||||
limit * 2
|
||||
end
|
||||
|
||||
def throttle_count
|
||||
described_class.cache.read("#{counter_prefix}:#{throttle}:#{remote_ip}") || 0
|
||||
end
|
||||
|
||||
def counter_prefix
|
||||
(Time.now.to_i / period.seconds).to_i
|
||||
end
|
||||
|
||||
def increment_counter
|
||||
described_class.cache.count("#{throttle}:#{remote_ip}", period)
|
||||
end
|
||||
end
|
||||
|
||||
let(:remote_ip) { '1.2.3.5' }
|
||||
|
||||
describe 'throttle excessive sign-up requests by IP address' do
|
||||
context 'when accessed through the website' do
|
||||
let(:throttle) { 'throttle_sign_up_attempts/ip' }
|
||||
let(:limit) { 25 }
|
||||
let(:period) { 5.minutes }
|
||||
let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
|
@ -65,6 +91,7 @@ describe Rack::Attack, type: :request do
|
|||
end
|
||||
|
||||
context 'when accessed through the API' do
|
||||
let(:throttle) { 'throttle_api_sign_up' }
|
||||
let(:limit) { 5 }
|
||||
let(:period) { 30.minutes }
|
||||
let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
|
@ -87,6 +114,7 @@ describe Rack::Attack, type: :request do
|
|||
end
|
||||
|
||||
describe 'throttle excessive sign-in requests by IP address' do
|
||||
let(:throttle) { 'throttle_login_attempts/ip' }
|
||||
let(:limit) { 25 }
|
||||
let(:period) { 5.minutes }
|
||||
let(:request) { -> { post path, headers: { 'REMOTE_ADDR' => remote_ip } } }
|
||||
|
|
|
@ -14,11 +14,8 @@ RSpec.describe Api::OEmbedController do
|
|||
get :show, params: { url: short_account_status_url(alice, status) }, format: :json
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns private cache control headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns private cache control headers' do
|
||||
expect(response.headers['Cache-Control']).to include('private, no-store')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,11 +41,9 @@ describe Api::V1::Accounts::CredentialsController do
|
|||
}
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates account info', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates account info' do
|
||||
user.reload
|
||||
user.account.reload
|
||||
|
||||
|
@ -55,9 +53,7 @@ describe Api::V1::Accounts::CredentialsController do
|
|||
expect(user.account.header).to exist
|
||||
expect(user.setting_default_privacy).to eq('unlisted')
|
||||
expect(user.setting_default_sensitive).to be(true)
|
||||
end
|
||||
|
||||
it 'queues up an account update distribution' do
|
||||
expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_async).with(user.account_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,23 +18,19 @@ describe Api::V1::Accounts::FollowerAccountsController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
it 'returns accounts following the given account', :aggregate_failures do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns accounts following the given account' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(body_as_json.size).to eq 2
|
||||
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
|
||||
end
|
||||
|
||||
it 'does not return blocked users' do
|
||||
it 'does not return blocked users', :aggregate_failures do
|
||||
user.account.block!(bob)
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq alice.id.to_s
|
||||
end
|
||||
|
|
|
@ -18,23 +18,19 @@ describe Api::V1::Accounts::FollowingAccountsController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
it 'returns accounts followed by the given account', :aggregate_failures do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns accounts followed by the given account' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(body_as_json.size).to eq 2
|
||||
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
|
||||
end
|
||||
|
||||
it 'does not return blocked users' do
|
||||
it 'does not return blocked users', :aggregate_failures do
|
||||
user.account.block!(bob)
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq alice.id.to_s
|
||||
end
|
||||
|
|
|
@ -19,30 +19,24 @@ describe Api::V1::Accounts::NotesController do
|
|||
post :create, params: { account_id: account.id, comment: comment }
|
||||
end
|
||||
|
||||
context 'when account note has reasonable length' do
|
||||
context 'when account note has reasonable length', :aggregate_failures do
|
||||
let(:comment) { 'foo' }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates account note' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(AccountNote.find_by(account_id: user.account.id, target_account_id: account.id).comment).to eq comment
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account note exceeds allowed length' do
|
||||
context 'when account note exceeds allowed length', :aggregate_failures do
|
||||
let(:comment) { 'a' * 2_001 }
|
||||
|
||||
it 'returns 422' do
|
||||
subject
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'does not create account note' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(422)
|
||||
expect(AccountNote.where(account_id: user.account.id, target_account_id: account.id)).to_not exist
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,14 +15,11 @@ RSpec.describe Api::V1::Accounts::PinsController do
|
|||
describe 'POST #create' do
|
||||
subject { post :create, params: { account_id: kevin.account.id } }
|
||||
|
||||
it 'returns 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates account_pin' do
|
||||
it 'creates account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -33,14 +30,11 @@ RSpec.describe Api::V1::Accounts::PinsController do
|
|||
Fabricate(:account_pin, account: john.account, target_account: kevin.account)
|
||||
end
|
||||
|
||||
it 'returns 200' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'destroys account_pin' do
|
||||
it 'destroys account_pin', :aggregate_failures do
|
||||
expect do
|
||||
subject
|
||||
end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(-1)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,13 +26,10 @@ describe Api::V1::Accounts::RelationshipsController do
|
|||
get :index, params: { id: simon.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns JSON with correct data' do
|
||||
it 'returns JSON with correct data', :aggregate_failures do
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json).to be_a Enumerable
|
||||
expect(json.first[:following]).to be true
|
||||
expect(json.first[:followed_by]).to be false
|
||||
|
@ -51,11 +48,14 @@ describe Api::V1::Accounts::RelationshipsController do
|
|||
context 'when there is returned JSON data' do
|
||||
let(:json) { body_as_json }
|
||||
|
||||
it 'returns an enumerable json' do
|
||||
it 'returns an enumerable json with correct elements', :aggregate_failures do
|
||||
expect(json).to be_a Enumerable
|
||||
|
||||
expect_simon_item_one
|
||||
expect_lewis_item_two
|
||||
end
|
||||
|
||||
it 'returns a correct first element' do
|
||||
def expect_simon_item_one
|
||||
expect(json.first[:id]).to eq simon.id.to_s
|
||||
expect(json.first[:following]).to be true
|
||||
expect(json.first[:showing_reblogs]).to be true
|
||||
|
@ -65,7 +65,7 @@ describe Api::V1::Accounts::RelationshipsController do
|
|||
expect(json.first[:domain_blocking]).to be false
|
||||
end
|
||||
|
||||
it 'returns a correct second element' do
|
||||
def expect_lewis_item_two
|
||||
expect(json.second[:id]).to eq lewis.id.to_s
|
||||
expect(json.second[:following]).to be false
|
||||
expect(json.second[:showing_reblogs]).to be false
|
||||
|
|
|
@ -14,15 +14,10 @@ describe Api::V1::Accounts::StatusesController do
|
|||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
it 'returns expected headers', :aggregate_failures do
|
||||
get :index, params: { account_id: user.account.id, limit: 1 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected headers' do
|
||||
get :index, params: { account_id: user.account.id, limit: 1 }
|
||||
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
|
||||
|
@ -44,14 +39,11 @@ describe Api::V1::Accounts::StatusesController do
|
|||
get :index, params: { account_id: user.account.id, exclude_replies: true }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns posts along with self replies' do
|
||||
it 'returns posts along with self replies', :aggregate_failures do
|
||||
json = body_as_json
|
||||
post_ids = json.map { |item| item[:id].to_i }.sort
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(post_ids).to eq [status.id, status_self_reply.id]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,15 +25,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
context 'when given truthy agreement' do
|
||||
let(:agreement) { 'true' }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns a new access token as JSON' do
|
||||
expect(body_as_json[:access_token]).to_not be_blank
|
||||
end
|
||||
|
||||
it 'creates a user' do
|
||||
user = User.find_by(email: 'hello@world.tld')
|
||||
expect(user).to_not be_nil
|
||||
expect(user.created_by_application_id).to eq app.id
|
||||
|
@ -65,18 +60,14 @@ RSpec.describe Api::V1::AccountsController do
|
|||
context 'with unlocked account' do
|
||||
let(:locked) { false }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a following relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns JSON with following=true and requested=false' do
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:following]).to be true
|
||||
expect(json[:requested]).to be false
|
||||
end
|
||||
|
||||
it 'creates a following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -86,18 +77,14 @@ RSpec.describe Api::V1::AccountsController do
|
|||
context 'with locked account' do
|
||||
let(:locked) { true }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a follow request relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns JSON with following=false and requested=true' do
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:following]).to be false
|
||||
expect(json[:requested]).to be true
|
||||
end
|
||||
|
||||
it 'creates a follow request relation between user and target user' do
|
||||
expect(user.account.requested?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -177,11 +164,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :unfollow, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the following relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -197,11 +181,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :remove_from_followers, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the followed relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the followed relation between user and target user' do
|
||||
expect(user.account.followed_by?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -217,15 +198,9 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :block, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a blocking relation', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be false
|
||||
end
|
||||
|
||||
it 'creates a blocking relation' do
|
||||
expect(user.account.blocking?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -241,11 +216,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :unblock, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the blocking relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the blocking relation between user and target user' do
|
||||
expect(user.account.blocking?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -261,19 +233,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :mute, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'mutes notifications', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not remove the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'creates a muting relation' do
|
||||
expect(user.account.muting?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'mutes notifications' do
|
||||
expect(user.account.muting_notifications?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -289,19 +252,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :mute, params: { id: other_account.id, notifications: false }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'does not mute notifications', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not remove the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'creates a muting relation' do
|
||||
expect(user.account.muting?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'does not mute notifications' do
|
||||
expect(user.account.muting_notifications?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
@ -317,19 +271,10 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :mute, params: { id: other_account.id, duration: 300 }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'mutes notifications', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not remove the following relation between user and target user' do
|
||||
expect(user.account.following?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'creates a muting relation' do
|
||||
expect(user.account.muting?(other_account)).to be true
|
||||
end
|
||||
|
||||
it 'mutes notifications' do
|
||||
expect(user.account.muting_notifications?(other_account)).to be true
|
||||
end
|
||||
|
||||
|
@ -345,11 +290,8 @@ RSpec.describe Api::V1::AccountsController do
|
|||
post :unmute, params: { id: other_account.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the muting relation between user and target user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the muting relation between user and target user' do
|
||||
expect(user.account.muting?(other_account)).to be false
|
||||
end
|
||||
|
||||
|
|
|
@ -44,11 +44,9 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
context "when called with #{params.inspect}" do
|
||||
let(:params) { params }
|
||||
|
||||
it 'returns http success' do
|
||||
it "returns the correct accounts (#{expected_results.inspect})", :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it "returns the correct accounts (#{expected_results.inspect})" do
|
||||
json = body_as_json
|
||||
|
||||
expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id })
|
||||
|
@ -79,15 +77,10 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'approves user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'approves user' do
|
||||
expect(account.reload.user_approved?).to be true
|
||||
end
|
||||
|
||||
it 'logs action' do
|
||||
log_item = Admin::ActionLog.last
|
||||
|
||||
expect(log_item).to_not be_nil
|
||||
|
@ -106,15 +99,10 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes user' do
|
||||
expect(User.where(id: account.user.id).count).to eq 0
|
||||
end
|
||||
|
||||
it 'logs action' do
|
||||
log_item = Admin::ActionLog.last
|
||||
|
||||
expect(log_item).to_not be_nil
|
||||
|
@ -133,11 +121,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'enables user', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'enables user' do
|
||||
expect(account.reload.user_disabled?).to be false
|
||||
end
|
||||
end
|
||||
|
@ -151,11 +136,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'unsuspends account', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unsuspends account' do
|
||||
expect(account.reload.suspended?).to be false
|
||||
end
|
||||
end
|
||||
|
@ -169,11 +151,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'unsensitizes account', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unsensitizes account' do
|
||||
expect(account.reload.sensitized?).to be false
|
||||
end
|
||||
end
|
||||
|
@ -187,11 +166,8 @@ RSpec.describe Api::V1::Admin::AccountsController do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'unsilences account', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unsilences account' do
|
||||
expect(account.reload.silenced?).to be false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Admin::Trends::LinksController do
|
||||
render_views
|
||||
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:preview_card) { Fabricate(:preview_card) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'returns http success' do
|
||||
get :index, params: { account_id: account.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #approve' do
|
||||
before do
|
||||
post :approve, params: { id: preview_card.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #reject' do
|
||||
before do
|
||||
post :reject, params: { id: preview_card.id }
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,11 +25,8 @@ RSpec.describe Api::V1::Announcements::ReactionsController do
|
|||
put :update, params: { announcement_id: announcement.id, id: '😂' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates reaction', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates reaction' do
|
||||
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
@ -53,11 +50,8 @@ RSpec.describe Api::V1::Announcements::ReactionsController do
|
|||
delete :destroy, params: { announcement_id: announcement.id, id: '😂' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates reaction', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates reaction' do
|
||||
expect(announcement.announcement_reactions.find_by(name: '😂', account: user.account)).to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,11 +47,8 @@ RSpec.describe Api::V1::AnnouncementsController do
|
|||
post :dismiss, params: { id: announcement.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'dismisses announcement', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'dismisses announcement' do
|
||||
expect(announcement.announcement_mutes.find_by(account: user.account)).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,45 +12,48 @@ RSpec.describe Api::V1::BlocksController do
|
|||
before { allow(controller).to receive(:doorkeeper_token) { token } }
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'limits according to limit parameter' do
|
||||
it 'limits according to limit parameter', :aggregate_failures do
|
||||
Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
get :index, params: { limit: 1 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
end
|
||||
|
||||
it 'queries blocks in range according to max_id' do
|
||||
it 'queries blocks in range according to max_id', :aggregate_failures do
|
||||
blocks = Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
|
||||
get :index, params: { max_id: blocks[1] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq blocks[0].target_account_id.to_s
|
||||
end
|
||||
|
||||
it 'queries blocks in range according to since_id' do
|
||||
it 'queries blocks in range according to since_id', :aggregate_failures do
|
||||
blocks = Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
|
||||
get :index, params: { since_id: blocks[0] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.size).to eq 1
|
||||
expect(body_as_json[0][:id]).to eq blocks[1].target_account_id.to_s
|
||||
end
|
||||
|
||||
it 'sets pagination header for next path' do
|
||||
it 'sets pagination header for next path', :aggregate_failures do
|
||||
blocks = Array.new(2) { Fabricate(:block, account: user.account) }
|
||||
get :index, params: { limit: 1, since_id: blocks[0] }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq api_v1_blocks_url(limit: 1, max_id: blocks[1])
|
||||
end
|
||||
|
||||
it 'sets pagination header for previous path' do
|
||||
it 'sets pagination header for previous path', :aggregate_failures do
|
||||
block = Fabricate(:block, account: user.account)
|
||||
get :index
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq api_v1_blocks_url(since_id: block)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq api_v1_blocks_url(since_id: block)
|
||||
end
|
||||
|
||||
context 'with wrong scopes' do
|
||||
|
|
|
@ -21,17 +21,14 @@ RSpec.describe Api::V1::ConversationsController do
|
|||
PostStatusService.new.call(user.account, text: 'Hey, nobody here', visibility: 'direct')
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :index
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns pagination headers' do
|
||||
it 'returns pagination headers', :aggregate_failures do
|
||||
get :index, params: { limit: 1 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
|
||||
it 'returns conversations' do
|
||||
it 'returns conversations', :aggregate_failures do
|
||||
get :index
|
||||
json = body_as_json
|
||||
expect(json.size).to eq 2
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::FavouritesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') }
|
||||
|
||||
describe 'GET #index' do
|
||||
context 'without token' do
|
||||
it 'returns http unauthorized' do
|
||||
get :index
|
||||
expect(response).to have_http_status 401
|
||||
end
|
||||
end
|
||||
|
||||
context 'with token' do
|
||||
context 'without read scope' do
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) do
|
||||
Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: '')
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns http forbidden' do
|
||||
get :index
|
||||
expect(response).to have_http_status 403
|
||||
end
|
||||
end
|
||||
|
||||
context 'without valid resource owner' do
|
||||
before do
|
||||
token = Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read')
|
||||
user.destroy!
|
||||
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
get :index
|
||||
expect(response).to have_http_status 422
|
||||
end
|
||||
end
|
||||
|
||||
context 'with read scope and valid resource owner' do
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) do
|
||||
Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:favourites')
|
||||
end
|
||||
end
|
||||
|
||||
it 'shows favourites owned by the user' do
|
||||
favourite_by_user = Fabricate(:favourite, account: user.account)
|
||||
favourite_by_others = Fabricate(:favourite)
|
||||
|
||||
get :index
|
||||
|
||||
expect(assigns(:statuses)).to contain_exactly(favourite_by_user.status)
|
||||
end
|
||||
|
||||
it 'adds pagination headers if necessary' do
|
||||
favourite = Fabricate(:favourite, account: user.account)
|
||||
|
||||
get :index, params: { limit: 1 }
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq "http://test.host/api/v1/favourites?limit=1&max_id=#{favourite.id}"
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq "http://test.host/api/v1/favourites?limit=1&min_id=#{favourite.id}"
|
||||
end
|
||||
|
||||
it 'does not add pagination headers if not necessary' do
|
||||
get :index
|
||||
|
||||
expect(response.headers['Link']).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -31,12 +31,10 @@ RSpec.describe Api::V1::FiltersController do
|
|||
post :create, params: { phrase: 'magic', context: %w(home), irreversible: irreversible, whole_word: whole_word }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a filter' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
filter = user.account.custom_filters.first
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
|
||||
expect(filter.context).to eq %w(home)
|
||||
|
@ -48,12 +46,10 @@ RSpec.describe Api::V1::FiltersController do
|
|||
let(:irreversible) { false }
|
||||
let(:whole_word) { true }
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a filter' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
filter = user.account.custom_filters.first
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.keywords.pluck(:keyword, :whole_word)).to eq [['magic', whole_word]]
|
||||
expect(filter.context).to eq %w(home)
|
||||
|
@ -83,11 +79,8 @@ RSpec.describe Api::V1::FiltersController do
|
|||
put :update, params: { id: keyword.id, phrase: 'updated' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the filter' do
|
||||
expect(keyword.reload.phrase).to eq 'updated'
|
||||
end
|
||||
end
|
||||
|
@ -101,11 +94,8 @@ RSpec.describe Api::V1::FiltersController do
|
|||
delete :destroy, params: { id: keyword.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the filter' do
|
||||
expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::FollowedTagsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:follows' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
|
||||
before { allow(controller).to receive(:doorkeeper_token) { token } }
|
||||
|
||||
describe 'GET #index' do
|
||||
let!(:tag_follows) { Fabricate.times(5, :tag_follow, account: user.account) }
|
||||
|
||||
before do
|
||||
get :index, params: { limit: 1 }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -5,7 +5,7 @@ require 'rails_helper'
|
|||
describe Api::V1::Instances::TranslationLanguagesController do
|
||||
describe 'GET #show' do
|
||||
context 'when no translation service is configured' do
|
||||
it 'returns empty language matrix' do
|
||||
it 'returns empty language matrix', :aggregate_failures do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
|
@ -19,7 +19,7 @@ describe Api::V1::Instances::TranslationLanguagesController do
|
|||
allow(TranslationService).to receive_messages(configured?: true, configured: service)
|
||||
end
|
||||
|
||||
it 'returns language matrix' do
|
||||
it 'returns language matrix', :aggregate_failures do
|
||||
get :show
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
|
|
|
@ -35,11 +35,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
post :create, params: { list_id: list.id, account_ids: [bob.id] }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'adds account to the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'adds account to the list' do
|
||||
expect(list.accounts.include?(bob)).to be true
|
||||
end
|
||||
end
|
||||
|
@ -50,11 +47,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
post :create, params: { list_id: list.id, account_ids: [bob.id] }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'adds account to the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'adds account to the list' do
|
||||
expect(list.accounts.include?(bob)).to be true
|
||||
end
|
||||
end
|
||||
|
@ -64,11 +58,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
post :create, params: { list_id: list.id, account_ids: [bob.id] }
|
||||
end
|
||||
|
||||
it 'returns http not found' do
|
||||
it 'does not add the account to the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
|
||||
it 'does not add the account to the list' do
|
||||
expect(list.accounts.include?(bob)).to be false
|
||||
end
|
||||
end
|
||||
|
@ -81,11 +72,8 @@ describe Api::V1::Lists::AccountsController do
|
|||
delete :destroy, params: { list_id: list.id, account_ids: [list.accounts.first.id] }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes account from the list', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes account from the list' do
|
||||
expect(list.accounts.count).to eq 0
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,13 +18,10 @@ RSpec.describe Api::V1::MarkersController do
|
|||
get :index, params: { timeline: %w(home notifications) }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns markers' do
|
||||
it 'returns markers', :aggregate_failures do
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json.key?(:home)).to be true
|
||||
expect(json[:home][:last_read_id]).to eq '123'
|
||||
expect(json.key?(:notifications)).to be true
|
||||
|
@ -38,11 +35,8 @@ RSpec.describe Api::V1::MarkersController do
|
|||
post :create, params: { home: { last_read_id: '69420' } }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a marker', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a marker' do
|
||||
expect(user.markers.first.timeline).to eq 'home'
|
||||
expect(user.markers.first.last_read_id).to eq 69_420
|
||||
end
|
||||
|
@ -54,11 +48,8 @@ RSpec.describe Api::V1::MarkersController do
|
|||
post :create, params: { home: { last_read_id: '70120' } }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates a marker', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates a marker' do
|
||||
expect(user.markers.first.timeline).to eq 'home'
|
||||
expect(user.markers.first.last_read_id).to eq 70_120
|
||||
end
|
||||
|
|
|
@ -38,19 +38,10 @@ RSpec.describe Api::V1::MediaController do
|
|||
post :create, params: { file: fixture_file_upload('attachment.jpg', 'image/jpeg') }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a media attachment', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a media attachment' do
|
||||
expect(MediaAttachment.first).to_not be_nil
|
||||
end
|
||||
|
||||
it 'uploads a file' do
|
||||
expect(MediaAttachment.first).to have_attached_file(:file)
|
||||
end
|
||||
|
||||
it 'returns media ID in JSON' do
|
||||
expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s
|
||||
end
|
||||
end
|
||||
|
@ -60,19 +51,10 @@ RSpec.describe Api::V1::MediaController do
|
|||
post :create, params: { file: fixture_file_upload('attachment.gif', 'image/gif') }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a media attachment', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a media attachment' do
|
||||
expect(MediaAttachment.first).to_not be_nil
|
||||
end
|
||||
|
||||
it 'uploads a file' do
|
||||
expect(MediaAttachment.first).to have_attached_file(:file)
|
||||
end
|
||||
|
||||
it 'returns media ID in JSON' do
|
||||
expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s
|
||||
end
|
||||
end
|
||||
|
@ -82,17 +64,10 @@ RSpec.describe Api::V1::MediaController do
|
|||
post :create, params: { file: fixture_file_upload('attachment.webm', 'video/webm') }
|
||||
end
|
||||
|
||||
it do
|
||||
# returns http success
|
||||
it 'creates a media attachment', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
|
||||
# creates a media attachment
|
||||
expect(MediaAttachment.first).to_not be_nil
|
||||
|
||||
# uploads a file
|
||||
expect(MediaAttachment.first).to have_attached_file(:file)
|
||||
|
||||
# returns media ID in JSON
|
||||
expect(body_as_json[:id]).to eq MediaAttachment.first.id.to_s
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,18 +18,13 @@ RSpec.describe Api::V1::Polls::VotesController do
|
|||
post :create, params: { poll_id: poll.id, choices: %w(1) }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a vote', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a vote' do
|
||||
vote = poll.votes.where(account: user.account).first
|
||||
|
||||
expect(vote).to_not be_nil
|
||||
expect(vote.choice).to eq 1
|
||||
end
|
||||
|
||||
it 'updates poll tallies' do
|
||||
expect(poll.reload.cached_tallies).to eq [0, 1]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Api::V1::ReportsController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
let(:scopes) { 'write:reports' }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:target_account) { status.account }
|
||||
let(:category) { nil }
|
||||
let(:forward) { nil }
|
||||
let(:rule_ids) { nil }
|
||||
|
||||
before do
|
||||
post :create, params: { status_ids: [status.id], account_id: target_account.id, comment: 'reasons', category: category, rule_ids: rule_ids, forward: forward }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a report' do
|
||||
expect(target_account.targeted_reports).to_not be_empty
|
||||
end
|
||||
|
||||
it 'saves comment' do
|
||||
expect(target_account.targeted_reports.first.comment).to eq 'reasons'
|
||||
end
|
||||
|
||||
it 'sends e-mails to admins' do
|
||||
expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email])
|
||||
end
|
||||
|
||||
context 'when a status does not belong to the reported account' do
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
|
||||
it 'returns http not found' do
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a category is chosen' do
|
||||
let(:category) { 'spam' }
|
||||
|
||||
it 'saves category' do
|
||||
expect(target_account.targeted_reports.first.spam?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when violated rules are chosen' do
|
||||
let(:rule) { Fabricate(:rule) }
|
||||
let(:category) { 'violation' }
|
||||
let(:rule_ids) { [rule.id] }
|
||||
|
||||
it 'saves category' do
|
||||
expect(target_account.targeted_reports.first.violation?).to be true
|
||||
end
|
||||
|
||||
it 'saves rule_ids' do
|
||||
expect(target_account.targeted_reports.first.rule_ids).to contain_exactly(rule.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,11 +21,8 @@ describe Api::V1::Statuses::MutesController do
|
|||
post :create, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a conversation mute', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a conversation mute' do
|
||||
expect(ConversationMute.find_by(account: user.account, conversation_id: status.conversation_id)).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
@ -38,11 +35,8 @@ describe Api::V1::Statuses::MutesController do
|
|||
post :destroy, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the conversation mute', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'destroys the conversation mute' do
|
||||
expect(ConversationMute.find_by(account: user.account, conversation_id: status.conversation_id)).to be_nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,14 +24,12 @@ RSpec.describe Api::V1::Statuses::RebloggedByAccountsController do
|
|||
Fabricate(:status, account: bob, reblog_of_id: status.id)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns accounts who reblogged the status', :aggregate_failures do
|
||||
get :index, params: { status_id: status.id, limit: 2 }
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
|
||||
it 'returns accounts who reblogged the status' do
|
||||
get :index, params: { status_id: status.id, limit: 2 }
|
||||
expect(body_as_json.size).to eq 2
|
||||
expect([body_as_json[0][:id], body_as_json[1][:id]]).to contain_exactly(alice.id.to_s, bob.id.to_s)
|
||||
end
|
||||
|
|
|
@ -28,19 +28,13 @@ describe Api::V1::Statuses::ReblogsController do
|
|||
end
|
||||
|
||||
context 'with public status' do
|
||||
it 'returns http success' do
|
||||
it 'reblogs the status', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the reblogs count' do
|
||||
expect(status.reblogs.count).to eq 1
|
||||
end
|
||||
|
||||
it 'updates the reblogged attribute' do
|
||||
expect(user.account.reblogged?(status)).to be true
|
||||
end
|
||||
|
||||
it 'returns json with updated attributes' do
|
||||
hash_body = body_as_json
|
||||
|
||||
expect(hash_body[:reblog][:id]).to eq status.id.to_s
|
||||
|
@ -67,19 +61,13 @@ describe Api::V1::Statuses::ReblogsController do
|
|||
post :destroy, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the reblog', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the reblogs count' do
|
||||
expect(status.reblogs.count).to eq 0
|
||||
end
|
||||
|
||||
it 'updates the reblogged attribute' do
|
||||
expect(user.account.reblogged?(status)).to be false
|
||||
end
|
||||
|
||||
it 'returns json with updated attributes' do
|
||||
hash_body = body_as_json
|
||||
|
||||
expect(hash_body[:id]).to eq status.id.to_s
|
||||
|
@ -97,19 +85,13 @@ describe Api::V1::Statuses::ReblogsController do
|
|||
post :destroy, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the reblog', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the reblogs count' do
|
||||
expect(status.reblogs.count).to eq 0
|
||||
end
|
||||
|
||||
it 'updates the reblogged attribute' do
|
||||
expect(user.account.reblogged?(status)).to be false
|
||||
end
|
||||
|
||||
it 'returns json with updated attributes' do
|
||||
hash_body = body_as_json
|
||||
|
||||
expect(hash_body[:id]).to eq status.id.to_s
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Statuses::SourcesController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:app) { Fabricate(:application, name: 'Test app', website: 'http://testapp.com') }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses', application: app) }
|
||||
|
||||
context 'with an oauth token' do
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
let(:status) { Fabricate(:status, account: user.account) }
|
||||
|
||||
before do
|
||||
get :show, params: { status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -30,14 +30,11 @@ RSpec.describe Api::V1::StatusesController do
|
|||
user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }])
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :show, params: { id: status.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns filter information' do
|
||||
it 'returns filter information', :aggregate_failures do
|
||||
get :show, params: { id: status.id }
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json[:filtered][0]).to include({
|
||||
filter: a_hash_including({
|
||||
id: user.account.custom_filters.first.id.to_s,
|
||||
|
@ -57,14 +54,11 @@ RSpec.describe Api::V1::StatusesController do
|
|||
filter.statuses.create!(status_id: status.id)
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :show, params: { id: status.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns filter information' do
|
||||
it 'returns filter information', :aggregate_failures do
|
||||
get :show, params: { id: status.id }
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json[:filtered][0]).to include({
|
||||
filter: a_hash_including({
|
||||
id: user.account.custom_filters.first.id.to_s,
|
||||
|
@ -83,14 +77,11 @@ RSpec.describe Api::V1::StatusesController do
|
|||
user.account.custom_filters.create!(phrase: 'filter1', context: %w(home), action: :hide, keywords_attributes: [{ keyword: 'banned' }, { keyword: 'irrelevant' }])
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
get :show, params: { id: status.id }
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns filter information' do
|
||||
it 'returns filter information', :aggregate_failures do
|
||||
get :show, params: { id: status.id }
|
||||
json = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(json[:reblog][:filtered][0]).to include({
|
||||
filter: a_hash_including({
|
||||
id: user.account.custom_filters.first.id.to_s,
|
||||
|
@ -125,11 +116,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: { status: 'Hello world' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns rate limit headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns rate limit headers' do
|
||||
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
|
||||
expect(response.headers['X-RateLimit-Remaining']).to eq (RateLimiter::FAMILIES[:statuses][:limit] - 1).to_s
|
||||
end
|
||||
|
@ -143,11 +131,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: { status: '@alice hm, @bob is really annoying lately', allowed_mentions: [alice.id] }
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
it 'returns serialized extra accounts in body', :aggregate_failures do
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'returns serialized extra accounts in body' do
|
||||
expect(body_as_json[:unexpected_accounts].map { |a| a.slice(:id, :acct) }).to eq [{ id: bob.id.to_s, acct: bob.acct }]
|
||||
end
|
||||
end
|
||||
|
@ -157,11 +142,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: {}
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
it 'returns rate limit headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'returns rate limit headers' do
|
||||
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
|
||||
end
|
||||
end
|
||||
|
@ -173,11 +155,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :create, params: { status: 'Hello world' }
|
||||
end
|
||||
|
||||
it 'returns http too many requests' do
|
||||
it 'returns rate limit headers', :aggregate_failures do
|
||||
expect(response).to have_http_status(429)
|
||||
end
|
||||
|
||||
it 'returns rate limit headers' do
|
||||
expect(response.headers['X-RateLimit-Limit']).to eq RateLimiter::FAMILIES[:statuses][:limit].to_s
|
||||
expect(response.headers['X-RateLimit-Remaining']).to eq '0'
|
||||
end
|
||||
|
@ -192,11 +171,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
post :destroy, params: { id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the status', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the status' do
|
||||
expect(Status.find_by(id: status.id)).to be_nil
|
||||
end
|
||||
end
|
||||
|
@ -209,11 +185,8 @@ RSpec.describe Api::V1::StatusesController do
|
|||
put :update, params: { id: status.id, status: 'I am updated' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates the status', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the status' do
|
||||
expect(status.reload.text).to eq 'I am updated'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe Api::V1::Timelines::TagController do
|
||||
render_views
|
||||
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:statuses') }
|
||||
|
||||
before do
|
||||
allow(controller).to receive(:doorkeeper_token) { token }
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
subject do
|
||||
get :show, params: { id: 'test' }
|
||||
end
|
||||
|
||||
before do
|
||||
PostStatusService.new.call(user.account, text: 'It is a #test')
|
||||
end
|
||||
|
||||
context 'when the instance allows public preview' do
|
||||
context 'when the user is not authenticated' do
|
||||
let(:token) { nil }
|
||||
|
||||
it 'returns http success', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is authenticated' do
|
||||
it 'returns http success', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the instance does not allow public preview' do
|
||||
before do
|
||||
Form::AdminSettings.new(timeline_preview: false).save
|
||||
end
|
||||
|
||||
context 'when the user is not authenticated' do
|
||||
let(:token) { nil }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is authenticated' do
|
||||
it 'returns http success', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(response.headers['Link'].links.size).to eq(2)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -44,14 +44,14 @@ RSpec.describe Api::V2::Admin::AccountsController do
|
|||
context "when called with #{params.inspect}" do
|
||||
let(:params) { params }
|
||||
|
||||
it 'returns http success' do
|
||||
it "returns the correct accounts (#{expected_results.inspect})" do
|
||||
expect(response).to have_http_status(200)
|
||||
|
||||
expect(body_json_ids).to eq(expected_results.map { |symbol| send(symbol).id })
|
||||
end
|
||||
|
||||
it "returns the correct accounts (#{expected_results.inspect})" do
|
||||
json = body_as_json
|
||||
|
||||
expect(json.map { |a| a[:id].to_i }).to eq(expected_results.map { |symbol| send(symbol).id })
|
||||
def body_json_ids
|
||||
body_as_json.map { |a| a[:id].to_i }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,17 +40,13 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
post :create, params: { filter_id: filter_id, keyword: 'magic', whole_word: false }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns a keyword' do
|
||||
json = body_as_json
|
||||
expect(json[:keyword]).to eq 'magic'
|
||||
expect(json[:whole_word]).to be false
|
||||
end
|
||||
|
||||
it 'creates a keyword' do
|
||||
filter = user.account.custom_filters.first
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.keywords.pluck(:keyword)).to eq ['magic']
|
||||
|
@ -73,11 +69,9 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
get :show, params: { id: keyword.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'responds with the keyword', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected data' do
|
||||
json = body_as_json
|
||||
expect(json[:keyword]).to eq 'foo'
|
||||
expect(json[:whole_word]).to be false
|
||||
|
@ -100,11 +94,9 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
get :update, params: { id: keyword.id, keyword: 'updated' }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'updates the keyword', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the keyword' do
|
||||
expect(keyword.reload.keyword).to eq 'updated'
|
||||
end
|
||||
|
||||
|
@ -125,11 +117,9 @@ RSpec.describe Api::V2::Filters::KeywordsController do
|
|||
delete :destroy, params: { id: keyword.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the keyword', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the filter' do
|
||||
expect { keyword.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
|
|
|
@ -41,16 +41,12 @@ RSpec.describe Api::V2::Filters::StatusesController do
|
|||
post :create, params: { filter_id: filter_id, status_id: status.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns a status filter' do
|
||||
json = body_as_json
|
||||
expect(json[:status_id]).to eq status.id.to_s
|
||||
end
|
||||
|
||||
it 'creates a status filter' do
|
||||
filter = user.account.custom_filters.first
|
||||
expect(filter).to_not be_nil
|
||||
expect(filter.statuses.pluck(:status_id)).to eq [status.id]
|
||||
|
@ -73,11 +69,9 @@ RSpec.describe Api::V2::Filters::StatusesController do
|
|||
get :show, params: { id: status_filter.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'responds with the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected data' do
|
||||
json = body_as_json
|
||||
expect(json[:status_id]).to eq status_filter.status_id.to_s
|
||||
end
|
||||
|
@ -99,11 +93,9 @@ RSpec.describe Api::V2::Filters::StatusesController do
|
|||
delete :destroy, params: { id: status_filter.id }
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
it 'destroys the filter', :aggregate_failures do
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the filter' do
|
||||
expect { status_filter.reload }.to raise_error ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
|
|
81
spec/features/admin/accounts_spec.rb
Normal file
81
spec/features/admin/accounts_spec.rb
Normal file
|
@ -0,0 +1,81 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Accounts' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
let(:unapproved_user_account) { Fabricate(:account) }
|
||||
let(:approved_user_account) { Fabricate(:account) }
|
||||
|
||||
before do
|
||||
unapproved_user_account.user.update(approved: false)
|
||||
approved_user_account.user.update(approved: true)
|
||||
|
||||
visit admin_accounts_path
|
||||
end
|
||||
|
||||
context 'without selecting any accounts' do
|
||||
it 'displays a notice about account selection' do
|
||||
click_on button_for_suspend
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with action of `suspend`' do
|
||||
it 'suspends the account' do
|
||||
batch_checkbox_for(approved_user_account).check
|
||||
|
||||
click_on button_for_suspend
|
||||
|
||||
expect(approved_user_account.reload).to be_suspended
|
||||
end
|
||||
end
|
||||
|
||||
context 'with action of `approve`' do
|
||||
it 'approves the account user' do
|
||||
batch_checkbox_for(unapproved_user_account).check
|
||||
|
||||
click_on button_for_approve
|
||||
|
||||
expect(unapproved_user_account.reload.user).to be_approved
|
||||
end
|
||||
end
|
||||
|
||||
context 'with action of `reject`' do
|
||||
it 'rejects and removes the account' do
|
||||
batch_checkbox_for(unapproved_user_account).check
|
||||
|
||||
click_on button_for_reject
|
||||
|
||||
expect { unapproved_user_account.reload }.to raise_error(ActiveRecord::RecordNotFound)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_suspend
|
||||
I18n.t('admin.accounts.perform_full_suspension')
|
||||
end
|
||||
|
||||
def button_for_approve
|
||||
I18n.t('admin.accounts.approve')
|
||||
end
|
||||
|
||||
def button_for_reject
|
||||
I18n.t('admin.accounts.reject')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.accounts.no_account_selected')
|
||||
end
|
||||
|
||||
def batch_checkbox_for(account)
|
||||
find("#form_account_batch_account_ids_#{account.id}")
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/custom_emojis_spec.rb
Normal file
33
spec/features/admin/custom_emojis_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::CustomEmojis' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_custom_emojis_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_enable
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_enable
|
||||
I18n.t('admin.custom_emojis.enable')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.custom_emojis.no_emoji_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/email_domain_blocks_spec.rb
Normal file
33
spec/features/admin/email_domain_blocks_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::EmailDomainBlocks' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_email_domain_blocks_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_delete
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_delete
|
||||
I18n.t('admin.email_domain_blocks.delete')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.email_domain_blocks.no_email_domain_block_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/ip_blocks_spec.rb
Normal file
33
spec/features/admin/ip_blocks_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::IpBlocks' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_ip_blocks_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_delete
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_delete
|
||||
I18n.t('admin.ip_blocks.delete')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.ip_blocks.no_ip_block_selected')
|
||||
end
|
||||
end
|
||||
end
|
34
spec/features/admin/statuses_spec.rb
Normal file
34
spec/features/admin/statuses_spec.rb
Normal file
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Statuses' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
_status = Fabricate(:status, account: current_user.account)
|
||||
visit admin_account_statuses_path(account_id: current_user.account_id)
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_report
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_report
|
||||
I18n.t('admin.statuses.batch.report')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.statuses.no_status_selected')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Links::PreviewCardProviders' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_links_preview_card_providers_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.links.publishers.no_publisher_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/trends/links_spec.rb
Normal file
33
spec/features/admin/trends/links_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Links' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_links_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.links.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.links.no_link_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/trends/statuses_spec.rb
Normal file
33
spec/features/admin/trends/statuses_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Statuses' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_statuses_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.statuses.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.statuses.no_status_selected')
|
||||
end
|
||||
end
|
||||
end
|
33
spec/features/admin/trends/tags_spec.rb
Normal file
33
spec/features/admin/trends/tags_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Admin::Trends::Tags' do
|
||||
let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
|
||||
before do
|
||||
sign_in current_user
|
||||
end
|
||||
|
||||
describe 'Performing batch updates' do
|
||||
before do
|
||||
visit admin_trends_tags_path
|
||||
end
|
||||
|
||||
context 'without selecting any records' do
|
||||
it 'displays a notice about selection' do
|
||||
click_on button_for_allow
|
||||
|
||||
expect(page).to have_content(selection_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
def button_for_allow
|
||||
I18n.t('admin.trends.allow')
|
||||
end
|
||||
|
||||
def selection_error_text
|
||||
I18n.t('admin.trends.tags.no_tag_selected')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -562,6 +562,44 @@ RSpec.describe FeedManager do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#unmerge_tag_from_home' do
|
||||
let(:receiver) { Fabricate(:account) }
|
||||
let(:tag) { Fabricate(:tag) }
|
||||
|
||||
it 'leaves a tagged status' do
|
||||
status = Fabricate(:status)
|
||||
status.tags << tag
|
||||
described_class.instance.push_to_home(receiver, status)
|
||||
|
||||
described_class.instance.unmerge_tag_from_home(tag, receiver)
|
||||
|
||||
expect(redis.zrange("feed:home:#{receiver.id}", 0, -1)).to_not include(status.id.to_s)
|
||||
end
|
||||
|
||||
it 'remains a tagged status written by receiver\'s followee' do
|
||||
followee = Fabricate(:account)
|
||||
receiver.follow!(followee)
|
||||
|
||||
status = Fabricate(:status, account: followee)
|
||||
status.tags << tag
|
||||
described_class.instance.push_to_home(receiver, status)
|
||||
|
||||
described_class.instance.unmerge_tag_from_home(tag, receiver)
|
||||
|
||||
expect(redis.zrange("feed:home:#{receiver.id}", 0, -1)).to include(status.id.to_s)
|
||||
end
|
||||
|
||||
it 'remains a tagged status written by receiver' do
|
||||
status = Fabricate(:status, account: receiver)
|
||||
status.tags << tag
|
||||
described_class.instance.push_to_home(receiver, status)
|
||||
|
||||
described_class.instance.unmerge_tag_from_home(tag, receiver)
|
||||
|
||||
expect(redis.zrange("feed:home:#{receiver.id}", 0, -1)).to include(status.id.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#clear_from_home' do
|
||||
let(:account) { Fabricate(:account) }
|
||||
let(:followed_account) { Fabricate(:account) }
|
||||
|
|
|
@ -54,26 +54,6 @@ Devise::Test::ControllerHelpers.module_eval do
|
|||
end
|
||||
end
|
||||
|
||||
module SignedRequestHelpers
|
||||
def get(path, headers: nil, sign_with: nil, **args)
|
||||
return super path, headers: headers, **args if sign_with.nil?
|
||||
|
||||
headers ||= {}
|
||||
headers['Date'] = Time.now.utc.httpdate
|
||||
headers['Host'] = ENV.fetch('LOCAL_DOMAIN')
|
||||
signed_headers = headers.merge('(request-target)' => "get #{path}").slice('(request-target)', 'Host', 'Date')
|
||||
|
||||
key_id = ActivityPub::TagManager.instance.key_uri_for(sign_with)
|
||||
keypair = sign_with.keypair
|
||||
signed_string = signed_headers.map { |key, value| "#{key.downcase}: #{value}" }.join("\n")
|
||||
signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string))
|
||||
|
||||
headers['Signature'] = "keyId=\"#{key_id}\",algorithm=\"rsa-sha256\",headers=\"#{signed_headers.keys.join(' ').downcase}\",signature=\"#{signature}\""
|
||||
|
||||
super path, headers: headers, **args
|
||||
end
|
||||
end
|
||||
|
||||
RSpec.configure do |config|
|
||||
# This is set before running spec:system, see lib/tasks/tests.rake
|
||||
config.filter_run_excluding type: lambda { |type|
|
||||
|
|
|
@ -51,14 +51,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :disable, :user
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'disables the target account' do
|
||||
expect { subject }.to change { target_account.reload.user_disabled? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,14 +65,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :sensitive, :account
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks the target account as sensitive' do
|
||||
expect { subject }.to change { target_account.reload.sensitized? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,14 +79,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :silence, :account
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks the target account as silenced' do
|
||||
expect { subject }.to change { target_account.reload.silenced? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -108,14 +93,9 @@ RSpec.describe 'Account actions' do
|
|||
it_behaves_like 'a successful notification delivery'
|
||||
it_behaves_like 'a successful logged action', :suspend, :account
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks the target account as suspended' do
|
||||
expect { subject }.to change { target_account.reload.suspended? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -92,15 +92,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
context 'when the requested canonical email block exists' do
|
||||
it 'returns http success' do
|
||||
it 'returns the requested canonical email block data correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the requested canonical email block data correctly' do
|
||||
subject
|
||||
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:id]).to eq(canonical_email_block.id.to_s)
|
||||
|
@ -142,29 +137,19 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
context 'when there is a matching canonical email block' do
|
||||
let!(:canonical_email_block) { CanonicalEmailBlock.create(params) }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected canonical email hash', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected canonical email hash' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[0][:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is no matching canonical email block' do
|
||||
it 'returns http success' do
|
||||
it 'returns an empty list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns an empty list' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to be_empty
|
||||
end
|
||||
end
|
||||
|
@ -183,15 +168,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the canonical_email_hash correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the canonical_email_hash correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
|
||||
end
|
||||
|
||||
|
@ -208,15 +188,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
context 'when the canonical_email_hash param is provided instead of email' do
|
||||
let(:params) { { canonical_email_hash: 'dd501ce4e6b08698f19df96f2f15737e48a75660b1fa79b6ff58ea25ee4851a4' } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct canonical_email_hash', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct canonical_email_hash' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:canonical_email_hash]).to eq(params[:canonical_email_hash])
|
||||
end
|
||||
end
|
||||
|
@ -224,15 +199,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
context 'when both email and canonical_email_hash params are provided' do
|
||||
let(:params) { { email: 'example@email.com', canonical_email_hash: 'dd501ce4e6b08698f19df96f2f15737e48a75660b1fa79b6ff58ea25ee4851a4' } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'ignores the canonical_email_hash param', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'ignores the canonical_email_hash param' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:canonical_email_hash]).to eq(canonical_email_block.canonical_email_hash)
|
||||
end
|
||||
end
|
||||
|
@ -262,15 +232,10 @@ RSpec.describe 'Canonical Email Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the canonical email block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the canonical email block' do
|
||||
subject
|
||||
|
||||
expect(CanonicalEmailBlock.find_by(id: canonical_email_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -75,15 +75,10 @@ RSpec.describe 'Domain Allows' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected allowed domain name', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected allowed domain name' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq domain_allow.domain
|
||||
end
|
||||
|
||||
|
@ -108,21 +103,11 @@ RSpec.describe 'Domain Allows' do
|
|||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
context 'with a valid domain name' do
|
||||
it 'returns http success' do
|
||||
it 'returns the expected domain name', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected domain name' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq 'foo.bar.com'
|
||||
end
|
||||
|
||||
it 'creates a domain allow' do
|
||||
subject
|
||||
|
||||
expect(DomainAllow.find_by(domain: 'foo.bar.com')).to be_present
|
||||
end
|
||||
end
|
||||
|
@ -171,15 +156,10 @@ RSpec.describe 'Domain Allows' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the allowed domain', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the allowed domain' do
|
||||
subject
|
||||
|
||||
expect(DomainAllow.find_by(id: domain_allow.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -143,16 +143,23 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected domain block content', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected domain block content' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to eq(expected_response)
|
||||
expect(body_as_json).to eq(
|
||||
{
|
||||
id: domain_block.id.to_s,
|
||||
domain: domain_block.domain,
|
||||
created_at: domain_block.created_at.strftime('%Y-%m-%dT%H:%M:%S.%LZ'),
|
||||
severity: domain_block.severity.to_s,
|
||||
reject_media: domain_block.reject_media,
|
||||
reject_reports: domain_block.reject_reports,
|
||||
private_comment: domain_block.private_comment,
|
||||
public_comment: domain_block.public_comment,
|
||||
obfuscate: domain_block.obfuscate,
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the requested domain block does not exist' do
|
||||
|
@ -175,27 +182,18 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns expected domain name and severity' do
|
||||
it 'returns expected domain name and severity', :aggregate_failures do
|
||||
subject
|
||||
|
||||
body = body_as_json
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body).to match a_hash_including(
|
||||
{
|
||||
domain: 'foo.bar.com',
|
||||
severity: 'silence',
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
it 'creates a domain block' do
|
||||
subject
|
||||
|
||||
expect(DomainBlock.find_by(domain: 'foo.bar.com')).to be_present
|
||||
end
|
||||
|
@ -205,15 +203,10 @@ RSpec.describe 'Domain Blocks' do
|
|||
Fabricate(:domain_block, domain: 'bar.com', severity: :suspend)
|
||||
end
|
||||
|
||||
it 'returns http unprocessable entity' do
|
||||
it 'returns existing domain block in error', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(422)
|
||||
end
|
||||
|
||||
it 'returns existing domain block in error' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:existing_domain_block][:domain]).to eq('bar.com')
|
||||
end
|
||||
end
|
||||
|
@ -241,15 +234,10 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the updated domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the updated domain block' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match a_hash_including(
|
||||
{
|
||||
id: domain_block.id.to_s,
|
||||
|
@ -283,15 +271,10 @@ RSpec.describe 'Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the domain block' do
|
||||
subject
|
||||
|
||||
expect(DomainBlock.find_by(id: domain_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -93,15 +93,10 @@ RSpec.describe 'Email Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
context 'when email domain block exists' do
|
||||
it 'returns http success' do
|
||||
it 'returns the correct blocked domain', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct blocked domain' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq(email_domain_block.domain)
|
||||
end
|
||||
end
|
||||
|
@ -126,15 +121,10 @@ RSpec.describe 'Email Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct blocked email domain', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct blocked email domain' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:domain]).to eq(params[:domain])
|
||||
end
|
||||
|
||||
|
@ -182,21 +172,11 @@ RSpec.describe 'Email Domain Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes email domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns an empty body' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to be_empty
|
||||
end
|
||||
|
||||
it 'deletes email domain block' do
|
||||
subject
|
||||
|
||||
expect(EmailDomainBlock.find_by(id: email_domain_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -84,15 +84,10 @@ RSpec.describe 'IP Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct ip block' do
|
||||
subject
|
||||
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:ip]).to eq("#{ip_block.ip}/#{ip_block.ip.prefix}")
|
||||
|
@ -119,15 +114,10 @@ RSpec.describe 'IP Blocks' do
|
|||
it_behaves_like 'forbidden for wrong role', ''
|
||||
it_behaves_like 'forbidden for wrong role', 'Moderator'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct ip block' do
|
||||
subject
|
||||
|
||||
json = body_as_json
|
||||
|
||||
expect(json[:ip]).to eq("#{params[:ip]}/32")
|
||||
|
@ -186,15 +176,10 @@ RSpec.describe 'IP Blocks' do
|
|||
let!(:ip_block) { IpBlock.create(ip: '185.200.13.3', severity: 'no_access', comment: 'Spam', expires_in: 48.hours) }
|
||||
let(:params) { { severity: 'sign_up_requires_approval', comment: 'Decreasing severity' } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the correct ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the correct ip block' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(hash_including({
|
||||
ip: "#{ip_block.ip}/#{ip_block.ip.prefix}",
|
||||
severity: 'sign_up_requires_approval',
|
||||
|
@ -226,21 +211,11 @@ RSpec.describe 'IP Blocks' do
|
|||
|
||||
let!(:ip_block) { IpBlock.create(ip: '185.200.13.3', severity: 'no_access') }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the ip block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns an empty body' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to be_empty
|
||||
end
|
||||
|
||||
it 'deletes the ip block' do
|
||||
subject
|
||||
|
||||
expect(IpBlock.find_by(id: ip_block.id)).to be_nil
|
||||
end
|
||||
|
||||
|
|
|
@ -122,15 +122,10 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the requested report content', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the requested report content' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to include(
|
||||
{
|
||||
id: report.id.to_s,
|
||||
|
@ -155,18 +150,10 @@ RSpec.describe 'Reports' do
|
|||
let!(:report) { Fabricate(:report, category: :other) }
|
||||
let(:params) { { category: 'spam' } }
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
it 'updates the report category', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.category }.from('other').to('spam')
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'updates the report category' do
|
||||
expect { subject }.to change { report.reload.category }.from('other').to('spam')
|
||||
end
|
||||
|
||||
it 'returns the updated report content' do
|
||||
subject
|
||||
|
||||
report.reload
|
||||
|
||||
|
@ -196,14 +183,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks report as resolved' do
|
||||
it 'marks report as resolved', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.unresolved? }.from(true).to(false)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -217,14 +199,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'marks report as unresolved' do
|
||||
it 'marks report as unresolved', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.unresolved? }.from(false).to(true)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -238,14 +215,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'assigns report to the requesting user' do
|
||||
it 'assigns report to the requesting user', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.assigned_account_id }.from(nil).to(user.account.id)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -259,14 +231,9 @@ RSpec.describe 'Reports' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'write:statuses'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'unassigns report from assignee' do
|
||||
it 'unassigns report from assignee', :aggregate_failures do
|
||||
expect { subject }.to change { report.reload.assigned_account_id }.from(user.account.id).to(nil)
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
129
spec/requests/api/v1/admin/trends/links/links_spec.rb
Normal file
129
spec/requests/api/v1/admin/trends/links/links_spec.rb
Normal file
|
@ -0,0 +1,129 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
describe 'Links' do
|
||||
let(:role) { UserRole.find_by(name: 'Admin') }
|
||||
let(:user) { Fabricate(:user, role: role) }
|
||||
let(:scopes) { 'admin:read admin:write' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/admin/trends/links' do
|
||||
subject do
|
||||
get '/api/v1/admin/trends/links', headers: headers
|
||||
end
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/admin/trends/links/:id/approve' do
|
||||
subject do
|
||||
post "/api/v1/admin/trends/links/#{preview_card.id}/approve", headers: headers
|
||||
end
|
||||
|
||||
let(:preview_card) { Fabricate(:preview_card, trendable: false) }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read write'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'sets the link as trendable' do
|
||||
expect { subject }.to change { preview_card.reload.trendable }.from(false).to(true)
|
||||
end
|
||||
|
||||
it 'returns the link data' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
url: preview_card.url,
|
||||
title: preview_card.title,
|
||||
description: preview_card.description,
|
||||
type: 'link',
|
||||
requires_review: false
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the link does not exist' do
|
||||
it 'returns http not found' do
|
||||
post '/api/v1/admin/trends/links/-1/approve', headers: headers
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST /api/v1/admin/trends/links/:id/reject' do
|
||||
subject do
|
||||
post "/api/v1/admin/trends/links/#{preview_card.id}/reject", headers: headers
|
||||
end
|
||||
|
||||
let(:preview_card) { Fabricate(:preview_card, trendable: false) }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read write'
|
||||
it_behaves_like 'forbidden for wrong role', ''
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'does not set the link as trendable' do
|
||||
expect { subject }.to_not(change { preview_card.reload.trendable })
|
||||
end
|
||||
|
||||
it 'returns the link data' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
url: preview_card.url,
|
||||
title: preview_card.title,
|
||||
description: preview_card.description,
|
||||
type: 'link',
|
||||
requires_review: false
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
context 'when the link does not exist' do
|
||||
it 'returns http not found' do
|
||||
post '/api/v1/admin/trends/links/-1/reject', headers: headers
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http forbidden' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(403)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,14 +12,10 @@ describe 'Credentials' do
|
|||
let(:token) { Fabricate(:accessible_access_token, scopes: 'read', application: Fabricate(:application)) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the app information correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the app information correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
|
|
|
@ -23,20 +23,11 @@ RSpec.describe 'Apps' do
|
|||
end
|
||||
|
||||
context 'with valid params' do
|
||||
it 'returns http success' do
|
||||
it 'creates an OAuth app', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates an OAuth app' do
|
||||
subject
|
||||
|
||||
expect(Doorkeeper::Application.find_by(name: client_name)).to be_present
|
||||
end
|
||||
|
||||
it 'returns client ID and client secret' do
|
||||
subject
|
||||
|
||||
body = body_as_json
|
||||
|
||||
|
@ -58,15 +49,10 @@ RSpec.describe 'Apps' do
|
|||
context 'with many duplicate scopes' do
|
||||
let(:scopes) { (%w(read) * 40).join(' ') }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'only saves the scope once', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'only saves the scope once' do
|
||||
subject
|
||||
|
||||
expect(Doorkeeper::Application.find_by(name: client_name).scopes.to_s).to eq 'read'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,15 +22,10 @@ RSpec.describe 'Domain blocks' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write:blocks'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the domains blocked by the requesting user', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the domains blocked by the requesting user' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(blocked_domains)
|
||||
end
|
||||
|
||||
|
@ -54,15 +49,10 @@ RSpec.describe 'Domain blocks' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:blocks'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a domain block' do
|
||||
subject
|
||||
|
||||
expect(user.account.domain_blocking?(params[:domain])).to be(true)
|
||||
end
|
||||
|
||||
|
@ -100,15 +90,10 @@ RSpec.describe 'Domain blocks' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:blocks'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the specified domain block', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the specified domain block' do
|
||||
subject
|
||||
|
||||
expect(user.account.domain_blocking?('example.com')).to be(false)
|
||||
end
|
||||
|
||||
|
|
71
spec/requests/api/v1/favourites_spec.rb
Normal file
71
spec/requests/api/v1/favourites_spec.rb
Normal file
|
@ -0,0 +1,71 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Favourites' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'read:favourites' }
|
||||
let(:headers) { { Authorization: "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/favourites' do
|
||||
subject do
|
||||
get '/api/v1/favourites', headers: headers, params: params
|
||||
end
|
||||
|
||||
let(:params) { {} }
|
||||
let!(:favourites) { Fabricate.times(3, :favourite, account: user.account) }
|
||||
|
||||
let(:expected_response) do
|
||||
favourites.map do |favourite|
|
||||
a_hash_including(id: favourite.status.id.to_s, account: a_hash_including(id: favourite.status.account.id.to_s))
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the favourites' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 2 } }
|
||||
|
||||
it 'returns only the requested number of favourites' do
|
||||
subject
|
||||
|
||||
expect(body_as_json.size).to eq(params[:limit])
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the prev path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq(api_v1_favourites_url(limit: params[:limit], min_id: favourites.last.id))
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the next path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq(api_v1_favourites_url(limit: params[:limit], max_id: favourites[1].id))
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -32,15 +32,10 @@ RSpec.describe 'Follow requests' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected content from accounts requesting to follow', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected content from accounts requesting to follow' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
|
||||
|
@ -68,19 +63,9 @@ RSpec.describe 'Follow requests' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'allows the requesting follower to follow' do
|
||||
it 'allows the requesting follower to follow', :aggregate_failures do
|
||||
expect { subject }.to change { follower.following?(user.account) }.from(false).to(true)
|
||||
end
|
||||
|
||||
it 'returns JSON with followed_by set to true' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json[:followed_by]).to be true
|
||||
end
|
||||
end
|
||||
|
@ -98,21 +83,11 @@ RSpec.describe 'Follow requests' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the follow request', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the follow request' do
|
||||
subject
|
||||
|
||||
expect(FollowRequest.where(target_account: user.account, account: follower)).to_not exist
|
||||
end
|
||||
|
||||
it 'returns JSON with followed_by set to false' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:followed_by]).to be false
|
||||
end
|
||||
end
|
||||
|
|
65
spec/requests/api/v1/followed_tags_spec.rb
Normal file
65
spec/requests/api/v1/followed_tags_spec.rb
Normal file
|
@ -0,0 +1,65 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Followed tags' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:follows' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/followed_tags' do
|
||||
subject do
|
||||
get '/api/v1/followed_tags', headers: headers, params: params
|
||||
end
|
||||
|
||||
let!(:tag_follows) { Fabricate.times(5, :tag_follow, account: user.account) }
|
||||
let(:params) { {} }
|
||||
|
||||
let(:expected_response) do
|
||||
tag_follows.map do |tag_follow|
|
||||
a_hash_including(name: tag_follow.tag.name, following: true)
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
Fabricate(:tag_follow)
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'returns the followed tags correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:params) { { limit: 3 } }
|
||||
|
||||
it 'returns only the requested number of follow tags' do
|
||||
subject
|
||||
|
||||
expect(body_as_json.size).to eq(params[:limit])
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the prev path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel prev)).href).to eq(api_v1_followed_tags_url(limit: params[:limit], since_id: tag_follows.last.id))
|
||||
end
|
||||
|
||||
it 'sets the correct pagination header for the next path' do
|
||||
subject
|
||||
|
||||
expect(response.headers['Link'].find_link(%w(rel next)).href).to eq(api_v1_followed_tags_url(limit: params[:limit], max_id: tag_follows[2].id))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -51,16 +51,11 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the expected lists', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the expected lists' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match_array(expected_response_with_antennas)
|
||||
expect(body_as_json).to match_array(expected_response)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -73,15 +68,10 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the requested list correctly', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the requested list correctly' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to eq({
|
||||
id: list.id.to_s,
|
||||
title: list.title,
|
||||
|
@ -119,21 +109,11 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the new list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the new list' do
|
||||
subject
|
||||
|
||||
expect(body_as_json).to match(a_hash_including(title: 'my list', replies_policy: 'none', exclusive: true))
|
||||
end
|
||||
|
||||
it 'creates a list' do
|
||||
subject
|
||||
|
||||
expect(List.where(account: user.account).count).to eq(1)
|
||||
end
|
||||
|
||||
|
@ -168,15 +148,10 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the updated list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the updated list' do
|
||||
subject
|
||||
|
||||
list.reload
|
||||
|
||||
expect(body_as_json).to eq({
|
||||
|
@ -228,15 +203,10 @@ RSpec.describe 'Lists' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:lists'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'deletes the list', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'deletes the list' do
|
||||
subject
|
||||
|
||||
expect(List.where(id: list.id)).to_not exist
|
||||
end
|
||||
|
||||
|
|
89
spec/requests/api/v1/reports_spec.rb
Normal file
89
spec/requests/api/v1/reports_spec.rb
Normal file
|
@ -0,0 +1,89 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Reports' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:scopes) { 'write:reports' }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'POST /api/v1/reports' do
|
||||
subject do
|
||||
post '/api/v1/reports', headers: headers, params: params
|
||||
end
|
||||
|
||||
let!(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
|
||||
let(:status) { Fabricate(:status) }
|
||||
let(:target_account) { status.account }
|
||||
let(:category) { 'other' }
|
||||
let(:forward) { nil }
|
||||
let(:rule_ids) { nil }
|
||||
|
||||
let(:params) do
|
||||
{
|
||||
status_ids: [status.id],
|
||||
account_id: target_account.id,
|
||||
comment: 'reasons',
|
||||
category: category,
|
||||
rule_ids: rule_ids,
|
||||
forward: forward,
|
||||
}
|
||||
end
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:reports'
|
||||
|
||||
it 'creates a report', :aggregate_failures do
|
||||
perform_enqueued_jobs do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to match(
|
||||
a_hash_including(
|
||||
status_ids: [status.id.to_s],
|
||||
category: category,
|
||||
comment: 'reasons'
|
||||
)
|
||||
)
|
||||
|
||||
expect(target_account.targeted_reports).to_not be_empty
|
||||
expect(target_account.targeted_reports.first.comment).to eq 'reasons'
|
||||
|
||||
expect(ActionMailer::Base.deliveries.first.to).to eq([admin.email])
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a status does not belong to the reported account' do
|
||||
let(:target_account) { Fabricate(:account) }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a category is chosen' do
|
||||
let(:category) { 'spam' }
|
||||
|
||||
it 'saves category' do
|
||||
subject
|
||||
|
||||
expect(target_account.targeted_reports.first.spam?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
context 'when violated rules are chosen' do
|
||||
let(:rule) { Fabricate(:rule) }
|
||||
let(:category) { 'violation' }
|
||||
let(:rule_ids) { [rule.id] }
|
||||
|
||||
it 'saves category and rule_ids' do
|
||||
subject
|
||||
|
||||
expect(target_account.targeted_reports.first.violation?).to be true
|
||||
expect(target_account.targeted_reports.first.rule_ids).to contain_exactly(rule.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
72
spec/requests/api/v1/statuses/sources_spec.rb
Normal file
72
spec/requests/api/v1/statuses/sources_spec.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Sources' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:statuses' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
describe 'GET /api/v1/statuses/:status_id/source' do
|
||||
subject do
|
||||
get "/api/v1/statuses/#{status.id}/source", headers: headers
|
||||
end
|
||||
|
||||
let(:status) { Fabricate(:status) }
|
||||
|
||||
it_behaves_like 'forbidden for wrong scope', 'write write:statuses'
|
||||
|
||||
context 'with public status' do
|
||||
it 'returns the source properties of the status', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to eq({
|
||||
id: status.id.to_s,
|
||||
text: status.text,
|
||||
spoiler_text: status.spoiler_text,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context 'with private status of non-followed account' do
|
||||
let(:status) { Fabricate(:status, visibility: :private) }
|
||||
|
||||
it 'returns http not found' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(404)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with private status of followed account' do
|
||||
let(:status) { Fabricate(:status, visibility: :private) }
|
||||
|
||||
before do
|
||||
user.account.follow!(status.account)
|
||||
end
|
||||
|
||||
it 'returns the source properties of the status', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json).to eq({
|
||||
id: status.id.to_s,
|
||||
text: status.text,
|
||||
spoiler_text: status.spoiler_text,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
context 'without an authorization header' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -17,15 +17,10 @@ RSpec.describe 'Tags' do
|
|||
let!(:tag) { Fabricate(:tag) }
|
||||
let(:name) { tag.name }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'returns the tag', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'returns the tag' do
|
||||
subject
|
||||
|
||||
expect(body_as_json[:name]).to eq(name)
|
||||
end
|
||||
end
|
||||
|
@ -62,15 +57,10 @@ RSpec.describe 'Tags' do
|
|||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
context 'when the tag exists' do
|
||||
it 'returns http success' do
|
||||
it 'creates follow', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(:success)
|
||||
end
|
||||
|
||||
it 'creates follow' do
|
||||
subject
|
||||
|
||||
expect(TagFollow.where(tag: tag, account: user.account)).to exist
|
||||
end
|
||||
end
|
||||
|
@ -78,21 +68,11 @@ RSpec.describe 'Tags' do
|
|||
context 'when the tag does not exist' do
|
||||
let(:name) { 'hoge' }
|
||||
|
||||
it 'returns http success' do
|
||||
it 'creates a new tag with the specified name', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'creates a new tag with the specified name' do
|
||||
subject
|
||||
|
||||
expect(Tag.where(name: name)).to exist
|
||||
end
|
||||
|
||||
it 'creates follow' do
|
||||
subject
|
||||
|
||||
expect(TagFollow.where(tag: Tag.find_by(name: name), account: user.account)).to exist
|
||||
end
|
||||
end
|
||||
|
@ -133,15 +113,10 @@ RSpec.describe 'Tags' do
|
|||
|
||||
it_behaves_like 'forbidden for wrong scope', 'read read:follows'
|
||||
|
||||
it 'returns http success' do
|
||||
it 'removes the follow', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
end
|
||||
|
||||
it 'removes the follow' do
|
||||
subject
|
||||
|
||||
expect(TagFollow.where(tag: tag, account: user.account)).to_not exist
|
||||
end
|
||||
|
||||
|
|
112
spec/requests/api/v1/timelines/tag_spec.rb
Normal file
112
spec/requests/api/v1/timelines/tag_spec.rb
Normal file
|
@ -0,0 +1,112 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe 'Tag' do
|
||||
let(:user) { Fabricate(:user) }
|
||||
let(:scopes) { 'read:statuses' }
|
||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||
|
||||
shared_examples 'a successful request to the tag timeline' do
|
||||
it 'returns the expected statuses', :aggregate_failures do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(200)
|
||||
expect(body_as_json.pluck(:id)).to match_array(expected_statuses.map { |status| status.id.to_s })
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v1/timelines/tag/:hashtag' do
|
||||
subject do
|
||||
get "/api/v1/timelines/tag/#{hashtag}", headers: headers, params: params
|
||||
end
|
||||
|
||||
let(:account) { Fabricate(:account) }
|
||||
let!(:private_status) { PostStatusService.new.call(account, visibility: :private, text: '#life could be a dream') } # rubocop:disable RSpec/LetSetup
|
||||
let!(:life_status) { PostStatusService.new.call(account, text: 'tell me what is my #life without your #love') }
|
||||
let!(:war_status) { PostStatusService.new.call(user.account, text: '#war, war never changes') }
|
||||
let!(:love_status) { PostStatusService.new.call(account, text: 'what is #love?') }
|
||||
let(:params) { {} }
|
||||
let(:hashtag) { 'life' }
|
||||
|
||||
context 'when given only one hashtag' do
|
||||
let(:expected_statuses) { [life_status] }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with any param' do
|
||||
let(:expected_statuses) { [life_status, love_status] }
|
||||
let(:params) { { any: %(love) } }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with all param' do
|
||||
let(:expected_statuses) { [life_status] }
|
||||
let(:params) { { all: %w(love) } }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with none param' do
|
||||
let(:expected_statuses) { [war_status] }
|
||||
let(:hashtag) { 'war' }
|
||||
let(:params) { { none: %w(life love) } }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
|
||||
context 'with limit param' do
|
||||
let(:hashtag) { 'love' }
|
||||
let(:params) { { limit: 1 } }
|
||||
|
||||
it 'returns only the requested number of statuses' do
|
||||
subject
|
||||
|
||||
expect(body_as_json.size).to eq(params[:limit])
|
||||
end
|
||||
|
||||
it 'sets the correct pagination headers', :aggregate_failures do
|
||||
subject
|
||||
|
||||
headers = response.headers['Link']
|
||||
|
||||
expect(headers.find_link(%w(rel prev)).href).to eq(api_v1_timelines_tag_url(limit: 1, min_id: love_status.id.to_s))
|
||||
expect(headers.find_link(%w(rel next)).href).to eq(api_v1_timelines_tag_url(limit: 1, max_id: love_status.id.to_s))
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the instance allows public preview' do
|
||||
context 'when the user is not authenticated' do
|
||||
let(:headers) { {} }
|
||||
let(:expected_statuses) { [life_status] }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the instance does not allow public preview' do
|
||||
before do
|
||||
Form::AdminSettings.new(timeline_preview: false).save
|
||||
end
|
||||
|
||||
context 'when the user is not authenticated' do
|
||||
let(:headers) { {} }
|
||||
|
||||
it 'returns http unauthorized' do
|
||||
subject
|
||||
|
||||
expect(response).to have_http_status(401)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is authenticated' do
|
||||
let(:expected_statuses) { [life_status] }
|
||||
|
||||
it_behaves_like 'a successful request to the tag timeline'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
spec/support/signed_request_helpers.rb
Normal file
21
spec/support/signed_request_helpers.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module SignedRequestHelpers
|
||||
def get(path, headers: nil, sign_with: nil, **args)
|
||||
return super path, headers: headers, **args if sign_with.nil?
|
||||
|
||||
headers ||= {}
|
||||
headers['Date'] = Time.now.utc.httpdate
|
||||
headers['Host'] = ENV.fetch('LOCAL_DOMAIN')
|
||||
signed_headers = headers.merge('(request-target)' => "get #{path}").slice('(request-target)', 'Host', 'Date')
|
||||
|
||||
key_id = ActivityPub::TagManager.instance.key_uri_for(sign_with)
|
||||
keypair = sign_with.keypair
|
||||
signed_string = signed_headers.map { |key, value| "#{key.downcase}: #{value}" }.join("\n")
|
||||
signature = Base64.strict_encode64(keypair.sign(OpenSSL::Digest.new('SHA256'), signed_string))
|
||||
|
||||
headers['Signature'] = "keyId=\"#{key_id}\",algorithm=\"rsa-sha256\",headers=\"#{signed_headers.keys.join(' ').downcase}\",signature=\"#{signature}\""
|
||||
|
||||
super path, headers: headers, **args
|
||||
end
|
||||
end
|
|
@ -67,39 +67,31 @@ describe MoveWorker do
|
|||
end
|
||||
|
||||
shared_examples 'block and mute handling' do
|
||||
it 'makes blocks carry over and add a note' do
|
||||
it 'makes blocks and mutes carry over and adds a note' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
|
||||
expect(block_service).to have_received(:call).with(blocking_account, target_account)
|
||||
expect(AccountNote.find_by(account: blocking_account, target_account: target_account).comment).to include(source_account.acct)
|
||||
end
|
||||
|
||||
it 'makes mutes carry over and add a note' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(muting_account.muting?(target_account)).to be true
|
||||
expect(AccountNote.find_by(account: muting_account, target_account: target_account).comment).to include(source_account.acct)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'followers count handling' do
|
||||
it 'updates the source account followers count' do
|
||||
it 'updates the source and target account followers counts' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(source_account.reload.followers_count).to eq(source_account.passive_relationships.count)
|
||||
end
|
||||
|
||||
it 'updates the target account followers count' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(source_account.reload.followers_count).to eq(source_account.passive_relationships.count)
|
||||
expect(target_account.reload.followers_count).to eq(target_account.passive_relationships.count)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'lists handling' do
|
||||
it 'puts the new account on the list' do
|
||||
it 'puts the new account on the list and makes valid lists', sidekiq: :inline do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(list.accounts.include?(target_account)).to be true
|
||||
end
|
||||
|
||||
it 'does not create invalid list memberships' do
|
||||
subject.perform(source_account.id, target_account.id)
|
||||
expect(list.accounts.include?(target_account)).to be true
|
||||
expect(ListAccount.all).to all be_valid
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue