Add ability to view previous edits of a status in admin UI (#19462)
* Add ability to view previous edits of a status in admin UI * Change moderator access to posts to be controlled by a separate policyshrike
parent
dee69be60e
commit
f8ca3bb2a1
|
@ -3,18 +3,23 @@
|
||||||
module Admin
|
module Admin
|
||||||
class StatusesController < BaseController
|
class StatusesController < BaseController
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
before_action :set_statuses
|
before_action :set_statuses, except: :show
|
||||||
|
before_action :set_status, only: :show
|
||||||
|
|
||||||
PER_PAGE = 20
|
PER_PAGE = 20
|
||||||
|
|
||||||
def index
|
def index
|
||||||
authorize :status, :index?
|
authorize [:admin, :status], :index?
|
||||||
|
|
||||||
@status_batch_action = Admin::StatusBatchAction.new
|
@status_batch_action = Admin::StatusBatchAction.new
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
authorize [:admin, @status], :show?
|
||||||
|
end
|
||||||
|
|
||||||
def batch
|
def batch
|
||||||
authorize :status, :index?
|
authorize [:admin, :status], :index?
|
||||||
|
|
||||||
@status_batch_action = Admin::StatusBatchAction.new(admin_status_batch_action_params.merge(current_account: current_account, report_id: params[:report_id], type: action_from_button))
|
@status_batch_action = Admin::StatusBatchAction.new(admin_status_batch_action_params.merge(current_account: current_account, report_id: params[:report_id], type: action_from_button))
|
||||||
@status_batch_action.save!
|
@status_batch_action.save!
|
||||||
|
@ -32,6 +37,7 @@ module Admin
|
||||||
|
|
||||||
def after_create_redirect_path
|
def after_create_redirect_path
|
||||||
report_id = @status_batch_action&.report_id || params[:report_id]
|
report_id = @status_batch_action&.report_id || params[:report_id]
|
||||||
|
|
||||||
if report_id.present?
|
if report_id.present?
|
||||||
admin_report_path(report_id)
|
admin_report_path(report_id)
|
||||||
else
|
else
|
||||||
|
@ -43,6 +49,10 @@ module Admin
|
||||||
@account = Account.find(params[:account_id])
|
@account = Account.find(params[:account_id])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_status
|
||||||
|
@status = @account.statuses.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
def set_statuses
|
def set_statuses
|
||||||
@statuses = Admin::StatusFilter.new(@account, filter_params).results.preload(:application, :preloadable_poll, :media_attachments, active_mentions: :account, reblog: [:account, :application, :preloadable_poll, :media_attachments, active_mentions: :account]).page(params[:page]).per(PER_PAGE)
|
@statuses = Admin::StatusFilter.new(@account, filter_params).results.preload(:application, :preloadable_poll, :media_attachments, active_mentions: :account, reblog: [:account, :application, :preloadable_poll, :media_attachments, active_mentions: :account]).page(params[:page]).per(PER_PAGE)
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
class Admin::Trends::StatusesController < Admin::BaseController
|
class Admin::Trends::StatusesController < Admin::BaseController
|
||||||
def index
|
def index
|
||||||
authorize :status, :review?
|
authorize [:admin, :status], :review?
|
||||||
|
|
||||||
@locales = StatusTrend.pluck('distinct language')
|
@locales = StatusTrend.pluck('distinct language')
|
||||||
@statuses = filtered_statuses.page(params[:page])
|
@statuses = filtered_statuses.page(params[:page])
|
||||||
|
@ -10,7 +10,7 @@ class Admin::Trends::StatusesController < Admin::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def batch
|
def batch
|
||||||
authorize :status, :review?
|
authorize [:admin, :status], :review?
|
||||||
|
|
||||||
@form = Trends::StatusBatch.new(trends_status_batch_params.merge(current_account: current_account, action: action_from_button))
|
@form = Trends::StatusBatch.new(trends_status_batch_params.merge(current_account: current_account, action: action_from_button))
|
||||||
@form.save
|
@form.save
|
||||||
|
|
|
@ -323,7 +323,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
if ((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
|
if ((this.context.identity.permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||||
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses?id=${status.get('id')}` });
|
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -254,7 +254,7 @@ class ActionBar extends React.PureComponent {
|
||||||
if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
|
if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||||
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses?id=${status.get('id')}` });
|
menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1752,3 +1752,67 @@ a.sparkline {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history {
|
||||||
|
counter-reset: step 0;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
counter-increment: step 1;
|
||||||
|
padding-left: 2.5rem;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
position: relative;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
content: counter(step);
|
||||||
|
font-size: 0.625rem;
|
||||||
|
font-weight: 500;
|
||||||
|
left: 0;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: calc(1.375rem + 1px);
|
||||||
|
height: calc(1.375rem + 1px);
|
||||||
|
background: $ui-base-color;
|
||||||
|
border: 1px solid $highlight-text-color;
|
||||||
|
color: $highlight-text-color;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
width: 1px;
|
||||||
|
background: $highlight-text-color;
|
||||||
|
bottom: 0;
|
||||||
|
top: calc(1.875rem + 1px);
|
||||||
|
left: 0.6875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__entry {
|
||||||
|
h5 {
|
||||||
|
font-weight: 500;
|
||||||
|
color: $primary-text-color;
|
||||||
|
line-height: 25px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
border: 1px solid lighten($ui-base-color, 4%);
|
||||||
|
background: $ui-base-color;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
class Admin::StatusFilter
|
class Admin::StatusFilter
|
||||||
KEYS = %i(
|
KEYS = %i(
|
||||||
media
|
media
|
||||||
id
|
|
||||||
report_id
|
report_id
|
||||||
).freeze
|
).freeze
|
||||||
|
|
||||||
|
@ -28,12 +27,10 @@ class Admin::StatusFilter
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def scope_for(key, value)
|
def scope_for(key, _value)
|
||||||
case key.to_s
|
case key.to_s
|
||||||
when 'media'
|
when 'media'
|
||||||
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id).reorder('statuses.id desc')
|
Status.joins(:media_attachments).merge(@account.media_attachments.reorder(nil)).group(:id).reorder('statuses.id desc')
|
||||||
when 'id'
|
|
||||||
Status.where(id: value)
|
|
||||||
else
|
else
|
||||||
raise "Unknown filter: #{key}"
|
raise "Unknown filter: #{key}"
|
||||||
end
|
end
|
||||||
|
|
|
@ -30,7 +30,7 @@ class StatusEdit < ApplicationRecord
|
||||||
:preview_remote_url, :text_url, :meta, :blurhash,
|
:preview_remote_url, :text_url, :meta, :blurhash,
|
||||||
:not_processed?, :needs_redownload?, :local?,
|
:not_processed?, :needs_redownload?, :local?,
|
||||||
:file, :thumbnail, :thumbnail_remote_url,
|
:file, :thumbnail, :thumbnail_remote_url,
|
||||||
:shortcode, to: :media_attachment
|
:shortcode, :video?, :audio?, to: :media_attachment
|
||||||
end
|
end
|
||||||
|
|
||||||
rate_limit by: :account, family: :statuses
|
rate_limit by: :account, family: :statuses
|
||||||
|
@ -40,7 +40,8 @@ class StatusEdit < ApplicationRecord
|
||||||
|
|
||||||
default_scope { order(id: :asc) }
|
default_scope { order(id: :asc) }
|
||||||
|
|
||||||
delegate :local?, to: :status
|
delegate :local?, :application, :edited?, :edited_at,
|
||||||
|
:discarded?, :visibility, to: :status
|
||||||
|
|
||||||
def emojis
|
def emojis
|
||||||
return @emojis if defined?(@emojis)
|
return @emojis if defined?(@emojis)
|
||||||
|
@ -59,4 +60,12 @@ class StatusEdit < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def proper
|
||||||
|
self
|
||||||
|
end
|
||||||
|
|
||||||
|
def reblog?
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Admin::StatusPolicy < ApplicationPolicy
|
||||||
|
def initialize(current_account, record, preloaded_relations = {})
|
||||||
|
super(current_account, record)
|
||||||
|
|
||||||
|
@preloaded_relations = preloaded_relations
|
||||||
|
end
|
||||||
|
|
||||||
|
def index?
|
||||||
|
role.can?(:manage_reports, :manage_users)
|
||||||
|
end
|
||||||
|
|
||||||
|
def show?
|
||||||
|
role.can?(:manage_reports, :manage_users) && (record.public_visibility? || record.unlisted_visibility? || record.reported?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy?
|
||||||
|
role.can?(:manage_reports)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update?
|
||||||
|
role.can?(:manage_reports)
|
||||||
|
end
|
||||||
|
|
||||||
|
def review?
|
||||||
|
role.can?(:manage_taxonomies)
|
||||||
|
end
|
||||||
|
end
|
|
@ -7,10 +7,6 @@ class StatusPolicy < ApplicationPolicy
|
||||||
@preloaded_relations = preloaded_relations
|
@preloaded_relations = preloaded_relations
|
||||||
end
|
end
|
||||||
|
|
||||||
def index?
|
|
||||||
role.can?(:manage_reports, :manage_users)
|
|
||||||
end
|
|
||||||
|
|
||||||
def show?
|
def show?
|
||||||
return false if author.suspended?
|
return false if author.suspended?
|
||||||
|
|
||||||
|
@ -32,17 +28,13 @@ class StatusPolicy < ApplicationPolicy
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy?
|
def destroy?
|
||||||
role.can?(:manage_reports) || owned?
|
owned?
|
||||||
end
|
end
|
||||||
|
|
||||||
alias unreblog? destroy?
|
alias unreblog? destroy?
|
||||||
|
|
||||||
def update?
|
def update?
|
||||||
role.can?(:manage_reports) || owned?
|
owned?
|
||||||
end
|
|
||||||
|
|
||||||
def review?
|
|
||||||
role.can?(:manage_taxonomies)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
- if status.ordered_media_attachments.first.video?
|
||||||
|
- video = status.ordered_media_attachments.first
|
||||||
|
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), frameRate: video.file.meta.dig('original', 'frame_rate'), blurhash: video.blurhash, sensitive: status.sensitive?, visible: false, width: 610, height: 343, inline: true, alt: video.description, media: [ActiveModelSerializers::SerializableResource.new(video, serializer: REST::MediaAttachmentSerializer)].as_json
|
||||||
|
- elsif status.ordered_media_attachments.first.audio?
|
||||||
|
- audio = status.ordered_media_attachments.first
|
||||||
|
= react_component :audio, src: audio.file.url(:original), height: 110, alt: audio.description, duration: audio.file.meta.dig(:original, :duration)
|
||||||
|
- else
|
||||||
|
= react_component :media_gallery, height: 343, sensitive: status.sensitive?, visible: false, media: status.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
|
|
@ -12,14 +12,7 @@
|
||||||
= prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis)
|
= prerender_custom_emojis(status_content_format(status.proper), status.proper.emojis)
|
||||||
|
|
||||||
- unless status.proper.ordered_media_attachments.empty?
|
- unless status.proper.ordered_media_attachments.empty?
|
||||||
- if status.proper.ordered_media_attachments.first.video?
|
= render partial: 'admin/reports/media_attachments', locals: { status: status.proper }
|
||||||
- video = status.proper.ordered_media_attachments.first
|
|
||||||
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), frameRate: video.file.meta.dig('original', 'frame_rate'), blurhash: video.blurhash, sensitive: status.proper.sensitive?, visible: false, width: 610, height: 343, inline: true, alt: video.description, media: [ActiveModelSerializers::SerializableResource.new(video, serializer: REST::MediaAttachmentSerializer)].as_json
|
|
||||||
- elsif status.proper.ordered_media_attachments.first.audio?
|
|
||||||
- audio = status.proper.ordered_media_attachments.first
|
|
||||||
= react_component :audio, src: audio.file.url(:original), height: 110, alt: audio.description, duration: audio.file.meta.dig(:original, :duration)
|
|
||||||
- else
|
|
||||||
= react_component :media_gallery, height: 343, sensitive: status.proper.sensitive?, visible: false, media: status.proper.ordered_media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }
|
|
||||||
|
|
||||||
.detailed-status__meta
|
.detailed-status__meta
|
||||||
- if status.application
|
- if status.application
|
||||||
|
@ -29,7 +22,7 @@
|
||||||
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
|
%time.formatted{ datetime: status.created_at.iso8601, title: l(status.created_at) }= l(status.created_at)
|
||||||
- if status.edited?
|
- if status.edited?
|
||||||
·
|
·
|
||||||
= t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted'))
|
= link_to t('statuses.edited_at_html', date: content_tag(:time, l(status.edited_at), datetime: status.edited_at.iso8601, title: l(status.edited_at), class: 'formatted')), admin_account_status_path(status.account_id, status), class: 'detailed-status__datetime'
|
||||||
- if status.discarded?
|
- if status.discarded?
|
||||||
·
|
·
|
||||||
%span.negative-hint= t('admin.statuses.deleted')
|
%span.negative-hint= t('admin.statuses.deleted')
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
.status
|
||||||
|
.status__content><
|
||||||
|
- if status_edit.spoiler_text.blank?
|
||||||
|
= prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis)
|
||||||
|
- else
|
||||||
|
%details<
|
||||||
|
%summary><
|
||||||
|
%strong> Content warning: #{prerender_custom_emojis(h(status_edit.spoiler_text), status_edit.emojis)}
|
||||||
|
= prerender_custom_emojis(status_content_format(status_edit), status_edit.emojis)
|
||||||
|
|
||||||
|
- unless status_edit.ordered_media_attachments.empty?
|
||||||
|
= render partial: 'admin/reports/media_attachments', locals: { status: status_edit }
|
||||||
|
|
||||||
|
.detailed-status__meta
|
||||||
|
%time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at)
|
||||||
|
|
||||||
|
- if status_edit.sensitive?
|
||||||
|
·
|
||||||
|
= fa_icon('eye-slash fw')
|
||||||
|
= t('stream_entries.sensitive_content')
|
|
@ -0,0 +1,64 @@
|
||||||
|
- content_for :header_tags do
|
||||||
|
= javascript_pack_tag 'admin', async: true, crossorigin: 'anonymous'
|
||||||
|
|
||||||
|
- content_for :page_title do
|
||||||
|
= t('statuses.title', name: display_name(@account), quote: truncate(@status.spoiler_text.presence || @status.text, length: 50, omission: '…', escape: false))
|
||||||
|
|
||||||
|
- content_for :heading_actions do
|
||||||
|
= link_to t('admin.statuses.open'), ActivityPub::TagManager.instance.url_for(@status), class: 'button', target: '_blank'
|
||||||
|
|
||||||
|
%h3= t('admin.statuses.metadata')
|
||||||
|
|
||||||
|
.table-wrapper
|
||||||
|
%table.table.horizontal-table
|
||||||
|
%tbody
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.account')
|
||||||
|
%td= admin_account_link_to @status.account
|
||||||
|
- if @status.reply?
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.in_reply_to')
|
||||||
|
%td= admin_account_link_to @status.in_reply_to_account, path: admin_account_status_path(@status.thread.account_id, @status.in_reply_to_id)
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.application')
|
||||||
|
%td= @status.application&.name
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.language')
|
||||||
|
%td= standard_locale_name(@status.language)
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.visibility')
|
||||||
|
%td= t("statuses.visibilities.#{@status.visibility}")
|
||||||
|
- if @status.trend
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.trending')
|
||||||
|
%td
|
||||||
|
- if @status.trend.allowed?
|
||||||
|
%abbr{ title: t('admin.trends.tags.current_score', score: @status.trend.score) }= t('admin.trends.tags.trending_rank', rank: @status.trend.rank)
|
||||||
|
- elsif @status.trend.requires_review?
|
||||||
|
= t('admin.trends.pending_review')
|
||||||
|
- else
|
||||||
|
= t('admin.trends.not_allowed_to_trend')
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.reblogs')
|
||||||
|
%td= friendly_number_to_human @status.reblogs_count
|
||||||
|
%tr
|
||||||
|
%th= t('admin.statuses.favourites')
|
||||||
|
%td= friendly_number_to_human @status.favourites_count
|
||||||
|
|
||||||
|
%hr.spacer/
|
||||||
|
|
||||||
|
%h3= t('admin.statuses.history')
|
||||||
|
|
||||||
|
%ol.history
|
||||||
|
- @status.edits.includes(:account, status: [:account]).each.with_index do |status_edit, i|
|
||||||
|
%li
|
||||||
|
.history__entry
|
||||||
|
%h5
|
||||||
|
- if i.zero?
|
||||||
|
= t('admin.statuses.original_status')
|
||||||
|
- else
|
||||||
|
= t('admin.statuses.status_changed')
|
||||||
|
·
|
||||||
|
%time.formatted{ datetime: status_edit.created_at.iso8601, title: l(status_edit.created_at) }= l(status_edit.created_at)
|
||||||
|
|
||||||
|
= render status_edit
|
|
@ -705,16 +705,29 @@ en:
|
||||||
delete: Delete uploaded file
|
delete: Delete uploaded file
|
||||||
destroyed_msg: Site upload successfully deleted!
|
destroyed_msg: Site upload successfully deleted!
|
||||||
statuses:
|
statuses:
|
||||||
|
account: Author
|
||||||
|
application: Application
|
||||||
back_to_account: Back to account page
|
back_to_account: Back to account page
|
||||||
back_to_report: Back to report page
|
back_to_report: Back to report page
|
||||||
batch:
|
batch:
|
||||||
remove_from_report: Remove from report
|
remove_from_report: Remove from report
|
||||||
report: Report
|
report: Report
|
||||||
deleted: Deleted
|
deleted: Deleted
|
||||||
|
favourites: Favourites
|
||||||
|
history: Version history
|
||||||
|
in_reply_to: Replying to
|
||||||
|
language: Language
|
||||||
media:
|
media:
|
||||||
title: Media
|
title: Media
|
||||||
|
metadata: Metadata
|
||||||
no_status_selected: No posts were changed as none were selected
|
no_status_selected: No posts were changed as none were selected
|
||||||
|
open: Open post
|
||||||
|
original_status: Original post
|
||||||
|
reblogs: Reblogs
|
||||||
|
status_changed: Post changed
|
||||||
title: Account posts
|
title: Account posts
|
||||||
|
trending: Trending
|
||||||
|
visibility: Visibility
|
||||||
with_media: With media
|
with_media: With media
|
||||||
strikes:
|
strikes:
|
||||||
actions:
|
actions:
|
||||||
|
|
|
@ -325,7 +325,7 @@ Rails.application.routes.draw do
|
||||||
resource :reset, only: [:create]
|
resource :reset, only: [:create]
|
||||||
resource :action, only: [:new, :create], controller: 'account_actions'
|
resource :action, only: [:new, :create], controller: 'account_actions'
|
||||||
|
|
||||||
resources :statuses, only: [:index] do
|
resources :statuses, only: [:index, :show] do
|
||||||
collection do
|
collection do
|
||||||
post :batch
|
post :batch
|
||||||
end
|
end
|
||||||
|
|
|
@ -96,10 +96,6 @@ RSpec.describe StatusPolicy, type: :model do
|
||||||
expect(subject).to permit(status.account, status)
|
expect(subject).to permit(status.account, status)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'grants access when account is admin' do
|
|
||||||
expect(subject).to permit(admin.account, status)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'denies access when account is not deleter' do
|
it 'denies access when account is not deleter' do
|
||||||
expect(subject).to_not permit(bob, status)
|
expect(subject).to_not permit(bob, status)
|
||||||
end
|
end
|
||||||
|
@ -125,27 +121,9 @@ RSpec.describe StatusPolicy, type: :model do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
permissions :index? 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
|
|
||||||
|
|
||||||
permissions :update? do
|
permissions :update? do
|
||||||
it 'grants access if staff' do
|
|
||||||
expect(subject).to permit(admin.account, status)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'grants access if owner' do
|
it 'grants access if owner' do
|
||||||
expect(subject).to permit(status.account, status)
|
expect(subject).to permit(status.account, status)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'denies access unless staff' do
|
|
||||||
expect(subject).to_not permit(bob, status)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue