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
da94aca5
Commit
da94aca5
authored
Apr 29, 2015
by
zubair-arbi
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add location_id field for the Reverification XBlock in VerificationStatus model
ECOM-1477
parent
5a1d180f
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
201 additions
and
27 deletions
+201
-27
lms/djangoapps/verify_student/migrations/0007_auto__add_field_verificationstatus_location_id.py
+123
-0
lms/djangoapps/verify_student/models.py
+29
-15
lms/djangoapps/verify_student/tests/test_models.py
+48
-11
lms/djangoapps/verify_student/views.py
+1
-1
No files found.
lms/djangoapps/verify_student/migrations/0007_auto__add_field_verificationstatus_location_id.py
0 → 100644
View file @
da94aca5
# -*- 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 'VerificationStatus.location_id'
db
.
add_column
(
'verify_student_verificationstatus'
,
'location_id'
,
self
.
gf
(
'django.db.models.fields.CharField'
)(
max_length
=
255
,
null
=
True
,
blank
=
True
),
keep_default
=
False
)
def
backwards
(
self
,
orm
):
# Deleting field 'VerificationStatus.location_id'
db
.
delete_column
(
'verify_student_verificationstatus'
,
'location_id'
)
models
=
{
'auth.group'
:
{
'Meta'
:
{
'object_name'
:
'Group'
},
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'80'
}),
'permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
})
},
'auth.permission'
:
{
'Meta'
:
{
'ordering'
:
"('content_type__app_label', 'content_type__model', 'codename')"
,
'unique_together'
:
"(('content_type', 'codename'),)"
,
'object_name'
:
'Permission'
},
'codename'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'content_type'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['contenttypes.ContentType']"
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
})
},
'auth.user'
:
{
'Meta'
:
{
'object_name'
:
'User'
},
'date_joined'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'email'
:
(
'django.db.models.fields.EmailField'
,
[],
{
'max_length'
:
'75'
,
'blank'
:
'True'
}),
'first_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'groups'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Group']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'is_active'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
}),
'is_staff'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'is_superuser'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'last_login'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'datetime.datetime.now'
}),
'last_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'30'
,
'blank'
:
'True'
}),
'password'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'128'
}),
'user_permissions'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['auth.Permission']"
,
'symmetrical'
:
'False'
,
'blank'
:
'True'
}),
'username'
:
(
'django.db.models.fields.CharField'
,
[],
{
'unique'
:
'True'
,
'max_length'
:
'30'
})
},
'contenttypes.contenttype'
:
{
'Meta'
:
{
'ordering'
:
"('name',)"
,
'unique_together'
:
"(('app_label', 'model'),)"
,
'object_name'
:
'ContentType'
,
'db_table'
:
"'django_content_type'"
},
'app_label'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'model'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'100'
})
},
'reverification.midcoursereverificationwindow'
:
{
'Meta'
:
{
'object_name'
:
'MidcourseReverificationWindow'
},
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'end_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'start_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'default'
:
'None'
,
'null'
:
'True'
,
'blank'
:
'True'
})
},
'verify_student.incoursereverificationconfiguration'
:
{
'Meta'
:
{
'object_name'
:
'InCourseReverificationConfiguration'
},
'change_date'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'changed_by'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
,
'null'
:
'True'
,
'on_delete'
:
'models.PROTECT'
}),
'enabled'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'False'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
})
},
'verify_student.skippedreverification'
:
{
'Meta'
:
{
'unique_together'
:
"(('user', 'course_id'),)"
,
'object_name'
:
'SkippedReverification'
},
'checkpoint'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'skipped_checkpoint'"
,
'to'
:
"orm['verify_student.VerificationCheckpoint']"
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
},
'verify_student.softwaresecurephotoverification'
:
{
'Meta'
:
{
'ordering'
:
"['-created_at']"
,
'object_name'
:
'SoftwareSecurePhotoVerification'
},
'created_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'db_index'
:
'True'
,
'blank'
:
'True'
}),
'display'
:
(
'django.db.models.fields.BooleanField'
,
[],
{
'default'
:
'True'
,
'db_index'
:
'True'
}),
'error_code'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'50'
,
'blank'
:
'True'
}),
'error_msg'
:
(
'django.db.models.fields.TextField'
,
[],
{
'blank'
:
'True'
}),
'face_image_url'
:
(
'django.db.models.fields.URLField'
,
[],
{
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'photo_id_image_url'
:
(
'django.db.models.fields.URLField'
,
[],
{
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'photo_id_key'
:
(
'django.db.models.fields.TextField'
,
[],
{
'max_length'
:
'1024'
}),
'receipt_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'default'
:
"'9997c000-3299-4097-a2cf-9ab35f9efdb5'"
,
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'reviewing_service'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'blank'
:
'True'
}),
'reviewing_user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'default'
:
'None'
,
'related_name'
:
"'photo_verifications_reviewed'"
,
'null'
:
'True'
,
'to'
:
"orm['auth.User']"
}),
'status'
:
(
'model_utils.fields.StatusField'
,
[],
{
'default'
:
"'created'"
,
'max_length'
:
'100'
,
u'no_check_for_status'
:
'True'
}),
'status_changed'
:
(
'model_utils.fields.MonitorField'
,
[],
{
'default'
:
'datetime.datetime.now'
,
u'monitor'
:
"u'status'"
}),
'submitted_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'null'
:
'True'
,
'db_index'
:
'True'
}),
'updated_at'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now'
:
'True'
,
'db_index'
:
'True'
,
'blank'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
}),
'window'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['reverification.MidcourseReverificationWindow']"
,
'null'
:
'True'
})
},
'verify_student.verificationcheckpoint'
:
{
'Meta'
:
{
'unique_together'
:
"(('course_id', 'checkpoint_name'),)"
,
'object_name'
:
'VerificationCheckpoint'
},
'checkpoint_name'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
}),
'course_id'
:
(
'xmodule_django.models.CourseKeyField'
,
[],
{
'max_length'
:
'255'
,
'db_index'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'photo_verification'
:
(
'django.db.models.fields.related.ManyToManyField'
,
[],
{
'to'
:
"orm['verify_student.SoftwareSecurePhotoVerification']"
,
'symmetrical'
:
'False'
})
},
'verify_student.verificationstatus'
:
{
'Meta'
:
{
'object_name'
:
'VerificationStatus'
},
'checkpoint'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'related_name'
:
"'checkpoint_status'"
,
'to'
:
"orm['verify_student.VerificationCheckpoint']"
}),
'error'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'id'
:
(
'django.db.models.fields.AutoField'
,
[],
{
'primary_key'
:
'True'
}),
'location_id'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'255'
,
'null'
:
'True'
,
'blank'
:
'True'
}),
'response'
:
(
'django.db.models.fields.TextField'
,
[],
{
'null'
:
'True'
,
'blank'
:
'True'
}),
'status'
:
(
'django.db.models.fields.CharField'
,
[],
{
'max_length'
:
'32'
,
'db_index'
:
'True'
}),
'timestamp'
:
(
'django.db.models.fields.DateTimeField'
,
[],
{
'auto_now_add'
:
'True'
,
'blank'
:
'True'
}),
'user'
:
(
'django.db.models.fields.related.ForeignKey'
,
[],
{
'to'
:
"orm['auth.User']"
})
}
}
complete_apps
=
[
'verify_student'
]
\ No newline at end of file
lms/djangoapps/verify_student/models.py
View file @
da94aca5
...
...
@@ -13,34 +13,32 @@ from email.utils import formatdate
import
functools
import
json
import
logging
import
uuid
from
boto.s3.connection
import
S3Connection
from
boto.s3.key
import
Key
from
django.core.exceptions
import
ObjectDoesNotExist
import
pytz
import
requests
import
uuid
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.core.exceptions
import
ObjectDoesNotExist
from
django.core.urlresolvers
import
reverse
from
django.db
import
models
from
django.contrib.auth.models
import
User
from
django.utils.translation
import
ugettext
as
_
from
django.utils.translation
import
ugettext
as
_
,
ugettext_lazy
from
boto.s3.connection
import
S3Connection
from
boto.s3.key
import
Key
from
config_models.models
import
ConfigurationModel
from
model_utils.models
import
StatusModel
from
model_utils
import
Choices
from
reverification.models
import
MidcourseReverificationWindow
from
verify_student.ssencrypt
import
(
random_aes_key
,
encrypt_and_encode
,
generate_signed_message
,
rsa_encrypt
)
from
xmodule_django.models
import
CourseKeyField
from
reverification.models
import
MidcourseReverificationWindow
from
xmodule_django.models
import
CourseKeyField
log
=
logging
.
getLogger
(
__name__
)
from
config_models.models
import
ConfigurationModel
def
generateUUID
():
# pylint: disable=invalid-name
""" Utility function; generates UUIDs """
...
...
@@ -1018,21 +1016,30 @@ class VerificationStatus(models.Model):
response
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
error
=
models
.
TextField
(
null
=
True
,
blank
=
True
)
# This field is used to save location of Reverification module in courseware
location_id
=
models
.
CharField
(
null
=
True
,
blank
=
True
,
max_length
=
255
,
help_text
=
ugettext_lazy
(
"Usage id of Reverification XBlock."
)
)
class
Meta
(
object
):
# pylint: disable=missing-docstring
get_latest_by
=
"timestamp"
@classmethod
def
add_verification_status
(
cls
,
checkpoint
,
user
,
status
):
def
add_verification_status
(
cls
,
checkpoint
,
user
,
status
,
location_id
=
''
):
""" Create new verification status object
Arguments:
checkpoint(VerificationCheckpoint): VerificationCheckpoint object
user(User): user object
status(str): String representing the status from VERIFICATION_STATUS_CHOICES
location_id(str): Usage key of Reverification XBlock
Returns:
None
"""
cls
.
objects
.
create
(
checkpoint
=
checkpoint
,
user
=
user
,
status
=
status
)
cls
.
objects
.
create
(
checkpoint
=
checkpoint
,
user
=
user
,
status
=
status
,
location_id
=
location_id
)
@classmethod
def
add_status_from_checkpoints
(
cls
,
checkpoints
,
user
,
status
):
...
...
@@ -1046,7 +1053,14 @@ class VerificationStatus(models.Model):
None
"""
for
checkpoint
in
checkpoints
:
cls
.
objects
.
create
(
checkpoint
=
checkpoint
,
user
=
user
,
status
=
status
)
# get 'location_id' from last entry (if it exists) and add it in
# new entry
try
:
location_id
=
cls
.
objects
.
filter
(
checkpoint
=
checkpoint
)
.
latest
()
.
location_id
except
cls
.
DoesNotExist
:
location_id
=
''
cls
.
objects
.
create
(
checkpoint
=
checkpoint
,
user
=
user
,
status
=
status
,
location_id
=
location_id
)
class
InCourseReverificationConfiguration
(
ConfigurationModel
):
...
...
lms/djangoapps/verify_student/tests/test_models.py
View file @
da94aca5
...
...
@@ -675,7 +675,7 @@ class VerificationCheckpointTest(ModuleStoreTestCase):
@ddt.ddt
class
VerificationStatusTest
(
ModuleStoreTestCase
):
"""Tests for the VerificationStatus model. """
"""
Tests for the VerificationStatus model. """
def
setUp
(
self
):
super
(
VerificationStatusTest
,
self
)
.
setUp
()
...
...
@@ -683,33 +683,70 @@ class VerificationStatusTest(ModuleStoreTestCase):
self
.
course
=
CourseFactory
.
create
()
self
.
check_point1
=
VerificationCheckpoint
.
objects
.
create
(
course_id
=
self
.
course
.
id
,
checkpoint_name
=
"midterm"
)
self
.
check_point2
=
VerificationCheckpoint
.
objects
.
create
(
course_id
=
self
.
course
.
id
,
checkpoint_name
=
"final"
)
self
.
dummy_reverification_item_id_1
=
'i4x://{}/{}/edx-reverification-block/related_assessment_1'
.
format
(
self
.
course
.
location
.
org
,
self
.
course
.
location
.
course
)
self
.
dummy_reverification_item_id_2
=
'i4x://{}/{}/edx-reverification-block/related_assessment_2'
.
format
(
self
.
course
.
location
.
org
,
self
.
course
.
location
.
course
)
@ddt.data
(
'submitted'
,
"approved"
,
"denied"
,
"error"
)
def
test_add_verification_status
(
self
,
status
):
"""
adding verfication status using the class method.
"""
"""
Adding verification status using the class method.
"""
# adding verification status
VerificationStatus
.
add_verification_status
(
checkpoint
=
self
.
check_point1
,
user
=
self
.
user
,
status
=
status
)
VerificationStatus
.
add_verification_status
(
checkpoint
=
self
.
check_point1
,
user
=
self
.
user
,
status
=
status
,
location_id
=
self
.
dummy_reverification_item_id_1
)
# getting the status from db
result
=
VerificationStatus
.
objects
.
filter
(
checkpoint
=
self
.
check_point1
)[
0
]
self
.
assertEqual
(
result
.
status
,
status
)
self
.
assertEqual
(
result
.
user
,
self
.
user
)
@ddt.data
(
'submitted'
,
"approved"
,
"denied"
,
"error"
)
@ddt.data
(
"approved"
,
"denied"
,
"error"
)
def
test_add_status_from_checkpoints
(
self
,
status
):
"""adding verfication status for checkpoints list."""
""" Adding verification status for checkpoints list after submitting sspv. """
# add initial verification status for checkpoints
initial_status
=
"submitted"
VerificationStatus
.
add_verification_status
(
checkpoint
=
self
.
check_point1
,
user
=
self
.
user
,
status
=
initial_status
,
location_id
=
self
.
dummy_reverification_item_id_1
)
VerificationStatus
.
add_verification_status
(
checkpoint
=
self
.
check_point2
,
user
=
self
.
user
,
status
=
initial_status
,
location_id
=
self
.
dummy_reverification_item_id_2
)
#
adding verification status with multiple
points
#
now add verification status for multiple checkpoint
points
VerificationStatus
.
add_status_from_checkpoints
(
checkpoints
=
[
self
.
check_point1
,
self
.
check_point2
],
user
=
self
.
user
,
status
=
status
)
# getting the status from db.
result
=
VerificationStatus
.
objects
.
filter
(
user
=
self
.
user
)
self
.
assertEqual
(
len
(
result
),
len
([
self
.
check_point1
.
checkpoint_name
,
self
.
check_point2
.
checkpoint_name
]))
self
.
assertEqual
(
result
[
0
]
.
checkpoint
.
checkpoint_name
,
self
.
check_point1
.
checkpoint_name
)
self
.
assertEqual
(
result
[
1
]
.
checkpoint
.
checkpoint_name
,
self
.
check_point2
.
checkpoint_name
)
# test that verification status entries with new status have been added
# for both checkpoints and all entries have related 'location_id'.
result
=
VerificationStatus
.
objects
.
filter
(
user
=
self
.
user
,
checkpoint
=
self
.
check_point1
)
self
.
assertEqual
(
len
(
result
),
len
(
self
.
check_point1
.
checkpoint_status
.
all
()))
self
.
assertEqual
(
list
(
result
.
values_list
(
'location_id'
,
flat
=
True
)),
list
(
self
.
check_point1
.
checkpoint_status
.
all
()
.
values_list
(
'location_id'
,
flat
=
True
))
)
result
=
VerificationStatus
.
objects
.
filter
(
user
=
self
.
user
,
checkpoint
=
self
.
check_point2
)
self
.
assertEqual
(
len
(
result
),
len
(
self
.
check_point2
.
checkpoint_status
.
all
()))
self
.
assertEqual
(
list
(
result
.
values_list
(
'location_id'
,
flat
=
True
)),
list
(
self
.
check_point2
.
checkpoint_status
.
all
()
.
values_list
(
'location_id'
,
flat
=
True
))
)
class
SkippedReverificationTest
(
ModuleStoreTestCase
):
...
...
lms/djangoapps/verify_student/views.py
View file @
da94aca5
...
...
@@ -1244,7 +1244,7 @@ class InCourseReverifyView(View):
request
.
user
,
request
.
POST
[
'face_image'
],
init_verification
.
photo_id_key
)
checkpoint
.
add_verification_attempt
(
attempt
)
VerificationStatus
.
add_verification_status
(
checkpoint
,
user
,
"submitted"
)
VerificationStatus
.
add_verification_status
(
checkpoint
,
user
,
"submitted"
,
usage_id
)
# emit the reverification event
self
.
_track_reverification_events
(
...
...
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