- Publicity: Public Only All
sync-test-procs.tcl
Automated tests for synchronization API
- Location:
- packages/acs-authentication/tcl/test/sync-test-procs.tcl
- Created:
- 05 September 2003
- Author:
- Lars Pind <lars@collaboraid.biz>
- CVS Identification:
$Id: sync-test-procs.tcl,v 1.28.2.13 2024/08/28 10:06:11 gustafn Exp $
Procedures in this file
- _acs-authentication__auth_sync_process_ims_implementations (private)
- _acs-authentication__sync_actions (private)
- _acs-authentication__sync_batch_for_local (private)
- _acs-authentication__sync_batch_ims_example_doc (private)
- _acs-authentication__sync_batch_ims_test (private)
- _acs-authentication__sync_file_get_document (private)
- _acs-authentication__sync_get_parameters (private)
- _acs-authentication__sync_http_get_document (private)
- _acs-authentication__sync_snapshot (private)
- _acs-authentication__sync_start_end (private)
Detailed information
_acs-authentication__auth_sync_process_ims_implementations (private)
_acs-authentication__auth_sync_process_ims_implementations
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_actions (private)
_acs-authentication__sync_actions
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_batch_for_local (private)
_acs-authentication__sync_batch_for_local
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_batch_ims_example_doc (private)
_acs-authentication__sync_batch_ims_example_doc
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_batch_ims_test (private)
_acs-authentication__sync_batch_ims_test
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_file_get_document (private)
_acs-authentication__sync_file_get_document
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_get_parameters (private)
_acs-authentication__sync_get_parameters
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_http_get_document (private)
_acs-authentication__sync_http_get_document
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_snapshot (private)
_acs-authentication__sync_snapshot
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
_acs-authentication__sync_start_end (private)
_acs-authentication__sync_start_end
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
Content File Source
ad_library { Automated tests for synchronization API @author Lars Pind (lars@collaboraid.biz) @creation-date 05 September 2003 @cvs-id $Id: sync-test-procs.tcl,v 1.28.2.13 2024/08/28 10:06:11 gustafn Exp $ } aa_register_case \ -cats {api db} \ -procs { auth::authority::local auth::sync::job::create_entry auth::sync::job::end auth::sync::job::end_get_document auth::sync::job::start auth::sync::job::start_get_document auth::sync::purge_jobs auth::sync::job::get_authority_id } \ sync_start_end { Test batch job basics: Starting, getting document, adding entries, ending. } { aa_run_with_teardown \ -rollback \ -test_code { # Start noninteractive job set local_authority_id [auth::authority::local] set job_id [auth::sync::job::start \ -authority_id $local_authority_id] aa_equals "Authority has been stored correctly" \ [auth::sync::job::get_authority_id -job_id $job_id] \ $local_authority_id set broken_job_id [db_string get_broken_job { select max(job_id) + 1 from auth_batch_jobs }] aa_true "Querying the authority on an invalid job id fails" [catch { auth::sync::job::get_authority_id -job_id $broken_job_id }] aa_true "Returns a job_id" {$job_id ne ""} # Get doc auth::sync::job::start_get_document -job_id $job_id auth::sync::job::end_get_document \ -job_id $job_id \ -doc_status "ok" \ -doc_message "" \ -document {<enterprise><person recstatus="1"></person></enterprise>} # Valid successful log entry auth::sync::job::create_entry \ -job_id $job_id \ -operation "insert" \ -username "foobar" \ -user_id [ad_conn user_id] \ -success # Valid unsuccessful log entry auth::sync::job::create_entry \ -job_id $job_id \ -operation "insert" \ -username "foobar" \ -user_id [ad_conn user_id] \ -message "A problem" \ -element_messages "" # End job array set job [auth::sync::job::end -job_id $job_id] aa_true "Elapsed time less than 30 seconds" {$job(run_time_seconds) < 30} aa_log "Elapsed time: $job(run_time_seconds) seconds" aa_false "Not interactive" [string is true -strict $job(interactive_p)] aa_equals "Number of actions" $job(num_actions) 2 aa_equals "Number of problems" $job(num_problems) 1 aa_false "Log URL nonempty" {$job(log_url) eq ""} # Purge not deleting the job auth::sync::purge_jobs \ -num_days 1 aa_equals "Job still exists" [db_string job_exists_p { select count(*) from auth_batch_job_entries where job_id = :job_id }] 2 # Tricking it into deleting the job aa_log "Updating the job end time" db_dml update_job { update auth_batch_jobs set job_end_time = to_date('1974-03-27', 'YYYY-MM-DD') where job_id = :job_id } auth::sync::purge_jobs \ -num_days 1 aa_equals "Job has been purged" [db_string job_exists_p { select count(*) from auth_batch_job_entries where job_id = :job_id }] 0 } } aa_register_case \ -cats {api} \ -procs { acs_user::get acs_user::get_user_info ad_generate_random_string auth::authority::local auth::sync::job::action auth::sync::job::end auth::sync::job::get_entry auth::sync::job::start util_sets_equal_p } \ sync_actions { Test job actions: insert, update, delete. } { aa_run_with_teardown \ -rollback \ -test_code { # Start noninteractive job set job_id [auth::sync::job::start -authority_id [auth::authority::local]] aa_true "Returns a job_id" {[info exists job_id]} ##### # # Valid insert action # ##### array unset user_info set username1 [ad_generate_random_string] set email1 "[ad_generate_random_string]@foo.bar" set screen_name1 [ad_generate_random_string] set user_info(email) $email1 set user_info(first_names) [ad_generate_random_string] set user_info(last_name) [ad_generate_random_string] set user_info(url) "http://[ad_generate_random_string].com" set user_info(screen_name) $screen_name1 aa_log "--- Valid insert --- auth::sync::job::action -opration insert -username $username1 -email $email1" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "insert" \ -username $username1 \ -array user_info] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "t" aa_equals "entry.message" $entry(message) {} aa_equals "entry.element_messages" $entry(element_messages) {} aa_log "entry.user_id = '$entry(user_id)'" aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" if { [aa_true "Entry has user_id set" {$entry(user_id) ne ""}] } { set user [acs_user::get -user_id $entry(user_id)] aa_equals "user.first_names" [dict get $user first_names] $user_info(first_names) aa_equals "user.last_name" [dict get $user last_name] $user_info(last_name) aa_equals "user.email" [dict get $user email] [string tolower $email1] aa_equals "user.authority_id" [dict get $user authority_id] [auth::authority::local] aa_equals "user.username" [dict get $user username] $username1 aa_equals "user.url" [dict get $user url] $user_info(url) aa_equals "user.screen_name" [dict get $user screen_name] $user_info(screen_name) } ##### # # Invalid insert action: Reusing username, email # ##### aa_log "--- Invalid insert: reusing username, email --- auth::sync::job::action -opration insert -username $username1 -email $email1" array unset user_info set user_info(first_names) [ad_generate_random_string] set user_info(last_name) [ad_generate_random_string] set user_info(email) $email1 set user_info(url) "http://" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "insert" \ -username $username1 \ -array user_info] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "f" aa_true "entry.message not empty" {$entry(message) ne ""} aa_log "entry.user_id = '$entry(user_id)'" aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" ##### # # Valid update action # ##### set email2 "[ad_generate_random_string]@foo.bar" array unset user_info set user_info(first_names) [ad_generate_random_string] set user_info(last_name) [ad_generate_random_string] set user_info(url) "http://[ad_generate_random_string].com" set user_info(email) $email2 aa_log "--- Valid update --- auth::sync::job::action -opration update -username $username1" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "update" \ -username $username1 \ -array user_info] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "t" aa_equals "entry.message" $entry(message) {} aa_equals "entry.element_messages" $entry(element_messages) {} aa_log "entry.user_id = '$entry(user_id)'" aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" if { [aa_true "Entry has user_id set" {$entry(user_id) ne ""}] } { set user [acs_user::get -user_id $entry(user_id)] aa_equals "user.first_names" [dict get $user first_names] $user_info(first_names) aa_equals "user.last_name" [dict get $user last_name] $user_info(last_name) aa_equals "user.email" [dict get $user email] [string tolower $email2] aa_equals "user.authority_id" [dict get $user authority_id] [auth::authority::local] aa_equals "user.username" [dict get $user username] $username1 aa_equals "user.url" [dict get $user url] $user_info(url) } ##### # # Valid update action, not changing any columns # ##### # copy the old user_info array array set user_info2 [array get user_info] array unset user_info aa_log "--- Valid update, no changes --- auth::sync::job::action -opration update -username $username1" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "update" \ -username $username1 \ -array user_info] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "t" aa_equals "entry.message" $entry(message) {} aa_equals "entry.element_messages" $entry(element_messages) {} aa_log "entry.user_id = '$entry(user_id)'" aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" if { [aa_true "Entry has user_id set" {$entry(user_id) ne ""}] } { set user [acs_user::get -user_id $entry(user_id)] aa_equals "user.first_names" [dict get $user first_names] $user_info2(first_names) aa_equals "user.last_name" [dict get $user last_name] $user_info2(last_name) aa_equals "user.email" [dict get $user email] $user_info2(email) aa_equals "user.authority_id" [dict get $user authority_id] [auth::authority::local] aa_equals "user.username" [dict get $user username] $username1 aa_equals "user.url" [dict get $user url] $user_info2(url) } ##### # # Invalid insert action: Missing first_names, last_name invalid, email, url invalid # ##### set username2 [ad_generate_random_string] array unset user_info set user_info(last_name) {<b>Foobar</b>} set user_info(email) "not_an_email" set user_info(url) "NotAURL" aa_log "--- Invalid insert --- auth::sync::job::action -opration update -username $username2" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "insert" \ -username $username2 \ -array user_info] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "f" aa_log "entry.message = '$entry(message)'" if { [aa_true "entry.element_messages not empty" \ {[info exists entry(element_messages)] && $entry(element_messages) ne ""}] } { aa_log "entry.element_messages = '$entry(element_messages)'" array unset elm_msgs array set elm_msgs $entry(element_messages) aa_log "array names elm_msgs = '[array names elm_msgs]'" aa_true "first_names, last_name, email, url have problems" [util_sets_equal_p { first_names last_name email url } [array names elm_msgs]] } ##### # # Valid delete action # ##### aa_log "--- Valid delete --- auth::sync::job::action -opration delete -username $username1" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "delete" \ -username $username1] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "t" aa_log "entry.message = '$entry(message)'" if { [aa_true "Entry has user_id set" {[info exists entry(user_id)] && $entry(user_id) ne ""}] } { set member_state [acs_user::get_user_info \ -user_id $entry(user_id) -element "member_state"] aa_equals "User member state is banned" $member_state "banned" } ##### # # End job # ##### array set job [auth::sync::job::end -job_id $job_id] aa_true "Elapsed time less than 30 seconds" {$job(run_time_seconds) < 30} aa_false "Not interactive" [string is true -strict $job(interactive_p)] aa_equals "Number of actions" $job(num_actions) 6 aa_equals "Number of problems" $job(num_problems) 2 aa_false "Log URL nonempty" {$job(log_url) eq ""} } } aa_register_case \ -cats {api db} \ -procs { acs_user::get ad_generate_random_string auth::authority::get_id auth::sync::job::action auth::sync::job::end auth::sync::job::get_entry auth::sync::job::snapshot_delete_remaining auth::sync::job::start } \ sync_snapshot { Test a snapshot job } { aa_run_with_teardown \ -rollback \ -test_code { # Start noninteractive job set test_authority_id [auth::authority::get_id -short_name "acs_testing"] set job_id [auth::sync::job::start -authority_id $test_authority_id] aa_true "Returns a job_id" {$job_id ne ""} ##### # # Valid insert action # ##### set username1 [ad_generate_random_string] set email1 "[ad_generate_random_string]@foo.bar" array unset user_info set user_info(email) $email1 set user_info(first_names) [ad_generate_random_string] set user_info(last_name) [ad_generate_random_string] set user_info(url) "http://[ad_generate_random_string].com" aa_log "--- Valid insert --- auth::sync::job::action -opration insert -username $username1 -email $email1" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "snapshot" \ -username $username1 \ -array user_info] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "t" aa_equals "entry.message" $entry(message) {} aa_equals "entry.element_messages" $entry(element_messages) {} aa_equals "entry.operation" $entry(operation) "insert" aa_log "entry.user_id = '$entry(user_id)'" aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" if { [aa_true "Entry has user_id set" {$entry(user_id) ne ""}] } { set user [acs_user::get -user_id $entry(user_id)] aa_equals "user.first_names" [dict get $user first_names] $user_info(first_names) aa_equals "user.last_name" [dict get $user last_name] $user_info(last_name) aa_equals "user.email" [dict get $user email] [string tolower $email1] aa_equals "user.authority_id" [dict get $user authority_id] $test_authority_id aa_equals "user.username" [dict get $user username] $username1 aa_equals "user.url" [dict get $user url] $user_info(url) } ##### # # Valid update action # ##### array unset user_info set user_info(email) "[ad_generate_random_string]@foo.bar" set user_info(first_names) [ad_generate_random_string] set user_info(last_name) [ad_generate_random_string] set user_info(url) "http://[ad_generate_random_string].com" aa_log "--- Valid update --- auth::sync::job::action -opration update -username $username1" set entry_id [auth::sync::job::action \ -job_id $job_id \ -operation "snapshot" \ -username $username1 \ -array user_info] array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_equals "entry.success_p" $entry(success_p) "t" aa_equals "entry.message" $entry(message) {} aa_equals "entry.element_messages" $entry(element_messages) {} aa_equals "entry.operation" $entry(operation) "update" aa_log "entry.user_id = '$entry(user_id)'" aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" if { [aa_true "Entry has user_id set" {$entry(user_id) ne ""}] } { set user [acs_user::get -user_id $entry(user_id)] aa_equals "user.first_names" [dict get $user first_names] $user_info(first_names) aa_equals "user.last_name" [dict get $user last_name] $user_info(last_name) aa_equals "user.email" [dict get $user email] [string tolower $user_info(email)] aa_equals "user.authority_id" [dict get $user authority_id] $test_authority_id aa_equals "user.username" [dict get $user username] $username1 aa_equals "user.url" [dict get $user url] $user_info(url) } ##### # # Wrap up batch sync job # ##### # We need this number to check the counts below set authority_id $test_authority_id set num_users_not_banned [db_string select_num { select count(*) from cc_users where authority_id = :authority_id and member_state != 'banned' }] auth::sync::job::snapshot_delete_remaining \ -job_id $job_id ##### # # End job # ##### array set job [auth::sync::job::end -job_id $job_id] aa_true "Elapsed time less than 30 seconds" {$job(run_time_seconds) < 30} aa_false "Not interactive" [string is true -strict $job(interactive_p)] aa_equals "Number of actions" $job(num_actions) [expr {$num_users_not_banned + 1}] aa_equals "Number of problems" $job(num_problems) 0 aa_false "Log URL nonempty" {$job(log_url) eq ""} } } aa_register_case \ -cats {api smoke} \ -procs { auth::authority::batch_sync auth::authority::local auth::sync::job::get } \ sync_batch_for_local { Test a batch job for the local authority } { aa_run_with_teardown \ -rollback \ -test_code { set job_id [auth::authority::batch_sync -authority_id [auth::authority::local]] auth::sync::job::get -job_id $job_id -array job aa_log "job.message = '$job(message)'" aa_true "job.message not empty when called for local authority" {$job(message) ne ""} } } aa_register_case \ -cats {api} \ -procs { acs_sc::impl::get_id auth::authority::batch_sync auth::authority::create auth::sync::job::get auth::sync::job::get_entries auth::sync::job::get_entry util_sets_equal_p util_text_to_url } \ sync_batch_ims_example_doc { Test IMS Enterprise 1.1 batch sync with the XML document from the specification. } { aa_stub acs_sc::invoke { if { $contract eq "auth_sync_retrieve" && $operation eq "GetDocument" } { array set result { doc_status ok doc_message {} document {} snapshot_p f } # Example document grabbed pulled from # http://www.imsglobal.org/enterprise/entv1p1/imsent_bestv1p1.html#1404584 set result(document) { <enterprise> <properties> <datasource>Dunelm Services Limited</datasource> <target>Telecommunications LMS</target> <type>DATABASE UPDATE</type> <datetime>2001-08-08</datetime> </properties> <person recstatus = "1"> <comments>Add a new Person record.</comments> <sourcedid> <source>Dunelm Services Limited</source> <id>CK1</id> </sourcedid> <name> <fn>Clark Kent</fn> <sort>Kent, C</sort> <nickname>Superman</nickname> </name> <demographics> <gender>2</gender> </demographics> <adr> <extadd>The Daily Planet</extadd> <locality>Metropolis</locality> <country>USA</country> </adr> </person> <person recstatus = "2"> <comments>Update a previously created record.</comments> <sourcedid> <source>Dunelm Services Limited</source> <id>CS1</id> </sourcedid> <name> <fn>Colin Smythe</fn> <sort>Smythe, C</sort> <nickname>Colin</nickname> <n> <family>Smythe</family> <given>Colin</given> <other>Manfred</other> <other>Wingarde</other> <prefix>Dr.</prefix> <suffix>C.Eng</suffix> <partname partnametype = "Initials">C.M.W.</partname> </n> </name> <demographics> <gender>2</gender> <bday>1958-02-18</bday> <disability>None.</disability> </demographics> <email>colin@dunelm.com</email> <url>http://www.dunelm.com</url> <tel teltype = "Mobile">4477932335019</tel> <adr> <extadd>Dunelm Services Limited</extadd> <street>34 Acorn Drive</street> <street>Stannington</street> <locality> Sheffield</locality> <region>S.Yorks</region> <pcode>S7 6WA</pcode> <country>UK</country> </adr> <photo imgtype = "gif"> <extref>http://www.dunelm.com/staff/colin2.gif</extref> </photo> <institutionrole primaryrole = "No" institutionroletype = "Alumni"/> <datasource>dunelm:colinsmythe:1</datasource> </person> <person recstatus = "3"> <comments>Delete this record.</comments> <sourcedid> <source>Dunelm Services Limited</source> <id>LL1</id> </sourcedid> <name> <fn>Lois Lane</fn> <sort>Lane, L</sort> </name> </person> </enterprise> } return [array get result] } else { acs_sc::invoke_unstubbed \ -contract $contract \ -operation $operation \ -impl $impl \ -impl_id $impl_id \ -call_args $call_args \ -error=$error_p } } aa_run_with_teardown \ -rollback \ -test_code { # Create a new dummy authority with the dummy IMS get-document driver and the IMS Enterprise 1.1 process driver. array set new_auth { short_name dummy-test pretty_name dummy-test enabled_p t sort_order 999 auth_impl_id {} pwd_impl_id {} forgotten_pwd_url {} change_pwd_url {} register_impl_id {} register_url {} help_contact_text {} batch_sync_enabled_p f } set new_auth(get_doc_impl_id) 1 set new_auth(process_doc_impl_id) [acs_sc::impl::get_id -owner "acs-authentication" -name "IMS_Enterprise_v_1p1"] set new_auth(get_doc_impl_id) [acs_sc::impl::get_id -owner "acs-authentication" -name "HTTPGet"] set authority_id [auth::authority::create \ -array new_auth] set job_id [auth::authority::batch_sync -authority_id $authority_id] auth::sync::job::get -job_id $job_id -array job aa_equals "Number of actions" $job(num_actions) 3 aa_equals "Number of problems" $job(num_problems) 3 foreach entry_id [auth::sync::job::get_entries -job_id $job_id] { array unset entry auth::sync::job::get_entry \ -entry_id $entry_id \ -array entry aa_false "Success_p is false" [string is true -strict $entry(success_p)] array unset elm_msgs array set elm_msgs $entry(element_messages) aa_log "entry.operation = '$entry(operation)'" aa_log "entry.username = '$entry(username)'" aa_log "entry.message = '$entry(message)'" aa_log "array names elm_msgs = '[array names elm_msgs]'" switch $entry(operation) { insert { aa_true "email has a problem (email missing)" [util_sets_equal_p { email } [array names elm_msgs]] } update { aa_true "User does not exist" {$entry(message) ne ""} } delete { aa_false "Message is not empty" {$entry(message) eq ""} } } } aa_log "job.message = '$job(message)'" } } aa_register_case \ -cats {api} \ -procs { acs_sc::impl::get_id acs_user::get acs_user::get_user_info ad_generate_random_string auth::authority::batch_sync auth::authority::create auth::driver::set_parameter_value auth::sync::GetElements auth::sync::process_doc::ims::GetElements auth::sync::job::get auth::sync::job::get_entries auth::sync::job::get_entry util_text_to_url } \ sync_batch_ims_test { Test IMS Enterprise 1.1 batch sync with a constructed document which actually works } { aa_stub acs_sc::invoke { if { $contract eq "auth_sync_retrieve" && $operation eq "GetDocument" } { array set result { doc_status ok doc_message {} document {} } global ims_doc set result(document) "<enterprise> <person recstatus=\"$ims_doc(recstatus)\"> <sourcedid> <id>$ims_doc(username)</id> </sourcedid> <name> <fn>$ims_doc(first_names) $ims_doc(last_name)</fn> <n> <given>$ims_doc(first_names)</given> <family>$ims_doc(last_name)</family> </n> </name> <email>$ims_doc(email)</email> <url>$ims_doc(url)</url> </person> </enterprise>" return [array get result] } else { acs_sc::invoke_unstubbed \ -contract $contract \ -operation $operation \ -impl $impl \ -impl_id $impl_id \ -call_args $call_args \ -error=$error_p } } aa_run_with_teardown \ -rollback \ -test_code { # Create a new dummy authority with the dummy IMS get-document driver and the IMS Enterprise 1.1 process driver. array set new_auth { short_name dummy-test pretty_name dummy-test enabled_p t sort_order 999 auth_impl_id {} pwd_impl_id {} forgotten_pwd_url {} change_pwd_url {} register_impl_id {} register_url {} help_contact_text {} batch_sync_enabled_p f } set new_auth(process_doc_impl_id) [acs_sc::impl::get_id -owner "acs-authentication" -name "IMS_Enterprise_v_1p1"] set new_auth(get_doc_impl_id) [acs_sc::impl::get_id -owner "acs-authentication" -name "HTTPGet"] set authority_id [auth::authority::create \ -array new_auth] global ims_doc ##### # # Insert # ##### aa_log "--- Insert test ---" # 1 = insert operation set ims_doc(recstatus) 1 # dummy user variables set ims_doc(username) [ad_generate_random_string] set ims_doc(first_names) [ad_generate_random_string] set ims_doc(last_name) [ad_generate_random_string] set ims_doc(email) [string tolower "[ad_generate_random_string]@foo.bar"] set ims_doc(url) "http://www.[ad_generate_random_string].com" set job_id [auth::authority::batch_sync -authority_id $authority_id] auth::sync::job::get -job_id $job_id -array job aa_equals "Number of actions" $job(num_actions) 1 aa_equals "Number of problems" $job(num_problems) 0 aa_log "job.message = '$job(message)'" set entry_id [auth::sync::job::get_entries -job_id $job_id] aa_equals "One entry" [llength $entry_id] 1 array unset entry auth::sync::job::get_entry -entry_id $entry_id -array entry aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" set user [acs_user::get -user_id $entry(user_id)] foreach varname { username first_names last_name email url } { aa_equals "$varname" [dict get $user $varname] $ims_doc($varname) } aa_equals "authority_id" [dict get $user authority_id] $authority_id aa_false "member_state not banned" {[dict get $user member_state] eq "banned"} # saving this for later set first_user_id $entry(user_id) ##### # # Update # ##### aa_log "--- Update test ---" # 2 = update operation set ims_doc(recstatus) 2 # dummy user variables # username is unchanged set ims_doc(first_names) [ad_generate_random_string] set ims_doc(last_name) [ad_generate_random_string] set ims_doc(email) [string tolower "[ad_generate_random_string]@foo.bar"] set ims_doc(url) "http://www.[ad_generate_random_string].com" set job_id [auth::authority::batch_sync -authority_id $authority_id] auth::sync::job::get -job_id $job_id -array job aa_equals "Number of actions" $job(num_actions) 1 aa_equals "Number of problems" $job(num_problems) 0 aa_log "job.message = '$job(message)'" set entry_id [auth::sync::job::get_entries -job_id $job_id] aa_equals "One entry" [llength $entry_id] 1 array unset entry auth::sync::job::get_entry -entry_id $entry_id -array entry aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" set user [acs_user::get -user_id $entry(user_id)] foreach varname { username first_names last_name email url } { aa_equals "$varname" [dict get $user $varname] $ims_doc($varname) } aa_false "member_state not banned" {[dict get $user member_state] eq "banned"} ##### # # Delete # ##### aa_log "--- Delete test ---" # 3 = delete operation set ims_doc(recstatus) 3 # user variables stay the same, we are deleting set job_id [auth::authority::batch_sync -authority_id $authority_id] auth::sync::job::get -job_id $job_id -array job aa_equals "Number of actions" $job(num_actions) 1 aa_equals "Number of problems" $job(num_problems) 0 aa_log "job.message = '$job(message)'" set entry_id [auth::sync::job::get_entries -job_id $job_id] aa_equals "One entry" [llength $entry_id] 1 array unset entry auth::sync::job::get_entry -entry_id $entry_id -array entry aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" aa_log "entry.user_id = '$entry(user_id)'" set user_info [acs_user::get_user_info -user_id $entry(user_id)] aa_equals "username" [dict get $user_info username] $ims_doc(username) aa_equals "member_state" [dict get $user_info member_state] "banned" ##### # # Reuse username and email. This should fail, as we don't # allow 'stealing' usernames from banned users. # ##### aa_log "--- Reuse username/email of a deleted user test ---" # 1 = insert operation set ims_doc(recstatus) 1 # attributes of the previously deletes user set old_doc [array get ims_doc] # dummy user variables # same username set ims_doc(first_names) [ad_generate_random_string] set ims_doc(last_name) [ad_generate_random_string] # same email set ims_doc(url) "http://www.[ad_generate_random_string].com" set job_id [auth::authority::batch_sync -authority_id $authority_id] auth::sync::job::get -job_id $job_id -array job # operation has failed because user exists already aa_equals "Number of actions" $job(num_actions) 1 aa_equals "Number of problems" $job(num_problems) 1 aa_log "job.message = '$job(message)'" set entry_id [auth::sync::job::get_entries -job_id $job_id] aa_equals "One entry" [llength $entry_id] 1 array unset entry auth::sync::job::get_entry -entry_id $entry_id -array entry aa_log "entry.message = '$entry(message)'" aa_log "entry.element_messages = '$entry(element_messages)'" aa_log "entry.user_id = '$entry(user_id)'" # all attributes remained the same set user [acs_user::get -user_id $entry(user_id)] foreach varname { username email first_names last_name url } { aa_true "$varname" {[dict get $user $varname] eq [dict get $old_doc $varname]} } aa_equals "authority_id" [dict get $user authority_id] $authority_id # previously deleted user keeps being banned aa_true "member_state is still banned" {[dict get $user member_state] eq "banned"} # Check that first_user_id has had username/email changed ##### # # Test GetElements # ##### aa_log "--- GetElements test ---" set desired_elements [ad_generate_random_string] auth::driver::set_parameter_value \ -authority_id $authority_id \ -impl_id [acs_sc::impl::get_id -owner "acs-authentication" -name "IMS_Enterprise_v_1p1"] \ -parameter Elements \ -value $desired_elements set elements [auth::sync::GetElements -authority_id $authority_id] aa_equals "Elements are '$desired_elements'" $elements $desired_elements } } aa_register_case \ -cats {api smoke} \ -procs { ad_url acs_sc::invoke util_current_location util_text_to_url ad_sign ad_get_signed_cookie_with_expr ad_verify_signature_with_expr auth::sync::get_doc::http::GetDocument } \ sync_http_get_document { Test the HTTPGet implementation of GetDocument service contract. } { set url [::acs::test::url] # When the server is configured with wildcard IPv4 address 0.0.0.0 # and the hostname "localhost", and localhost is mapped on the # host to the IPv6 address "::1", then ns_http to # http://localhost:.../ is rejected, while the connection to the # current IPv4 address http://127.0.0.1:.../ succeeds. However, # the determination of the current IP address requires NaviServer # 4.99.17d3 or newer, so we can't assume, this works always. # # If ad_url is empty, try util_current_location instead. # if {$url eq ""} { set url [util_current_location] } set parsed_url [ns_parseurl $url] if {[dict get $parsed_url host] eq "localhost"} { set url [dict get $parsed_url proto]://127.0.0.1:[dict get $parsed_url port] set url [string trimright $url ":"] } array set result [acs_sc::invoke \ -error \ -contract "auth_sync_retrieve" \ -impl "HTTPGet" \ -operation "GetDocument" \ -call_args [list [list SnapshotURL {} IncrementalURL "$url/SYSTEM/dbtest.tcl"]]] aa_equals "result.doc_status is ok" $result(doc_status) "ok" aa_true "result.doc_message is empty" {$result(doc_message) eq ""} aa_equals "result.document is 'success'" $result(document) "success" } aa_register_case \ -cats {api web} \ -procs { acs_sc::invoke template::util::read_file auth::sync::get_doc::file::GetDocument } \ sync_file_get_document { Test the LocalFilesystem implementation of GetDocument service contract. } { set path "$::acs::rootdir/www/SYSTEM/dbtest.tcl" aa_log "Getting path '$path'" array set result [acs_sc::invoke \ -error \ -contract "auth_sync_retrieve" \ -impl "LocalFilesystem" \ -operation "GetDocument" \ -call_args [list [list SnapshotPath {} IncrementalPath $path]]] aa_equals "result.doc_status is ok" $result(doc_status) "ok" aa_true "result.doc_message is empty" {$result(doc_message) eq ""} aa_equals "result.document is 'success'" $result(document) [template::util::read_file $path] } aa_register_case \ -cats {api web} \ -procs { auth::sync::get_doc::http::GetParameters auth::sync::get_doc::file::GetParameters } \ sync_get_parameters { Test the HTTPGet and LocalFilesystem implementations of GetParameter service contract. } { set result [acs_sc::invoke \ -error \ -contract auth_sync_retrieve \ -impl HTTPGet \ -operation GetParameters] aa_equals "Impl 'HTTPGet' parameters are ok" \ [lsort [dict keys $result]] {IncrementalURL SnapshotURL} set result [acs_sc::invoke \ -error \ -contract auth_sync_retrieve \ -impl LocalFilesystem \ -operation GetParameters] aa_equals "Impl 'LocalFilesystem' parameters are ok" \ [lsort [dict keys $result]] {IncrementalPath SnapshotPath} } aa_register_case \ -cats {api web} \ -procs { auth::sync::process_doc::ims::GetAcknowledgementDocument auth::sync::process_doc::ims::GetElements auth::sync::process_doc::ims::GetParameters auth::sync::process_doc::ims::ProcessDocument auth::sync::job::start auth::sync::job::create_entry } \ auth_sync_process_ims_implementations { Test the IMS_Enterprise_v_1p1 implementations of auth_sync_process service contract. } { aa_section auth::sync::process_doc::ims::GetParameters set parameters [acs_sc::invoke \ -contract auth_sync_process \ -impl IMS_Enterprise_v_1p1 \ -operation GetParameters] aa_equals "Parameters are correct" \ [dict keys $parameters] Elements aa_section auth::sync::process_doc::ims::GetElements aa_equals "Elements correspond to the 'Elements' value in the parameters" \ [acs_sc::invoke \ -contract auth_sync_process \ -impl IMS_Enterprise_v_1p1 \ -operation GetElements \ -call_args [list $parameters]] \ [dict get $parameters Elements] aa_section auth::sync::process_doc::ims::GetAcknowledgementDocument aa_run_with_teardown \ -rollback \ -test_code { set user [acs::test::user::create] set authority_id [acs_user::get \ -user_id [dict get $user user_id] \ -element authority_id] set job_id [auth::sync::job::start \ -authority_id $authority_id] array set recstatus { insert 1 update 2 delete 3 } aa_log "One insert operation" auth::sync::job::create_entry \ -job_id $job_id \ -operation insert \ -username [dict get $user username] \ -success set timestamp 12345 set doc "" append doc {<?xml version="1.0" encoding="} [ns_config "ns/parameters" OutputCharset] {"?>} \n append doc {<enterprise>} \n append doc { <properties>} \n append doc { <type>acknowledgement</type>} \n append doc { <datetime>} $timestamp {</datetime>} \n append doc { </properties>} \n # Loop over successful actions db_foreach select_success_actions { select entry_id, operation, username from auth_batch_job_entries where job_id = :job_id and success_p = 't' order by entry_id } { if { [info exists recstatus($operation)] } { append doc { <person recstatus="} $recstatus($operation) {">} \n append doc { <sourcedid><source>OpenACS</source><id>} $username {</id></sourcedid>} \n append doc { </person>} \n } } append doc {</enterprise>} \n aa_equals "Document was built as expected" \ [acs_sc::invoke \ -contract auth_sync_process \ -impl IMS_Enterprise_v_1p1 \ -operation GetAcknowledgementDocument \ -call_args [list $job_id $doc [list]]] \ $doc aa_log "One invalid operation" aa_true "With invalid operations, call returns an error" [catch { # This is in fact the call that will fail, because # of a check constraint on the 'operation' column. aa_silence_log_entries -serverities error { auth::sync::job::create_entry \ -job_id $job_id \ -operation broken \ -username [dict get $user username] \ -success } # If the check was not there in the database, this # call would also fail, as the check is # implemented in tcl as well. acs_sc::invoke \ -contract auth_sync_process \ -impl IMS_Enterprise_v_1p1 \ -operation GetAcknowledgementDocument \ -call_args [list $job_id $doc [list]] }] } aa_section auth::sync::process_doc::ims::ProcessDocument aa_run_with_teardown \ -rollback \ -test_code { # This user will be updated set existing_user [acs::test::user::create] set existing_user_id [dict get $existing_user user_id] set authority_id [acs_user::get \ -user_id $existing_user_id \ -element authority_id] set job_id [auth::sync::job::start \ -authority_id $authority_id] set existing_username [dict get $existing_user username] set existing_first_names AAAA set existing_last_name BBBB # This user will be created set new_user_username [db_string get_new_username { select max(username) || 'A' from users }] # Usernames could be emails, make sure the fake test # email is formally correct regardless set new_user_email [string tolower [string map {@ "" . ""} $new_user_username]@test.com] set new_user_first_names AAAA set new_user_last_name BBBB # This user will be deleted set rascal_user [acs::test::user::create] set rascal_user_id [dict get $rascal_user user_id] set rascal_username [dict get $rascal_user username] set doc "" append doc {<?xml version="1.0" encoding="} [ns_config "ns/parameters" OutputCharset] {"?>} \n append doc {<enterprise>} \n append doc { <properties>} \n append doc { <type>acknowledgement</type>} \n append doc { <datetime>2022-09-19</datetime>} \n append doc { </properties>} \n append doc { <person recstatus="1">} \n append doc { <email>} $new_user_email {</email>} \n append doc { <name><n><given>} $new_user_first_names {</given><family>} $new_user_last_name {</family></n></name>} \n append doc { <sourcedid><source>OpenACS</source><id>} $new_user_username {</id></sourcedid>} \n append doc { </person>} \n append doc { <person recstatus="2">} \n append doc { <sourcedid><source>OpenACS</source><id>} $existing_username {</id></sourcedid>} \n append doc { <name><n><given>} $existing_first_names {</given><family>} $existing_last_name {</family></n></name>} \n append doc { </person>} \n append doc { <person recstatus="3">} \n append doc { <sourcedid><source>OpenACS</source><id>} $rascal_username {</id></sourcedid>} \n append doc { </person>} \n append doc {</enterprise>} \n acs_sc::invoke \ -contract auth_sync_process \ -impl IMS_Enterprise_v_1p1 \ -operation ProcessDocument \ -call_args [list $job_id $doc [list]] set existing_user [acs_user::get -user_id $existing_user_id] aa_equals "User '$existing_user_id' First Names was modified" \ [dict get $existing_user first_names] $existing_first_names aa_equals "User '$existing_user_id' Last Name was modified" \ [dict get $existing_user last_name] $existing_last_name set new_user_id [acs_user::get_by_username \ -authority_id $authority_id \ -username $new_user_username] aa_true "New User was created" {$new_user_id ne ""} if {$new_user_id ne ""} { set new_user [acs_user::get -user_id $new_user_id] aa_equals "User '$new_user_id' Email was modified" \ [dict get $new_user email] $new_user_email aa_equals "User '$new_user_id' First Names was modified" \ [dict get $new_user first_names] $new_user_first_names aa_equals "User '$new_user_id' Last Name was modified" \ [dict get $new_user last_name] $new_user_last_name } aa_equals "Rascal user '$rascal_user_id' was banned" \ [acs_user::get \ -user_id $rascal_user_id \ -element member_state] \ banned } } # Local variables: # mode: tcl # tcl-indent-level: 4 # indent-tabs-mode: nil # End: