Skip to content

Commit

Permalink
implemented scoping when saving/deleting taxa; added tests; some may …
Browse files Browse the repository at this point in the history
…not work maybe due to constraints
  • Loading branch information
khustochka committed Dec 25, 2009
1 parent cb16a52 commit aa8746e
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 55 deletions.
25 changes: 20 additions & 5 deletions app/models/taxonomy/taxon.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,26 @@ def to_param
end

def insert_mind_sorting
latest = self.class.count + 1
scope = ""
if self.respond_to?(:supertaxon)
fk = self.supertaxon.class.to_s.foreign_key
scope = " AND #{fk} = #{self[fk]}"
end
latest = (self.respond_to?(:supertaxon) ? self.supertaxon.subtaxa.count : self.class.count) + 1
self.sort = latest if self.sort > latest || self.sort == 0
self.class.transaction do
self.class.update_all("sort = sort + 1", "sort >= #{self.sort}") # TODO: mind the scope
self.class.update_all("sort = sort + 1", "sort >= #{self.sort}" + scope) # TODO: mind the scope
save!
end
end

def update_mind_sorting(attributes)
latest = self.class.count
scope = ""
if self.respond_to?(:supertaxon)
fk = self.supertaxon.class.to_s.foreign_key
scope = " AND #{fk} = #{self[fk]}"
end
latest = self.respond_to?(:supertaxon) ? self.supertaxon.subtaxa.count : self.class.count
current = attributes[:sort].to_i
new_sort = attributes[:sort] =
current > latest || current == 0 ?
Expand All @@ -32,16 +42,21 @@ def update_mind_sorting(attributes)
diff = (old_sort - new_sort) / (old_sort - new_sort).abs
max_sort = [old_sort, new_sort - diff].max
min_sort = [old_sort, new_sort - diff].min
self.class.update_all("sort = sort + (#{diff})", "sort > #{min_sort} AND sort < #{max_sort}") # TODO: mind the scope
self.class.update_all("sort = sort + (#{diff})", "sort > #{min_sort} AND sort < #{max_sort}" + scope) # TODO: mind the scope
end
update_attributes!(attributes)
end
end

def destroy_mind_sorting
scope = ""
if self.respond_to?(:supertaxon)
fk = self.supertaxon.class.to_s.foreign_key
scope = " AND #{fk} = #{self[fk]}"
end
self.class.transaction do
destroy
self.class.update_all("sort = sort - 1", "sort > #{self[:sort]}")
self.class.update_all("sort = sort - 1", "sort > #{self[:sort]}" + scope)
end
end

Expand Down
93 changes: 93 additions & 0 deletions test/functional/taxonomy/familiae_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
require 'test_helper'

class FamiliaeControllerTest < ActionController::TestCase

test "should get index" do
http_auth
get :index
assert_response :success
assert_not_nil assigns(:bunch)
end

test "should get new" do
http_auth
get :new
assert_response :success
end

test "should create familia" do
http_auth
assert_difference('Familia.count') do
post :create, :familia => { :name_la => "Mididae", :name_ru => "Средневые", :name_uk => "Середньові", :description => '', :ordo_id => ordines(:ordines_011).id, :sort => Familia.count / 2 }
end
assert_redirected_to familia_path(assigns(:taxon))
end

test "should show familia" do
http_auth
get :show, :id => familiae(:familiae_014).to_param
assert_response :success
end

test "should get edit" do
http_auth
get :edit, :id => familiae(:familiae_014).to_param
assert_response :redirect
assert_redirected_to familia_path(familiae(:familiae_014))
end

test "should update familia" do
http_auth
post :update, :id => familiae(:familiae_014).to_param, :familia => { :name_la => "Insertidae", :name_ru => "Вставные", :name_uk => "Вставні", :sort => Familia.count / 3 }
assert_redirected_to familia_path(assigns(:taxon))
end

test "should destroy familia" do
http_auth
assert_difference('Familia.count', -1) do
delete :destroy, :id => familiae(:familiae_014).to_param
end
assert_redirected_to familiae_path
end

# Restriction tests

test "not admin should not get index" do
get :index
assert_response :not_found
end

test "not admin should not get new" do
get :new
assert_response :not_found
end

test "not admin should not create familia" do
assert_difference('Familia.count', 0) do
post :create, :familia => { :name_la => "Mididae", :name_ru => "Средневые", :name_uk => "Середневі", :description => '', :ordo_id => ordines(:ordines_011).id, :sort => Familia.count / 2 }
end
assert_response :not_found
end

test "not admin should not show familia" do
get :show, :id => familiae(:familiae_014).to_param
assert_response :not_found
end

test "not admin should not get edit" do
get :edit, :id => familiae(:familiae_014).to_param
assert_response :not_found
end

test "not admin should not update familia" do
post :update, :id => familiae(:familiae_014).to_param, :familia => { :name_la => "Insertidae", :name_ru => "Вставные", :name_uk => "Вставні", :sort => Familia.count / 3 }
assert_response :not_found
end

test "not admin should not destroy familia" do
assert_difference('Familia.count', 0) do
delete :destroy, :id => familiae(:familiae_014).to_param
end
assert_response :not_found
end
end
45 changes: 0 additions & 45 deletions test/functional/taxonomy/familiae_controller_test.rb.tmp

This file was deleted.

8 changes: 7 additions & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@ class ActiveSupport::TestCase
# Add more helper methods to be used by all tests here...

def assert_sorting_preserved(klass)
assert_equal( (1..klass.count).to_a, klass.all(:order => :sort).map {|item| item[:sort] }, "Sorting invalid" )
if klass.reflect_on_association(:supertaxon).nil?
assert_equal( (1..klass.count).to_a, klass.all(:order => :sort).map {|item| item[:sort] }, "Sorting invalid" )
else
klass.reflect_on_association(:supertaxon).klass.all(:order => :sort, :include => :subtaxa).each do |parent|
assert_equal( (1..parent.subtaxa.count).to_a, parent.subtaxa.map {|item| item[:sort] }, "Sorting invalid" )
end
end
end

def http_auth
Expand Down
9 changes: 9 additions & 0 deletions test/unit/helpers/test_helper_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'test/test_helper'

class TestHelperTest < ActionView::TestCase
test "assert_sorting_preserved helper is valid" do
assert_sorting_preserved(Ordo)
assert_sorting_preserved(Familia)
assert_sorting_preserved(Species)
end
end
104 changes: 100 additions & 4 deletions test/unit/taxonomy/familia_test.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,104 @@
require 'test_helper'

class FamiliaTest < ActiveSupport::TestCase
# Replace this with your real tests.
# test "the truth" do
# assert true
# end

test "insert should preserve sorting" do
parent = ordines(:ordines_011)
new_sort = parent.subtaxa.count / 2
assert_difference("parent.subtaxa.count", 1) do
Familia.new(:name_la => "Mididae", :name_ru => "Средневые", :name_uk => "Середневі", :description => '', :ordo_id => ordines(:ordines_011).id, :sort => new_sort).insert_mind_sorting
end
assert_equal new_sort, Familia.find_by_name_la("Mididae")[:sort], "Badly inserted"
assert_sorting_preserved(Familia)
end

test "destroy should preserve sorting" do
parent = ordines(:ordines_011)
assert_difference("parent.subtaxa.count", -1) do
familiae(:familiae_013).destroy_mind_sorting
end
assert_sorting_preserved(Familia)
end

test "move down should preserve sorting" do
parent = ordines(:ordines_011)
new_sort = parent.subtaxa.count * 2 / 3
for_update = familiae(:familiae_013)
for_update.update_mind_sorting(:sort => new_sort)

assert_equal new_sort, Familia.find_by_name_la(for_update[:name_la])[:sort], "Badly inserted"
assert_sorting_preserved(Familia)
end

test "move up should preserve sorting" do
parent = ordines(:ordines_011)
new_sort = parent.subtaxa.count / 3
for_update = familiae(:familiae_013)
for_update.update_mind_sorting(:sort => new_sort)

assert_equal new_sort, Familia.find_by_name_la(for_update[:name_la])[:sort], "Badly inserted"
assert_sorting_preserved(Familia)
end

test "invalid add should preserve sorting" do
parent = ordines(:ordines_011)
assert_raise(ActiveRecord::RecordInvalid) do
assert_difference("parent.subtaxa.count", 0) do
Familia.new(:name_la => "Scolopaci", :ordo_id => ordines(:ordines_011).id, :sort => parent.subtaxa.count / 2).insert_mind_sorting
end
end
assert_nil Familia.find_by_name_la("Scolopaci")
assert_sorting_preserved(Familia)
end

test "invalid edit should preserve sorting" do
parent = ordines(:ordines_011)
assert_raise(ActiveRecord::RecordInvalid) do
assert_difference("parent.subtaxa.count", 0) do
for_update = familiae(:familiae_013)
for_update.update_mind_sorting(:name_la => "Scolopaci", :sort => parent.subtaxa.count / 3)
end
end
assert_nil Familia.find_by_name_la("Scolopaci")
assert_sorting_preserved(Familia)
end

test "insert with illegal or 0 sort value should append to the end" do
parent = ordines(:ordines_011)
assert_difference("parent.subtaxa.count", 1) do
Familia.new(:name_la => "Zerodae", :name_ru => "Нулебразные", :name_uk => "Нульові", :description => '', :ordo_id => ordines(:ordines_011).id, :sort => 0).insert_mind_sorting
end
assert_equal parent.subtaxa.count, Familia.find_by_name_la("Zerodae")[:sort], "Badly inserted"
assert_sorting_preserved(Familia)

assert_difference("parent.subtaxa.count", 1) do
Familia.new(:name_la => "Superidae", :name_ru => "Сверхвые", :name_uk => "Наднові", :description => '', :ordo_id => ordines(:ordines_011).id, :sort => 1000).insert_mind_sorting
end
assert_equal parent.subtaxa.count, Familia.find_by_name_la("Superidae")[:sort], "Badly inserted"
assert_sorting_preserved(Familia)

assert_difference("parent.subtaxa.count", 1) do
Familia.new(:name_la => "Xxxdae", :name_ru => "Хххвые", :name_uk => "Хххві", :description => '', :ordo_id => ordines(:ordines_011).id, :sort => "xxx").insert_mind_sorting
end
assert_equal parent.subtaxa.count, Familia.find_by_name_la("Xxxdae")[:sort], "Badly inserted"
assert_sorting_preserved(Familia)
end

test "update with illegal or 0 sort value should move to the end" do
parent = ordines(:ordines_011)
for_update = familiae(:familiae_013)
for_update.update_mind_sorting(:sort => 0)
assert_equal parent.subtaxa.count, Familia.find_by_name_la(for_update[:name_la])[:sort], "Badly inserted"
assert_sorting_preserved(Familia)

for_update = familiae(:familiae_013)
for_update.update_mind_sorting(:sort => 1000)
assert_equal parent.subtaxa.count, Familia.find_by_name_la(for_update[:name_la])[:sort], "Badly inserted"
assert_sorting_preserved(Familia)

for_update = familiae(:familiae_013)
for_update.update_mind_sorting(:sort => "xxxx")
assert_equal parent.subtaxa.count, Familia.find_by_name_la(for_update[:name_la])[:sort], "Badly inserted"
assert_sorting_preserved(Familia)
end
end

0 comments on commit aa8746e

Please sign in to comment.