about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThibG <thib@sitedethib.com>2018-12-19 16:19:00 +0100
committerGitHub <noreply@github.com>2018-12-19 16:19:00 +0100
commitaae088aaf0d5de542d917d11b7b2e86047645dd7 (patch)
treea4a58bba9c294d0c3ed0ea5c6c54e3bfa0507263
parent655da1be2029cecedcaf86479938d7805e72107d (diff)
parent222865584842de9c2bd3f47737e9ccf6aa8eac93 (diff)
Merge pull request #865 from ThibG/glitch-soc/merge-upstream
Merge upstream changes
-rw-r--r--app/javascript/flavours/glitch/styles/components/accounts.scss2
-rw-r--r--app/javascript/mastodon/features/public_timeline/index.js9
-rw-r--r--app/javascript/mastodon/features/ui/index.js2
-rw-r--r--app/javascript/mastodon/locales/defaultMessages.json110
-rw-r--r--app/javascript/mastodon/locales/en.json33
-rw-r--r--app/javascript/mastodon/locales/ja.json27
-rw-r--r--app/javascript/styles/mastodon/components.scss2
-rw-r--r--config/locales/en.yml2
-rw-r--r--config/locales/ja.yml13
-rw-r--r--config/locales/simple_form.ja.yml1
-rw-r--r--spec/policies/account_moderation_note_policy_spec.rb52
-rw-r--r--spec/policies/account_policy_spec.rb86
-rw-r--r--spec/policies/status_policy_spec.rb28
13 files changed, 345 insertions, 22 deletions
diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss
index 5f465259f..2b4ba8592 100644
--- a/app/javascript/flavours/glitch/styles/components/accounts.scss
+++ b/app/javascript/flavours/glitch/styles/components/accounts.scss
@@ -451,10 +451,12 @@
   border-bottom: 1px solid lighten($ui-base-color, 8%);
   cursor: default;
   display: flex;
+  flex-shrink: 0;
 
   button {
     background: darken($ui-base-color, 4%);
     border: 0;
+    margin: 0;
   }
 
   button,
diff --git a/app/javascript/mastodon/features/public_timeline/index.js b/app/javascript/mastodon/features/public_timeline/index.js
index 46d972251..d640033eb 100644
--- a/app/javascript/mastodon/features/public_timeline/index.js
+++ b/app/javascript/mastodon/features/public_timeline/index.js
@@ -100,13 +100,6 @@ class PublicTimeline extends React.PureComponent {
     dispatch(expandPublicTimeline({ maxId, onlyMedia }));
   }
 
-  handleSettingChanged = (key, checked) => {
-    const { columnId } = this.props;
-    if (!columnId && key[0] === 'other' && key[1] === 'onlyMedia') {
-      this.context.router.history.replace(`/timelines/public${checked ? '/media' : ''}`);
-    }
-  }
-
   render () {
     const { intl, shouldUpdateScroll, columnId, hasUnread, multiColumn, onlyMedia } = this.props;
     const pinned = !!columnId;
@@ -123,7 +116,7 @@ class PublicTimeline extends React.PureComponent {
           pinned={pinned}
           multiColumn={multiColumn}
         >
-          <ColumnSettingsContainer onChange={this.handleSettingChanged} columnId={columnId} />
+          <ColumnSettingsContainer columnId={columnId} />
         </ColumnHeader>
 
         <StatusListContainer
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index e11235a81..cc192fe10 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -150,9 +150,7 @@ class SwitchingColumnsArea extends React.PureComponent {
           <WrappedRoute path='/keyboard-shortcuts' component={KeyboardShortcuts} content={children} />
           <WrappedRoute path='/timelines/home' component={HomeTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
           <WrappedRoute path='/timelines/public' exact component={PublicTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
-          <WrappedRoute path='/timelines/public/media' component={PublicTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, onlyMedia: true }} />
           <WrappedRoute path='/timelines/public/local' exact component={CommunityTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
-          <WrappedRoute path='/timelines/public/local/media' component={CommunityTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll, onlyMedia: true }} />
           <WrappedRoute path='/timelines/direct' component={DirectTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
           <WrappedRoute path='/timelines/tag/:id' component={HashtagTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
           <WrappedRoute path='/timelines/list/:id' component={ListTimeline} content={children} componentParams={{ shouldUpdateScroll: this.shouldUpdateScroll }} />
diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json
index 1015aba1b..ebf43bf50 100644
--- a/app/javascript/mastodon/locales/defaultMessages.json
+++ b/app/javascript/mastodon/locales/defaultMessages.json
@@ -1372,6 +1372,79 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "First steps",
+        "id": "introduction.welcome.headline"
+      },
+      {
+        "defaultMessage": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
+        "id": "introduction.welcome.text"
+      },
+      {
+        "defaultMessage": "Let's go!",
+        "id": "introduction.welcome.action"
+      },
+      {
+        "defaultMessage": "Home",
+        "id": "introduction.federation.home.headline"
+      },
+      {
+        "defaultMessage": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+        "id": "introduction.federation.home.text"
+      },
+      {
+        "defaultMessage": "Local",
+        "id": "introduction.federation.local.headline"
+      },
+      {
+        "defaultMessage": "Public posts from people on the same server as you will appear in the local timeline.",
+        "id": "introduction.federation.local.text"
+      },
+      {
+        "defaultMessage": "Federated",
+        "id": "introduction.federation.federated.headline"
+      },
+      {
+        "defaultMessage": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+        "id": "introduction.federation.federated.text"
+      },
+      {
+        "defaultMessage": "Next",
+        "id": "introduction.federation.action"
+      },
+      {
+        "defaultMessage": "Reply",
+        "id": "introduction.interactions.reply.headline"
+      },
+      {
+        "defaultMessage": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+        "id": "introduction.interactions.reply.text"
+      },
+      {
+        "defaultMessage": "Boost",
+        "id": "introduction.interactions.reblog.headline"
+      },
+      {
+        "defaultMessage": "You can share other people's toots with your followers by boosting them.",
+        "id": "introduction.interactions.reblog.text"
+      },
+      {
+        "defaultMessage": "Favourite",
+        "id": "introduction.interactions.favourite.headline"
+      },
+      {
+        "defaultMessage": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+        "id": "introduction.interactions.favourite.text"
+      },
+      {
+        "defaultMessage": "Finish tutorial!",
+        "id": "introduction.interactions.action"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/introduction/index.json"
+  },
+  {
+    "descriptors": [
+      {
         "defaultMessage": "Keyboard Shortcuts",
         "id": "keyboard_shortcuts.heading"
       },
@@ -1613,6 +1686,14 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Show",
+        "id": "notifications.column_settings.filter_bar.show"
+      },
+      {
+        "defaultMessage": "Display all categories",
+        "id": "notifications.column_settings.filter_bar.advanced"
+      },
+      {
         "defaultMessage": "Desktop notifications",
         "id": "notifications.column_settings.alert"
       },
@@ -1629,6 +1710,10 @@
         "id": "notifications.column_settings.push"
       },
       {
+        "defaultMessage": "Quick filter bar",
+        "id": "notifications.column_settings.filter_bar.category"
+      },
+      {
         "defaultMessage": "New followers:",
         "id": "notifications.column_settings.follow"
       },
@@ -1650,6 +1735,31 @@
   {
     "descriptors": [
       {
+        "defaultMessage": "Mentions",
+        "id": "notifications.filter.mentions"
+      },
+      {
+        "defaultMessage": "Favourites",
+        "id": "notifications.filter.favourites"
+      },
+      {
+        "defaultMessage": "Boosts",
+        "id": "notifications.filter.boosts"
+      },
+      {
+        "defaultMessage": "Follows",
+        "id": "notifications.filter.follows"
+      },
+      {
+        "defaultMessage": "All",
+        "id": "notifications.filter.all"
+      }
+    ],
+    "path": "app/javascript/mastodon/features/notifications/components/filter_bar.json"
+  },
+  {
+    "descriptors": [
+      {
         "defaultMessage": "{name} followed you",
         "id": "notification.follow"
       },
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index d20ac1f88..e9b5fad0d 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -153,6 +153,23 @@
   "home.column_settings.basic": "Basic",
   "home.column_settings.show_reblogs": "Show boosts",
   "home.column_settings.show_replies": "Show replies",
+  "introduction.federation.action": "Next",
+  "introduction.federation.federated.headline": "Federated",
+  "introduction.federation.federated.text": "Public posts from other servers of the fediverse will appear in the federated timeline.",
+  "introduction.federation.home.headline": "Home",
+  "introduction.federation.home.text": "Posts from people you follow will appear in your home feed. You can follow anyone on any server!",
+  "introduction.federation.local.headline": "Local",
+  "introduction.federation.local.text": "Public posts from people on the same server as you will appear in the local timeline.",
+  "introduction.interactions.action": "Finish tutorial!",
+  "introduction.interactions.favourite.headline": "Favourite",
+  "introduction.interactions.favourite.text": "You can save a toot for later, and let the author know that you liked it, by favouriting it.",
+  "introduction.interactions.reblog.headline": "Boost",
+  "introduction.interactions.reblog.text": "You can share other people's toots with your followers by boosting them.",
+  "introduction.interactions.reply.headline": "Reply",
+  "introduction.interactions.reply.text": "You can reply to other people's and your own toots, which will chain them together in a conversation.",
+  "introduction.welcome.action": "Let's go!",
+  "introduction.welcome.headline": "First steps",
+  "introduction.welcome.text": "Welcome to the fediverse! In a few moments, you'll be able to broadcast messages and talk to your friends across a wide variety of servers. But this server, {domain}, is special—it hosts your profile, so remember its name.",
   "keyboard_shortcuts.back": "to navigate back",
   "keyboard_shortcuts.blocked": "to open blocked users list",
   "keyboard_shortcuts.boost": "to boost",
@@ -228,22 +245,22 @@
   "notification.reblog": "{name} boosted your status",
   "notifications.clear": "Clear notifications",
   "notifications.clear_confirmation": "Are you sure you want to permanently clear all your notifications?",
-  "notifications.filter.all": "All",
-  "notifications.filter.mentions": "Mentions",
-  "notifications.filter.favourites": "Favourites",
-  "notifications.filter.boosts": "Boosts",
-  "notifications.filter.follows": "Follows",
-  "notifications.column_settings.filter_bar.category": "Quick filter bar",
-  "notifications.column_settings.filter_bar.show": "Show",
-  "notifications.column_settings.filter_bar.advanced": "Display all categories",
   "notifications.column_settings.alert": "Desktop notifications",
   "notifications.column_settings.favourite": "Favourites:",
+  "notifications.column_settings.filter_bar.advanced": "Display all categories",
+  "notifications.column_settings.filter_bar.category": "Quick filter bar",
+  "notifications.column_settings.filter_bar.show": "Show",
   "notifications.column_settings.follow": "New followers:",
   "notifications.column_settings.mention": "Mentions:",
   "notifications.column_settings.push": "Push notifications",
   "notifications.column_settings.reblog": "Boosts:",
   "notifications.column_settings.show": "Show in column",
   "notifications.column_settings.sound": "Play sound",
+  "notifications.filter.all": "All",
+  "notifications.filter.boosts": "Boosts",
+  "notifications.filter.favourites": "Favourites",
+  "notifications.filter.follows": "Follows",
+  "notifications.filter.mentions": "Mentions",
   "notifications.group": "{count} notifications",
   "onboarding.done": "Done",
   "onboarding.next": "Next",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 4e8862201..a93ee68fd 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -17,7 +17,7 @@
   "account.follows_you": "フォローされています",
   "account.hide_reblogs": "@{name}さんからのブーストを非表示",
   "account.link_verified_on": "このリンクの所有権は{date}に確認されました",
-  "account.locked_info": "このアカウントは承認制に設定されています。フォローするには所有者の確認が必要です。",
+  "account.locked_info": "このアカウントは承認制アカウントです。相手が確認するまでフォローは完了しません。",
   "account.media": "メディア",
   "account.mention": "@{name}さんにトゥート",
   "account.moved_to": "{name}さんは引っ越しました:",
@@ -153,6 +153,23 @@
   "home.column_settings.basic": "基本設定",
   "home.column_settings.show_reblogs": "ブースト表示",
   "home.column_settings.show_replies": "返信表示",
+  "introduction.federation.action": "次へ",
+  "introduction.federation.federated.headline": "連合タイムライン",
+  "introduction.federation.federated.text": "Fediverseの他のサーバーからの公開投稿は連合タイムラインに表示されます。",
+  "introduction.federation.home.headline": "ホームタイムライン",
+  "introduction.federation.home.text": "フォローしている人々の投稿はホームタイムラインに表示されます。どこのサーバーの誰でもフォローできます!",
+  "introduction.federation.local.headline": "ローカルタイムライン",
+  "introduction.federation.local.text": "同じサーバーにいる人々の公開投稿はローカルタイムラインに表示されます。",
+  "introduction.interactions.action": "はじめよう!",
+  "introduction.interactions.favourite.headline": "お気に入り",
+  "introduction.interactions.favourite.text": "お気に入り登録することで後から見られるよう保存したり、「好き」を相手に伝えたりできます。",
+  "introduction.interactions.reblog.headline": "ブースト",
+  "introduction.interactions.reblog.text": "ブーストすることでフォロワーにそのトゥートを共有できます。",
+  "introduction.interactions.reply.headline": "返信",
+  "introduction.interactions.reply.text": "自身や人々のトゥートに返信することで、一連の会話に繋げることができます。",
+  "introduction.welcome.action": "はじめる!",
+  "introduction.welcome.headline": "はじめに",
+  "introduction.welcome.text": "Fediverseの世界へようこそ!あと少しでメッセージを配信したり、さまざまなサーバーを越えた友達と話せるようになります。ところでここ{domain}は特別なサーバーです…あなたのプロフィールを持つ主体のサーバーですので、名前を覚えておきましょう。",
   "keyboard_shortcuts.back": "戻る",
   "keyboard_shortcuts.blocked": "ブロックしたユーザーのリストを開く",
   "keyboard_shortcuts.boost": "ブースト",
@@ -230,12 +247,20 @@
   "notifications.clear_confirmation": "本当に通知を消去しますか?",
   "notifications.column_settings.alert": "デスクトップ通知",
   "notifications.column_settings.favourite": "お気に入り:",
+  "notifications.column_settings.filter_bar.advanced": "すべてのカテゴリを表示",
+  "notifications.column_settings.filter_bar.category": "クイックフィルターバー",
+  "notifications.column_settings.filter_bar.show": "表示",
   "notifications.column_settings.follow": "新しいフォロワー:",
   "notifications.column_settings.mention": "返信:",
   "notifications.column_settings.push": "プッシュ通知",
   "notifications.column_settings.reblog": "ブースト:",
   "notifications.column_settings.show": "カラムに表示",
   "notifications.column_settings.sound": "通知音を再生",
+  "notifications.filter.all": "すべて",
+  "notifications.filter.boosts": "ブースト",
+  "notifications.filter.favourites": "お気に入り",
+  "notifications.filter.follows": "フォロー",
+  "notifications.filter.mentions": "返信",
   "notifications.group": "{count} 件の通知",
   "onboarding.done": "完了",
   "onboarding.next": "次へ",
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index 61e330a26..eaf25e787 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -4806,10 +4806,12 @@ a.status-card.compact:hover {
   border-bottom: 1px solid lighten($ui-base-color, 8%);
   cursor: default;
   display: flex;
+  flex-shrink: 0;
 
   button {
     background: darken($ui-base-color, 4%);
     border: 0;
+    margin: 0;
   }
 
   button,
diff --git a/config/locales/en.yml b/config/locales/en.yml
index d6f071c78..735a88efd 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -104,6 +104,7 @@ en:
       followers: Followers
       followers_url: Followers URL
       follows: Follows
+      header: Header
       inbox_url: Inbox URL
       ip: IP
       location:
@@ -134,6 +135,7 @@ en:
       push_subscription_expires: PuSH subscription expires
       redownload: Refresh avatar
       remove_avatar: Remove avatar
+      remove_header: Remove header
       resend_confirmation:
         already_confirmed: This user is already confirmed
         send: Resend confirmation email
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 21e4236a8..5879755e9 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -104,6 +104,7 @@ ja:
       followers: フォロワー数
       followers_url: Followers URL
       follows: フォロー数
+      header: ヘッダー
       inbox_url: Inbox URL
       ip: IP
       location:
@@ -115,10 +116,10 @@ ja:
       media_attachments: 添付されたメディア
       memorialize: 追悼アカウント化
       moderation:
-        active: 有効
+        active: アクティブ
         all: すべて
-        silenced: サイレンス中
-        suspended: 停止中
+        silenced: サイレンス済み
+        suspended: 停止済み
         title: モデレーション
       moderation_notes: モデレーションメモ
       most_recent_activity: 直近の活動
@@ -134,6 +135,7 @@ ja:
       push_subscription_expires: PuSH購読期限
       redownload: アバターの更新
       remove_avatar: アイコンを削除
+      remove_header: ヘッダーを削除
       resend_confirmation:
         already_confirmed: メールアドレスは確認済みです
         send: 確認メールを再送
@@ -229,6 +231,7 @@ ja:
       config: 構成
       feature_deletions: アカウント削除
       feature_invites: 招待リンク
+      feature_profile_directory: ディレクトリ
       feature_registrations: 新規登録
       feature_relay: 連合リレー
       features: 機能
@@ -376,6 +379,9 @@ ja:
       preview_sensitive_media:
         desc_html: 他のウェブサイトにリンクを貼った際、メディアが閲覧注意としてマークされていてもサムネイルが表示されます
         title: OpenGraphによるプレビューで閲覧注意のメディアも表示する
+      profile_directory:
+        desc_html: ユーザーが見つかりやすくできるようになります
+        title: ディレクトリを有効にする
       registrations:
         closed_message:
           desc_html: 新規登録を停止しているときにフロントページに表示されます。HTMLタグが使えます
@@ -529,6 +535,7 @@ ja:
     warning_title: 共有されたコンテンツについて
   directories:
     directory: ディレクトリ
+    explanation: 興味のある人を見つけよう
     explore_mastodon: "%{title}を探索"
     people:
       one: "%{count} 人"
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index 07ae66c79..b64974ffd 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -19,6 +19,7 @@ ja:
         password: 少なくとも8文字は入力してください
         phrase: トゥートの大文字小文字や閲覧注意に関係なく一致
         scopes: アプリの API に許可するアクセス権を選択してください。最上位のスコープを選択する場合、個々のスコープを選択する必要はありません。
+        setting_aggregate_reblogs: 最近ブーストされたトゥートが新たにブーストされても表示しません (設定後受信したものにのみ影響)
         setting_default_language: トゥートの言語は自動的に検出されますが、必ずしも正確とは限りません
         setting_display_media_default: 閲覧注意としてマークされたメディアは隠す
         setting_display_media_hide_all: 全てのメディアを常に隠す
diff --git a/spec/policies/account_moderation_note_policy_spec.rb b/spec/policies/account_moderation_note_policy_spec.rb
new file mode 100644
index 000000000..bb7af94e4
--- /dev/null
+++ b/spec/policies/account_moderation_note_policy_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe AccountModerationNotePolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :create? do
+    context 'staff' do
+      it 'grants to create' do
+        expect(subject).to permit(admin, AccountModerationNotePolicy)
+      end
+    end
+
+    context 'not staff' do
+      it 'denies to create' do
+        expect(subject).to_not permit(john, AccountModerationNotePolicy)
+      end
+    end
+  end
+
+  permissions :destroy? do
+    let(:account_moderation_note) do
+      Fabricate(:account_moderation_note,
+                account: john,
+                target_account: Fabricate(:account))
+    end
+
+    context 'admin' do
+      it 'grants to destroy' do
+        expect(subject).to permit(admin, AccountModerationNotePolicy)
+      end
+    end
+
+    context 'owner' do
+      it 'grants to destroy' do
+        expect(subject).to permit(john, account_moderation_note)
+      end
+    end
+
+    context 'neither admin nor owner' do
+      let(:kevin) { Fabricate(:user).account }
+
+      it 'denies to destroy' do
+        expect(subject).to_not permit(kevin, account_moderation_note)
+      end
+    end
+  end
+end
diff --git a/spec/policies/account_policy_spec.rb b/spec/policies/account_policy_spec.rb
new file mode 100644
index 000000000..6648b0888
--- /dev/null
+++ b/spec/policies/account_policy_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+require 'pundit/rspec'
+
+RSpec.describe AccountPolicy do
+  let(:subject) { described_class }
+  let(:admin)   { Fabricate(:user, admin: true).account }
+  let(:john)    { Fabricate(:user).account }
+
+  permissions :index?, :show?, :unsuspend?, :unsilence?, :remove_avatar?, :remove_header? do
+    context 'staff' do
+      it 'permits' do
+        expect(subject).to permit(admin)
+      end
+    end
+
+    context 'not staff' do
+      it 'denies' do
+        expect(subject).to_not permit(john)
+      end
+    end
+  end
+
+  permissions :redownload?, :subscribe?, :unsubscribe? do
+    context 'admin' do
+      it 'permits' do
+        expect(subject).to permit(admin)
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john)
+      end
+    end
+  end
+
+  permissions :suspend?, :silence? do
+    let(:staff) { Fabricate(:user, admin: true).account }
+
+    context 'staff' do
+      context 'record is staff' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, staff)
+        end
+      end
+
+      context 'record is not staff' do
+        it 'permits' do
+          expect(subject).to permit(admin, john)
+        end
+      end
+    end
+
+    context 'not staff' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Account)
+      end
+    end
+  end
+
+  permissions :memorialize? do
+    let(:other_admin) { Fabricate(:user, admin: true).account }
+
+    context 'admin' do
+      context 'record is admin' do
+        it 'denies' do
+          expect(subject).to_not permit(admin, other_admin)
+        end
+      end
+
+      context 'record is not admin' do
+        it 'permits' do
+          expect(subject).to permit(admin, john)
+        end
+      end
+    end
+
+    context 'not admin' do
+      it 'denies' do
+        expect(subject).to_not permit(john, Account)
+      end
+    end
+  end
+end
diff --git a/spec/policies/status_policy_spec.rb b/spec/policies/status_policy_spec.rb
index 837fa9cee..8bce29cad 100644
--- a/spec/policies/status_policy_spec.rb
+++ b/spec/policies/status_policy_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'rails_helper'
 require 'pundit/rspec'
 
@@ -118,4 +120,30 @@ RSpec.describe StatusPolicy, type: :model do
       expect(subject).to_not permit(nil, status)
     end
   end
+
+  permissions :favourite? do
+    it 'grants access when viewer is not blocked' do
+      follow         = Fabricate(:follow)
+      status.account = follow.target_account
+
+      expect(subject).to permit(follow.account, status)
+    end
+
+    it 'denies when viewer is blocked' do
+      block          = Fabricate(:block)
+      status.account = block.target_account
+
+      expect(subject).to_not permit(block.account, status)
+    end
+  end
+
+  permissions :index?, :update? do
+    it 'grants access if staff' do
+      expect(subject).to permit(admin.account)
+    end
+
+    it 'denies access unless staff' do
+      expect(subject).to_not permit(alice)
+    end
+  end
 end