summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAurélien Bompard2016-02-10 13:59:50 +0100
committerBarry Warsaw2016-03-31 18:29:27 -0400
commite622e265f1570ff9128aa1b5e4c7f326dc367994 (patch)
treebd6517c3a4e46e466073bb5b96a7aed6aa8901cb /src
parent71cfeda5fb51c49fd87b6d34e00221a3725b9ec0 (diff)
downloadmailman-e622e265f1570ff9128aa1b5e4c7f326dc367994.tar.gz
mailman-e622e265f1570ff9128aa1b5e4c7f326dc367994.tar.zst
mailman-e622e265f1570ff9128aa1b5e4c7f326dc367994.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/database/alembic/versions/7b254d88f122_members_and_list_moderation_action.py73
-rw-r--r--src/mailman/database/tests/test_migrations.py67
2 files changed, 140 insertions, 0 deletions
diff --git a/src/mailman/database/alembic/versions/7b254d88f122_members_and_list_moderation_action.py b/src/mailman/database/alembic/versions/7b254d88f122_members_and_list_moderation_action.py
new file mode 100644
index 000000000..fb02ccaed
--- /dev/null
+++ b/src/mailman/database/alembic/versions/7b254d88f122_members_and_list_moderation_action.py
@@ -0,0 +1,73 @@
+"""Members and list moderation action
+
+Revision ID: 7b254d88f122
+Revises: bfda02ab3a9b
+Create Date: 2016-02-10 11:31:04.233619
+
+This is a data-only migration. If a member has the same moderation action as
+the mailing list's default, then set its moderation action to None and use the
+fallback to the list's default.
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '7b254d88f122'
+down_revision = 'd4fbb4fd34ca'
+
+import sqlalchemy as sa
+from alembic import op
+from mailman.database.types import Enum
+from mailman.interfaces.action import Action
+from mailman.interfaces.member import MemberRole
+
+mailinglist_table = sa.sql.table(
+ 'mailinglist',
+ sa.sql.column('id', sa.Integer),
+ sa.sql.column('list_id', sa.Unicode),
+ sa.sql.column('default_member_action', Enum(Action)),
+ sa.sql.column('default_nonmember_action', Enum(Action)),
+ )
+
+member_table = sa.sql.table(
+ 'member',
+ sa.sql.column('id', sa.Integer),
+ sa.sql.column('list_id', sa.Unicode),
+ sa.sql.column('role', Enum(MemberRole)),
+ sa.sql.column('moderation_action', Enum(Action)),
+ )
+
+# This migration only considers members and nonmembers.
+members_query = member_table.select().where(sa.or_(
+ member_table.c.role == MemberRole.member,
+ member_table.c.role == MemberRole.nonmember,
+ ))
+
+
+def _get_default_action(connection, member):
+ mailing_list = connection.execute(mailinglist_table.select().where(
+ mailinglist_table.c.list_id == member['list_id'])).fetchone()
+ return mailing_list['default_{}_action'.format(member['role'].name)]
+
+
+def upgrade():
+ connection = op.get_bind()
+ for member in connection.execute(members_query).fetchall():
+ default_action = _get_default_action(connection, member)
+ # If the (non)member's moderation action is the same as the mailing
+ # list's default, then set it to None. The moderation rule will
+ # fallback to the list's default.
+ if member['moderation_action'] == default_action:
+ connection.execute(member_table.update().where(
+ member_table.c.id == member['id']
+ ).values(moderation_action=None))
+
+
+def downgrade():
+ connection = op.get_bind()
+ for member in connection.execute(members_query.where(
+ member_table.c.moderation_action == None)).fetchall():
+ default_action = _get_default_action(connection, member)
+ # Use the mailing list's default action
+ connection.execute(member_table.update().where(
+ member_table.c.id == member['id']
+ ).values(moderation_action=default_action))
diff --git a/src/mailman/database/tests/test_migrations.py b/src/mailman/database/tests/test_migrations.py
index 3087c46ee..bc394149b 100644
--- a/src/mailman/database/tests/test_migrations.py
+++ b/src/mailman/database/tests/test_migrations.py
@@ -218,3 +218,70 @@ class TestMigrations(unittest.TestCase):
os.path.join(config.LIST_DATA_DIR, 'ant@example.com')))
self.assertTrue(os.path.exists(ant.data_path))
self.assertTrue(os.path.exists(bee.data_path))
+
+ def test_7b254d88f122_moderation_action(self):
+ from mailman.database.types import Enum
+ from mailman.interfaces.action import Action
+ from mailman.interfaces.member import MemberRole
+ from mailman.interfaces.usermanager import IUserManager
+ from zope.component import getUtility
+ mailinglist_table = sa.sql.table(
+ 'mailinglist',
+ sa.sql.column('id', sa.Integer),
+ sa.sql.column('list_id', sa.Unicode),
+ sa.sql.column('default_member_action', Enum(Action)),
+ sa.sql.column('default_nonmember_action', Enum(Action)),
+ )
+
+ member_table = sa.sql.table(
+ 'member',
+ sa.sql.column('id', sa.Integer),
+ sa.sql.column('list_id', sa.Unicode),
+ sa.sql.column('address_id', sa.Integer),
+ sa.sql.column('role', Enum(MemberRole)),
+ sa.sql.column('moderation_action', Enum(Action)),
+ )
+ user_manager = getUtility(IUserManager)
+ with transaction():
+ # Start at the previous revision
+ alembic.command.downgrade(alembic_cfg, 'd4fbb4fd34ca')
+ # Create a mailing list through the standard API.
+ ant = create_list('ant@example.com')
+ # Create members
+ anne = user_manager.create_address('anne@example.com')
+ bart = user_manager.create_address('bart@example.com')
+ cris = user_manager.create_address('cris@example.com')
+ dana = user_manager.create_address('dana@example.com')
+ config.db.store.flush() # to get the last auto-increment id.
+ config.db.store.execute(member_table.insert().values([
+ {'address_id': anne.id, 'role': MemberRole.owner,
+ 'list_id': ant.list_id, 'moderation_action': Action.accept},
+ {'address_id': bart.id, 'role': MemberRole.moderator,
+ 'list_id': ant.list_id, 'moderation_action': Action.accept},
+ {'address_id': cris.id, 'role': MemberRole.member,
+ 'list_id': ant.list_id, 'moderation_action': Action.defer},
+ {'address_id': dana.id, 'role': MemberRole.nonmember,
+ 'list_id': ant.list_id, 'moderation_action': Action.hold},
+ ]))
+ # Upgrade and check the moderation_action.
+ alembic.command.upgrade(alembic_cfg, '7b254d88f122')
+ members = config.db.store.execute(sa.select([
+ member_table.c.address_id, member_table.c.moderation_action,
+ ])).fetchall()
+ self.assertEqual(members, [
+ (anne.id, Action.accept),
+ (bart.id, Action.accept),
+ (cris.id, None),
+ (dana.id, None),
+ ])
+ # Downgrade and check.
+ alembic.command.downgrade(alembic_cfg, 'd4fbb4fd34ca')
+ members = config.db.store.execute(sa.select([
+ member_table.c.address_id, member_table.c.moderation_action,
+ ])).fetchall()
+ self.assertEqual(members, [
+ (anne.id, Action.accept),
+ (bart.id, Action.accept),
+ (cris.id, Action.defer),
+ (dana.id, Action.hold),
+ ])