def test_only_print_queries(model_name, config, monkeypatch, caplog): """ Test that if --only-print-queries is passed, the SQL query is printed but no deletions or simulation occurs. """ caplog.set_level('INFO') delete_mock = mock.Mock() monkeypatch.setattr(QuerySet, 'delete', delete_mock) command = delete_old_records.Command() model = apps.get_model(model_name) mapping = MAPPING[model_name] model_factory = mapping['factory'] for _ in range(3): _create_model_obj(model_factory, **mapping['expired_objects_kwargs'][0]) management.call_command(command, model_name, only_print_queries=True) assert not delete_mock.called log_text = caplog.text.lower() assert f'{model._meta.verbose_name_plural} to delete:' in log_text for relation in get_relations_to_delete(model): related_meta = relation.related_model._meta expected_related_log = ( f'{related_meta.verbose_name_plural} to delete ' f'(via {related_meta.model_name}.{relation.remote_field.name}): ' ).lower() assert expected_related_log in log_text assert f'from "{related_meta.db_table}"' in log_text
def test_only_print_queries(cleanup_commands_and_configs, monkeypatch, caplog): """ Test that if --only-print-queries is passed, the SQL query is printed but no deletions or simulation occurs. """ caplog.set_level('INFO') delete_mock = mock.Mock() monkeypatch.setattr(QuerySet, 'delete', delete_mock) command, model_name, config = cleanup_commands_and_configs model = apps.get_model(model_name) mapping = MAPPINGS[model_name] model_factory = mapping['factory'] datetime_older_than_threshold = FROZEN_TIME - config.age_threshold - relativedelta( days=1) for _ in range(3): create_orphanable_model(model_factory, config, datetime_older_than_threshold) management.call_command(command, model_name, only_print_queries=True) assert not delete_mock.called log_text = caplog.text.lower() assert f'{model._meta.verbose_name_plural} to delete:' in log_text for relation in get_relations_to_delete(model): related_meta = relation.related_model._meta assert ( f'{related_meta.verbose_name_plural} to delete ' f'(via {related_meta.model_name}.{relation.remote_field.name}): ' ) in log_text assert f'from "{related_meta.db_table}"' in log_text
def _print_queries(self, model, qs): # relationships that would get deleted in cascade for related in get_relations_to_delete(model): related_model = related.related_model related_qs = related_model._base_manager.filter( **{f'{related.field.name}__in': Subquery(qs.values('pk'))}, ) _print_query(related_model, related_qs, related) # main model _print_query(model, qs)
def test_simulate(s3_stubber, caplog, investment_projects_and_csv_content): """Test that the command only simulates the actions if --simulate is passed in.""" caplog.set_level('INFO') investment_projects, csv_content = investment_projects_and_csv_content bucket = 'test_bucket' object_key = 'test_key' s3_stubber.add_response( 'get_object', { 'Body': BytesIO(bytes(csv_content)), }, expected_params={ 'Bucket': bucket, 'Key': object_key, }, ) # Calculate the number of records to be deleted just for one investment project. Three projects # tested have the same number of related records so it is enough to calculate just for one. # 1 for the investment project itself plus related records records_to_be_deleted = 1 relations_to_delete = get_relations_to_delete(InvestmentProject) for related in relations_to_delete: related_model = related.related_model related_qs = related_model._base_manager.filter( **{related.field.name: investment_projects[0].id}, ) related_qs_count = related_qs.count() records_to_be_deleted += related_qs_count call_command('delete_investment_project', bucket, object_key, simulate=True) # In the test, two investment projects should be deleted assert caplog.text.count( f'{records_to_be_deleted} records deleted for investment project: ', ) == 2 assert 'InvestmentProject matching query does not exist' in caplog.text for investment_project in investment_projects: investment_project.refresh_from_db() assert investment_project.id is not None