Last active
September 3, 2019 17:18
-
-
Save ghiculescu/a3a713134f18e351c7ba521377146014 to your computer and use it in GitHub Desktop.
How to replicate https://github.com/CanCanCommunity/cancancan/pull/600 - switch to master, add this test file, then run the test command below. It should fail for you too!
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require 'spec_helper' | |
if CanCan::ModelAdapters::ActiveRecordAdapter.version_greater_or_equal?('5.0.0') | |
describe CanCan::ModelAdapters::ActiveRecord5Adapter do | |
context 'with postgresql' do | |
before :each do | |
connect_db | |
ActiveRecord::Migration.verbose = false | |
ActiveRecord::Schema.define do | |
create_table(:blog_authors) do |t| | |
t.string :name, null: false | |
t.timestamps null: false | |
end | |
create_table(:blog_posts) do |t| | |
t.references :blog_author | |
t.string :title, null: false | |
t.timestamps null: false | |
end | |
create_table(:blog_post_comments) do |t| | |
t.references :blog_post | |
t.string :body, null: false | |
t.timestamps null: false | |
end | |
end | |
unless defined?(BlogAuthor) | |
class BlogAuthor < ActiveRecord::Base | |
has_many :blog_posts | |
has_many :blog_post_comments, through: :blog_posts | |
end | |
end | |
unless defined?(BlogPost) | |
class BlogPost < ActiveRecord::Base | |
has_many :blog_post_comments | |
belongs_to :blog_author | |
default_scope -> { order(:title) } | |
end | |
end | |
unless defined?(BlogPostComment) | |
class BlogPostComment < ActiveRecord::Base | |
belongs_to :blog_post | |
default_scope -> { order(created_at: :desc) } | |
end | |
end | |
end | |
subject(:ability) { Ability.new(nil) } | |
let(:alex) { BlogAuthor.create!(name: 'Alex') } | |
let(:josh) { BlogAuthor.create!(name: 'Josh') } | |
let(:p1) { josh.blog_posts.create!(title: 'p1') } | |
let(:p2) { alex.blog_posts.create!(title: 'p2') } | |
let(:p1c1) { p1.blog_post_comments.create!(body: 'p1c1', created_at: Time.new(2019, 8, 25, 1)) } | |
let(:p1c2) { p1.blog_post_comments.create!(body: 'p1c2', created_at: Time.new(2019, 8, 25, 2)) } | |
let(:p2c1) { p2.blog_post_comments.create!(body: 'p2c1', created_at: Time.new(2019, 8, 25, 3)) } | |
let(:p2c2) { p2.blog_post_comments.create!(body: 'p2c2', created_at: Time.new(2019, 8, 25, 4)) } | |
context 'when default scope sets an order, and abilities dont have extra checks' do | |
before do | |
ability.can :read, BlogPost | |
ability.can :read, BlogPostComment | |
end | |
it 'can get accessible records' do | |
expected_bodies_in_order = [p2c2, p2c1, p1c2, p1c1].map(&:body) | |
accessible = BlogPostComment.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(4) | |
end | |
it 'can get accessible records from a has_many' do | |
expected_bodies_in_order = [p2c2, p2c1].map(&:body) | |
accessible = p2.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(2) | |
end | |
it 'can get accessible records from a has_many - other post' do | |
expected_bodies_in_order = [p1c2, p1c1].map(&:body) | |
accessible = p1.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(2) | |
end | |
it 'can get accessible records from a has_many :through' do | |
expected_bodies_in_order = [p2c2, p2c1].map(&:body) | |
accessible = alex.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(2) | |
end | |
it 'can get accessible records from a has_many :through - other user' do | |
expected_bodies_in_order = [p1c2, p1c1].map(&:body) | |
accessible = josh.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(2) | |
end | |
end | |
context 'when default scope sets an order, and abilities have extra checks' do | |
before do | |
ability.can :read, BlogPost | |
# this is the only change vs. the above context -- in this context we can *only* see alex's posts | |
ability.can :read, BlogPostComment, blog_post: { blog_author_id: alex.id } | |
end | |
it 'can get accessible records' do | |
expected_bodies_in_order = [p2c2, p2c1].map(&:body) | |
accessible = BlogPostComment.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(2) | |
end | |
it 'can get accessible records from a has_many' do | |
expected_bodies_in_order = [p2c2, p2c1].map(&:body) | |
accessible = p2.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(2) | |
end | |
it 'can get accessible records from a has_many - none returned' do | |
expected_bodies_in_order = [] | |
accessible = p1.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(0) | |
end | |
it 'can get accessible records from a has_many :through' do | |
expected_bodies_in_order = [p2c2, p2c1].map(&:body) | |
accessible = alex.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(2) | |
end | |
it 'can get accessible records from a has_many :through - none returned' do | |
expected_bodies_in_order = [] | |
accessible = josh.blog_post_comments.accessible_by(ability) | |
expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
expect(accessible.count).to eq(0) | |
end | |
end | |
end | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ DB=postgres bundle exec appraisal activerecord_5.2.2 rspec spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb | |
>> BUNDLE_GEMFILE=/Users/alex/code/cancancan/gemfiles/activerecord_5.2.2.gemfile bundle exec rspec spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb | |
Run options: include {:focus=>true} | |
All examples were filtered out; ignoring {:focus=>true} | |
Randomized with seed 56631 | |
.....F...F | |
Failures: | |
1) CanCan::ModelAdapters::ActiveRecord5Adapter with postgresql when default scope sets an order, and abilities have extra checks can get accessible records from a has_many :through | |
Failure/Error: expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
ActiveRecord::StatementInvalid: | |
PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list | |
LINE 1: ... ORDER BY "blog_post_comments"."created_at" DESC, "blog_post... | |
^ | |
: SELECT DISTINCT "blog_post_comments".* FROM "blog_post_comments" INNER JOIN "blog_posts" ON "blog_post_comments"."blog_post_id" = "blog_posts"."id" LEFT OUTER JOIN "blog_posts" "blog_posts_blog_post_comments" ON "blog_posts_blog_post_comments"."id" = "blog_post_comments"."blog_post_id" WHERE "blog_posts"."blog_author_id" = $1 AND "blog_posts"."blog_author_id" = $2 ORDER BY "blog_post_comments"."created_at" DESC, "blog_posts"."title" ASC | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:677:in `prepare' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:677:in `block in prepare_statement' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:672:in `prepare_statement' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:617:in `exec_cache' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:600:in `execute_and_clear' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:81:in `exec_query' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:482:in `select_prepared' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:68:in `select_all' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:106:in `select_all' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/querying.rb:41:in `find_by_sql' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:560:in `block in exec_queries' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:584:in `skip_query_cache_if_necessary' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:547:in `exec_queries' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/association_relation.rb:34:in `exec_queries' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:422:in `load' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:200:in `records' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation/delegation.rb:71:in `each' | |
# ./spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb:143:in `map' | |
# ./spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb:143:in `block (4 levels) in <top (required)>' | |
# ------------------ | |
# --- Caused by: --- | |
# PG::InvalidColumnReference: | |
# ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list | |
# LINE 1: ... ORDER BY "blog_post_comments"."created_at" DESC, "blog_post... | |
# ^ | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:677:in `prepare' | |
2) CanCan::ModelAdapters::ActiveRecord5Adapter with postgresql when default scope sets an order, and abilities have extra checks can get accessible records from a has_many :through - none returned | |
Failure/Error: expect(accessible.map(&:body)).to eq(expected_bodies_in_order) | |
ActiveRecord::StatementInvalid: | |
PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list | |
LINE 1: ... ORDER BY "blog_post_comments"."created_at" DESC, "blog_post... | |
^ | |
: SELECT DISTINCT "blog_post_comments".* FROM "blog_post_comments" INNER JOIN "blog_posts" ON "blog_post_comments"."blog_post_id" = "blog_posts"."id" LEFT OUTER JOIN "blog_posts" "blog_posts_blog_post_comments" ON "blog_posts_blog_post_comments"."id" = "blog_post_comments"."blog_post_id" WHERE "blog_posts"."blog_author_id" = $1 AND "blog_posts"."blog_author_id" = $2 ORDER BY "blog_post_comments"."created_at" DESC, "blog_posts"."title" ASC | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:677:in `prepare' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:677:in `block in prepare_statement' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:672:in `prepare_statement' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:617:in `exec_cache' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:600:in `execute_and_clear' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:81:in `exec_query' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:482:in `select_prepared' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:68:in `select_all' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:106:in `select_all' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/querying.rb:41:in `find_by_sql' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:560:in `block in exec_queries' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:584:in `skip_query_cache_if_necessary' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:547:in `exec_queries' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/association_relation.rb:34:in `exec_queries' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:422:in `load' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation.rb:200:in `records' | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/relation/delegation.rb:71:in `each' | |
# ./spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb:150:in `map' | |
# ./spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb:150:in `block (4 levels) in <top (required)>' | |
# ------------------ | |
# --- Caused by: --- | |
# PG::InvalidColumnReference: | |
# ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list | |
# LINE 1: ... ORDER BY "blog_post_comments"."created_at" DESC, "blog_post... | |
# ^ | |
# /Users/alex/.rvm/gems/ruby-2.6.3/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:677:in `prepare' | |
Finished in 9.34 seconds (files took 0.63906 seconds to load) | |
10 examples, 2 failures | |
Failed examples: | |
rspec ./spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb:140 # CanCan::ModelAdapters::ActiveRecord5Adapter with postgresql when default scope sets an order, and abilities have extra checks can get accessible records from a has_many :through | |
rspec ./spec/cancan/model_adapters/active_record_5_adapter_with_default_scopes_spec.rb:147 # CanCan::ModelAdapters::ActiveRecord5Adapter with postgresql when default scope sets an order, and abilities have extra checks can get accessible records from a has_many :through - none returned | |
Randomized with seed 56631 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment