Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Commit

Permalink
duplicate specs for schema_auto_foreign_keys
Browse files Browse the repository at this point in the history
  • Loading branch information
ronen committed May 17, 2015
1 parent 9fe4651 commit 5550834
Show file tree
Hide file tree
Showing 5 changed files with 1,475 additions and 0 deletions.
206 changes: 206 additions & 0 deletions spec/schema_auto_foreign_keys/foreign_key_spec.rb
@@ -0,0 +1,206 @@
require 'spec_helper'

describe "Foreign Key" do

let(:migration) { ::ActiveRecord::Migration }

context "created with table" do
before(:all) do
define_schema(:auto_create => true) do
create_table :users, :force => true do |t|
t.string :login
end
create_table :comments, :force => true do |t|
t.integer :user_id
t.foreign_key :user_id, :users
end
end
class User < ::ActiveRecord::Base ; end
class Comment < ::ActiveRecord::Base ; end
end

it "should report foreign key constraints" do
expect(Comment.foreign_keys.collect(&:column).flatten).to eq([ "user_id" ])
end

it "should report reverse foreign key constraints" do
expect(User.reverse_foreign_keys.collect(&:column).flatten).to eq([ "user_id" ])
end

end

context "modification" do

before(:each) do
define_schema(:auto_create => false) do
create_table :users, :force => true do |t|
t.string :login
t.datetime :deleted_at
end

create_table :posts, :force => true do |t|
t.text :body
t.integer :user_id
t.integer :author_id
end

create_table :comments, :force => true do |t|
t.text :body
t.integer :post_id
t.foreign_key :post_id, :posts
end
end
class User < ::ActiveRecord::Base ; end
class Post < ::ActiveRecord::Base ; end
class Comment < ::ActiveRecord::Base ; end
Comment.reset_column_information
end


context "works", :sqlite3 => :skip do

context "when is added", "posts(author_id)" do

before(:each) do
add_foreign_key(:posts, :users, :column => :author_id, :on_update => :cascade, :on_delete => :restrict)
end

it "references users(id)" do
expect(Post).to reference(:users, :id).on(:author_id)
end

it "cascades on update" do
expect(Post).to reference(:users).on_update(:cascade)
end

it "restricts on delete" do
expect(Post).to reference(:users).on_delete(:restrict)
end

it "is available in Post.foreign_keys" do
expect(Post.foreign_keys.collect(&:column)).to include('author_id')
end

it "is available in User.reverse_foreign_keys" do
expect(User.reverse_foreign_keys.collect(&:column)).to include('author_id')
end

end

context "when is dropped", "comments(post_id)" do

let(:foreign_key_name) { fk = Comment.foreign_keys.detect(&its.column == 'post_id') and fk.name }

before(:each) do
remove_foreign_key(:comments, name: foreign_key_name)
end

it "doesn't reference posts(id)" do
expect(Comment).not_to reference(:posts).on(:post_id)
end

it "is no longer available in Post.foreign_keys" do
expect(Comment.foreign_keys.collect(&:column)).not_to include('post_id')
end

it "is no longer available in User.reverse_foreign_keys" do
expect(Post.reverse_foreign_keys.collect(&:column)).not_to include('post_id')
end

end

context "when drop using hash", "comments(post_id)" do

let(:foreign_key_name) { fk = Comment.foreign_keys.detect(&its.column == 'post_id') and fk.name }

it "finds by name" do
remove_foreign_key(:comments, name: foreign_key_name)
expect(Comment).not_to reference(:posts).on(:post_id)
end

it "finds by column_names" do
remove_foreign_key(:comments, column: "post_id", to_table: "posts")
expect(Comment).not_to reference(:posts).on(:post_id)
end
end

context "when attempt to drop nonexistent foreign key" do
it "raises error" do
expect{remove_foreign_key(:comments, "posts", column: "nonesuch")}.to raise_error(/no foreign key/i)
end

it "does not error with :if_exists" do
expect{remove_foreign_key(:comments, "posts", column: "nonesuch", :if_exists => true)}.to_not raise_error
end
end

context "when referencing column and column is removed" do

let(:foreign_key_name) { Comment.foreign_keys.detect { |definition| definition.column == 'post_id' }.name }

it "should remove foreign keys" do
remove_foreign_key(:comments, name: foreign_key_name)
expect(Post.reverse_foreign_keys.collect { |fk| fk.column == 'post_id' && fk.from_table == "comments" }).to be_empty
end

end

context "when table name is a reserved word" do
before(:each) do
migration.suppress_messages do
migration.create_table :references, :force => true do |t|
t.integer :post_id, :foreign_key => false
end
end
end

it "can add, detect, and remove a foreign key without error" do
migration.suppress_messages do
expect {
migration.add_foreign_key(:references, :posts)
foreign_key = migration.foreign_keys(:references).detect{|definition| definition.column == "post_id"}
migration.remove_foreign_key(:references, name: foreign_key.name)
}.to_not raise_error
end
end
end

end

context "raises an exception", :sqlite3 => :only do

it "when attempting to add" do
expect {
add_foreign_key(:posts, :users, :column => :author_id, :on_update => :cascade, :on_delete => :restrict)
}.to raise_error(NotImplementedError)
end

it "when attempting to remove" do
expect {
remove_foreign_key(:posts, name: "dummy")
}.to raise_error(NotImplementedError)
end

end
end

protected
def add_foreign_key(*args)
migration.suppress_messages do
migration.add_foreign_key(*args)
end
User.reset_column_information
Post.reset_column_information
Comment.reset_column_information
end

def remove_foreign_key(*args)
migration.suppress_messages do
migration.remove_foreign_key(*args)
end
User.reset_column_information
Post.reset_column_information
Comment.reset_column_information
end

end

0 comments on commit 5550834

Please sign in to comment.