about summary refs log tree commit diff
path: root/spec/policies/status_policy_spec.rb
blob: 38b9c4fdb6197a4c11cbd8f78b01f1069ab18637 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# frozen_string_literal: true

require 'rails_helper'
require 'pundit/rspec'

RSpec.describe StatusPolicy, type: :model do
  subject { described_class }

  let(:admin) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) }
  let(:alice) { Fabricate(:account, username: 'alice') }
  let(:bob) { Fabricate(:account, username: 'bob') }
  let(:status) { Fabricate(:status, account: alice) }

  permissions :show?, :reblog? do
    it 'grants access when no viewer' do
      expect(subject).to permit(nil, status)
    end

    it 'denies access when viewer is blocked' do
      block = Fabricate(:block)
      status.visibility = :private
      status.account = block.target_account

      expect(subject).to_not permit(block.account, status)
    end
  end

  permissions :show? do
    it 'grants access when direct and account is viewer' do
      status.visibility = :direct

      expect(subject).to permit(status.account, status)
    end

    it 'grants access when direct and viewer is mentioned' do
      status.visibility = :direct
      status.mentions = [Fabricate(:mention, account: alice)]

      expect(subject).to permit(alice, status)
    end

    it 'grants access when direct and non-owner viewer is mentioned and mentions are loaded' do
      status.visibility = :direct
      status.mentions = [Fabricate(:mention, account: bob)]
      status.mentions.load

      expect(subject).to permit(bob, status)
    end

    it 'denies access when direct and viewer is not mentioned' do
      viewer = Fabricate(:account)
      status.visibility = :direct

      expect(subject).to_not permit(viewer, status)
    end

    it 'grants access when private and account is viewer' do
      status.visibility = :private

      expect(subject).to permit(status.account, status)
    end

    it 'grants access when private and account is following viewer' do
      follow = Fabricate(:follow)
      status.visibility = :private
      status.account = follow.target_account

      expect(subject).to permit(follow.account, status)
    end

    it 'grants access when private and viewer is mentioned' do
      status.visibility = :private
      status.mentions = [Fabricate(:mention, account: alice)]

      expect(subject).to permit(alice, status)
    end

    it 'denies access when private and viewer is not mentioned or followed' do
      viewer = Fabricate(:account)
      status.visibility = :private

      expect(subject).to_not permit(viewer, status)
    end

    it 'denies access when local-only and the viewer is not logged in' do
      allow(status).to receive(:local_only?).and_return(true)

      expect(subject).to_not permit(nil, status)
    end

    it 'denies access when local-only and the viewer is from another domain' do
      viewer = Fabricate(:account, domain: 'remote-domain')
      allow(status).to receive(:local_only?).and_return(true)
      expect(subject).to_not permit(viewer, status)
    end
  end

  permissions :reblog? do
    it 'denies access when private' do
      viewer = Fabricate(:account)
      status.visibility = :private

      expect(subject).to_not permit(viewer, status)
    end

    it 'denies access when direct' do
      viewer = Fabricate(:account)
      status.visibility = :direct

      expect(subject).to_not permit(viewer, status)
    end
  end

  permissions :destroy?, :unreblog? do
    it 'grants access when account is deleter' do
      expect(subject).to permit(status.account, status)
    end

    it 'denies access when account is not deleter' do
      expect(subject).to_not permit(bob, status)
    end

    it 'denies access when no deleter' 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 :update? do
    it 'grants access if owner' do
      expect(subject).to permit(status.account, status)
    end
  end
end