From: Michael Orlitzky Date: Sun, 5 Jan 2014 03:35:46 +0000 (-0500) Subject: Make list_users() methods public in several plugins. X-Git-Tag: 0.0.1~63 X-Git-Url: http://gitweb.michael.orlitzky.com/?p=mailshears.git;a=commitdiff_plain;h=bf7d0402eda27d9487ca9402156818545fdda286 Make list_users() methods public in several plugins. Add a list_aliases() method to the PostfixAdminPlugin module. Rename the existing test file. Add a README.fixtures giving an overview of what's in the test databases. Check the database for expected contents after removing a user and domain. --- diff --git a/Rakefile b/Rakefile index c859ae6..7138d8a 100644 --- a/Rakefile +++ b/Rakefile @@ -18,7 +18,7 @@ task :install => :build do end Rake::TestTask.new do |t| - t.pattern = 'test/*test.rb' + t.pattern = 'test/test*.rb' t.libs << 'test' end diff --git a/lib/common/agendav_plugin.rb b/lib/common/agendav_plugin.rb index 7522b2c..ae9b11c 100644 --- a/lib/common/agendav_plugin.rb +++ b/lib/common/agendav_plugin.rb @@ -32,10 +32,11 @@ module AgendavPlugin end - protected; - - def list_users() + # + # Produce a list of AgenDAV users. This is public because it's + # useful in testing. + # usernames = [] # Just assume PostgreSQL for now. diff --git a/lib/common/davical_plugin.rb b/lib/common/davical_plugin.rb index a1dcba0..8c9646f 100644 --- a/lib/common/davical_plugin.rb +++ b/lib/common/davical_plugin.rb @@ -33,10 +33,12 @@ module DavicalPlugin end - protected; - - def get_principal_id(user) - principal_id = nil + def list_users() + # + # Produce a list of DAViCal users. This is public because it's + # useful for testing. + # + usernames = [] begin connection = PGconn.connect(@db_host, @@ -47,30 +49,27 @@ module DavicalPlugin @db_user, @db_pass) - sql_query = "SELECT principal.principal_id " - sql_query += "FROM (principal INNER JOIN usr " - sql_query += " ON principal.user_no = usr.user_no) " - sql_query += "WHERE usr.username = $1;" + # User #1 is the super-user, and not tied to an email address. + sql_query = "SELECT username FROM usr WHERE user_no > 1" - connection.query(sql_query, [user]) do |result| - if result.num_tuples > 0 - principal_id = result[0]['principal_id'] - end + connection.query(sql_query) do |result| + usernames = result.field_values('username') end connection.close() - rescue PGError => e # Pretend like we're database-agnostic in case we ever are. raise DatabaseError.new(e) end - return principal_id + return usernames end - def list_users() - usernames = [] + protected; + + def get_principal_id(user) + principal_id = nil begin connection = PGconn.connect(@db_host, @@ -81,20 +80,25 @@ module DavicalPlugin @db_user, @db_pass) - # User #1 is the super-user, and not tied to an email address. - sql_query = "SELECT username FROM usr WHERE user_no > 1" + sql_query = "SELECT principal.principal_id " + sql_query += "FROM (principal INNER JOIN usr " + sql_query += " ON principal.user_no = usr.user_no) " + sql_query += "WHERE usr.username = $1;" - connection.query(sql_query) do |result| - usernames = result.field_values('username') + connection.query(sql_query, [user]) do |result| + if result.num_tuples > 0 + principal_id = result[0]['principal_id'] + end end connection.close() + rescue PGError => e # Pretend like we're database-agnostic in case we ever are. raise DatabaseError.new(e) end - return usernames + return principal_id end end diff --git a/lib/common/postfixadmin_plugin.rb b/lib/common/postfixadmin_plugin.rb index 5556d5a..b14f295 100644 --- a/lib/common/postfixadmin_plugin.rb +++ b/lib/common/postfixadmin_plugin.rb @@ -70,8 +70,6 @@ module PostfixadminPlugin @db_user, @db_pass) - # If address = goto, then the alias basically says, "really - # deliver to that address; it's not an alias." sql_query = 'SELECT username FROM mailbox;' connection.query(sql_query) do |result| users = result.field_values('username') @@ -114,4 +112,35 @@ module PostfixadminPlugin return usernames end + + def list_aliases() + # + # Get a list of all aliases, useful for testing. + # + aliases = [] + + # Just assume PostgreSQL for now. + begin + connection = PGconn.connect(@db_host, + @db_port, + @db_opts, + @db_tty, + @db_name, + @db_user, + @db_pass) + + sql_query = 'SELECT address,goto FROM alias;' + results = connection.query(sql_query) + results.each do |row| + aliases << row # row should be a hash + end + connection.close() + rescue PGError => e + # But pretend like we're database-agnostic in case we ever are. + raise DatabaseError.new(e) + end + + return aliases + end + end diff --git a/lib/common/roundcube_plugin.rb b/lib/common/roundcube_plugin.rb index 0f80f72..1f9805a 100644 --- a/lib/common/roundcube_plugin.rb +++ b/lib/common/roundcube_plugin.rb @@ -32,11 +32,12 @@ module RoundcubePlugin end - protected; - - def get_user_id(user) - user_id = nil + def list_users() + # Produce a list of Roundcube users. This is used in prune/rm, and + # is public because it is useful in testing. + usernames = [] + # Just assume PostgreSQL for now. begin connection = PGconn.connect(@db_host, @db_port, @@ -46,30 +47,25 @@ module RoundcubePlugin @db_user, @db_pass) - sql_query = "SELECT user_id FROM users WHERE username = $1;" - - connection.query(sql_query, [user]) do |result| - if result.num_tuples > 0 - user_id = result[0]['user_id'] - end + sql_query = "SELECT username FROM users;" + connection.query(sql_query) do |result| + usernames = result.field_values('username') end connection.close() - rescue PGError => e # Pretend like we're database-agnostic in case we ever are. raise DatabaseError.new(e) end - return user_id + return usernames end + protected; - # Used in both prune/rm. - def list_users() - usernames = [] + def get_user_id(user) + user_id = nil - # Just assume PostgreSQL for now. begin connection = PGconn.connect(@db_host, @db_port, @@ -79,18 +75,23 @@ module RoundcubePlugin @db_user, @db_pass) - sql_query = "SELECT username FROM users;" - connection.query(sql_query) do |result| - usernames = result.field_values('username') + sql_query = "SELECT user_id FROM users WHERE username = $1;" + + connection.query(sql_query, [user]) do |result| + if result.num_tuples > 0 + user_id = result[0]['user_id'] + end end connection.close() + rescue PGError => e # Pretend like we're database-agnostic in case we ever are. raise DatabaseError.new(e) end - return usernames + return user_id end + end diff --git a/test/rm_account_test.rb b/test/rm_account_test.rb deleted file mode 100644 index bd0ac30..0000000 --- a/test/rm_account_test.rb +++ /dev/null @@ -1,112 +0,0 @@ -require 'pg' -require 'test/unit' - -require 'common/configuration' - -class RmAccountTest < Test::Unit::TestCase - - TESTCONF_PATH = 'test/mailshears.test.conf.yml' - - def connect_superuser() - db_host = 'localhost' - db_port = 5432 - db_opts = nil - db_tty = nil - db_name = 'postgres' - db_user = 'postgres' - db_pass = nil - - connection = PGconn.connect(db_host, - db_port, - db_opts, - db_tty, - db_name, - db_user, - db_pass) - - return connection - end - - - def test_single_rm - cfg = Configuration.new(TESTCONF_PATH) - argv = ["adam@example.net"] - - # Load each of the plugins that we'll need. - cfg.plugins.each do |plugin_file| - require "rm/plugins/#{plugin_file}" - end - - # And the runners. - require "rm/rm_runner" - require "rm/rm_dummy_runner" - - require 'stringio' - output_buffer = StringIO.new() - - $stdout = output_buffer - plugin_class = RmPlugin.run(cfg, *argv) - $stdout = STDOUT - - actual = output_buffer.string() - - expected = "PostfixadminRm - Removed user: " + - "adam@example.net (adam@example.net)\n" + - "RoundcubeRm - Removed user: adam@example.net (User ID: 2)\n" + - "AgendavRm - Removed user: adam@example.net " + - "(Username: adam@example.net)\n" + - "DavicalRm - User not found: adam@example.net\n" - assert(actual == expected) - end - - def setup - # Create databases using from the test configuration file. - cfg = Configuration.new(TESTCONF_PATH) - connection = connect_superuser() - - cfg.plugins.each do |plugin| - plugin_dbname = cfg.send("#{plugin}_dbname") - query = "CREATE DATABASE #{plugin_dbname};" - connection.query(query) - - plugin_dbhost = cfg.send("#{plugin}_dbhost") - plugin_dbport = cfg.send("#{plugin}_dbport") - plugin_dbopts = cfg.send("#{plugin}_dbopts") - plugin_dbtty = cfg.send("#{plugin}_dbtty") - plugin_dbuser = cfg.send("#{plugin}_dbuser") - plugin_dbpass = cfg.send("#{plugin}_dbpass") - - plugin_conn = PGconn.connect(plugin_dbhost, - plugin_dbport, - plugin_dbopts, - plugin_dbtty, - plugin_dbname, - plugin_dbuser, - plugin_dbpass) - - sql = File.open("test/sql/#{plugin}.sql").read() - plugin_conn.query(sql) - sql = File.open("test/sql/#{plugin}-fixtures.sql").read() - plugin_conn.query(sql) - plugin_conn.close() - end - - connection.close() - end - - - def teardown - # Destroy databases using from the test configuration file. - cfg = Configuration.new(TESTCONF_PATH) - connection = connect_superuser() - - cfg.plugins.each do |plugin| - plugin_dbname = cfg.send("#{plugin}_dbname") - query = "DROP DATABASE #{plugin_dbname};" - connection.query(query) - end - - connection.close() - end - -end diff --git a/test/sql/README.fixtures b/test/sql/README.fixtures new file mode 100644 index 0000000..b4a242c --- /dev/null +++ b/test/sql/README.fixtures @@ -0,0 +1,113 @@ +Here's a quick (incomplete!) overview of what winds up in your tables. + + +1. agendav_test + ++----------------------------+ +| prefs | ++------------------+---------+ +| username | options | ++------------------+---------+ +| adam@example.net | herp | ++------------------+---------+ + + ++------------------------------------------------------+ +| shared | ++-----+------------------+----------+------------------+ +| sid | user_from | calendar | user_which | ++-----+------------------+----------+------------------+ +| 1 | adam@example.net | derp | beth@example.net | ++-----+------------------+----------+------------------+ + + +2. davical_test + ++-------------------------------------------------------+ +| usr | ++---------+--------+----------------+-------------------+ +| user_no | active | joined | username | ++---------+--------+----------------+-------------------+ +| 17 | t | 2014-01-04 ... | alice@example.com | ++---------+--------+----------------+-------------------+ + ++-----------------------------------------+ +| usr_setting | ++---------+--------------+----------------+ +| user_no | setting_name | setting_value | ++---------+--------------+----------------+ +| 17 | dumb setting | its dumb value | ++---------+--------------+----------------+ + + +3. postfixadmin_test + ++-------------+ +| domain | ++-------------+ +| domain | ++-------------+ +| ALL | ++-------------+ +| example.com | ++-------------+ +| example.net | ++-------------+ + + ++----------------------------------------------+ +| mailbox | ++-------------------+-------------+------------+ +| username | domain | local_part | ++-------------------+-------------+------------+ +| alice@example.com | example.com | alice | ++-------------------+-------------+------------+ +| bob@example.com | example.com | bob | ++-------------------+-------------+------------+ +| adam@example.net | example.net | adam | ++-------------------+-------------+------------+ +| beth@example.net | example.net | beth | ++-------------------+-------------+------------+ +| carol@example.net | example.net | carol | ++-------------------+-------------+------------+ + + ++------------------------------------------------------+ +| alias | ++-------------------+-------------------+--------------+ +| address | goto | domain | ++-------------------+-------------------+--------------+ +| alice@example.com | alice@example.com | example.com | ++-------------------+-------------------+--------------+ +| bob@example.com | bob@example.com | example.com | ++-------------------+-------------------+--------------+ +| adam@example.net | adam@example.net | example.net | ++-------------------+-------------------+--------------+ +| beth@example.net | beth@example.net | example.net | ++-------------------+-------------------+--------------+ +| carol@example.net | carol@example.net | example.net | ++-------------------+-------------------+--------------+ + + ++---------------------------------+ +| domain_admins | ++-------------------+-------------+ +| username | domain | ++-------------------+-------------+ +| admin@example.com | example.com | ++-------------------+-------------+ +| admin@example.com | example.net | ++-------------------+-------------+ + + + +4. roundcube_test + + ++---------+-------------------+ +| user_id | username | ++---------+-------------------+ +| 1 | alice@example.com | ++---------+-------------------+ +| 2 | adam@example.net | ++---------+-------------------+ diff --git a/test/test_rm.rb b/test/test_rm.rb new file mode 100644 index 0000000..01d2c1c --- /dev/null +++ b/test/test_rm.rb @@ -0,0 +1,213 @@ +require 'pg' +require 'stringio' +require 'test/unit' + +# WARNING: Test output is dependent on the order these classes include +# certain modules; i.e. on the 'require' order. +require 'common/configuration' +require "rm/plugins/agendav" +require "rm/plugins/davical" +require "rm/plugins/postfixadmin" +require "rm/plugins/roundcube" +require "rm/rm_runner" +require "rm/rm_dummy_runner" + + +class TestRm < Test::Unit::TestCase + + TESTCONF_PATH = 'test/mailshears.test.conf.yml' + + def connect_superuser() + db_host = 'localhost' + db_port = 5432 + db_opts = nil + db_tty = nil + db_name = 'postgres' + db_user = 'postgres' + db_pass = nil + + connection = PGconn.connect(db_host, + db_port, + db_opts, + db_tty, + db_name, + db_user, + db_pass) + + return connection + end + + def setup + # Create databases using from the test configuration file. + cfg = Configuration.new(TESTCONF_PATH) + connection = connect_superuser() + + cfg.plugins.each do |plugin| + plugin_dbname = cfg.send("#{plugin}_dbname") + query = "CREATE DATABASE #{plugin_dbname};" + connection.query(query) + + plugin_dbhost = cfg.send("#{plugin}_dbhost") + plugin_dbport = cfg.send("#{plugin}_dbport") + plugin_dbopts = cfg.send("#{plugin}_dbopts") + plugin_dbtty = cfg.send("#{plugin}_dbtty") + plugin_dbuser = cfg.send("#{plugin}_dbuser") + plugin_dbpass = cfg.send("#{plugin}_dbpass") + + plugin_conn = PGconn.connect(plugin_dbhost, + plugin_dbport, + plugin_dbopts, + plugin_dbtty, + plugin_dbname, + plugin_dbuser, + plugin_dbpass) + + sql = File.open("test/sql/#{plugin}.sql").read() + plugin_conn.query(sql) + sql = File.open("test/sql/#{plugin}-fixtures.sql").read() + plugin_conn.query(sql) + plugin_conn.close() + end + + connection.close() + end + + + + def test_rm_user + cfg = Configuration.new(TESTCONF_PATH) + argv = ["adam@example.net"] + + output_buffer = StringIO.new() + + $stdout = output_buffer + plugin_class = RmPlugin.run(cfg, *argv) + $stdout = STDOUT + + actual = output_buffer.string() + + expected = + "AgendavRm - Removed user: adam@example.net " + + "(Username: adam@example.net)\n" + + "DavicalRm - User not found: adam@example.net\n" + + "PostfixadminRm - Removed user: " + + "adam@example.net (adam@example.net)\n" + + "RoundcubeRm - Removed user: adam@example.net (User ID: 2)\n" + + assert_equal(expected, actual) + + # Now make sure the database has what we expect. + + arm = AgendavRm.new(cfg) + actual = arm.list_users() + expected = [] + assert_equal(expected, actual) + + drm = DavicalRm.new(cfg) + actual = drm.list_users() + expected = ['alice@example.com'] + assert_equal(expected, actual) + + pfarm = PostfixadminRm.new(cfg) + actual = pfarm.list_users() + expected = ['alice@example.com', + 'bob@example.com', + 'beth@example.net', + 'carol@example.net'] + assert_equal(expected, actual) + + actual = pfarm.list_domains() + expected = ['example.com', 'example.net'] + assert_equal(expected, actual) + + actual = pfarm.list_aliases() + expected = [{'address' => 'alice@example.com', + 'goto' => 'alice@example.com'}, + {'address' => 'bob@example.com', + 'goto' => 'bob@example.com'}, + {'address' => 'beth@example.net', + 'goto' => 'beth@example.net'}, + {'address' => 'carol@example.net', + 'goto' => 'carol@example.net'}] + assert_equal(expected, actual) + + rrm = RoundcubeRm.new(cfg) + actual = rrm.list_users() + expected = ['alice@example.com'] + assert_equal(expected, actual) + end + + + def test_rm_domain + # + # This must (and should) run after test_rm_user(). + # + cfg = Configuration.new(TESTCONF_PATH) + argv = ["example.net"] + + output_buffer = StringIO.new() + + $stdout = output_buffer + plugin_class = RmPlugin.run(cfg, *argv) + $stdout = STDOUT + + actual = output_buffer.string() + + expected = + "AgendavRm - Removed domain: example.net (example.net)\n" + + "DavicalRm - Domain not found: example.net\n" + + "PostfixadminRm - Removed domain: example.net (example.net)\n" + + "RoundcubeRm - Removed domain: example.net (example.net)\n" + + assert_equal(expected, actual) + + # Now make sure the database has what we expect. + + arm = AgendavRm.new(cfg) + actual = arm.list_users() + expected = [] + assert_equal(expected, actual) + + drm = DavicalRm.new(cfg) + actual = drm.list_users() + expected = ['alice@example.com'] + assert_equal(expected, actual) + + pfarm = PostfixadminRm.new(cfg) + actual = pfarm.list_users() + expected = ['alice@example.com', 'bob@example.com'] + assert_equal(expected, actual) + + actual = pfarm.list_domains() + expected = ['example.com'] + assert_equal(expected, actual) + + actual = pfarm.list_aliases() + expected = [{'address' => 'alice@example.com', + 'goto' => 'alice@example.com'}, + {'address' => 'bob@example.com', + 'goto' => 'bob@example.com'}] + assert_equal(expected, actual) + + rrm = RoundcubeRm.new(cfg) + actual = rrm.list_users() + expected = ['alice@example.com'] + assert_equal(expected, actual) + end + + + + def teardown + cfg = Configuration.new(TESTCONF_PATH) + connection = connect_superuser() + + cfg.plugins.each do |plugin| + plugin_dbname = cfg.send("#{plugin}_dbname") + query = "DROP DATABASE #{plugin_dbname};" + connection.query(query) + end + + connection.close() + end + +end