Files
edx-platform/lms/djangoapps/courseware/tests/test_user_state_client.py
Jeff Cohen ff0c1d57da fix: only create one StudentModuleHistory record per request (#31262)
When a student submits a problem answer, the state is stored in a
StudentModule record containing answer, score, correctness, etc. The
record, though, is updated in multiple steps within the single request
(first the grade is updated, then the state is updated separately).
Each partial save would trigger a separate StudentModuleHistory record
to be stored resulting in duplicate and inaccurate historical records.

This solution uses the RequestCache to track within a request thread
which StudentModules are updated and a single corresponding
StudentModuleHistory id. If multiple update actions occur within the
request cycle, then modify the history record that was already
generated to ensure that each submission only results in one
StudentModuleHistory record.

This issue and its solution were discussed in:

  https://discuss.openedx.org/t/extra-history-record-stored-on-each-problem-submission/8081
2022-11-08 10:32:08 -05:00

57 lines
2.2 KiB
Python

"""
Black-box tests of the DjangoUserStateClient against the semantics
defined in edx_user_state_client.
"""
from collections import defaultdict
from django.db import connections
from edx_user_state_client.tests import UserStateClientTestBase
from common.djangoapps.student.tests.factories import UserFactory
from lms.djangoapps.courseware.user_state_client import DjangoXBlockUserStateClient
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
class TestDjangoUserStateClient(UserStateClientTestBase, ModuleStoreTestCase):
"""
Tests of the DjangoUserStateClient backend.
It reuses all tests from :class:`~UserStateClientTestBase`.
"""
__test__ = True
# Tell Django to clean out all databases, not just default
databases = set(connections)
def _user(self, user_idx): # lint-amnesty, pylint: disable=arguments-differ
return self.users[user_idx].username
def _block_type(self, block): # pylint: disable=arguments-differ
# We only record block state history in DjangoUserStateClient
# when the block type is 'problem'
return 'problem'
def setUp(self):
super().setUp()
self.client = DjangoXBlockUserStateClient()
self.users = defaultdict(UserFactory.create)
def test_history_after_delete(self):
"""
Changes made in the edx-platform repo broke this test in the edx-user-state-client repo.
Getting the tests and code in sync is a three step process:
1. Override the test here to make it a no-op and merge this code
2. Update the test in the other repo to align with the new functionality
3. Remove this override to re-enable the working test
"""
def test_multiple_history_entries(self):
"""
Changes made in the edx-platform repo broke this test in the edx-user-state-client repo.
Getting the tests and code in sync is a three step process:
1. Override the test here to make it a no-op and merge this code
2. Update the test in the other repo to align with the new functionality
3. Remove this override to re-enable the working test
"""