Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f5647878
Commit
f5647878
authored
Oct 19, 2016
by
sanfordstudent
Committed by
GitHub
Oct 19, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #13771 from edx/sstudent/TNL-5658
add grading policy hash to transformer
parents
d777749f
9209eef7
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
88 additions
and
0 deletions
+88
-0
lms/djangoapps/grades/tests/test_transformer.py
+55
-0
lms/djangoapps/grades/transformer.py
+33
-0
No files found.
lms/djangoapps/grades/tests/test_transformer.py
View file @
f5647878
...
...
@@ -7,9 +7,11 @@ import pytz
import
random
import
ddt
from
copy
import
deepcopy
from
student.tests.factories
import
UserFactory
from
xmodule.modulestore
import
ModuleStoreEnum
from
xmodule.modulestore.django
import
modulestore
from
xmodule.modulestore.tests.django_utils
import
SharedModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
check_mongo_calls
...
...
@@ -39,6 +41,27 @@ class GradesTransformerTestCase(CourseStructureTestCase):
self
.
student
=
UserFactory
.
create
(
is_staff
=
False
,
username
=
u'test_student'
,
password
=
password
)
self
.
client
.
login
(
username
=
self
.
student
.
username
,
password
=
password
)
def
_update_course_grading_policy
(
self
,
course
,
grading_policy
):
"""
Helper to update a course's grading policy in the modulestore.
"""
course
.
set_grading_policy
(
grading_policy
)
modulestore
()
.
update_item
(
course
,
self
.
user
.
id
)
def
_validate_grading_policy_hash
(
self
,
course_location
,
grading_policy_hash
):
"""
Helper to retrieve the course at the given course_location and
assert that its hashed grading policy (from the grades transformer)
is as expected.
"""
block_structure
=
get_course_blocks
(
self
.
student
,
course_location
,
self
.
transformers
)
self
.
assert_collected_transformer_block_fields
(
block_structure
,
course_location
,
self
.
TRANSFORMER_CLASS_TO_TEST
,
grading_policy_hash
=
grading_policy_hash
,
)
def
assert_collected_xblock_fields
(
self
,
block_structure
,
usage_key
,
**
expectations
):
"""
Given a block structure, a block usage key, and a list of keyword
...
...
@@ -330,6 +353,38 @@ class GradesTransformerTestCase(CourseStructureTestCase):
block_structure
=
get_course_blocks
(
self
.
student
,
blocks
[
u'course'
]
.
location
,
self
.
transformers
)
self
.
assertIsNotNone
(
block_structure
.
get_xblock_field
(
blocks
[
u'course'
]
.
location
,
u'course_version'
))
def
test_grading_policy_collected
(
self
):
# the calculated hash of the original and updated grading policies of the test course
original_grading_policy_hash
=
u'ChVp0lHGQGCevD0t4njna/C44zQ='
updated_grading_policy_hash
=
u'TsbX04qWOy1WRnC0NHy+94upPd4='
blocks
=
self
.
build_course_with_problems
()
course_block
=
blocks
[
u'course'
]
self
.
_validate_grading_policy_hash
(
course_block
.
location
,
original_grading_policy_hash
)
# make sure the hash changes when the course grading policy is edited
grading_policy_with_updates
=
course_block
.
grading_policy
original_grading_policy
=
deepcopy
(
grading_policy_with_updates
)
for
section
in
grading_policy_with_updates
[
'GRADER'
]:
self
.
assertNotEqual
(
section
[
'weight'
],
0.25
)
section
[
'weight'
]
=
0.25
self
.
_update_course_grading_policy
(
course_block
,
grading_policy_with_updates
)
self
.
_validate_grading_policy_hash
(
course_block
.
location
,
updated_grading_policy_hash
)
# reset the grading policy and ensure the hash matches the original
self
.
_update_course_grading_policy
(
course_block
,
original_grading_policy
)
self
.
_validate_grading_policy_hash
(
course_block
.
location
,
original_grading_policy_hash
)
class
MultiProblemModulestoreAccessTestCase
(
CourseStructureTestCase
,
SharedModuleStoreTestCase
):
"""
...
...
lms/djangoapps/grades/transformer.py
View file @
f5647878
"""
Grades Transformer
"""
from
base64
import
b64encode
from
django.test.client
import
RequestFactory
from
functools
import
reduce
as
functools_reduce
from
hashlib
import
sha1
from
logging
import
getLogger
import
json
from
courseware.model_data
import
FieldDataCache
from
courseware.module_render
import
get_module_for_descriptor
...
...
@@ -64,6 +67,7 @@ class GradesTransformer(BlockStructureTransformer):
filter_by
=
lambda
block_key
:
block_key
.
block_type
==
'sequential'
,
)
cls
.
_collect_explicit_graded
(
block_structure
)
cls
.
_collect_grading_policy_hash
(
block_structure
)
def
transform
(
self
,
block_structure
,
usage_context
):
"""
...
...
@@ -128,6 +132,35 @@ class GradesTransformer(BlockStructureTransformer):
if
max_score
is
None
:
log
.
warning
(
"GradesTransformer: max_score is None for {}"
.
format
(
module
.
location
))
@classmethod
def
_collect_grading_policy_hash
(
cls
,
block_structure
):
"""
Collect a hash of the course's grading policy, storing it as a
`transformer_block_field` associated with the `GradesTransformer`.
"""
def
_hash_grading_policy
(
policy
):
"""
Creates a hash from the course grading policy.
The keys are sorted in order to make the hash
agnostic to the ordering of the policy coming in.
"""
ordered_policy
=
json
.
dumps
(
policy
,
separators
=
(
','
,
':'
),
# Remove spaces from separators for more compact representation
sort_keys
=
True
,
)
return
b64encode
(
sha1
(
ordered_policy
)
.
digest
())
course_location
=
block_structure
.
root_block_usage_key
course_block
=
block_structure
.
get_xblock
(
course_location
)
grading_policy
=
course_block
.
grading_policy
block_structure
.
set_transformer_block_field
(
course_block
.
location
,
cls
,
"grading_policy_hash"
,
_hash_grading_policy
(
grading_policy
)
)
@staticmethod
def
_iter_scorable_xmodules
(
block_structure
):
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment