fix: restored badges handlers feat: remove FE code for badges fix: resolved failing tests fix: removed test case for badges app fix: unused import error fix: Response Field Count fix: shareable account response length fix: resolved PR comments fix: revert settings override feat!: Removed Badges App fix: restored badges handlers feat: remove FE code for badges fix: resolved failing tests fix: removed test case for badges app fix: unused import error fix: Response Field Count fix: shareable account response length fix: revert subscription badge
142 lines
5.2 KiB
Python
142 lines
5.2 KiB
Python
"""Tests for util.db module."""
|
|
|
|
from io import StringIO
|
|
|
|
import ddt
|
|
import unittest
|
|
from django.core.management import call_command
|
|
from django.db.transaction import TransactionManagementError, atomic
|
|
from django.test import TestCase, TransactionTestCase
|
|
from django.test.utils import override_settings
|
|
|
|
from common.djangoapps.util.db import enable_named_outer_atomic, generate_int_id, outer_atomic
|
|
|
|
|
|
def do_nothing():
|
|
"""Just return."""
|
|
return
|
|
|
|
|
|
class TransactionManagersTestCase(TransactionTestCase):
|
|
"""
|
|
Tests outer_atomic.
|
|
"""
|
|
|
|
def test_outer_atomic_nesting(self):
|
|
"""
|
|
Test that outer_atomic raises an error if it is nested inside
|
|
another atomic.
|
|
"""
|
|
outer_atomic()(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with atomic():
|
|
atomic()(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with outer_atomic():
|
|
atomic()(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with self.assertRaisesRegex(TransactionManagementError, 'Cannot be inside an atomic block.'):
|
|
with atomic():
|
|
outer_atomic()(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with self.assertRaisesRegex(TransactionManagementError, 'Cannot be inside an atomic block.'):
|
|
with outer_atomic():
|
|
outer_atomic()(do_nothing)() # pylint: disable=not-callable
|
|
|
|
def test_named_outer_atomic_nesting(self):
|
|
"""
|
|
Test that a named outer_atomic raises an error only if nested in
|
|
enable_named_outer_atomic and inside another atomic.
|
|
"""
|
|
outer_atomic(name='abc')(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with atomic():
|
|
outer_atomic(name='abc')(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with enable_named_outer_atomic('abc'):
|
|
|
|
outer_atomic(name='abc')(do_nothing)() # pylint: disable=not-callable # Not nested.
|
|
|
|
with atomic():
|
|
outer_atomic(name='pqr')(do_nothing)() # pylint: disable=not-callable # Not enabled.
|
|
|
|
with self.assertRaisesRegex(TransactionManagementError, 'Cannot be inside an atomic block.'):
|
|
with atomic():
|
|
outer_atomic(name='abc')(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with enable_named_outer_atomic('abc', 'def'):
|
|
|
|
outer_atomic(name='def')(do_nothing)() # pylint: disable=not-callable # Not nested.
|
|
|
|
with atomic():
|
|
outer_atomic(name='pqr')(do_nothing)() # pylint: disable=not-callable # Not enabled.
|
|
|
|
with self.assertRaisesRegex(TransactionManagementError, 'Cannot be inside an atomic block.'):
|
|
with atomic():
|
|
outer_atomic(name='def')(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with self.assertRaisesRegex(TransactionManagementError, 'Cannot be inside an atomic block.'):
|
|
with outer_atomic():
|
|
outer_atomic(name='def')(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with self.assertRaisesRegex(TransactionManagementError, 'Cannot be inside an atomic block.'):
|
|
with atomic():
|
|
outer_atomic(name='abc')(do_nothing)() # pylint: disable=not-callable
|
|
|
|
with self.assertRaisesRegex(TransactionManagementError, 'Cannot be inside an atomic block.'):
|
|
with outer_atomic():
|
|
outer_atomic(name='abc')(do_nothing)() # pylint: disable=not-callable
|
|
|
|
|
|
@ddt.ddt
|
|
class GenerateIntIdTestCase(TestCase):
|
|
"""Tests for `generate_int_id`"""
|
|
@ddt.data(10)
|
|
def test_no_used_ids(self, times):
|
|
"""
|
|
Verify that we get a random integer within the specified range
|
|
when there are no used ids.
|
|
"""
|
|
minimum = 1
|
|
maximum = times
|
|
for __ in range(times):
|
|
assert generate_int_id(minimum, maximum) in list(range(minimum, (maximum + 1)))
|
|
|
|
@ddt.data(10)
|
|
def test_used_ids(self, times):
|
|
"""
|
|
Verify that we get a random integer within the specified range
|
|
but not in a list of used ids.
|
|
"""
|
|
minimum = 1
|
|
maximum = times
|
|
used_ids = {2, 4, 6, 8}
|
|
for __ in range(times):
|
|
int_id = generate_int_id(minimum, maximum, used_ids)
|
|
assert int_id in list(set(range(minimum, (maximum + 1))) - used_ids)
|
|
|
|
|
|
class MigrationTests(TestCase):
|
|
"""
|
|
Tests for migrations.
|
|
"""
|
|
|
|
@unittest.skip("Migration will delete several models. Need to ship not referencing it first")
|
|
@override_settings(MIGRATION_MODULES={})
|
|
def test_migrations_are_in_sync(self):
|
|
"""
|
|
Tests that the migration files are in sync with the models.
|
|
If this fails, you needs to run the Django command makemigrations.
|
|
|
|
The test is set up to override MIGRATION_MODULES to ensure migrations are
|
|
enabled for purposes of this test regardless of the overall test settings.
|
|
|
|
TODO: Find a general way of handling the case where if we're trying to
|
|
make a migrationless release that'll require a separate migration
|
|
release afterwards, this test doesn't fail.
|
|
"""
|
|
out = StringIO()
|
|
call_command("makemigrations", dry_run=True, verbosity=3, stdout=out)
|
|
output = out.getvalue()
|
|
assert 'No changes detected' in output
|