# encoding: utf-8
require File.expand_path(File.dirname(__FILE__) + '/../boot')
class ObserverControllerTest < FunctionalTestCase
# Test constructing observations in various ways (with minimal namings).
def generic_construct_observation(params, o_num, g_num, n_num, user = @rolf)
o_count = Observation.count
g_count = Naming.count
n_count = Name.count
score = user.reload.contribution
params[:observation] = {
:place_name => 'Right Here, Massachusetts, USA',
:lat => '',
:long => '',
:alt => '',
'when(1i)' => '2007',
'when(2i)' => '10',
'when(3i)' => '31',
:specimen => '0',
:thumb_image_id => '0',
}.merge(params[:observation] || {})
params[:vote] = {
:value => '3',
}.merge(params[:vote] || {})
params[:username] = user.login
post_requires_login(:create_observation, params)
# either_requires_either(:post, :create_observation, nil, params, :username => user.login)
if o_num == 0
assert_response(:success)
elsif Location.find_by_name(params[:observation][:place_name]) or
Location.is_unknown?(params[:observation][:place_name]) or
params[:observation][:place_name].blank?
assert_response(:action => :show_observation)
else
assert_response(:action => :create_location)
end
assert_equal(o_count + o_num, Observation.count)
assert_equal(g_count + g_num, Naming.count)
assert_equal(n_count + n_num, Name.count)
assert_equal(score + o_num + 2*g_num + 10*n_num, user.reload.contribution)
if o_num == 1
assert_not_equal(0, @controller.instance_variable_get('@observation').thumb_image_id)
end
end
################################################################################
# ----------------------------
# General tests.
# ----------------------------
def test_page_loads
get_with_dump(:index)
assert_response('list_rss_logs')
assert_link_in_html(:app_intro.t, :action => 'intro')
assert_link_in_html(:app_create_account.t, :controller => 'account',
:action => 'signup')
get_with_dump(:ask_webmaster_question)
assert_response('ask_webmaster_question')
assert_form_action(:action => 'ask_webmaster_question')
get_with_dump(:color_themes)
assert_response('color_themes')
for theme in CSS
get_with_dump(theme)
assert_response(theme)
end
get_with_dump(:how_to_help)
assert_response('how_to_help')
get_with_dump(:how_to_use)
assert_response('how_to_use')
get_with_dump(:intro)
assert_response('intro')
get_with_dump(:list_observations)
assert_response('list_observations')
# Test again, this time specifying page number via an observation id.
get(:list_observations, :id => 4)
assert_response('list_observations')
get(:observations_for_project, :id => projects(:bolete_project).id)
assert_response('list_observations')
get_with_dump(:list_rss_logs)
assert_response('list_rss_logs')
get_with_dump(:news)
assert_response('news')
get_with_dump(:observations_by_name)
assert_response('list_observations')
get_with_dump(:rss)
assert_response('rss')
get_with_dump(:show_rss_log, :id => 1)
assert_response('show_rss_log')
get_with_dump(:users_by_contribution)
assert_response('users_by_contribution')
get_with_dump(:show_user, :id => 1)
assert_response('show_user')
get_with_dump(:show_site_stats)
assert_response('show_site_stats')
get_with_dump(:observations_by_user, :id => 1)
assert_response('list_observations')
get_with_dump(:login)
assert_response(:controller => "account", :action => "login")
get_with_dump(:textile)
assert_response('textile_sandbox')
get_with_dump(:textile_sandbox)
assert_response('textile_sandbox')
end
def test_altering_types_shown_by_rss_log_index
# Show none.
post(:index_rss_log)
assert_response('list_rss_logs')
# Show one.
post(:index_rss_log, :show_observations => '1')
assert_response('list_rss_logs')
# Show all.
params = {}
for type in RssLog.all_types
params["show_#{type}"] = '1'
end
post(:index_rss_log, params)
assert_response('list_rss_logs')
end
def test_prev_and_next_observation
# Uses default observation query
get(:next_observation, :id => 4)
assert_response(:action => "show_observation", :id => 3,
:params => @controller.query_params(Query.last))
get(:prev_observation, :id => 4)
assert_response(:action => "show_observation", :id => 5,
:params => @controller.query_params(Query.last))
end
def test_prev_and_next_observation_with_fancy_query
n1 = names(:agaricus_campestras)
n2 = names(:agaricus_campestris)
n3 = names(:agaricus_campestros)
n4 = names(:agaricus_campestrus)
n2.transfer_synonym(n1)
n2.transfer_synonym(n3)
n2.transfer_synonym(n4)
n1.correct_spelling = n2
n1.save_without_our_callbacks
o1 = n1.observations.first
o2 = n2.observations.first
o3 = n3.observations.first
o4 = n4.observations.first
# When requesting non-synonym observations of n2, it should include n1,
# since an observation of n1 was clearly intended to be an observation of
# n2.
query = Query.lookup_and_save(:Observation, :of_name, :synonyms => :no,
:name => n2, :by => :name)
assert_equal(2, query.num_results)
# Likewise, when requesting *synonym* observations, neither n1 nor n2
# should be included.
query = Query.lookup_and_save(:Observation, :of_name, :synonyms => :exclusive,
:name => n2, :by => :name)
assert_equal(2, query.num_results)
# But for our prev/next test, lets do the all-inclusive query.
query = Query.lookup_and_save(:Observation, :of_name, :synonyms => :all,
:name => n2, :by => :name)
assert_equal(4, query.num_results)
qp = @controller.query_params(query)
get(:next_observation, qp.merge(:id => 1))
assert_response(:action => 'show_observation', :id => 1, :params => qp)
assert_flash(/can.*t find.*results.*index/i)
get(:next_observation, qp.merge(:id => o1.id))
assert_response(:action => 'show_observation', :id => o2.id, :params => qp)
get(:next_observation, qp.merge(:id => o2.id))
assert_response(:action => 'show_observation', :id => o3.id, :params => qp)
get(:next_observation, qp.merge(:id => o3.id))
assert_response(:action => 'show_observation', :id => o4.id, :params => qp)
get(:next_observation, qp.merge(:id => o4.id))
assert_response(:action => 'show_observation', :id => o4.id, :params => qp)
assert_flash(/no more/i)
get(:prev_observation, qp.merge(:id => o4.id))
assert_response(:action => 'show_observation', :id => o3.id, :params => qp)
get(:prev_observation, qp.merge(:id => o3.id))
assert_response(:action => 'show_observation', :id => o2.id, :params => qp)
get(:prev_observation, qp.merge(:id => o2.id))
assert_response(:action => 'show_observation', :id => o1.id, :params => qp)
get(:prev_observation, qp.merge(:id => o1.id))
assert_response(:action => 'show_observation', :id => o1.id, :params => qp)
assert_flash(/no more/i)
get(:prev_observation, qp.merge(:id => 1))
assert_response(:action => 'show_observation', :id => 1, :params => qp)
assert_flash(/can.*t find.*results.*index/i)
end
def test_advanced_search_form
for model in [ Name, Image, Observation ]
post('advanced_search_form',
:search => {
:name => "Don't know",
:user => "myself",
:type => model.name.underscore,
:content => "Long pink stem and small pink cap",
:location => "Eastern Oklahoma"
},
:commit => "Search"
)
assert_response(:controller => model.show_controller,
:action => 'advanced_search')
end
end
def test_advanced_search
query = Query.lookup_and_save(:Observation, :advanced_search,
:name => "Don't know",
:user => "myself",
:content => "Long pink stem and small pink cap",
:location => "Eastern Oklahoma"
)
get(:advanced_search, @controller.query_params(query))
assert_response('list_observations')
end
def test_pattern_search
params = {:search => {:pattern => '12', :type => 'observation'}}
get_with_dump(:pattern_search, params)
assert_response(:controller => 'observer', :action => 'observation_search',
:pattern => '12')
params = {:search => {:pattern => '34', :type => 'image'}}
get_with_dump(:pattern_search, params)
assert_response(:controller => 'image', :action => 'image_search',
:pattern => '34')
params = {:search => {:pattern => '56', :type => 'name'}}
get_with_dump(:pattern_search, params)
assert_response(:controller => 'name', :action => 'name_search',
:pattern => '56')
params = {:search => {:pattern => '78', :type => 'location'}}
get_with_dump(:pattern_search, params)
assert_response(:controller => 'location', :action => 'location_search',
:pattern => '78')
params = {:search => {:pattern => '90', :type => 'comment'}}
get_with_dump(:pattern_search, params)
assert_response(:controller => 'comment', :action => 'comment_search',
:pattern => '90')
params = {:search => {:pattern => '12', :type => 'species_list'}}
get_with_dump(:pattern_search, params)
assert_response(:controller => 'species_list', :action => 'species_list_search',
:pattern => '12')
params = {:search => {:pattern => '34', :type => 'user'}}
get_with_dump(:pattern_search, params)
assert_response(:controller => 'observer', :action => 'user_search',
:pattern => '34')
end
def test_observation_search
get_with_dump(:observation_search, :pattern => '120')
assert_response('list_observations')
assert_equal(:query_title_pattern_search.t(:types => 'Observations', :pattern => '120'),
@controller.instance_variable_get('@title'))
get_with_dump(:observation_search, :pattern => '120', :page => 2)
assert_response('list_observations')
assert_equal(:query_title_pattern_search.t(:types => 'Observations', :pattern => '120'),
@controller.instance_variable_get('@title'))
end
# Created in response to a bug seen in the wild
def test_where_search_next_page
params = { :place_name => 'Burbank', :page => 2 }
get_with_dump(:observations_at_where, params)
assert_response('list_observations')
end
# Created in response to a bug seen in the wild
def test_where_search_pattern
params = { :place_name => "Burbank" }
get_with_dump(:observations_at_where, params)
assert_response('list_observations')
end
def test_send_webmaster_question
params = {
:user => { :email => "rolf@mushroomobserver.org" },
:question => { :content => "Some content" },
}
post(:ask_webmaster_question, params)
assert_response(:controller => "observer", :action => "list_rss_logs")
params[:user][:email] = ''
post(:ask_webmaster_question, params)
assert_response(:success)
assert_flash(:runtime_ask_webmaster_need_address.t)
params[:user][:email] = 'spammer'
post(:ask_webmaster_question, params)
assert_response(:success)
assert_flash(:runtime_ask_webmaster_need_address.t)
params[:user][:email] = 'bogus@email.com'
params[:question][:content] = ''
post(:ask_webmaster_question, params)
assert_response(:success)
assert_flash(:runtime_ask_webmaster_need_content.t)
params[:question][:content] = "Buy Me!"
post(:ask_webmaster_question, params)
assert_response(:success)
assert_flash(:runtime_ask_webmaster_antispam.t)
end
def test_show_observation
assert_equal(0, Query.count)
# Test it on obs with no namings first.
obs_id = observations(:unknown_with_no_naming).id
get_with_dump(:show_observation, :id => obs_id)
assert_response('show_observation')
assert_form_action(:action => 'show_observation', :id => obs_id)
# Test it on obs with two namings (Rolf's and Mary's), but no one logged in.
obs_id = observations(:coprinus_comatus_obs).id
get_with_dump(:show_observation, :id => obs_id)
assert_response('show_observation')
assert_form_action(:action => 'show_observation', :id => obs_id)
# Test it on obs with two namings, with owner logged in.
login('rolf')
obs_id = observations(:coprinus_comatus_obs).id
get_with_dump(:show_observation, :id => obs_id)
assert_response('show_observation')
assert_form_action(:action => 'show_observation', :id => obs_id)
# Test it on obs with two namings, with non-owner logged in.
login('mary')
obs_id = observations(:coprinus_comatus_obs).id
get_with_dump(:show_observation, :id => obs_id)
assert_response('show_observation')
assert_form_action(:action => 'show_observation', :id => obs_id)
# Test a naming owned by the observer but the observer has 'No Opinion'.
# This is a regression test for a bug in _show_namings.rhtml
# Ensure that rolf owns @obs_with_no_opinion.
user = login('rolf')
obs = observations(:strobilurus_diminutivus_obs)
assert_equal(obs.user, user)
get(:show_observation, :id => obs.id)
assert_response('show_observation')
# Make sure no queries created for show_image links. (Well, okay, four
# queries are created for Darvin's new "show species" and "show similar
# observations" links...)
assert_equal(4, Query.count)
end
def test_show_observation_edit_links
obs = observations(:detailed_unknown)
proj = projects(:bolete_project)
assert_equal(@mary.id, obs.user_id) # owned by mary
assert(obs.projects.include?(proj)) # owned by bolete project
assert_equal([@dick.id], proj.user_group.users.map(&:id)) # dick is only member of bolete project
login('rolf')
get(:show_observation, :id => obs.id)
assert_select('a[href*=edit_observation]', :count => 0)
assert_select('a[href*=destroy_observation]', :count => 0)
assert_select('a[href*=add_image]', :count => 0)
assert_select('a[href*=remove_image]', :count => 0)
assert_select('a[href*=reuse_image]', :count => 0)
get(:edit_observation, :id => obs.id)
assert_response(:redirect)
get(:destroy_observation, :id => obs.id)
assert_flash_error
login('mary')
get(:show_observation, :id => obs.id)
assert_select('a[href*=edit_observation]', :minimum => 1)
assert_select('a[href*=destroy_observation]', :minimum => 1)
assert_select('a[href*=add_image]', :minimum => 1)
assert_select('a[href*=remove_image]', :minimum => 1)
assert_select('a[href*=reuse_image]', :minimum => 1)
get(:edit_observation, :id => obs.id)
assert_response(:success)
login('dick')
get(:show_observation, :id => obs.id)
assert_select('a[href*=edit_observation]', :minimum => 1)
assert_select('a[href*=destroy_observation]', :minimum => 1)
assert_select('a[href*=add_image]', :minimum => 1)
assert_select('a[href*=remove_image]', :minimum => 1)
assert_select('a[href*=reuse_image]', :minimum => 1)
get(:edit_observation, :id => obs.id)
assert_response(:success)
get(:destroy_observation, :id => obs.id)
assert_flash_success
end
def test_show_user_no_id
get_with_dump(:show_user)
assert_response(:action => 'index_user')
end
def test_ask_questions
id = observations(:coprinus_comatus_obs).id
requires_login(:ask_observation_question, :id => id)
assert_form_action(:action => 'ask_observation_question', :id => id)
id = @mary.id
requires_login(:ask_user_question, :id => id)
assert_form_action(:action => 'ask_user_question', :id => id)
id = images(:in_situ).id
requires_login(:commercial_inquiry, :id => id)
assert_form_action(:action => 'commercial_inquiry', :id => id)
end
def test_destroy_observation
assert(obs = observations(:minimal_unknown))
id = obs.id
params = { :id => id.to_s }
assert_equal("mary", obs.user.login)
requires_user(:destroy_observation, [:show_observation], params, 'mary')
assert_response(:action => :list_observations)
assert_raises(ActiveRecord::RecordNotFound) do
obs = Observation.find(id)
end
end
def test_some_admin_pages
for (page, response, params) in [
[ :users_by_name, 'users_by_name', {} ],
[ :email_features, 'email_features', {} ],
]
logout
get(page, params)
assert_response(:controller => "account", :action => "login")
login('rolf')
get(page, params)
assert_response(:action => "list_rss_logs")
assert_flash(/denied|only.*admin/i)
make_admin('rolf')
get_with_dump(page, params)
assert_response(response)
end
end
def test_some_admin_pages
page = :email_features
params = {:feature_email => {:content => 'test'}}
logout
post(page, params)
assert_response(:controller => "account", :action => "login")
login('rolf')
post(page, params)
assert_response(:controller => "observer", :action => "list_rss_logs")
assert_flash(/denied|only.*admin/i)
make_admin('rolf')
post_with_dump(page, params)
assert_response(:controller => "observer", :action => :users_by_name)
end
def test_send_emails
image = images(:commercial_inquiry_image)
params = {
:id => image.id,
:commercial_inquiry => {
:content => "Testing commercial_inquiry"
}
}
post_requires_login(:commercial_inquiry, params)
assert_response(:controller => :image, :action => :show_image)
obs = observations(:minimal_unknown)
params = {
:id => obs.id,
:question => {
:content => "Testing question"
}
}
post_requires_login(:ask_observation_question, params)
assert_response(:action => :show_observation)
assert_flash(:runtime_ask_observation_question_success.t)
user = @mary
params = {
:id => user.id,
:email => {
:subject => "Email subject",
:content => "Email content"
}
}
post_requires_login(:ask_user_question, params)
assert_response(:action => :show_user)
assert_flash(:runtime_ask_user_question_success.t)
end
def test_show_notifications
# First, create a naming notification email, making sure it has a template,
# and making sure the person requesting the notifcation is not the same
# person who created the underlying observation (otherwise nothing happens).
note = notifications(:coprinus_comatus_notification)
note.user = @mary
note.note_template = 'blah!'
assert(note.save)
QueuedEmail.queue_emails(true)
QueuedEmail::NameTracking.create_email(note, namings(:coprinus_comatus_other_naming))
# Now we can be sure show_notifications is supposed to actually show a
# non-empty list, and thus that this test is meaningful.
requires_login(:show_notifications, :id => observations(:coprinus_comatus_obs))
assert_response('show_notifications')
end
def test_author_request
id = name_descriptions(:coprinus_comatus_desc).id
requires_login(:author_request, :id => id, :type => 'name_description')
assert_form_action(:action => 'author_request', :id => id,
:type => 'name_description')
id = location_descriptions(:albion_desc).id
requires_login(:author_request, :id => id, :type => 'location_description')
assert_form_action(:action => 'author_request', :id => id,
:type => 'location_description')
params = {
:id => name_descriptions(:coprinus_comatus_desc).id,
:type => 'name_description',
:email => {
:subject => "Author request subject",
:message => "Message for authors"
}
}
post_requires_login(:author_request, params)
assert_response(:controller => 'name', :action => 'show_name_description',
:id => name_descriptions(:coprinus_comatus_desc).id)
assert_flash(:request_success.t)
params = {
:id => location_descriptions(:albion_desc).id,
:type => 'location_description',
:email => {
:subject => "Author request subject",
:message => "Message for authors"
}
}
post_requires_login(:author_request, params)
assert_response(:controller => 'location', :action => 'show_location_description',
:id => location_descriptions(:albion_desc).id)
assert_flash(:request_success.t)
end
def test_review_authors_locatios
desc = location_descriptions(:albion_desc)
params = { :id => desc.id, :type => 'LocationDescription' }
desc.authors.clear
assert_user_list_equal([], desc.reload.authors)
# Make sure it lets Rolf and only Rolf see this page.
assert(!@mary.in_group?('reviewers'))
assert(@rolf.in_group?('reviewers'))
requires_user(:review_authors, :show_location, params)
assert_response('review_authors')
# Remove Rolf from reviewers group.
user_groups(:reviewers).users.delete(@rolf)
@rolf.reload
assert(!@rolf.in_group?('reviewers'))
# Make sure it fails to let unauthorized users see page.
get(:review_authors, params)
assert_response(:action => :show_location, :id => desc.id)
# Make Rolf an author.
desc.add_author(@rolf)
desc.save
desc.reload
assert_user_list_equal([@rolf], desc.authors)
# Rolf should be able to do it now.
get(:review_authors, params)
assert_response('review_authors')
# Rolf giveth with one hand...
post(:review_authors, params.merge(:add => @mary.id))
assert_response('review_authors')
desc.reload
assert_user_list_equal([@mary, @rolf], desc.authors)
# ...and taketh with the other.
post(:review_authors, params.merge(:remove => @mary.id))
assert_response('review_authors')
desc.reload
assert_user_list_equal([@rolf], desc.authors)
end
def test_review_authors_name
name = names(:peltigera)
desc = name.description
params = { :id => desc.id, :type => 'NameDescription' }
# Make sure it lets reviewers get to page.
requires_login(:review_authors, params)
assert_response('review_authors')
# Remove Rolf from reviewers group.
user_groups(:reviewers).users.delete(@rolf)
assert(!@rolf.reload.in_group?('reviewers'))
# Make sure it fails to let unauthorized users see page.
get(:review_authors, params)
assert_response(:action => :show_name, :id => name.id)
# Make Rolf an author.
desc.add_author(@rolf)
assert_user_list_equal([@rolf], desc.reload.authors)
# Rolf should be able to do it again now.
get(:review_authors, params)
assert_response('review_authors')
# Rolf giveth with one hand...
post(:review_authors, params.merge(:add => @mary.id))
assert_response('review_authors')
assert_user_list_equal([@mary, @rolf], desc.reload.authors)
# ...and taketh with the other.
post(:review_authors, params.merge(:remove => @mary.id))
assert_response('review_authors')
assert_user_list_equal([@rolf], desc.reload.authors)
end
# Test setting export status of names and descriptions.
def test_set_export_status
name = names(:petigera)
params = {
:id => name.id,
:type => 'name',
:value => '1',
}
# Require login.
get('set_export_status', params)
assert_response(:controller => 'account', :action => 'login')
# Require reviewer.
login('dick')
get('set_export_status', params)
assert_flash_error
logout
# Require correct params.
login('rolf')
get('set_export_status', params.merge(:id => 9999))
assert_flash_error
get('set_export_status', params.merge(:type => 'bogus'))
assert_flash_error
get('set_export_status', params.merge(:value => 'true'))
assert_flash_error
# Now check *correct* usage.
assert_equal(true, name.reload.ok_for_export)
get('set_export_status', params.merge(:value => '0'))
assert_response(:controller => 'name', :action => 'show_name', :id => name.id)
assert_equal(false, name.reload.ok_for_export)
get('set_export_status', params.merge(:value => '1'))
assert_response(:controller => 'name', :action => 'show_name', :id => name.id)
assert_equal(true, name.reload.ok_for_export)
end
def test_original_filename_visibility
login('rolf')
get(:show_observation, :id => 4)
assert_true(@response.body.include?('áč€εиts'))
login('mary')
get(:show_observation, :id => 4)
assert_false(@response.body.include?('áč€εиts'))
end
# ------------------------------
# Test creating observations.
# ------------------------------
# Test "get" side of create_observation.
def test_create_observation
requires_login(:create_observation)
assert_form_action(:action => 'create_observation', :approved_name => '')
end
def test_construct_observation_approved_place_name
where = "Albion, California, USA"
generic_construct_observation({
:observation => { :place_name => where},
:name => { :name => "Coprinus comatus"},
:approved_place_name => ""
}, 1, 1, 0)
obs = assigns(:observation)
assert_equal(where, obs.place_name)
end
def test_construct_observation
# Test a simple observation creation with an approved unique name
where = "Simple, Massachusetts, USA"
generic_construct_observation({
:observation => { :place_name => where, :thumb_image_id => '0' },
:name => { :name => "Coprinus comatus" }
}, 1,1,0)
obs = assigns(:observation)
nam = assigns(:naming)
assert_equal(where, obs.where)
assert_equal(names(:coprinus_comatus).id, nam.name_id)
assert_equal("2.03659", "%.5f" % obs.vote_cache)
assert_not_nil(obs.rss_log)
# This was getting set to zero instead of nil if no images were uploaded
# when obs was created.
assert_equal(nil, obs.thumb_image_id)
# Test a simple observation creation of an unknown
where = "Unknown, Massachusetts, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 1,0,0)
obs = assigns(:observation)
assert_equal(where, obs.where) # Make sure it's the right observation
assert_not_nil(obs.rss_log)
# Test an observation creation with a new name
generic_construct_observation({
:name => { :name => "New name" }
}, 0,0,0)
# Test an observation creation with an approved new name
new_name = "Argus arg-arg"
generic_construct_observation({
:name => { :name => new_name },
:approved_name => new_name
}, 1,1,2)
# Test an observation creation with an approved new name with extra space
new_name = "Another new-name"
generic_construct_observation({
:name => { :name => new_name + " " },
:approved_name => new_name + " "
}, 1,1,2)
# Test an observation creation with an approved section (should fail)
new_name = "Argus section Argus"
generic_construct_observation({
:name => { :name => new_name },
:approved_name => new_name
}, 0,0,0)
# Test an observation creation with an approved junk name
new_name = "This is a bunch of junk"
generic_construct_observation({
:name => { :name => new_name },
:approved_name => new_name
}, 0,0,0)
# Test an observation creation with multiple matches
generic_construct_observation({
:name => { :name => "Amanita baccata" }
}, 0,0,0)
# Test an observation creation with one of the multiple matches chosen
generic_construct_observation({
:name => { :name => "Amanita baccata" },
:chosen_name => { :name_id => names(:amanita_baccata_arora).id }
}, 1,1,0)
# Test an observation creation with one of the multiple matches chosen
generic_construct_observation({
:name => { :name => names(:pluteus_petasatus_deprecated).text_name }
}, 1,1,0)
nam = assigns(:naming)
assert_equal(names(:pluteus_petasatus_approved).id, nam.name_id)
# Test an observation creation with a deprecated name
generic_construct_observation({
:name => { :name => "Lactarius subalpinus" }
}, 0,0,0)
# Test an observation creation with a deprecated name, but a chosen approved alternative
new_name = "Lactarius subalpinus"
generic_construct_observation({
:name => { :name => new_name },
:approved_name => new_name,
:chosen_name => { :name_id => names(:lactarius_alpinus).id }
}, 1,1,0)
nam = assigns(:naming)
assert_equal(nam.name, names(:lactarius_alpinus))
# Test an observation creation with a deprecated name that has been approved
new_name = "Lactarius subalpinus"
generic_construct_observation({
:name => { :name => new_name },
:approved_name => new_name,
:chosen_name => { }
}, 1,1,0)
nam = assigns(:naming)
assert_equal(nam.name, names(:lactarius_subalpinus))
# Test an observation creation with an approved new name
new_name = "Agaricus novus"
Name.find_by_text_name('Agaricus').destroy
generic_construct_observation({
:name => { :name => new_name },
:approved_name => new_name
}, 1,1,2)
name = Name.find_by_text_name(new_name)
assert(name)
assert_equal(new_name, name.text_name)
# Test an observation that generates emails
QueuedEmail.queue_emails(true)
count_before = QueuedEmail.count
name = names(:agaricus_campestris)
notifications = Notification.find_all_by_flavor_and_obj_id(:name, name.id)
assert_equal(2, notifications.length)
where = "Simple, Massachusetts, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => name.text_name }
}, 1,1,0)
obs = assigns(:observation)
nam = assigns(:naming)
assert_equal(where, obs.where) # Make sure it's the right observation
assert_equal(name.id, nam.name_id) # Make sure it's the right name
assert_not_nil(obs.rss_log)
count_after = QueuedEmail.count
assert_equal(count_before+2, count_after)
# Test a simple observation creation of an unknown with a lat/long
lat = 34.1622
long = -118.3521
generic_construct_observation({
:observation => { :place_name => '', :lat => lat, :long => long },
:name => { :name => "Unknown" },
}, 1,0,0)
obs = assigns(:observation)
assert_equal(lat.to_s, obs.lat.to_s)
assert_equal(long.to_s, obs.long.to_s)
assert_objs_equal(Location.unknown, obs.location)
assert_not_nil(obs.rss_log)
lat2 = '34°9’43.92”N'
long2 = '118°21′7.56″W'
generic_construct_observation({
:observation => { :place_name => '', :lat => lat2, :long => long2 },
:name => { :name => "Unknown" },
}, 1,0,0)
obs = assigns(:observation)
assert_equal(lat.to_s, obs.lat.to_s)
assert_equal(long.to_s, obs.long.to_s)
assert_objs_equal(Location.unknown, obs.location)
assert_not_nil(obs.rss_log)
# Make sure it doesn't accept no location AND no lat/long.
generic_construct_observation({
:observation => { :place_name => '', :lat => '', :long => '' },
:name => { :name => "Unknown" },
}, 0,0,0)
# ... unless explicitly tell it "unknown" location.
generic_construct_observation({
:observation => { :place_name => 'Earth', :lat => '', :long => '' },
:name => { :name => "Unknown" },
}, 1,0,0)
# Test a simple observation creation of an unknown with various altitudes
for input, output in [
[ '500', 500 ],
[ '500m', 500 ],
[ '500 ft.', 152 ],
[ ' 500\' ', 152 ]
]
where = 'Unknown, Massachusetts, USA'
generic_construct_observation({
:observation => { :place_name => where, :alt => input },
:name => { :name => 'Unknown' },
}, 1,0,0)
obs = assigns(:observation)
assert_equal(output, obs.alt)
assert_equal(where, obs.where) # Make sure it's the right observation
assert_not_nil(obs.rss_log)
end
end
def test_construct_observation_dubious_place_names
# Test a reversed name with a scientific user
where = "USA, Massachusetts, Reversed"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 1,0,0, @roy)
# Test a reversible order
where = "Reversible, Massachusetts,USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0)
where = "USA,Massachusetts, Reversible"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0, @roy)
# Test a bogus country name
where = "Bogus, Massachusetts, UAS"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0)
where = "UAS, Massachusetts, Bogus"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0, @roy)
# Test a bad state name
where = "Bad State Name, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0)
where = "USA, Bad State Name"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0, @roy)
# Test mix of city and county
where = "Burbank, Los Angeles Co., California, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0)
where = "USA, California, Los Angeles Co., Burbank"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0, @roy)
# Test mix of city and county
where = "Falmouth, Barnstable Co., Massachusetts, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0)
where = "USA, Massachusetts, Barnstable Co., Falmouth"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0, @roy)
# Test some bad terms
where = "Some County, Ohio, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0)
where = "Old Rd, Ohio, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 0,0,0)
where = "Old Rd., Ohio, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 1,0,0)
# Test some acceptable additions
where = "near Burbank, Southern California, USA"
generic_construct_observation({
:observation => { :place_name => where },
:name => { :name => "Unknown" }
}, 1,0,0)
end
def test_name_resolution
login('rolf')
params = {
:observation => {
:when => Time.now,
:place_name => 'Somewhere, Massachusetts, USA',
:specimen => '0',
:thumb_image_id => '0',
},
:name => {},
:vote => { :value => "3" },
}
expected_page = "create_location"
# Can we create observation with existing genus?
agaricus = names(:agaricus)
params[:name][:name] = 'Agaricus'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
params[:name][:name] = 'Agaricus sp'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
params[:name][:name] = 'Agaricus sp.'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
# Can we create observation with genus and add author?
params[:name][:name] = 'Agaricus Author'
params[:approved_name] = 'Agaricus Author'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
assert_equal('Agaricus sp. Author', agaricus.reload.search_name)
agaricus.author = nil
agaricus.search_name = 'Agaricus sp.'
agaricus.save
params[:name][:name] = 'Agaricus sp Author'
params[:approved_name] = 'Agaricus sp Author'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
assert_equal('Agaricus sp. Author', agaricus.reload.search_name)
agaricus.author = nil
agaricus.search_name = 'Agaricus sp.'
agaricus.save
params[:name][:name] = 'Agaricus sp. Author'
params[:approved_name] = 'Agaricus sp. Author'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
assert_equal('Agaricus sp. Author', agaricus.reload.search_name)
# Can we create observation with genus specifying author?
params[:name][:name] = 'Agaricus Author'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
params[:name][:name] = 'Agaricus sp Author'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
params[:name][:name] = 'Agaricus sp. Author'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(agaricus.id, assigns(:observation).name_id)
# Can we create observation with deprecated genus?
psalliota = names(:psalliota)
params[:name][:name] = 'Psalliota'
params[:approved_name] = 'Psalliota'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(psalliota.id, assigns(:observation).name_id)
params[:name][:name] = 'Psalliota sp'
params[:approved_name] = 'Psalliota sp'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(psalliota.id, assigns(:observation).name_id)
params[:name][:name] = 'Psalliota sp.'
params[:approved_name] = 'Psalliota sp.'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(psalliota.id, assigns(:observation).name_id)
# Can we create observation with deprecated genus, adding author?
params[:name][:name] = 'Psalliota Author'
params[:approved_name] = 'Psalliota Author'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(psalliota.id, assigns(:observation).name_id)
assert_equal('Psalliota sp. Author', psalliota.reload.search_name)
psalliota.author = nil
psalliota.search_name = 'Psalliota sp.'
psalliota.save
params[:name][:name] = 'Psalliota sp Author'
params[:approved_name] = 'Psalliota sp Author'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(psalliota.id, assigns(:observation).name_id)
assert_equal('Psalliota sp. Author', psalliota.reload.search_name)
psalliota.author = nil
psalliota.search_name = 'Psalliota sp.'
psalliota.save
params[:name][:name] = 'Psalliota sp. Author'
params[:approved_name] = 'Psalliota sp. Author'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal(psalliota.id, assigns(:observation).name_id)
assert_equal('Psalliota sp. Author', psalliota.reload.search_name)
# Can we create new quoted genus?
params[:name][:name] = '"One"'
params[:approved_name] = '"One"'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One"', assigns(:observation).name.text_name)
assert_equal('"One" sp.', assigns(:observation).name.search_name)
params[:name][:name] = '"Two" sp'
params[:approved_name] = '"Two" sp'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"Two"', assigns(:observation).name.text_name)
assert_equal('"Two" sp.', assigns(:observation).name.search_name)
params[:name][:name] = '"Three" sp.'
params[:approved_name] = '"Three" sp.'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"Three"', assigns(:observation).name.text_name)
assert_equal('"Three" sp.', assigns(:observation).name.search_name)
params[:name][:name] = '"One"'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One"', assigns(:observation).name.text_name)
params[:name][:name] = '"One" sp'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One"', assigns(:observation).name.text_name)
params[:name][:name] = '"One" sp.'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One"', assigns(:observation).name.text_name)
# Can we create species under the quoted genus?
params[:name][:name] = '"One" foo'
params[:approved_name] = '"One" foo'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One" foo', assigns(:observation).name.text_name)
params[:name][:name] = '"One" "bar"'
params[:approved_name] = '"One" "bar"'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One" "bar"', assigns(:observation).name.text_name)
params[:name][:name] = '"One" Author'
params[:approved_name] = '"One" Author'
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One"', assigns(:observation).name.text_name)
assert_equal('"One" sp. Author', assigns(:observation).name.search_name)
params[:name][:name] = '"One" sp Author'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One"', assigns(:observation).name.text_name)
assert_equal('"One" sp. Author', assigns(:observation).name.search_name)
params[:name][:name] = '"One" sp. Author'
params[:approved_name] = nil
post(:create_observation, params)
assert_response(:action => expected_page)
assert_equal('"One"', assigns(:observation).name.text_name)
assert_equal('"One" sp. Author', assigns(:observation).name.search_name)
end
# ----------------------------------------------------------------
# Test edit_observation and edit_naming, both "get" and "post".
# ----------------------------------------------------------------
# (Sorry, these used to all be edit/update_observation, now they're
# confused because of the naming stuff.)
def test_edit_observation_get
obs = observations(:coprinus_comatus_obs)
assert_equal("rolf", obs.user.login)
params = { :id => obs.id.to_s }
requires_user(:edit_observation, ["observer", "show_observation"], params)
assert_form_action(:action => 'edit_observation', :id => obs.id.to_s)
end
def test_edit_observation
obs = observations(:detailed_unknown)
modified = obs.rss_log.modified
new_where = "Somewhere In, Japan"
new_notes = "blather blather blather"
new_specimen = false
params = {
:id => obs.id.to_s,
:observation => {
:place_name => new_where,
"when(1i)" => "2001",
"when(2i)" => "2",
"when(3i)" => "3",
:notes => new_notes,
:specimen => new_specimen,
:thumb_image_id => "0",
},
:good_images => '1 2',
:good_image => {
'1' => {
:notes => 'new notes',
:original_name => 'new name',
:copyright_holder => 'someone else',
'when(1i)' => '2012',
'when(2i)' => '4',
'when(3i)' => '6',
:license_id => '3',
},
},
:log_change => { :checked => '1' }
}
post_requires_user(:edit_observation, ["observer", "show_observation"], params, 'mary')
assert_response(:controller => :location, :action => :create_location)
assert_equal(10, @rolf.reload.contribution)
obs = assigns(:observation)
assert_equal(new_where, obs.where)
assert_equal("2001-02-03", obs.when.to_s)
assert_equal(new_notes, obs.notes)
assert_equal(new_specimen, obs.specimen)
assert_not_equal(modified, obs.rss_log.modified)
assert_not_equal(0, obs.thumb_image_id)
img = images(:in_situ).reload
assert_equal('new notes', img.notes)
assert_equal('new name', img.original_name)
assert_equal('someone else', img.copyright_holder)
assert_equal('2012-04-06', img.when.to_s)
assert_equal(licenses(:ccwiki30), img.license)
end
def test_edit_observation_no_logging
obs = observations(:detailed_unknown)
modified = obs.rss_log.modified
where = "Somewhere, China"
params = {
:id => obs.id.to_s,
:observation => {
:place_name => where,
:when => obs.when,
:notes => obs.notes,
:specimen => obs.specimen,
},
:log_change => { :checked => '0' }
}
post_requires_user(:edit_observation, ["observer", "show_observation"], params, 'mary')
assert_response(:controller => :location, :action => :create_location)
assert_equal(10, @rolf.reload.contribution)
obs = assigns(:observation)
assert_equal(where, obs.where)
assert_equal(modified, obs.rss_log.modified)
end
def test_edit_observation_bad_place_name
obs = observations(:detailed_unknown)
modified = obs.rss_log.modified
new_where = "test_update_observation"
new_notes = "blather blather blather"
new_specimen = false
params = {
:id => obs.id.to_s,
:observation => {
:place_name => new_where,
"when(1i)" => "2001",
"when(2i)" => "2",
"when(3i)" => "3",
:notes => new_notes,
:specimen => new_specimen,
:thumb_image_id => "0",
},
:log_change => { :checked => '1' }
}
post_requires_user(:edit_observation, ["observer", "show_observation"], params, 'mary')
assert_response(:success) # Which really means failure
end
def test_edit_observation_with_another_users_image
img1 = images(:in_situ)
img2 = images(:turned_over)
img3 = images(:commercial_inquiry_image)
obs = observations(:detailed_unknown)
obs.images << img3
obs.save
obs.reload
assert_equal(img1.user_id, obs.user_id)
assert_equal(img2.user_id, obs.user_id)
assert_not_equal(img3.user_id, obs.user_id)
img_ids = obs.images.map(&:id)
assert_equal([1, 2, 3], img_ids)
old_img1_notes = img1.notes
old_img2_notes = img2.notes
old_img3_notes = img3.notes
params = {
:id => obs.id.to_s,
:observation => {
:place_name => obs.place_name,
:when => obs.when,
:notes => obs.notes,
:specimen => obs.specimen,
:thumb_image_id => "0",
},
:good_images => img_ids.map(&:to_s).join(' '),
:good_image => {
img2.id.to_s => { :notes => 'new notes for two', },
img3.id.to_s => { :notes => 'new notes for three', },
},
}
login('mary')
post(:edit_observation, params)
assert_response(:action => :show_observation)
assert_flash_success
assert_equal(old_img1_notes, img1.reload.notes)
assert_equal('new notes for two', img2.reload.notes)
assert_equal(old_img3_notes, img3.reload.notes)
end
def test_edit_observation_with_non_image
obs = observations(:minimal_unknown)
file = FilePlus.new("#{RAILS_ROOT}/test/fixtures/projects.yml")
file.content_type = 'text/plain'
params = {
:id => obs.id,
:observation => {
:place_name => obs.place_name,
:when => obs.when,
:notes => obs.notes,
:specimen => obs.specimen,
:thumb_image_id => '0',
},
:good_images => '',
:good_image => {},
:image => {
'0' => {
:image => file,
:when => Time.now,
},
},
}
login('mary')
post(:edit_observation, params)
assert_response(:success) # means failure!
assert_flash_error
end
# ----------------------------
# Test namings.
# ----------------------------
# Now test the naming part of it.
def test_create_naming_get
obs = observations(:coprinus_comatus_obs)
params = {
:id => obs.id.to_s
}
requires_login(:create_naming, params)
assert_form_action(:action => 'create_naming', :approved_name => '', :id => obs.id.to_s)
end
# Now test the naming part of it.
def test_edit_naming_get
nam = namings(:coprinus_comatus_naming)
params = {
:id => nam.id.to_s
}
requires_user(:edit_naming, ["observer", "show_observation"], params)
assert_form_action(:action => 'edit_naming', :approved_name => nam.text_name, :id => nam.id.to_s)
end
def test_update_observation_new_name
login('rolf')
nam = namings(:coprinus_comatus_naming)
old_name = nam.text_name
new_name = "Easter bunny"
params = {
:id => nam.id.to_s,
:name => { :name => new_name }
}
post(:edit_naming, params)
assert_response('edit_naming')
assert_equal(10, @rolf.reload.contribution)
obs = assigns(:naming)
assert_not_equal(new_name, nam.text_name)
assert_equal(old_name, nam.text_name)
end
def test_update_observation_approved_new_name
login('rolf')
nam = namings(:coprinus_comatus_naming)
old_name = nam.text_name
new_name = "Easter bunny"
params = {
:id => nam.id.to_s,
:name => { :name => new_name },
:approved_name => new_name,
:vote => { :value => 1 }
}
post(:edit_naming, params)
assert_response(:action => :show_observation)
# Clones naming, creates Easter sp and E. bunny, but no votes.
assert_equal(10 + 10*2 + 2, @rolf.reload.contribution)
nam = assigns(:naming)
assert_equal(new_name, nam.text_name)
assert_not_equal(old_name, nam.text_name)
assert(!nam.name.deprecated)
end
def test_update_observation_multiple_match
login('rolf')
nam = namings(:coprinus_comatus_naming)
old_name = nam.text_name
new_name = "Amanita baccata"
params = {
:id => nam.id.to_s,
:name => { :name => new_name }
}
post(:edit_naming, params)
assert_response('edit_naming')
assert_equal(10, @rolf.reload.contribution)
nam = assigns(:naming)
assert_not_equal(new_name, nam.text_name)
assert_equal(old_name, nam.text_name)
end
def test_update_observation_chosen_multiple_match
login('rolf')
nam = namings(:coprinus_comatus_naming)
old_name = nam.text_name
new_name = "Amanita baccata"
params = {
:id => nam.id.to_s,
:name => { :name => new_name },
:chosen_name => { :name_id => names(:amanita_baccata_arora).id },
:vote => { :value => 1 }
}
post(:edit_naming, params)
assert_response(:action => :show_observation)
# Must be cloning naming with no vote.
assert_equal(12, @rolf.reload.contribution)
nam = assigns(:naming)
assert_equal(new_name, nam.name.text_name)
assert_equal(new_name + " sensu Arora", nam.text_name)
assert_not_equal(old_name, nam.text_name)
end
def test_update_observation_deprecated
login('rolf')
nam = namings(:coprinus_comatus_naming)
old_name = nam.text_name
new_name = "Lactarius subalpinus"
params = {
:id => nam.id.to_s,
:name => { :name => new_name }
}
post(:edit_naming, params)
assert_response('edit_naming')
assert_equal(10, @rolf.reload.contribution)
nam = assigns(:naming)
assert_not_equal(new_name, nam.text_name)
assert_equal(old_name, nam.text_name)
end
def test_update_observation_chosen_deprecated
login('rolf')
nam = namings(:coprinus_comatus_naming)
start_name = nam.name
new_name = "Lactarius subalpinus"
chosen_name = names(:lactarius_alpinus)
params = {
:id => nam.id.to_s,
:name => { :name => new_name },
:approved_name => new_name,
:chosen_name => { :name_id => chosen_name.id },
:vote => { :value => 1 }
}
post(:edit_naming, params)
assert_response(:action => :show_observation)
# Must be cloning naming, with no vote.
assert_equal(12, @rolf.reload.contribution)
nam = assigns(:naming)
assert_not_equal(start_name.id, nam.name_id)
assert_equal(chosen_name.id, nam.name_id)
end
def test_update_observation_accepted_deprecated
login('rolf')
nam = namings(:coprinus_comatus_naming)
start_name = nam.name
new_text_name = names(:lactarius_subalpinus).text_name
params = {
:id => nam.id.to_s,
:name => { :name => new_text_name },
:approved_name => new_text_name,
:chosen_name => { },
:vote => { :value => 3 },
}
post(:edit_naming, params)
assert_response(:action => :show_observation)
# Must be cloning the naming, but no votes?
assert_equal(12, @rolf.reload.contribution)
nam = assigns(:naming)
assert_not_equal(start_name.id, nam.name_id)
assert_equal(new_text_name, nam.name.text_name)
end
# ------------------------------------------------------------
# Test proposing new names, casting and changing votes, and
# setting and changing preferred_namings.
# ------------------------------------------------------------
# This is the standard case, nothing unusual or stressful here.
def test_propose_naming
o_count = Observation.count
g_count = Naming.count
n_count = Name.count
v_count = Vote.count
# Make a few assertions up front to make sure fixtures are as expected.
assert_equal(names(:coprinus_comatus).id, observations(:coprinus_comatus_obs).name_id)
assert(namings(:coprinus_comatus_naming).user_voted?(@rolf))
assert(namings(:coprinus_comatus_naming).user_voted?(@mary))
assert(!namings(:coprinus_comatus_naming).user_voted?(@dick))
assert(namings(:coprinus_comatus_other_naming).user_voted?(@rolf))
assert(namings(:coprinus_comatus_other_naming).user_voted?(@mary))
assert(!namings(:coprinus_comatus_other_naming).user_voted?(@dick))
# Rolf, the owner of observations(:coprinus_comatus_obs), already has a naming, which
# he's 80% sure of. Create a new one (the genus Agaricus) that he's 100%
# sure of. (Mary also has a naming with two votes.)
params = {
:id => observations(:coprinus_comatus_obs).id,
:name => { :name => "Agaricus" },
:vote => { :value => "3" },
:reason => {
"1" => { :check => "1", :notes => "Looks good to me." },
"2" => { :check => "1", :notes => "" },
"3" => { :check => "0", :notes => "Spore texture." },
"4" => { :check => "0", :notes => "" }
}
}
login('rolf')
post(:create_naming, params)
assert_response(:redirect)
# Make sure the right number of objects were created.
assert_equal(o_count + 0, Observation.count)
assert_equal(g_count + 1, Naming.count)
assert_equal(n_count + 0, Name.count)
assert_equal(v_count + 1, Vote.count)
# Make sure contribution is updated correctly.
assert_equal(12, @rolf.reload.contribution)
# Make sure everything I need is reloaded.
observations(:coprinus_comatus_obs).reload
# Get new objects.
naming = Naming.last
vote = Vote.last
# Make sure observation was updated and referenced correctly.
assert_equal(3, observations(:coprinus_comatus_obs).namings.length)
assert_equal(names(:agaricus).id, observations(:coprinus_comatus_obs).name_id)
# Make sure naming was created correctly and referenced.
assert_equal(observations(:coprinus_comatus_obs), naming.observation)
assert_equal(names(:agaricus).id, naming.name_id)
assert_equal(@rolf, naming.user)
assert_equal(3, naming.get_reasons.select(&:used?).length)
assert_equal(1, naming.votes.length)
# Make sure vote was created correctly.
assert_equal(naming, vote.naming)
assert_equal(@rolf, vote.user)
assert_equal(3, vote.value)
# Make sure reasons were created correctly.
nr1, nr2, nr3, nr4 = naming.get_reasons
assert_equal(1, nr1.num)
assert_equal(2, nr2.num)
assert_equal(3, nr3.num)
assert_equal(4, nr4.num)
assert_equal("Looks good to me.", nr1.notes)
assert_equal("", nr2.notes)
assert_equal("Spore texture.", nr3.notes)
assert_equal(nil, nr4.notes)
assert(nr1.used?)
assert(nr2.used?)
assert(nr3.used?)
assert(!nr4.used?)
# Make sure a few random methods work right, too.
assert_equal(3, naming.vote_sum)
assert_equal(vote, naming.users_vote(@rolf))
assert(naming.user_voted?(@rolf))
assert(!naming.user_voted?(@mary))
end
# Now see what happens when rolf's new naming is less confident than old.
def test_propose_uncertain_naming
g_count = Naming.count
params = {
:id => observations(:coprinus_comatus_obs).id,
:name => { :name => "Agaricus" },
:vote => { :value => "-1" },
}
login('rolf')
post(:create_naming, params)
assert_response(:redirect)
assert_equal(12, @rolf.reload.contribution)
# Make sure everything I need is reloaded.
observations(:coprinus_comatus_obs).reload
namings(:coprinus_comatus_naming).reload
# Get new objects.
naming = Naming.last
# Make sure observation was updated right.
assert_equal(names(:coprinus_comatus).id, observations(:coprinus_comatus_obs).name_id)
# Sure, check the votes, too, while we're at it.
assert_equal(3, namings(:coprinus_comatus_naming).vote_sum) # 2+1 = 3
end
# Now see what happens when a third party proposes a name, and it wins.
def test_propose_dicks_naming
o_count = Observation.count
g_count = Naming.count
n_count = Name.count
v_count = Vote.count
# Dick proposes "Conocybe filaris" out of the blue.
params = {
:id => observations(:coprinus_comatus_obs).id,
:name => { :name => "Conocybe filaris" },
:vote => { :value => "3" },
}
login("dick")
post(:create_naming, params)
assert_response(:redirect)
assert_equal(12, @dick.reload.contribution)
naming = Naming.last
# Make sure the right number of objects were created.
assert_equal(o_count + 0, Observation.count)
assert_equal(g_count + 1, Naming.count)
assert_equal(n_count + 0, Name.count)
assert_equal(v_count + 1, Vote.count)
# Make sure everything I need is reloaded.
observations(:coprinus_comatus_obs).reload
namings(:coprinus_comatus_naming).reload
namings(:coprinus_comatus_other_naming).reload
# Check votes.
assert_equal(3, namings(:coprinus_comatus_naming).vote_sum)
assert_equal(0, namings(:coprinus_comatus_other_naming).vote_sum)
assert_equal(3, naming.vote_sum)
assert_equal(2, namings(:coprinus_comatus_naming).votes.length)
assert_equal(2, namings(:coprinus_comatus_other_naming).votes.length)
assert_equal(1, naming.votes.length)
# Make sure observation was updated right.
assert_equal(names(:conocybe_filaris).id, observations(:coprinus_comatus_obs).name_id)
end
# Test a bug in name resolution: was failing to recognize that
# "Genus species (With) Author" was recognized even if "Genus species"
# was already in the database.
def test_create_naming_with_author_when_name_without_author_already_exists
params = {
:id => observations(:coprinus_comatus_obs).id,
:name => { :name => "Conocybe filaris (With) Author" },
:vote => { :value => "3" },
}
login("dick")
post(:create_naming, params)
assert_response(:action => "show_observation", :id => observations(:coprinus_comatus_obs).id)
# Dick is getting points for the naming, vote, and name change.
assert_equal(12 + 10, @dick.reload.contribution)
naming = Naming.last
assert_equal("Conocybe filaris", naming.name.text_name)
assert_equal("(With) Author", naming.name.author)
assert_equal(names(:conocybe_filaris).id, naming.name_id)
end
# Test a bug in name resolution: was failing to recognize that
# "Genus species (With) Author" was recognized even if "Genus species"
# was already in the database.
def test_create_naming_fill_in_author
params = {
:id => observations(:coprinus_comatus_obs).id,
:name => { :name => 'Agaricus campestris' },
}
login("dick")
post(:create_naming, params)
assert_response(:success) # really means failed
assert_equal('Agaricus campestris L.', @controller.instance_variable_get('@what'))
end
# Test a bug in name resolution: was failing to recognize that
# "Genus species (With) Author" was recognized even if "Genus species"
# was already in the database.
def test_create_name_with_quotes
name = 'Foo "bar" Author'
params = {
:id => observations(:coprinus_comatus_obs).id,
:name => { :name => name },
:approved_name => name
}
login("dick")
post(:create_naming, params)
assert_response(:success) # really means failed
assert(name = Name.find_by_text_name('Foo "bar"'))
assert_equal('Foo "bar" Author', name.search_name)
end
# ----------------------------
# Test voting.
# ----------------------------
# Now have Dick vote on Mary's name.
# Votes: rolf=2/-3, mary=1/3, dick=-1/3
# Rolf prefers naming 3 (vote 2 -vs- -3).
# Mary prefers naming 9 (vote 1 -vs- 3).
# Dick now prefers naming 9 (vote 3).
# Summing, 3 gets 2+1/3=1, 9 gets -3+3+3/4=.75, so 3 gets it.
def test_cast_vote_dick
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
login('dick')
post(:cast_vote, :value => "3", :id => nam2.id)
assert_equal(11, @dick.reload.contribution)
# Check votes.
assert_equal(3, nam1.reload.vote_sum)
assert_equal(2, nam1.votes.length)
assert_equal(3, nam2.reload.vote_sum)
assert_equal(3, nam2.votes.length)
# Make sure observation was updated right.
assert_equal(names(:coprinus_comatus).id, obs.reload.name_id)
# If Dick votes on the other as well, then his first vote should
# get demoted and his preference should change.
# Summing, 3 gets 2+1+3/4=1.5, 9 gets -3+3+2/4=.5, so 3 keeps it.
obs.change_vote(nam1, 3, @dick)
assert_equal(12, @dick.reload.contribution)
assert_equal(3, nam1.reload.users_vote(@dick).value)
assert_equal(6, nam1.vote_sum)
assert_equal(3, nam1.votes.length)
assert_equal(2, nam2.reload.users_vote(@dick).value)
assert_equal(2, nam2.vote_sum)
assert_equal(3, nam2.votes.length)
assert_equal(names(:coprinus_comatus).id, obs.reload.name_id)
end
# Now have Rolf change his vote on his own naming. (no change in prefs)
# Votes: rolf=3->2/-3, mary=1/3, dick=x/x
def test_cast_vote_rolf_change
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
login('rolf')
post(:cast_vote, :value => "2", :id => nam1.id)
assert_equal(10, @rolf.reload.contribution)
# Make sure observation was updated right.
assert_equal(names(:coprinus_comatus).id, obs.reload.name_id)
# Check vote.
assert_equal(3, nam1.reload.vote_sum)
assert_equal(2, nam1.votes.length)
end
# Now have Rolf increase his vote for Mary's. (changes consensus)
# Votes: rolf=2/-3->3, mary=1/3, dick=x/x
def test_cast_vote_rolf_second_greater
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
login('rolf')
post(:cast_vote, :value => "3", :id => nam2.id)
assert_equal(10, @rolf.reload.contribution)
# Make sure observation was updated right.
assert_equal(names(:agaricus_campestris).id, obs.reload.name_id)
# Check vote.
assert_equal(6, nam2.reload.vote_sum)
assert_equal(2, nam2.votes.length)
end
# Now have Rolf increase his vote for Mary's insufficiently. (no change)
# Votes: rolf=2/-3->-1, mary=1/3, dick=x/x
# Summing, 3 gets 2+1=3, 9 gets -1+3=2, so 3 keeps it.
def test_cast_vote_rolf_second_lesser
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
login('rolf')
post(:cast_vote,
:value => "-1",
:id => nam2.id
)
assert_equal(10, @rolf.reload.contribution)
# Make sure observation was updated right.
assert_equal(names(:coprinus_comatus).id, obs.reload.name_id)
# Check vote.
assert_equal(3, nam1.reload.vote_sum)
assert_equal(2, nam2.reload.vote_sum)
assert_equal(2, nam2.votes.length)
end
# Now, have Mary delete her vote against Rolf's naming. This NO LONGER has the effect
# of excluding Rolf's naming from the consensus calculation due to too few votes.
# (Have Dick vote first... I forget what this was supposed to test for, but it's clearly
# superfluous now).
# Votes: rolf=2/-3, mary=1->x/3, dick=x/x->3
# Summing after Dick votes, 3 gets 2+1/3=1, 9 gets -3+3+3/4=.75, 3 keeps it.
# Summing after Mary deletes, 3 gets 2/2=1, 9 gets -3+3+3/4=.75, 3 still keeps it in this voting algorithm, arg.
def test_cast_vote_mary
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
login('dick')
obs.change_vote(nam2, 3, @dick)
assert_equal(names(:coprinus_comatus).id, obs.reload.name_id)
assert_equal(11, @dick.reload.contribution)
login('mary')
post(:cast_vote, :value => Vote.delete_vote, :id => nam1.id)
assert_equal(9, @mary.reload.contribution)
# Check votes.
assert_equal(2, nam1.reload.vote_sum)
assert_equal(1, nam1.votes.length)
assert_equal(3, nam2.reload.vote_sum)
assert_equal(3, nam2.votes.length)
# Make sure observation is changed correctly.
assert_equal(names(:coprinus_comatus).search_name, obs.reload.name.search_name,
"Cache for 3: #{nam1.vote_cache}, 9: #{nam2.vote_cache}")
end
# Rolf can destroy his naming if Mary deletes her vote on it.
def test_rolf_destroy_rolfs_naming
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
# First delete Mary's vote for it.
login('mary')
obs.change_vote(nam1, Vote.delete_vote, @mary)
assert_equal(9, @mary.reload.contribution)
old_naming_id = nam1.id
old_vote1_id = votes(:coprinus_comatus_owner_vote).id
old_vote2_id = votes(:coprinus_comatus_other_vote).id rescue nil
login('rolf')
get(:destroy_naming, :id => nam1.id)
# Make sure naming and associated vote and reason were actually destroyed.
assert_raises(ActiveRecord::RecordNotFound) do
Naming.find(old_naming_id)
end
assert_raises(ActiveRecord::RecordNotFound) do
Vote.find(old_vote1_id)
end
assert_raises(ActiveRecord::RecordNotFound) do
Vote.find(old_vote2_id)
end
# Make sure observation was updated right.
assert_equal(names(:agaricus_campestris).id, obs.reload.name_id)
# Check votes. (should be no change)
assert_equal(0, nam2.reload.vote_sum)
assert_equal(2, nam2.votes.length)
end
# Make sure Rolf can't destroy his naming if Dick prefers it.
def test_rolf_destroy_rolfs_naming_when_dick_prefers_it
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
old_naming_id = nam1.id
old_vote1_id = votes(:coprinus_comatus_owner_vote).id
old_vote2_id = votes(:coprinus_comatus_other_vote).id
# Make Dick prefer it.
login('dick')
obs.change_vote(nam1, 3, @dick)
assert_equal(11, @dick.reload.contribution)
# Have Rolf try to destroy it.
login('rolf')
get(:destroy_naming, :id => nam1.id)
# Make sure naming and associated vote and reason are still there.
assert(Naming.find(old_naming_id))
assert(Vote.find(old_vote1_id))
assert(Vote.find(old_vote2_id))
# Make sure observation is unchanged.
assert_equal(names(:coprinus_comatus).id, obs.reload.name_id)
# Check votes are unchanged.
assert_equal(6, nam1.reload.vote_sum)
assert_equal(3, nam1.votes.length)
assert_equal(0, nam2.reload.vote_sum)
assert_equal(2, nam2.votes.length)
end
# Rolf makes changes to vote and reasons of his naming. Shouldn't matter
# whether Mary has voted on it.
def test_edit_naming_thats_being_used_just_change_reasons
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
o_count = Observation.count
g_count = Naming.count
n_count = Name.count
v_count = Vote.count
# Rolf makes superficial changes to his naming.
login('rolf')
post(:edit_naming,
:id => nam1.id,
:name => { :name => names(:coprinus_comatus).search_name },
:vote => { :value => "3" },
:reason => {
"1" => { :check => "1", :notes => "Change to macro notes." },
"2" => { :check => "1", :notes => "" },
"3" => { :check => "0", :notes => "Add some micro notes." },
"4" => { :check => "0", :notes => "" }
}
)
assert_equal(10, @rolf.reload.contribution)
# Make sure the right number of objects were created.
assert_equal(o_count + 0, Observation.count)
assert_equal(g_count + 0, Naming.count)
assert_equal(n_count + 0, Name.count)
assert_equal(v_count + 0, Vote.count)
# Make sure observation is unchanged.
assert_equal(names(:coprinus_comatus).id, obs.reload.name_id)
# Check votes.
assert_equal(4, nam1.reload.vote_sum) # 2+1 -> 3+1
assert_equal(2, nam1.votes.length)
# Check new reasons.
nrs = nam1.get_reasons
assert_equal(3, nrs.select(&:used?).length)
assert_equal(1, nrs[0].num)
assert_equal(2, nrs[1].num)
assert_equal(3, nrs[2].num)
assert_equal("Change to macro notes.", nrs[0].notes)
assert_equal("", nrs[1].notes)
assert_equal("Add some micro notes.", nrs[2].notes)
assert_nil(nrs[3].notes)
end
# Rolf makes changes to name of his naming. Shouldn't be allowed to do this
# if Mary has voted on it. Should clone naming, vote, and reasons.
def test_edit_naming_thats_being_used_change_name
obs = observations(:coprinus_comatus_obs)
nam1 = namings(:coprinus_comatus_naming)
nam2 = namings(:coprinus_comatus_other_naming)
o_count = Observation.count
g_count = Naming.count
n_count = Name.count
v_count = Vote.count
# Now, Rolf makes name change to his naming (leave rest the same).
login('rolf')
assert_equal(10, @rolf.contribution)
post(:edit_naming,
:id => nam1.id,
:name => { :name => "Conocybe filaris" },
:vote => { :value => "2" },
:reason => {
"1" => { :check => "1", :notes => "Isn't it obvious?" },
"2" => { :check => "0", :notes => "" },
"3" => { :check => "0", :notes => "" },
"4" => { :check => "0", :notes => "" }
}
)
assert_response(:redirect) # redirect indicates success
assert_equal(12, @rolf.reload.contribution)
# Make sure the right number of objects were created.
assert_equal(o_count + 0, Observation.count)
assert_equal(g_count + 1, Naming.count)
assert_equal(n_count + 0, Name.count)
assert_equal(v_count + 1, Vote.count)
# Get new objects.
naming = Naming.last
vote = Vote.last
# Make sure observation is unchanged.
assert_equal(names(:conocybe_filaris).id, obs.reload.name_id)
# Make sure old naming is unchanged.
assert_equal(names(:coprinus_comatus).id, nam1.reload.name_id)
assert_equal(1, nam1.get_reasons.select(&:used?).length)
assert_equal(3, nam1.vote_sum)
assert_equal(2, nam1.votes.length)
# Check new naming.
assert_equal(observations(:coprinus_comatus_obs), naming.observation)
assert_equal(names(:conocybe_filaris).id, naming.name_id)
assert_equal(@rolf, naming.user)
nrs = naming.get_reasons.select(&:used?)
assert_equal(1, nrs.length)
assert_equal(1, nrs.first.num)
assert_equal("Isn't it obvious?", nrs.first.notes)
assert_equal(2, naming.vote_sum)
assert_equal(1, naming.votes.length)
assert_equal(vote, naming.votes.first)
assert_equal(2, vote.value)
assert_equal(@rolf, vote.user)
end
def test_show_votes
# First just make sure the page displays.
get_with_dump(:show_votes, :id => namings(:coprinus_comatus_naming).id)
assert_response('show_votes')
# Now try to make somewhat sure the content is right.
table = namings(:coprinus_comatus_naming).calc_vote_table
str1 = Vote.agreement(votes(:coprinus_comatus_owner_vote).value)
str2 = Vote.agreement(votes(:coprinus_comatus_other_vote).value)
for str in table.keys
if str == str1 && str1 == str2
assert_equal(2, table[str][:num])
elsif str == str1
assert_equal(1, table[str][:num])
elsif str == str2
assert_equal(1, table[str][:num])
else
assert_equal(0, table[str][:num])
end
end
end
# -----------------------------------
# Test extended observation forms.
# -----------------------------------
def test_javascripty_name_reasons
login('rolf')
# If javascript isn't enabled, then checkbox isn't required.
post(:create_observation,
:observation => { :place_name => 'Where, Japan', :when => Time.now },
:name => { :name => names(:coprinus_comatus).text_name },
:vote => { :value => 3 },
:reason => {
"1" => { :check => '0', :notes => '' },
"2" => { :check => '0', :notes => 'foo' },
"3" => { :check => '1', :notes => '' },
"4" => { :check => '1', :notes => 'bar' }
}
)
assert_response(:redirect) # redirected = successfully created
naming = Naming.find(assigns(:naming).id)
reasons = naming.get_reasons.select(&:used?).map(&:num).sort
assert_equal([2,3,4], reasons)
# If javascript IS enabled, then checkbox IS required.
post(:create_observation,
:observation => { :place_name => 'Where, Japan', :when => Time.now },
:name => { :name => names(:coprinus_comatus).text_name },
:vote => { :value => 3 },
:reason => {
"1" => { :check => '0', :notes => '' },
"2" => { :check => '0', :notes => 'foo' },
"3" => { :check => '1', :notes => '' },
"4" => { :check => '1', :notes => 'bar' }
},
:was_js_on => 'yes'
)
assert_response(:redirect) # redirected = successfully created
naming = Naming.find(assigns(:naming).id)
reasons = naming.get_reasons.select(&:used?).map(&:num).sort
assert_equal([3,4], reasons)
end
def test_create_with_image_upload
login('rolf')
time0 = Time.utc(2000)
time1 = Time.utc(2001)
time2 = Time.utc(2002)
time3 = Time.utc(2003)
week_ago = 1.week.ago
setup_image_dirs
file = "#{RAILS_ROOT}/test/fixtures/images/Coprinus_comatus.jpg"
file1 = FilePlus.new(file)
file1.content_type = 'image/jpeg'
file2 = FilePlus.new(file)
file2.content_type = 'image/jpeg'
file3 = FilePlus.new(file)
file3.content_type = 'image/jpeg'
new_image_1 = Image.create(
:copyright_holder => 'holder_1',
:when => time1,
:notes => 'notes_1',
:user_id => 1,
:image => file1,
:content_type => 'image/jpeg',
:created => week_ago,
:modified => week_ago
)
new_image_2 = Image.create(
:copyright_holder => 'holder_2',
:when => time2,
:notes => 'notes_2',
:user_id => 1,
:image => file2,
:content_type => 'image/jpeg',
:created => week_ago,
:modified => week_ago
)
assert(new_image_1.modified < 1.day.ago)
assert(new_image_2.modified < 1.day.ago)
post(:create_observation,
:observation => {
:place_name => 'Zzyzx, Japan',
:when => time0,
:thumb_image_id => 0, # (make new image the thumbnail)
:notes => 'blah',
},
:image => {
'0' => {
:image => file3,
:copyright_holder => 'holder_3',
:when => time3,
:notes => 'notes_3',
},
},
:good_image => {
new_image_1.id.to_s => {
},
new_image_2.id.to_s => {
:notes => 'notes_2_new',
},
},
# (attach these two images once observation created)
:good_images => "#{new_image_1.id} #{new_image_2.id}",
)
assert_response(:redirect) # redirected = successfully created
obs = Observation.find_by_where('Zzyzx, Japan')
assert_equal(1, obs.user_id)
assert_equal(time0, obs.when)
assert_equal('Zzyzx, Japan', obs.place_name)
new_image_1.reload
new_image_2.reload
imgs = obs.images.sort_by(&:id)
img_ids = imgs.map(&:id)
assert_equal([new_image_1.id, new_image_2.id, new_image_2.id+1], img_ids)
assert_equal(new_image_2.id+1, obs.thumb_image_id)
assert_equal('holder_1', imgs[0].copyright_holder)
assert_equal('holder_2', imgs[1].copyright_holder)
assert_equal('holder_3', imgs[2].copyright_holder)
assert_equal(time1, imgs[0].when)
assert_equal(time2, imgs[1].when)
assert_equal(time3, imgs[2].when)
assert_equal('notes_1', imgs[0].notes)
assert_equal('notes_2_new', imgs[1].notes)
assert_equal('notes_3', imgs[2].notes)
assert(imgs[0].modified < 1.day.ago) # notes not changed
assert(imgs[1].modified > 1.day.ago) # notes changed
end
def test_image_upload_when_create_fails
login('rolf')
setup_image_dirs
file = "#{RAILS_ROOT}/test/fixtures/images/Coprinus_comatus.jpg"
file = FilePlus.new(file)
file.content_type = 'image/jpeg'
post(:create_observation,
:observation => {
:place_name => '', # will cause failure
:when => Time.now,
},
:image => { '0' => {
:image => file,
:copyright_holder => 'zuul',
:when => Time.now,
}}
)
assert_response(:success) # success = failure, paradoxically
# Make sure image was created, but that it is unattached, and that it has
# been kept in the @good_images array for attachment later.
img = Image.find_by_copyright_holder('zuul')
assert(img)
assert_equal([], img.observations)
assert_equal([img.id], @controller.instance_variable_get('@good_images').map(&:id))
end
def test_project_checkboxes_in_create_observation
init_for_project_checkbox_tests
login('rolf')
get(:create_observation)
assert_project_checks(@proj1.id => :unchecked, @proj2.id => :no_field)
login('dick')
get(:create_observation)
assert_project_checks(@proj1.id => :no_field, @proj2.id => :unchecked)
# Should have different default if recently posted observation attached to project.
obs = Observation.create!
@proj2.add_observation(obs)
get(:create_observation)
assert_project_checks(@proj1.id => :no_field, @proj2.id => :checked)
# Make sure it remember state of checks if submit fails.
post(:create_observation,
:name => {:name => 'Screwy Name'}, # (ensures it will fail)
:project => {"id_#{@proj1.id}" => '0'}
)
assert_project_checks(@proj1.id => :no_field, @proj2.id => :unchecked)
end
def test_project_checkboxes_in_edit_observation
init_for_project_checkbox_tests
login('rolf')
get(:edit_observation, :id => @obs1.id)
assert_response(:redirect)
get(:edit_observation, :id => @obs2.id)
assert_project_checks(@proj1.id => :unchecked, @proj2.id => :no_field)
post(:edit_observation, :id => @obs2.id,
:observation => { :place_name => 'blah blah blah' }, # (ensures it will fail)
:project => { "id_#{@proj1.id}" => '1' }
)
assert_project_checks(@proj1.id => :checked, @proj2.id => :no_field)
post(:edit_observation, :id => @obs2.id,
:project => { "id_#{@proj1.id}" => '1' }
)
assert_response(:redirect)
assert_obj_list_equal([@proj1], @obs2.reload.projects)
assert_obj_list_equal([@proj1], @img2.reload.projects)
login('mary')
get(:edit_observation, :id => @obs2.id)
assert_project_checks(@proj1.id => :checked, @proj2.id => :no_field)
get(:edit_observation, :id => @obs1.id)
assert_project_checks(@proj1.id => :unchecked, @proj2.id => :checked)
post(:edit_observation, :id => @obs1.id,
:observation => { :place_name => 'blah blah blah' }, # (ensures it will fail)
:project => {
"id_#{@proj1.id}" => '1',
"id_#{@proj2.id}" => '0',
}
)
assert_project_checks(@proj1.id => :checked, @proj2.id => :unchecked)
post(:edit_observation, :id => @obs1.id,
:project => {
"id_#{@proj1.id}" => '1',
"id_#{@proj2.id}" => '1',
}
)
assert_response(:redirect)
assert_obj_list_equal([@proj1, @proj2], @obs1.reload.projects.sort_by(&:id))
assert_obj_list_equal([@proj1, @proj2], @img1.reload.projects.sort_by(&:id))
login('dick')
get(:edit_observation, :id => @obs2.id)
assert_response(:redirect)
get(:edit_observation, :id => @obs1.id)
assert_project_checks(@proj1.id => :checked_but_disabled, @proj2.id => :checked)
end
def init_for_project_checkbox_tests
@proj1 = projects(:eol_project)
@proj2 = projects(:bolete_project)
@obs1 = observations(:detailed_unknown)
@obs2 = observations(:coprinus_comatus_obs)
@img1 = @obs1.images.first
@img2 = @obs2.images.first
assert_users_equal(@mary, @obs1.user)
assert_users_equal(@rolf, @obs2.user)
assert_users_equal(@mary, @img1.user)
assert_users_equal(@rolf, @img2.user)
assert_obj_list_equal([@proj2], @obs1.projects)
assert_obj_list_equal([], @obs2.projects)
assert_obj_list_equal([@proj2], @img1.projects)
assert_obj_list_equal([], @img2.projects)
assert_obj_list_equal([@rolf, @mary, @katrina], @proj1.user_group.users)
assert_obj_list_equal([@dick], @proj2.user_group.users)
end
def assert_project_checks(project_states)
for id, state in project_states
assert_checkbox_state("project_id_#{id}", state)
end
end
def test_list_checkboxes_in_create_observation
init_for_list_checkbox_tests
login('rolf')
get(:create_observation)
assert_list_checks(@spl1.id => :unchecked, @spl2.id => :no_field)
login('mary')
get(:create_observation)
assert_list_checks(@spl1.id => :no_field, @spl2.id => :unchecked)
login('katrina')
get(:create_observation)
assert_list_checks(@spl1.id => :no_field, @spl2.id => :no_field)
# Dick is on project that owns @spl2.
login('dick')
get(:create_observation)
assert_list_checks(@spl1.id => :no_field, @spl2.id => :unchecked)
# Should have different default if recently posted observation attached to project.
obs = Observation.create!
@spl1.add_observation(obs) # (shouldn't affect anything for create)
@spl2.add_observation(obs)
get(:create_observation)
assert_list_checks(@spl1.id => :no_field, @spl2.id => :checked)
# Make sure it remember state of checks if submit fails.
post(:create_observation,
:name => {:name => 'Screwy Name'}, # (ensures it will fail)
:list => {"id_#{@spl2.id}" => '0'}
)
assert_list_checks(@spl1.id => :no_field, @spl2.id => :unchecked)
end
def test_list_checkboxes_in_edit_observation
init_for_list_checkbox_tests
login('rolf')
get(:edit_observation, :id => @obs1.id)
assert_list_checks(@spl1.id => :unchecked, @spl2.id => :no_field)
post(:edit_observation, :id => @obs1.id,
:observation => { :place_name => 'blah blah blah' }, # (ensures it will fail)
:list => { "id_#{@spl1.id}" => '1' }
)
assert_list_checks(@spl1.id => :checked, @spl2.id => :no_field)
post(:edit_observation, :id => @obs1.id,
:list => { "id_#{@spl1.id}" => '1' }
)
assert_response(:redirect)
assert_obj_list_equal([@spl1], @obs1.reload.species_lists)
get(:edit_observation, :id => @obs2.id)
assert_response(:redirect)
login('mary')
get(:edit_observation, :id => @obs1.id)
assert_response(:redirect)
get(:edit_observation, :id => @obs2.id)
assert_list_checks(@spl1.id => :no_field, @spl2.id => :checked)
@spl1.add_observation(@obs2)
get(:edit_observation, :id => @obs2.id)
assert_list_checks(@spl1.id => :checked_but_disabled, @spl2.id => :checked)
login('dick')
get(:edit_observation, :id => @obs2.id)
assert_list_checks(@spl1.id => :checked_but_disabled, @spl2.id => :checked)
end
def init_for_list_checkbox_tests
@spl1 = species_lists(:first_species_list)
@spl2 = species_lists(:unknown_species_list)
@obs1 = observations(:coprinus_comatus_obs)
@obs2 = observations(:detailed_unknown)
assert_users_equal(@rolf, @spl1.user)
assert_users_equal(@mary, @spl2.user)
assert_users_equal(@rolf, @obs1.user)
assert_users_equal(@mary, @obs2.user)
assert_obj_list_equal([], @obs1.species_lists)
assert_obj_list_equal([@spl2], @obs2.species_lists)
end
def assert_list_checks(list_states)
for id, state in list_states
assert_checkbox_state("list_id_#{id}", state)
end
end
# ----------------------------
# Interest.
# ----------------------------
def test_interest_in_show_observation
login('rolf')
minimal_unknown = observations(:minimal_unknown)
# No interest in this observation yet.
get(:show_observation, :id => minimal_unknown.id)
assert_response(:success)
assert_link_in_html(/
]+watch\d*.png[^>]+>[\w\s]*/,
:controller => 'interest', :action => 'set_interest',
:type => 'Observation', :id => minimal_unknown.id, :state => 1
)
assert_link_in_html(/
]+ignore\d*.png[^>]+>[\w\s]*/,
:controller => 'interest', :action => 'set_interest',
:type => 'Observation', :id => minimal_unknown.id, :state => -1
)
# Turn interest on and make sure there is an icon linked to delete it.
Interest.create(:target => minimal_unknown, :user => @rolf, :state => true)
get(:show_observation, :id => minimal_unknown.id)
assert_response(:success)
assert_link_in_html(/
]+halfopen\d*.png[^>]+>/,
:controller => 'interest', :action => 'set_interest',
:type => 'Observation', :id => minimal_unknown.id, :state => 0
)
assert_link_in_html(/
]+ignore\d*.png[^>]+>/,
:controller => 'interest', :action => 'set_interest',
:type => 'Observation', :id => minimal_unknown.id, :state => -1
)
# Destroy that interest, create new one with interest off.
Interest.find_all_by_user_id(@rolf.id).last.destroy
Interest.create(:target => minimal_unknown, :user => @rolf, :state => false)
get(:show_observation, :id => minimal_unknown.id)
assert_response(:success)
assert_link_in_html(/
]+halfopen\d*.png[^>]+>/,
:controller => 'interest', :action => 'set_interest',
:type => 'Observation', :id => minimal_unknown.id, :state => 0
)
assert_link_in_html(/
]+watch\d*.png[^>]+>/,
:controller => 'interest', :action => 'set_interest',
:type => 'Observation', :id => minimal_unknown.id, :state => 1
)
end
# ----------------------------
# Lookup name.
# ----------------------------
def test_lookup_name
get(:lookup_comment, :id => 1)
assert_response(:controller => :comment, :action => :show_comment, :id => 1)
get(:lookup_comment, :id => 10000)
assert_response(:controller => :comment, :action => :index_comment)
assert_flash_error
get(:lookup_image, :id => 1)
assert_response(:controller => :image, :action => :show_image, :id => 1)
get(:lookup_image, :id => 10000)
assert_response(:controller => :image, :action => :index_image)
assert_flash_error
get(:lookup_location, :id => 1)
assert_response(:controller => :location, :action => :show_location, :id => 1)
get(:lookup_location, :id => 'Burbank, California')
assert_response(:controller => :location, :action => :show_location, :id => locations(:burbank).id)
get(:lookup_location, :id => 'California, Burbank')
assert_response(:controller => :location, :action => :show_location, :id => locations(:burbank).id)
get(:lookup_location, :id => 'Zyzyx, Califonria')
assert_response(:controller => :location, :action => :index_location)
assert_flash_error
get(:lookup_location, :id => 'California')
assert_response(:controller => :location, :action => :index_location)
assert_flash_warning
get(:lookup_name, :id => 1)
assert_response(:controller => :name, :action => :show_name, :id => 1)
get(:lookup_name, :id => names(:coprinus_comatus).id)
assert_response(:controller => :name, :action => :show_name, :id => names(:coprinus_comatus).id)
get(:lookup_name, :id => 'Agaricus campestris')
assert_response(:controller => :name, :action => :show_name, :id => names(:agaricus_campestris).id)
get(:lookup_name, :id => 'Agaricus newname')
assert_response(:controller => :name, :action => :index_name)
assert_flash_error
get(:lookup_name, :id => 'Amanita baccata sensu Borealis')
assert_response(:controller => :name, :action => :show_name, :id => names(:amanita_baccata_borealis).id)
get(:lookup_name, :id => 'Amanita baccata')
assert_response(:controller => :name, :action => :index_name)
assert_flash_warning
get(:lookup_name, :id => 'Agaricus campestris L.')
assert_response(:controller => :name, :action => :show_name, :id => names(:agaricus_campestris).id)
get(:lookup_name, :id => 'Agaricus campestris Linn.')
assert_response(:controller => :name, :action => :show_name, :id => names(:agaricus_campestris).id)
get(:lookup_project, :id => 1)
assert_response(:controller => :project, :action => :show_project, :id => 1)
get(:lookup_project, :id => 'Bolete')
assert_response(:controller => :project, :action => :show_project, :id => projects(:bolete_project).id)
get(:lookup_project, :id => 'Bogus')
assert_response(:controller => :project, :action => :index_project)
assert_flash_error
get(:lookup_project, :id => 'project')
assert_response(:controller => :project, :action => :index_project)
assert_flash_warning
get(:lookup_species_list, :id => 1)
assert_response(:controller => :species_list, :action => :show_species_list, :id => 1)
get(:lookup_species_list, :id => 'Mysteries')
assert_response(:controller => :species_list, :action => :show_species_list, :id => species_lists(:unknown_species_list).id)
get(:lookup_species_list, :id => 'species list')
assert_response(:controller => :species_list, :action => :index_species_list)
assert_flash_warning
get(:lookup_species_list, :id => 'Flibbertygibbets')
assert_response(:controller => :species_list, :action => :index_species_list)
assert_flash_error
get(:lookup_user, :id => 1)
assert_response(:controller => :observer, :action => :show_user, :id => 1)
get(:lookup_user, :id => 'mary')
assert_response(:controller => :observer, :action => :show_user, :id => @mary.id)
get(:lookup_user, :id => 'Einstein')
assert_response(:controller => :observer, :action => :index_rss_log)
assert_flash_error
end
end