Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions spec/dummy/app/resources/comment_resource.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
class CommentResource < JSONAPI::Resource
include JSONAPI::Authorization::PunditScopedResource

has_one :article
end
1 change: 1 addition & 0 deletions spec/dummy/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
jsonapi_resources :articles do
jsonapi_relationships
end
jsonapi_resources :comments
end
83 changes: 42 additions & 41 deletions spec/requests/tricky_operations_spec.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
require 'spec_helper'

RSpec.describe 'Tricky operations', type: :request do
include PunditStubs
include AuthorizationStubs
fixtures :all

let(:article) { Article.all.sample }
Expand All @@ -18,18 +18,8 @@
header 'Content-Type', 'application/vnd.api+json'
end

describe 'GET /articles/:id?includes=comments' do
subject(:last_response) { get("/articles/#{article.id}?includes=comments") }
let(:policy_scope) { Article.all }

context 'authorized for show? on article' do
before { allow_action('show?', article) }

xit 'displays only comments allowed by CommentPolicy::Scope'
end
end

describe 'POST /comments (with relationships link to articles)', pending: true do
describe 'POST /comments (with relationships link to articles)' do
subject(:last_response) { post("/comments", json) }
let(:json) do
<<-EOS.strip_heredoc
{
Expand All @@ -38,7 +28,7 @@
"relationships": {
"article": {
"data": {
"id": "1",
"id": "#{article.id}",
"type": "articles"
}
}
Expand All @@ -48,58 +38,69 @@
EOS
end

context 'unauthorized for update? on article' do
before { allow_action('update?', article) }
context 'authorized for create_resource on Comment and [article]' do
let(:policy_scope) { Article.where(id: article.id) }
before { allow_operation('create_resource', Comment, [article]) }

xcontext 'authorized for create? on comment' do
# This is a tricky one. In real life, this is often something you may
# want to permit. However, it is difficult to model with the typical
# Pundit actions without knowing the particular use case
it { is_expected.to be_successful }
end

it { is_expected.to be_forbidden }
end
context 'unauthorized for create_resource on Comment and [article]' do
let(:policy_scope) { Article.where(id: article.id) }
before { disallow_operation('create_resource', Comment, [article]) }

it { is_expected.to be_forbidden }
end
end

describe 'PATCH /articles/:id (mass-modifying relationships)', pending: true do
let(:existing) do
Article.new(comments: Comment.where(id: 3))
describe 'PATCH /articles/:id (mass-modifying relationships)' do
let!(:new_comments) do
Array.new(2) { Comment.create }
end
let(:policy_scope) { Article.where(id: article.id) }
let(:comments_policy_scope) { Comment.all }
before do
allow_any_instance_of(CommentPolicy::Scope).to receive(:resolve).and_return(comments_policy_scope)
end

let(:json) do
<<-EOS.strip_heredoc
{
"data": {
"id": "<<TODO>>"
"id": "#{article.id}",
"type": "articles",
"relationships": {
"comments": {
"data": [
{ "type": "comments", "id": "1" },
{ "type": "comments", "id": "2" }
{ "type": "comments", "id": "#{new_comments.first.id}" },
{ "type": "comments", "id": "#{new_comments.second.id}" }
]
}
}
}
}
EOS
end
subject(:last_response) { patch("/articles/#{article.id}", json) }

context 'authorized for update? on article' do
before { allow_action('update?', article) }

xcontext 'unauthorized for update? on comment 3' do
it { is_expected.to be_forbidden }
end
xcontext 'unauthorized for update? on comment 2' do
it { is_expected.to be_forbidden }
end
xcontext 'unauthorized for update? on comment 1' do
it { is_expected.to be_forbidden }
end
xcontext 'authorized for update? on comments 1,2,3' do
context 'authorized for replace_fields on article and all new records' do
context 'not limited by Comments policy scope' do
before { allow_operation('replace_fields', article, new_comments) }
it { is_expected.to be_successful }
end

context 'limited by Comments policy scope' do
let(:comments_policy_scope) { Comment.where("id NOT IN (?)", new_comments.map(&:id)) }
before { allow_operation('replace_fields', article, new_comments) }

it { pending 'DISCUSS: Should this error out somehow?'; is_expected.to be_not_found }
end
end

context 'unauthorized for replace_fields on article and all new records' do
before { disallow_operation('replace_fields', article, new_comments) }

it { is_expected.to be_forbidden }
end
end
end