diff --git a/api_tests/providers/registrations/views/test_registration_provider_schemas.py b/api_tests/providers/registrations/views/test_registration_provider_schemas.py index e68db401204..fb2db1e0184 100644 --- a/api_tests/providers/registrations/views/test_registration_provider_schemas.py +++ b/api_tests/providers/registrations/views/test_registration_provider_schemas.py @@ -106,7 +106,7 @@ def provider_with_reg(self, osf_reg_schema, egap_schema, schema, out_dated_schem def egap_admin(self): user = AuthUserFactory() user.save() - flag = Flag.objects.get(name=EGAP_ADMINS) + flag = Flag.objects.create(name=EGAP_ADMINS) group = Group.objects.create(name=EGAP_ADMINS) # Just using the same name for convenience flag.groups.add(group) group.user_set.add(user) diff --git a/api_tests/schemas/views/test_registration_schemas_list.py b/api_tests/schemas/views/test_registration_schemas_list.py index c2ddede0f7a..4e34f0a93a1 100644 --- a/api_tests/schemas/views/test_registration_schemas_list.py +++ b/api_tests/schemas/views/test_registration_schemas_list.py @@ -31,7 +31,7 @@ def url(self): def egap_admin(self): user = AuthUserFactory() user.save() - flag = Flag.objects.get(name=features.EGAP_ADMINS) + flag = Flag.objects.create(name=features.EGAP_ADMINS) group = Group.objects.create(name=features.EGAP_ADMINS) # Just using the same name for convenience flag.groups.add(group) group.user_set.add(user) diff --git a/osf/apps.py b/osf/apps.py index 63a7f9bedc4..ff34451084e 100644 --- a/osf/apps.py +++ b/osf/apps.py @@ -1,8 +1,9 @@ -from __future__ import unicode_literals - +import logging from django.apps import AppConfig as BaseAppConfig from django.db.models.signals import post_migrate -from osf.migrations import update_permission_groups +from osf.migrations import update_permission_groups, update_waffle_flags + +logger = logging.getLogger(__file__) class AppConfig(BaseAppConfig): @@ -16,3 +17,7 @@ def ready(self): update_permission_groups, dispatch_uid='osf.apps.update_permissions_groups' ) + post_migrate.connect( + update_waffle_flags, + dispatch_uid='osf.apps.update_waffle_flags' + ) diff --git a/osf/features.py b/osf/features.py index 1fa02508b6a..996876b9f81 100644 --- a/osf/features.py +++ b/osf/features.py @@ -1,49 +1,10 @@ -flags = { - 'STORAGE_USAGE': 'storage_usage', - 'INSTITUTIONAL_LANDING_FLAG': 'institutions_nav_bar', - 'STORAGE_I18N': 'storage_i18n', - 'OSF_GROUPS': 'osf_groups', - 'ENABLE_CHRONOS': 'enable_chronos', - 'EGAP_ADMINS': 'egap_admins', - 'EMBER_AB_TESTING_HOME_PAGE_VERSION_B': 'ab_testing_home_page_version_b', - 'EMBER_AB_TESTING_HOME_PAGE_HERO_TEXT_VERSION_B': 'ab_testing_home_page_hero_text_version_b', - 'EMBER_AUTH_REGISTER': 'ember_auth_register', - 'EMBER_CREATE_DRAFT_REGISTRATION': 'ember_create_draft_registration_page', - 'EMBER_EDIT_DRAFT_REGISTRATION': 'ember_edit_draft_registration_page', - 'EMBER_FILE_REGISTRATION_DETAIL': 'ember_file_registration_detail_page', - 'EMBER_FILE_PROJECT_DETAIL': 'ember_file_project_detail_page', - 'EMBER_MEETINGS': 'ember_meetings_page', - 'EMBER_MEETING_DETAIL': 'ember_meeting_detail_page', - 'EMBER_MY_PROJECTS': 'ember_my_projects_page', - 'EMBER_PROJECT_ANALYTICS': 'ember_project_analytics_page', - 'EMBER_PROJECT_CONTRIBUTORS': 'ember_project_contributors_page', - 'EMBER_PROJECT_DETAIL': 'ember_project_detail_page', - 'EMBER_REGISTRATION_FILES': 'ember_registration_files_page', - 'EMBER_PROJECT_FILES': 'ember_project_files_page', - 'EMBER_PROJECT_FORKS': 'ember_project_forks_page', - 'EMBER_PROJECT_REGISTRATIONS': 'ember_project_registrations_page', - 'EMBER_PROJECT_SETTINGS': 'ember_project_settings_page', - 'EMBER_PROJECT_WIKI': 'ember_project_wiki_page', - 'EMBER_REGISTRATION_FORM_DETAIL': 'ember_registration_form_detail_page', - 'EMBER_REGISTRIES_DETAIL_PAGE': 'ember_registries_detail_page', - 'EMBER_SEARCH_PAGE': 'ember_search_page', - 'EMBER_USER_PROFILE': 'ember_user_profile_page', - 'EMBER_USER_SETTINGS': 'ember_user_settings_page', - 'EMBER_USER_SETTINGS_ACCOUNTS': 'ember_user_settings_account_page', - 'EMBER_USER_SETTINGS_ADDONS': 'ember_user_settings_addons_page', - 'EMBER_USER_SETTINGS_APPS': 'ember_user_settings_apps_page', - 'EMBER_USER_SETTINGS_NOTIFICATIONS': 'ember_user_settings_notifications_page', - 'EMBER_USER_SETTINGS_TOKENS': 'ember_user_settings_tokens_page', -} +import yaml -switches = { - 'ENABLE_INACTIVE_SCHEMAS': 'enable_inactive_schemas', - 'OSF_PREREGISTRATION': 'osf_preregistration', - 'DISABLE_ENGAGEMENT_EMAILS': 'disable_engagement_emails', - 'ELASTICSEARCH_METRICS': 'elasticsearch_metrics', - 'ENFORCE_CSRF': 'enforce_csrf', - 'ENABLE_RAW_METRICS': 'enable_raw_metrics', -} +with open('osf/features.yaml', 'r') as stream: + features = yaml.safe_load(stream) -locals().update(flags) -locals().update(switches) +for flag in features['flags']: + locals()[flag.pop('flag_name')] = flag['name'] + +for switch in features['switches']: + locals()[switch.pop('flag_name')] = switch['name'] diff --git a/osf/features.yaml b/osf/features.yaml new file mode 100644 index 00000000000..07181d9cca4 --- /dev/null +++ b/osf/features.yaml @@ -0,0 +1,216 @@ +# This file contains the default configuration for our feature flipping using waffle flags and switches, this represents +# the intended configuration of flags at the time of release, if you plan to switch the activity status of a feature in +# after release (during normal operation) please make sure that is reflected in this document by not explicitly setting +# it here. However features not intended to be after a release flipped should explicitly stated. + +# Workflow: +# 1. Add a flag/switch with a name and value to this document +# 2. Run `manage_waffle` to create the flag(s) +# 3. Use the admin app to enable/disable the flag/switch at your convenience +# 4. When feature is complete add the activity status (active or everyone) to the value it will have in production until +# the old flipping code can be removed. +# 5. When a flag name is no longer referenced anywhere in this repo or in the Ember app remove it from this list. +flags: + - flag_name: EMBER_FILE_PROJECT_DETAIL + name: ember_file_project_detail_page + note: This is part of the upcoming files page redesign + everyone: true + + - flag_name: EMBER_PROJECT_FILES + name: ember_project_files_page + note: This is part of the upcoming files page redesign + everyone: true + + - flag_name: STORAGE_USAGE + name: storage_usage + note: Indicates whether we display the file storage usage for each node on the project overview page. + everyone: true + + - flag_name: INSTITUTIONAL_LANDING_FLAG + name: institutions_nav_bar + note: Indicates whether we display the institutions navbar. + everyone: true + + - flag_name: STORAGE_I18N + name: storage_i18n + note: Indicates whether region based storage is enabled. + everyone: true + + - flag_name: OSF_GROUPS + name: osf_groups + note: Indicates whether certain parts of the OSF groups feature are enabled. + everyone: true + + - flag_name: EGAP_ADMINS + name: egap_admins + note: Indicates whether EGAP admins have special access to custom schemas + everyone: true + + - flag_name: EMBER_AUTH_REGISTER + name: ember_auth_register + note: This indicates whether this view is routed for OSF register, redirect or go to `auth_logout` + everyone: true + + - flag_name: EMBER_PROJECT_DETAIL + name: ember_project_detail_page + note: This flag controls wheter the project overview page is routed to the ember app + everyone: false + + - flag_name: EMBER_CREATE_DRAFT_REGISTRATION + name: ember_create_draft_registration_page + note: This flag controls wheter POST requests to /project//registrations/ and + /project//node//registrations/ are routed to the ember app + everyone: false + + - flag_name: EMBER_MEETING_DETAIL + name: ember_meeting_detail_page + note: This flag controls wheter the `conference_results` view routes to the Ember app + everyone: true + + - flag_name: EMBER_MY_PROJECTS + name: ember_my_projects_page + note: This flag controls wheter the `My Projects Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_PROJECT_CONTRIBUTORS + name: ember_project_contributors_page + note: This flag controls wheter the `Node Contributor Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_PROJECT_SETTINGS + name: ember_project_settings_page + note: This flag controls wheter the `Node Settings Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_PROJECT_WIKI + name: ember_project_wiki_page + note: This flag controls wheter the `Project Wiki Home Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_REGISTRATION_FORM_DETAIL + name: ember_registration_form_detail_page + note: This flag controls wheter the `Node Register Template Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_SEARCH_PAGE + name: ember_search_page + note: This flag controls wheter the `Search Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_USER_PROFILE + name: ember_user_profile_page + note: This flag controls wheter the `User Profile Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_USER_SETTINGS + name: ember_user_settings_page + note: This flag controls wheter the `User Settings Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_USER_SETTINGS_ADDONS + name: ember_user_settings_addons_page + note: This flag controls wheter the `User Addons Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_USER_SETTINGS_NOTIFICATIONS + name: ember_user_settings_notifications_page + note: This flag controls wheter the `User Notifications Page` view routes to the Ember app + everyone: false + + - flag_name: EMBER_MEETINGS + name: ember_meetings_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_EDIT_DRAFT_REGISTRATION + name: ember_edit_draft_registration_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_FILE_REGISTRATION_DETAIL + name: ember_file_registration_detail_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_REGISTRATION_FILES + name: ember_registration_files_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_REGISTRIES_DETAIL_PAGE + name: ember_registries_detail_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_USER_SETTINGS_ACCOUNTS + name: ember_user_settings_account_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_USER_SETTINGS_APPS + name: ember_user_settings_apps_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_USER_SETTINGS_TOKENS + name: ember_user_settings_tokens_page + note: This is complete and should be permanently on. + everyone: true + + - flag_name: EMBER_AB_TESTING_HOME_PAGE_VERSION_B + name: ab_testing_home_page_version_b + note: This is no longer used. + + - flag_name: EMBER_AB_TESTING_HOME_PAGE_HERO_TEXT_VERSION_B + name: ab_testing_home_page_hero_text_version_b + note: This is no longer used. + everyone: true + + - flag_name: EMBER_PROJECT_ANALYTICS + name: ember_project_analytics_page + note: This is no longer used. + everyone: false + + - flag_name: EMBER_PROJECT_FORKS + name: ember_project_forks_page + note: This is no longer used. + everyone: false + + - flag_name: EMBER_PROJECT_REGISTRATIONS + name: ember_project_registrations_page + note: This is no longer used. + everyone: false + + - flag_name: ENABLE_CHRONOS + name: enable_chronos + note: This is not used + everyone: true + +switches: + - flag_name: DISABLE_ENGAGEMENT_EMAILS + name: disable_engagement_emails + note: if set to true, prevents engagment emails from being sent + active: false + + - flag_name: ELASTICSEARCH_METRICS + name: elasticsearch_metrics + note: enables ES metrics server + active: true + + - flag_name: ENFORCE_CSRF + name: enforce_csrf + note: enforces csrf for OSF session authentication + active: true + + - flag_name: ENABLE_RAW_METRICS + name: enable_raw_metrics + note: allows for raw queries againest our ES metrics database + active: false + + - flag_name: OSF_PREREGISTRATION + name: osf_preregistration + note: This is no longer used + + - flag_name: ENABLE_INACTIVE_SCHEMAS + name: enable_inactive_schemas + note: This is no longer used diff --git a/osf/management/commands/manage_switch_flags.py b/osf/management/commands/manage_switch_flags.py index 186ef15e682..b3b0f416502 100644 --- a/osf/management/commands/manage_switch_flags.py +++ b/osf/management/commands/manage_switch_flags.py @@ -1,38 +1,34 @@ # -*- coding: utf-8 -*- import logging +import yaml from django.core.management.base import BaseCommand -from osf.features import switches, flags -from waffle.models import Flag, Switch - logger = logging.getLogger(__name__) -def manage_waffle(delete_waffle=False): - file_switches = list(switches.values()) - current_switches = Switch.objects.values_list('name', flat=True) - add_switches = set(file_switches) - set(current_switches) - for switch in add_switches: - Switch.objects.get_or_create(name=switch, defaults={'active': False}) - logger.info('Adding switch: {}'.format(switch)) +def manage_waffle(delete_waffle=False): + from django.apps import apps - file_flags = list(flags.values()) - current_flags = Flag.objects.values_list('name', flat=True) + Flag = apps.get_model('waffle.Flag') + Switch = apps.get_model('waffle.Switch') - add_flags = set(file_flags) - set(current_flags) - for flag_name in add_flags: - Flag.objects.get_or_create(name=flag_name, defaults={'everyone': False}) - logger.info('Adding flag: {}'.format(flag_name)) + with open('osf/features.yaml', 'r') as stream: + features = yaml.safe_load(stream) + for flag in features['flags']: + flag.pop('flag_name') + Flag.objects.get_or_create(name=flag['name'], defaults=flag) + for switch in features['switches']: + switch.pop('flag_name') + Switch.objects.get_or_create(name=switch['name'], defaults=switch) if delete_waffle: - delete_switches = set(current_switches) - set(file_switches) - Switch.objects.filter(name__in=delete_switches).delete() - logger.info('Deleting switches: {}'.format(delete_switches)) + results = Switch.objects.exclude(name__in=[switch['name'] for switch in features['switches']]).delete() + logger.info(f'Deleting switches: {results}') + + results = Flag.objects.exclude(name__in=[flag['name'] for flag in features['flags']]).delete() + logger.info(f'Deleting flags: {results}') - delete_flags = set(current_flags) - set(file_flags) - Flag.objects.filter(name__in=delete_flags).delete() - logger.info('Deleting flags: {}'.format(delete_flags)) class Command(BaseCommand): """Ensure all features and switches are updated with the switch and flag files diff --git a/osf/migrations/0083_add_ember_waffle_flags.py b/osf/migrations/0083_add_ember_waffle_flags.py index 925da76a37c..f4cca4b73e3 100644 --- a/osf/migrations/0083_add_ember_waffle_flags.py +++ b/osf/migrations/0083_add_ember_waffle_flags.py @@ -56,5 +56,4 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(add_ember_waffle_flags, reverse_func) ] diff --git a/osf/migrations/0121_remove_support_page_waffle_flag.py b/osf/migrations/0121_remove_support_page_waffle_flag.py index 043b9a63f83..db51535e24a 100644 --- a/osf/migrations/0121_remove_support_page_waffle_flag.py +++ b/osf/migrations/0121_remove_support_page_waffle_flag.py @@ -20,5 +20,4 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(remove_support_page_waffle_flags, reverse_func) ] diff --git a/osf/migrations/0121_remove_waffle_flags.py b/osf/migrations/0121_remove_waffle_flags.py index f7728c6410e..b694d966379 100644 --- a/osf/migrations/0121_remove_waffle_flags.py +++ b/osf/migrations/0121_remove_waffle_flags.py @@ -31,5 +31,4 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(remove_waffle_flags, add_ember_waffle_flags) ] diff --git a/osf/migrations/0135_user_settings_waffles.py b/osf/migrations/0135_user_settings_waffles.py index 3ef7a18d1f0..988cd9c8829 100644 --- a/osf/migrations/0135_user_settings_waffles.py +++ b/osf/migrations/0135_user_settings_waffles.py @@ -5,7 +5,6 @@ from django.db import migrations from osf import features -from osf.utils.migrations import AddWaffleFlags USER_SETTINGS_FLAGS = [ @@ -24,5 +23,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags(USER_SETTINGS_FLAGS), ] diff --git a/osf/migrations/0136_add_ember_auth_register_waffle_flag.py b/osf/migrations/0136_add_ember_auth_register_waffle_flag.py index 915bf35e8c4..4ad3d61c4ba 100644 --- a/osf/migrations/0136_add_ember_auth_register_waffle_flag.py +++ b/osf/migrations/0136_add_ember_auth_register_waffle_flag.py @@ -3,8 +3,6 @@ from __future__ import unicode_literals from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleFlags class Migration(migrations.Migration): @@ -13,5 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags([features.EMBER_AUTH_REGISTER]), ] diff --git a/osf/migrations/0136_preprint_node_divorce.py b/osf/migrations/0136_preprint_node_divorce.py index 439192a1d36..870bacdd470 100644 --- a/osf/migrations/0136_preprint_node_divorce.py +++ b/osf/migrations/0136_preprint_node_divorce.py @@ -102,7 +102,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(emit_signals, reverse_func), migrations.RunSQL( [ """ diff --git a/osf/migrations/0137_transfer_preprint_service_permissions.py b/osf/migrations/0137_transfer_preprint_service_permissions.py index 3d80de1bbf4..300d88f42fd 100644 --- a/osf/migrations/0137_transfer_preprint_service_permissions.py +++ b/osf/migrations/0137_transfer_preprint_service_permissions.py @@ -3,11 +3,9 @@ from __future__ import unicode_literals from django.db import migrations -from django.core.management.sql import emit_post_migrate_signal def unmigrate_preprint_service_permissions(state, schema): - emit_post_migrate_signal(2, False, 'default') Permission = state.get_model('auth', 'permission') @@ -22,7 +20,6 @@ def migrate_preprint_service_permissions(state, schema): Django permissions on the preprint model have new names. """ # this is to make sure that the permissions created earlier exist! - emit_post_migrate_signal(2, False, 'default') Permission = state.get_model('auth', 'permission') diff --git a/osf/migrations/0142_remove_forks_flag.py b/osf/migrations/0142_remove_forks_flag.py index 9307b85b639..1fb41fa5e41 100644 --- a/osf/migrations/0142_remove_forks_flag.py +++ b/osf/migrations/0142_remove_forks_flag.py @@ -2,8 +2,6 @@ # Generated by Django 1.11.15 on 2018-10-29 21:29 from __future__ import unicode_literals from django.db import migrations -from osf.utils.migrations import DeleteWaffleFlags -from osf.features import EMBER_PROJECT_FORKS class Migration(migrations.Migration): @@ -13,5 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - DeleteWaffleFlags([EMBER_PROJECT_FORKS]) ] diff --git a/osf/migrations/0142_remove_waffle_analytics_flags.py b/osf/migrations/0142_remove_waffle_analytics_flags.py index 080e2e3d616..53ab673288d 100644 --- a/osf/migrations/0142_remove_waffle_analytics_flags.py +++ b/osf/migrations/0142_remove_waffle_analytics_flags.py @@ -2,8 +2,6 @@ # Generated by Django 1.11.15 on 2018-10-30 15:13 from __future__ import unicode_literals from django.db import migrations -from osf.utils.migrations import DeleteWaffleFlags -from osf.features import EMBER_PROJECT_ANALYTICS class Migration(migrations.Migration): @@ -11,5 +9,4 @@ class Migration(migrations.Migration): ('osf', '0142_remove_forks_flag'), ] operations = [ - DeleteWaffleFlags([EMBER_PROJECT_ANALYTICS]) ] diff --git a/osf/migrations/0144_add_prereg_winddown_switches.py b/osf/migrations/0144_add_prereg_winddown_switches.py index 375c25b621d..e5d2762a580 100644 --- a/osf/migrations/0144_add_prereg_winddown_switches.py +++ b/osf/migrations/0144_add_prereg_winddown_switches.py @@ -3,9 +3,6 @@ from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleSwitches - class Migration(migrations.Migration): @@ -14,5 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleSwitches([features.OSF_PREREGISTRATION], active=False), ] diff --git a/osf/migrations/0149_add_datacite_doi_switch.py b/osf/migrations/0149_add_datacite_doi_switch.py index 34d129ff787..278a277ad18 100644 --- a/osf/migrations/0149_add_datacite_doi_switch.py +++ b/osf/migrations/0149_add_datacite_doi_switch.py @@ -3,8 +3,6 @@ from django.db import migrations -from osf.utils.migrations import AddWaffleSwitches - class Migration(migrations.Migration): @@ -13,5 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleSwitches(['disable_datacite_dois'], active=False), ] diff --git a/osf/migrations/0154_remove_ember_project_registrations_flag.py b/osf/migrations/0154_remove_ember_project_registrations_flag.py index a8d16929170..8c9f09a9eaa 100644 --- a/osf/migrations/0154_remove_ember_project_registrations_flag.py +++ b/osf/migrations/0154_remove_ember_project_registrations_flag.py @@ -3,8 +3,7 @@ from __future__ import unicode_literals from django.db import migrations -from osf.utils.migrations import DeleteWaffleFlags -from osf.features import EMBER_PROJECT_REGISTRATIONS + class Migration(migrations.Migration): @@ -13,5 +12,4 @@ class Migration(migrations.Migration): ] operations = [ - DeleteWaffleFlags([EMBER_PROJECT_REGISTRATIONS]) ] diff --git a/osf/migrations/0157_add_storage_usage_flag.py b/osf/migrations/0157_add_storage_usage_flag.py index fdeddf6e590..57b9fbadc3d 100644 --- a/osf/migrations/0157_add_storage_usage_flag.py +++ b/osf/migrations/0157_add_storage_usage_flag.py @@ -2,9 +2,6 @@ from __future__ import unicode_literals from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleFlags - class Migration(migrations.Migration): dependencies = [ @@ -12,5 +9,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags([features.STORAGE_USAGE]), ] diff --git a/osf/migrations/0162_post_migrate.py b/osf/migrations/0162_post_migrate.py index 8486061a642..e0b7b5dd57c 100644 --- a/osf/migrations/0162_post_migrate.py +++ b/osf/migrations/0162_post_migrate.py @@ -21,5 +21,4 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(post_migrate_signal, migrations.RunPython.noop), ] diff --git a/osf/migrations/0167_auto_20190506_1556.py b/osf/migrations/0167_auto_20190506_1556.py index b63d94b9c53..2145ec2fa31 100644 --- a/osf/migrations/0167_auto_20190506_1556.py +++ b/osf/migrations/0167_auto_20190506_1556.py @@ -2,9 +2,6 @@ from __future__ import unicode_literals from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleFlags - class Migration(migrations.Migration): dependencies = [ @@ -12,5 +9,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags([features.OSF_GROUPS], on_for_everyone=False), ] diff --git a/osf/migrations/0174_add_ab_testing_home_page_version_b_flag.py b/osf/migrations/0174_add_ab_testing_home_page_version_b_flag.py index 73aa52be2c4..fd714e6bf8c 100644 --- a/osf/migrations/0174_add_ab_testing_home_page_version_b_flag.py +++ b/osf/migrations/0174_add_ab_testing_home_page_version_b_flag.py @@ -3,8 +3,6 @@ from __future__ import unicode_literals from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleFlags class Migration(migrations.Migration): @@ -13,5 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags([features.EMBER_AB_TESTING_HOME_PAGE_VERSION_B]), ] diff --git a/osf/migrations/0195_add_enable_chronos_waffle_flag.py b/osf/migrations/0195_add_enable_chronos_waffle_flag.py index b0c585474fb..42eeb83446c 100644 --- a/osf/migrations/0195_add_enable_chronos_waffle_flag.py +++ b/osf/migrations/0195_add_enable_chronos_waffle_flag.py @@ -3,8 +3,6 @@ from __future__ import unicode_literals from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleFlags class Migration(migrations.Migration): @@ -13,5 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags([features.ENABLE_CHRONOS]), ] diff --git a/osf/migrations/0197_add_ab_testing_home_page_hero_text_version_b_flag.py b/osf/migrations/0197_add_ab_testing_home_page_hero_text_version_b_flag.py index c8a55d4f956..323cc0dc960 100644 --- a/osf/migrations/0197_add_ab_testing_home_page_hero_text_version_b_flag.py +++ b/osf/migrations/0197_add_ab_testing_home_page_hero_text_version_b_flag.py @@ -3,8 +3,6 @@ from __future__ import unicode_literals from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleFlags, DeleteWaffleFlags class Migration(migrations.Migration): @@ -13,6 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags([features.EMBER_AB_TESTING_HOME_PAGE_HERO_TEXT_VERSION_B]), - DeleteWaffleFlags([features.EMBER_AB_TESTING_HOME_PAGE_VERSION_B]), ] diff --git a/osf/migrations/0199_draft_node_permissions.py b/osf/migrations/0199_draft_node_permissions.py index 1d6a34e6c66..1da33146cfb 100644 --- a/osf/migrations/0199_draft_node_permissions.py +++ b/osf/migrations/0199_draft_node_permissions.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals import logging from django.db import migrations -from django.core.management.sql import emit_post_migrate_signal from osf.migrations.sql.draft_nodes_migration import ( add_draft_read_write_admin_auth_groups, @@ -14,10 +13,6 @@ logger = logging.getLogger(__name__) -def post_migrate_signal(state, schema): - # this is to make sure that the draft registration permissions created earlier exist! - emit_post_migrate_signal(3, False, 'default') - class Migration(migrations.Migration): dependencies = [ @@ -25,7 +20,6 @@ class Migration(migrations.Migration): ] operations = [ - migrations.RunPython(post_migrate_signal, migrations.RunPython.noop), migrations.RunSQL(add_draft_read_write_admin_auth_groups, remove_draft_auth_groups), migrations.RunSQL(add_permissions_to_draft_registration_groups, drop_draft_reg_group_object_permission_table), ] diff --git a/osf/migrations/0201_add_egap_flag.py b/osf/migrations/0201_add_egap_flag.py index 54b7079d723..f93c9d41177 100644 --- a/osf/migrations/0201_add_egap_flag.py +++ b/osf/migrations/0201_add_egap_flag.py @@ -3,8 +3,6 @@ from __future__ import unicode_literals from django.db import migrations -from osf import features -from osf.utils.migrations import AddWaffleFlags class Migration(migrations.Migration): @@ -13,5 +11,4 @@ class Migration(migrations.Migration): ] operations = [ - AddWaffleFlags([features.EGAP_ADMINS], on_for_everyone=None), ] diff --git a/osf/migrations/__init__.py b/osf/migrations/__init__.py index 9b856bd1306..e25d43954c7 100644 --- a/osf/migrations/__init__.py +++ b/osf/migrations/__init__.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- +import sys import logging from django.db.utils import ProgrammingError +from osf.management.commands.manage_switch_flags import manage_waffle logger = logging.getLogger(__file__) @@ -119,3 +121,10 @@ def update_permission_groups(sender, verbosity=0, **kwargs): if getattr(sender, 'label', None) == 'osf': update_admin_permissions(verbosity) update_provider_auth_groups(verbosity) + + +def update_waffle_flags(sender, verbosity=0, **kwargs): + if getattr(sender, 'label', None) == 'osf': + if 'pytest' not in sys.modules: + manage_waffle() + logger.info('Waffle flags have been synced') diff --git a/osf_tests/management_commands/test_manage_switch_flags.py b/osf_tests/management_commands/test_manage_switch_flags.py index fb150294092..547d3062831 100644 --- a/osf_tests/management_commands/test_manage_switch_flags.py +++ b/osf_tests/management_commands/test_manage_switch_flags.py @@ -1,37 +1,40 @@ # -*- coding: utf-8 -*- import pytest +from unittest.mock import patch, mock_open from waffle.models import Flag, Switch -from osf.features import flags, switches from osf.management.commands.manage_switch_flags import manage_waffle -@pytest.fixture() -def test_switch(monkeypatch): - test_switches = switches.copy() - test_switches['TEST_SWITCH'] = 'new_test_switch' - monkeypatch.setattr('osf.management.commands.manage_switch_flags.switches', test_switches) - return test_switches - -@pytest.fixture() -def test_flag(monkeypatch): - test_flags = flags.copy() - test_flags['TEST_FLAG'] = 'new_test_flag' - monkeypatch.setattr('osf.management.commands.manage_switch_flags.flags', test_flags) - return test_flags - @pytest.mark.django_db -def test_manage_flags(test_switch, test_flag, monkeypatch): - manage_waffle() - assert Flag.objects.filter(name='new_test_flag') - assert Switch.objects.filter(name='new_test_switch') +class TestWaffleFlags(): + + @pytest.fixture() + def yaml_data(self): + return ''' + flags: + - flag_name: TEST_FLAG + name: test_flag_page + note: This is for tests only + everyone: true + switches: + - flag_name: TEST_SWITCH + name: test_switch_page + note: This is for tests only + active: false + ''' - monkeypatch.setattr('osf.management.commands.manage_switch_flags.flags', flags) - monkeypatch.setattr('osf.management.commands.manage_switch_flags.switches', switches) + def test_manage_flags(self, yaml_data): + with patch('builtins.open', mock_open(read_data=yaml_data)): + manage_waffle() + assert Flag.objects.all().count() == 1 + assert Switch.objects.all().count() == 1 - manage_waffle() - assert Flag.objects.filter(name='new_test_flag') - assert Switch.objects.filter(name='new_test_switch') + def test_manage_flags_delete(self, yaml_data): + Flag.objects.create(name='new_test_flag') + Switch.objects.create(name='new_test_flag') - manage_waffle(True) - assert not Flag.objects.filter(name='new_test_flag') - assert not Switch.objects.filter(name='new_test_switch') + with patch('builtins.open', mock_open(read_data=yaml_data)): + manage_waffle() + manage_waffle(delete_waffle=True) + assert not Flag.objects.filter(name='new_test_flag') + assert not Switch.objects.filter(name='new_test_switch')