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
38b859fd
Commit
38b859fd
authored
Jun 03, 2015
by
zubair-arbi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
use 'name' field in 'CreditRequirement' model to save the location of xblocks
parent
099be9e7
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
223 additions
and
96 deletions
+223
-96
openedx/core/djangoapps/credit/api.py
+19
-18
openedx/core/djangoapps/credit/exceptions.py
+9
-3
openedx/core/djangoapps/credit/migrations/0004_auto__add_field_creditrequirement_display_name.py
+71
-0
openedx/core/djangoapps/credit/models.py
+28
-15
openedx/core/djangoapps/credit/signals.py
+7
-4
openedx/core/djangoapps/credit/tasks.py
+15
-10
openedx/core/djangoapps/credit/tests/test_api.py
+37
-22
openedx/core/djangoapps/credit/tests/test_models.py
+14
-5
openedx/core/djangoapps/credit/tests/test_tasks.py
+22
-18
requirements/edx/github.txt
+1
-1
No files found.
openedx/core/djangoapps/credit/api.py
View file @
38b859fd
...
...
@@ -6,7 +6,7 @@ from openedx.core.djangoapps.credit.exceptions import InvalidCreditCourse
def
set_credit_requirements
(
course_key
,
requirements
):
"""
Add requirements to given course
"""
Add requirements to given course.
Args:
course_key(CourseKey): The identifier for course
...
...
@@ -17,23 +17,21 @@ def set_credit_requirements(course_key, requirements):
"course-v1-edX-DemoX-1T2015",
[
{
"namespace": "verification",
"name": "verification",
"criteria": {},
},
{
"namespace": "reverification",
"name": "midterm",
"name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
"display_name": "Assessment 1",
"criteria": {},
},
{
"namespace": "proctored_exam",
"name": "final",
"name": "i4x://edX/DemoX/proctoring-block/final_uuid",
"display_name": "Final Exam",
"criteria": {},
},
{
"namespace": "grade",
"name": "grade",
"display_name": "Grade",
"criteria": {"min_grade": 0.8},
},
])
...
...
@@ -65,7 +63,7 @@ def set_credit_requirements(course_key, requirements):
def
get_credit_requirements
(
course_key
,
namespace
=
None
):
"""
Returns the requirements of a given course and namespace
"""
Get credit eligibility requirements of a given course and namespace.
Args:
course_key(CourseKey): The identifier for course
...
...
@@ -77,23 +75,21 @@ def get_credit_requirements(course_key, namespace=None):
requirements =
[
{
"namespace": "verification",
"name": "verification",
"criteria": {},
},
{
"namespace": "reverification",
"name": "midterm",
"name": "i4x://edX/DemoX/edx-reverification-block/assessment_uuid",
"display_name": "Assessment 1",
"criteria": {},
},
{
"namespace": "proctored_exam",
"name": "final",
"name": "i4x://edX/DemoX/proctoring-block/final_uuid",
"display_name": "Final Exam",
"criteria": {},
},
{
"namespace": "grade",
"name": "grade",
"display_name": "Grade",
"criteria": {"min_grade": 0.8},
},
]
...
...
@@ -108,6 +104,7 @@ def get_credit_requirements(course_key, namespace=None):
{
"namespace"
:
requirement
.
namespace
,
"name"
:
requirement
.
name
,
"display_name"
:
requirement
.
display_name
,
"criteria"
:
requirement
.
criteria
}
for
requirement
in
requirements
...
...
@@ -115,7 +112,8 @@ def get_credit_requirements(course_key, namespace=None):
def
_get_requirements_to_disable
(
old_requirements
,
new_requirements
):
""" Returns the ids of CreditRequirement to be disabled that are deleted from the courseware
"""Get the ids of 'CreditRequirement' entries to be disabled that are
deleted from the courseware.
Args:
old_requirements(QuerySet): QuerySet of CreditRequirement
...
...
@@ -128,6 +126,7 @@ def _get_requirements_to_disable(old_requirements, new_requirements):
for
old_req
in
old_requirements
:
found_flag
=
False
for
req
in
new_requirements
:
# check if an already added requirement is modified
if
req
[
"namespace"
]
==
old_req
.
namespace
and
req
[
"name"
]
==
old_req
.
name
:
found_flag
=
True
break
...
...
@@ -137,7 +136,7 @@ def _get_requirements_to_disable(old_requirements, new_requirements):
def
_validate_requirements
(
requirements
):
"""
Validate the requirements
"""
Validate the requirements.
Args:
requirements(list): List of requirements
...
...
@@ -152,6 +151,8 @@ def _validate_requirements(requirements):
invalid_params
.
append
(
"namespace"
)
if
not
requirement
.
get
(
"name"
):
invalid_params
.
append
(
"name"
)
if
not
requirement
.
get
(
"display_name"
):
invalid_params
.
append
(
"display_name"
)
if
"criteria"
not
in
requirement
:
invalid_params
.
append
(
"criteria"
)
...
...
openedx/core/djangoapps/credit/exceptions.py
View file @
38b859fd
""" This module contains the exceptions raised in credit course requirements """
"""
This module contains the exceptions raised in credit course requirements.
"""
class
InvalidCreditRequirements
(
Exception
):
""" The exception occurs when the requirement dictionary has invalid format. """
"""
The exception occurs when the requirement dictionary has invalid format.
"""
pass
class
InvalidCreditCourse
(
Exception
):
""" The exception occurs when the the course is not marked as a Credit Course. """
"""
The exception occurs when the the course is not marked as a Credit Course.
"""
pass
openedx/core/djangoapps/credit/migrations/0004_auto__add_field_creditrequirement_display_name.py
0 → 100644
View file @
38b859fd
# -*- coding: utf-8 -*-
from
south.utils
import
datetime_utils
as
datetime
from
south.db
import
db
from
south.v2
import
SchemaMigration
from
django.db
import
models
class
Migration
(
SchemaMigration
):
def
forwards
(
self
,
orm
):
# Adding field 'CreditRequirement.display_name'
db
.
add_column
(
'credit_creditrequirement'
,
'display_name'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
default
=
''
,
max_length
=
255
),
keep_default
=
False
)
def
backwards
(
self
,
orm
):
# Deleting field 'CreditRequirement.display_name'
db
.
delete_column
(
'credit_creditrequirement'
,
'display_name'
)
models
=
{
'credit.creditcourse'
:
{
'Meta'
:
{
'object_name'
:
'CreditCourse'
},
'course_key'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'credit.crediteligibility'
:
{
'Meta'
:
{
'unique_together'
:
"(('username', 'course'),)"
,
'object_name'
:
'CreditEligibility'
},
'course'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'eligibilities'"
,
'to'
:
"orm['credit.CreditCourse']"
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'provider'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'eligibilities'"
,
'to'
:
"orm['credit.CreditProvider']"
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
})
},
'credit.creditprovider'
:
{
'Meta'
:
{
'object_name'
:
'CreditProvider'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'display_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'provider_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'255'
,
'db_index'
:
'True'
})
},
'credit.creditrequirement'
:
{
'Meta'
:
{
'unique_together'
:
"(('namespace', 'name', 'course'),)"
,
'object_name'
:
'CreditRequirement'
},
'active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'course'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'credit_requirements'"
,
'to'
:
"orm['credit.CreditCourse']"
}),
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'criteria'
:
(
'jsonfield.fields.JSONField'
,
[],
{}),
'display_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
}),
'namespace'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
})
},
'credit.creditrequirementstatus'
:
{
'Meta'
:
{
'object_name'
:
'CreditRequirementStatus'
},
'created'
:
(
'model_utils.fields.AutoCreatedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'modified'
:
(
'model_utils.fields.AutoLastModifiedField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'reason'
:
(
'jsonfield.fields.JSONField'
,
[],
{
'default'
:
'{}'
}),
'requirement'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'statuses'"
,
'to'
:
"orm['credit.CreditRequirement']"
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
})
}
}
complete_apps
=
[
'credit'
]
\ No newline at end of file
openedx/core/djangoapps/credit/models.py
View file @
38b859fd
...
...
@@ -19,14 +19,16 @@ log = logging.getLogger(__name__)
class
CreditCourse
(
models
.
Model
):
"""Model for tracking a credit course."""
"""
Model for tracking a credit course.
"""
course_key
=
CourseKeyField
(
max_length
=
255
,
db_index
=
True
,
unique
=
True
)
enabled
=
models
.
BooleanField
(
default
=
False
)
@classmethod
def
is_credit_course
(
cls
,
course_key
):
"""
Check that given course is credit or not
"""
Check that given course is credit or not.
Args:
course_key(CourseKey): The course identifier
...
...
@@ -38,7 +40,7 @@ class CreditCourse(models.Model):
@classmethod
def
get_credit_course
(
cls
,
course_key
):
"""
Get the credit course if exists for the given course_key
"""
Get the credit course if exists for the given 'course_key'.
Args:
course_key(CourseKey): The course identifier
...
...
@@ -65,28 +67,36 @@ class CreditProvider(TimeStampedModel):
class
CreditRequirement
(
TimeStampedModel
):
"""This model represents a credit requirement.
Each requirement is uniquely identified by a `namespace` and a `name`. CreditRequirements
also include a `criteria` dictionary, the format of which varies by the type of requirement.
The criteria dictionary provides additional information clients may need to determine
whether a user has satisfied the requirement.
Each requirement is uniquely identified by its 'namespace' and
'name' fields.
The 'name' field stores the unique name or location (in case of XBlock)
for a requirement, which serves as the unique identifier for that
requirement.
The 'display_name' field stores the display name of the requirement.
The 'criteria' field dictionary provides additional information, clients
may need to determine whether a user has satisfied the requirement.
"""
course
=
models
.
ForeignKey
(
CreditCourse
,
related_name
=
"credit_requirements"
)
namespace
=
models
.
CharField
(
max_length
=
255
)
name
=
models
.
CharField
(
max_length
=
255
)
display_name
=
models
.
CharField
(
max_length
=
255
)
criteria
=
JSONField
()
active
=
models
.
BooleanField
(
default
=
True
)
class
Meta
(
object
):
"""Model metadata"""
"""
Model metadata.
"""
unique_together
=
(
'namespace'
,
'name'
,
'course'
)
@classmethod
def
add_or_update_course_requirement
(
cls
,
credit_course
,
requirement
):
""" Add requirement to a given course
"""Add requirement to a given course.
Args:
credit_course(CreditCourse): The identifier for credit course
course
requirement(dict):
r
equirement dict to be added
credit_course(CreditCourse): The identifier for credit course
requirement(dict):
R
equirement dict to be added
Returns:
(CreditRequirement, created) tuple
...
...
@@ -96,6 +106,7 @@ class CreditRequirement(TimeStampedModel):
course
=
credit_course
,
namespace
=
requirement
[
"namespace"
],
name
=
requirement
[
"name"
],
display_name
=
requirement
[
"display_name"
],
defaults
=
{
"criteria"
:
requirement
[
"criteria"
],
"active"
:
True
}
)
if
not
created
:
...
...
@@ -107,11 +118,11 @@ class CreditRequirement(TimeStampedModel):
@classmethod
def
get_course_requirements
(
cls
,
course_key
,
namespace
=
None
):
"""
Get credit requirements of a given course
"""
Get credit requirements of a given course.
Args:
course_key(CourseKey): The identifier for a course
namespace(str):
n
amespace of credit course requirements
namespace(str):
N
amespace of credit course requirements
Returns:
QuerySet of CreditRequirement model
...
...
@@ -123,7 +134,7 @@ class CreditRequirement(TimeStampedModel):
@classmethod
def
disable_credit_requirements
(
cls
,
requirement_ids
):
"""
Mark the given requirements inactive
"""
Mark the given requirements inactive.
Args:
requirement_ids(list): List of ids
...
...
@@ -176,5 +187,7 @@ class CreditEligibility(TimeStampedModel):
provider
=
models
.
ForeignKey
(
CreditProvider
,
related_name
=
"eligibilities"
)
class
Meta
(
object
):
"""Model metadata"""
"""
Model metadata.
"""
unique_together
=
(
'username'
,
'course'
)
openedx/core/djangoapps/credit/signals.py
View file @
38b859fd
"""This file contains receivers of course publication signals."""
"""
This file contains receivers of course publication signals.
"""
from
django.dispatch
import
receiver
...
...
@@ -7,11 +9,12 @@ from xmodule.modulestore.django import SignalHandler
@receiver
(
SignalHandler
.
course_published
)
def
listen_for_course_publish
(
sender
,
course_key
,
**
kwargs
):
# pylint: disable=unused-argument
"""
Receives signal and kicks off celery task to update the
course requirements.
"""
Receive 'course_published' signal and kick off a celery task to update
the credit
course requirements.
"""
# import here, because signal is registered at startup, but items in tasks are not yet able to be loaded
# Import here, because signal is registered at startup, but items in tasks
# are not yet able to be loaded
from
.tasks
import
update_course_requirements
update_course_requirements
.
delay
(
unicode
(
course_key
))
openedx/core/djangoapps/credit/tasks.py
View file @
38b859fd
""" This file contains celery tasks for credit course views """
"""
This file contains celery tasks for credit course views.
"""
from
django.conf
import
settings
...
...
@@ -55,20 +57,20 @@ def _get_course_credit_requirements(course):
List of minimum_grade_credit and ICRV requirements
"""
icrv
_requirements
=
_get_credit_course_requirement_xblocks
(
course
)
credit_xblock
_requirements
=
_get_credit_course_requirement_xblocks
(
course
)
min_grade_requirement
=
_get_min_grade_requirement
(
course
)
credit_requirements
=
icrv
_requirements
+
min_grade_requirement
credit_requirements
=
credit_xblock
_requirements
+
min_grade_requirement
return
credit_requirements
def
_get_min_grade_requirement
(
course
):
"""
Returns the list of minimum_grade_credit requirements
for the given course.
"""
Get list of 'minimum_grade_credit' requirement
for the given course.
Args:
course(Course): The course object
Raises:
AttributeError if the course has not
minimum_grade_credit
attribute
AttributeError if the course has not
'minimum_grade_credit'
attribute
Returns:
The list of minimum_grade_credit requirements
...
...
@@ -80,6 +82,7 @@ def _get_min_grade_requirement(course):
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
getattr
(
course
,
"minimum_grade_credit"
)
}
...
...
@@ -91,7 +94,7 @@ def _get_min_grade_requirement(course):
def
_get_credit_course_requirement_xblocks
(
course
):
# pylint: disable=invalid-name
"""Generate
s
a course structure dictionary for the specified course.
"""Generate a course structure dictionary for the specified course.
Args:
course(Course): The course object
...
...
@@ -109,23 +112,25 @@ def _get_credit_course_requirement_xblocks(course): # pylint: disable=invalid-n
block
=
{
"namespace"
:
curr_block
.
get_credit_requirement_namespace
(),
"name"
:
curr_block
.
get_credit_requirement_name
(),
"display_name"
:
curr_block
.
get_credit_requirement_display_name
(),
"criteria"
:
""
}
requirements_blocks
.
append
(
block
)
# Add this blocks children to the stack so that we can traverse them as well.
# Add the children of current block to the stack so that we can
# traverse them as well.
blocks_stack
.
extend
(
children
)
return
requirements_blocks
def
_is_credit_requirement
(
xblock
):
"""Check if the given
xb
lock is a credit requirement.
"""Check if the given
XB
lock is a credit requirement.
Args:
xblock(XBlock): The given
xb
lock object
xblock(XBlock): The given
XB
lock object
Returns:
True if
xb
lock is a credit requirement else False
True if
XB
lock is a credit requirement else False
"""
is_credit_requirement
=
False
...
...
openedx/core/djangoapps/credit/tests/test_api.py
View file @
38b859fd
""" Tests for credit course api """
"""
Tests for credit course api.
"""
import
ddt
from
opaque_keys.edx.keys
import
CourseKey
from
openedx.core.djangoapps.credit.api
import
(
get_credit_requirements
,
set_credit_requirements
,
_get_requirements_to_disable
)
...
...
@@ -12,7 +16,9 @@ from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
@ddt.ddt
class
ApiTestCases
(
ModuleStoreTestCase
):
""" Tests for credit course api """
"""
Tests for credit course api.
"""
def
setUp
(
self
,
**
kwargs
):
super
(
ApiTestCases
,
self
)
.
setUp
()
...
...
@@ -39,6 +45,7 @@ class ApiTestCases(ModuleStoreTestCase):
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
}
]
)
...
...
@@ -48,25 +55,34 @@ class ApiTestCases(ModuleStoreTestCase):
set_credit_requirements
(
self
.
course_key
,
requirements
)
def
test_set_credit_requirements_invalid_course
(
self
):
"""Test that 'InvalidCreditCourse' exception is raise if we try to
set credit requirements for a non credit course.
"""
requirements
=
[
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{}
}
]
with
self
.
assertRaises
(
InvalidCreditCourse
):
set_credit_requirements
(
self
.
course_key
,
requirements
)
self
.
add_credit_course
(
enabled
=
False
)
with
self
.
assertRaises
(
InvalidCreditCourse
):
set_credit_requirements
(
self
.
course_key
,
requirements
)
def
test_set_get_credit_requirements
(
self
):
"""Test that if same requirement is added multiple times
then it is added only one time and update for next all iterations.
"""
self
.
add_credit_course
()
requirements
=
[
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
...
...
@@ -74,27 +90,26 @@ class ApiTestCases(ModuleStoreTestCase):
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
0.
8
"min_grade"
:
0.
9
}
}
]
set_credit_requirements
(
self
.
course_key
,
requirements
)
self
.
assertEqual
(
len
(
get_credit_requirements
(
self
.
course_key
)),
1
)
# now verify that the saved requirement has values of last requirement
# from all same requirements
self
.
assertEqual
(
get_credit_requirements
(
self
.
course_key
)[
0
],
requirements
[
1
])
def
test_disable_credit_requirements
(
self
):
self
.
add_credit_course
()
requirements
=
[
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
},
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
...
...
@@ -106,12 +121,14 @@ class ApiTestCases(ModuleStoreTestCase):
requirements
=
[
{
"namespace"
:
"reverification"
,
"name"
:
"midterm"
,
"name"
:
"i4x://edX/DemoX/edx-reverification-block/assessment_uuid"
,
"display_name"
:
"Assessment 1"
,
"criteria"
:
{}
}
]
set_credit_requirements
(
self
.
course_key
,
requirements
)
self
.
assertEqual
(
len
(
get_credit_requirements
(
self
.
course_key
)),
1
)
grade_req
=
CreditRequirement
.
objects
.
filter
(
namespace
=
"grade"
,
name
=
"grade"
)
self
.
assertEqual
(
len
(
grade_req
),
1
)
self
.
assertEqual
(
grade_req
[
0
]
.
active
,
False
)
...
...
@@ -122,13 +139,7 @@ class ApiTestCases(ModuleStoreTestCase):
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
},
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
...
...
@@ -142,7 +153,8 @@ class ApiTestCases(ModuleStoreTestCase):
requirements
=
[
{
"namespace"
:
"reverification"
,
"name"
:
"midterm"
,
"name"
:
"i4x://edX/DemoX/edx-reverification-block/assessment_uuid"
,
"display_name"
:
"Assessment 1"
,
"criteria"
:
{}
}
]
...
...
@@ -154,13 +166,15 @@ class ApiTestCases(ModuleStoreTestCase):
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
},
{
"namespace"
:
"reverification"
,
"name"
:
"midterm"
,
"name"
:
"i4x://edX/DemoX/edx-reverification-block/assessment_uuid"
,
"display_name"
:
"Assessment 1"
,
"criteria"
:
{}
}
]
...
...
@@ -168,8 +182,9 @@ class ApiTestCases(ModuleStoreTestCase):
self
.
assertEqual
(
len
(
requirements_to_disabled
),
0
)
def
add_credit_course
(
self
,
enabled
=
True
):
""" Mark the course as a credit """
"""
Mark the course as a credit.
"""
credit_course
=
CreditCourse
(
course_key
=
self
.
course_key
,
enabled
=
enabled
)
credit_course
.
save
()
return
credit_course
openedx/core/djangoapps/credit/tests/test_models.py
View file @
38b859fd
""" Tests for credit course models """
"""
Tests for credit course models.
"""
import
ddt
from
opaque_keys.edx.keys
import
CourseKey
from
openedx.core.djangoapps.credit.models
import
CreditCourse
,
CreditRequirement
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
@ddt.ddt
class
ModelTestCases
(
ModuleStoreTestCase
):
""" Tests for credit course models """
"""
Tests for credit course models.
"""
def
setUp
(
self
,
**
kwargs
):
super
(
ModelTestCases
,
self
)
.
setUp
()
...
...
@@ -28,6 +33,7 @@ class ModelTestCases(ModuleStoreTestCase):
requirement
=
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
...
...
@@ -43,6 +49,7 @@ class ModelTestCases(ModuleStoreTestCase):
requirement
=
{
"namespace"
:
"grade"
,
"name"
:
"grade"
,
"display_name"
:
"Grade"
,
"criteria"
:
{
"min_grade"
:
0.8
}
...
...
@@ -52,9 +59,10 @@ class ModelTestCases(ModuleStoreTestCase):
self
.
assertEqual
(
created
,
True
)
requirement
=
{
"namespace"
:
"icrv"
,
"name"
:
"midterm"
,
"criteria"
:
""
"namespace"
:
"reverification"
,
"name"
:
"i4x://edX/DemoX/edx-reverification-block/assessment_uuid"
,
"display_name"
:
"Assessment 1"
,
"criteria"
:
{}
}
credit_req
,
created
=
CreditRequirement
.
add_or_update_course_requirement
(
credit_course
,
requirement
)
self
.
assertEqual
(
credit_course
,
credit_req
.
course
)
...
...
@@ -62,6 +70,7 @@ class ModelTestCases(ModuleStoreTestCase):
requirements
=
CreditRequirement
.
get_course_requirements
(
self
.
course_key
)
self
.
assertEqual
(
len
(
requirements
),
2
)
requirements
=
CreditRequirement
.
get_course_requirements
(
self
.
course_key
,
namespace
=
"grade"
)
self
.
assertEqual
(
len
(
requirements
),
1
)
...
...
openedx/core/djangoapps/credit/tests/test_tasks.py
View file @
38b859fd
""" Tests for credit course tasks """
"""
Tests for credit course tasks.
"""
import
mock
from
datetime
import
datetime
...
...
@@ -13,16 +15,17 @@ from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
class
TestTaskExecution
(
ModuleStoreTestCase
):
"""
Set of tests to ensure that the task code will do the right thing when
executed directly. The test course gets created without the listeners
being present, which allows us to ensure that when the listener is
executed, it is done as expected.
"""Set of tests to ensure that the task code will do the right thing when
executed directly.
The test course gets created without the listeners being present, which
allows us to ensure that when the listener is executed, it is done as
expected.
"""
def
mocked_set_credit_requirements
(
course_key
,
requirements
):
# pylint: disable=no-self-argument, unused-argument
"""
Used as a side effect when mocking `verify_student.ssencrypt.has_valid_signature`
.
"""
Used as a side effect when mocking method credit api method
'set_credit_requirements'
.
"""
raise
InvalidCreditRequirements
...
...
@@ -46,8 +49,7 @@ class TestTaskExecution(ModuleStoreTestCase):
def
test_task_adding_requirements_invalid_course
(
self
):
"""
Make sure that the receiver correctly fires off the task when
invoked by signal
Test that credit requirements cannot be added for non credit course.
"""
requirements
=
get_credit_requirements
(
self
.
course
.
id
)
self
.
assertEqual
(
len
(
requirements
),
0
)
...
...
@@ -57,9 +59,10 @@ class TestTaskExecution(ModuleStoreTestCase):
self
.
assertEqual
(
len
(
requirements
),
0
)
def
test_task_adding_requirements
(
self
):
"""
"""Test that credit requirements are added properly for credit course.
Make sure that the receiver correctly fires off the task when
invoked by signal
invoked by signal
.
"""
self
.
add_credit_course
(
self
.
course
.
id
)
requirements
=
get_credit_requirements
(
self
.
course
.
id
)
...
...
@@ -70,9 +73,8 @@ class TestTaskExecution(ModuleStoreTestCase):
self
.
assertEqual
(
len
(
requirements
),
1
)
def
test_task_adding_icrv_requirements
(
self
):
"""
Make sure that the receiver correctly fires off the task when
invoked by signal
"""Make sure that the receiver correctly fires off the task when
invoked by signal.
"""
self
.
add_credit_course
(
self
.
course
.
id
)
self
.
add_icrv_xblock
()
...
...
@@ -90,7 +92,9 @@ class TestTaskExecution(ModuleStoreTestCase):
)
)
def
test_retry
(
self
):
"""
"""Test that adding credit requirements is retried when
'InvalidCreditRequirements' exception is raised.
Make sure that the receiver correctly fires off the task when
invoked by signal
"""
...
...
@@ -103,10 +107,10 @@ class TestTaskExecution(ModuleStoreTestCase):
self
.
assertEqual
(
len
(
requirements
),
0
)
def
add_credit_course
(
self
,
course_key
):
"""
Add the course as a credit
"""
Add the course as a credit.
Args:
course_key(CourseKey):
i
dentifier for the course
course_key(CourseKey):
I
dentifier for the course
Returns:
CreditCourse object added
...
...
requirements/edx/github.txt
View file @
38b859fd
...
...
@@ -50,7 +50,7 @@ git+https://github.com/hmarr/django-debug-toolbar-mongo.git@b0686a76f1ce3532088c
git+https://github.com/edx/edx-lint.git@ed8c8d2a0267d4d42f43642d193e25f8bd575d9b#egg=edx_lint==0.2.3
-e git+https://github.com/edx/xblock-utils.git@db22bc40fd2a75458a3c66d057f88aff5a7383e6#egg=xblock-utils
-e git+https://github.com/edx-solutions/xblock-google-drive.git@138e6fa0bf3a2013e904a085b9fed77dab7f3f21#egg=xblock-google-drive
-e git+https://github.com/edx/edx-reverification-block.git@
03da85753d5f563a22c1282c0e89fcb2e828b8c1
#egg=edx-reverification-block
-e git+https://github.com/edx/edx-reverification-block.git@
6e2834c5f7e998ad9b81170e7ceb4d8a64900eb0
#egg=edx-reverification-block
git+https://github.com/edx/ecommerce-api-client.git@1.0.0#egg=ecommerce-api-client==1.0.0
# Third Party XBlocks
...
...
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