-
Notifications
You must be signed in to change notification settings - Fork 86
/
Copy pathtest_utils.py
207 lines (178 loc) · 6.6 KB
/
test_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
"""
File that contains tests for the util methods.
"""
import binascii
import unittest
from datetime import datetime, timedelta
from itertools import product
import ddt
import pytz
from freezegun import freeze_time
from edx_proctoring.statuses import ProctoredExamStudentAttemptStatus
from edx_proctoring.tests.test_services import MockScheduleData, MockScheduleItemData
from edx_proctoring.utils import (
_emit_event,
decode_and_decrypt,
encrypt_and_encode,
get_time_remaining_for_attempt,
get_visibility_check_date,
humanized_time,
is_reattempting_exam,
obscured_user_id
)
class TestGetTimeRemainingForAttempt(unittest.TestCase):
"""
Class to test get_time_remaining_for_attempt
"""
def setUp(self):
"""
Initialize
"""
super().setUp()
self.now_utc = datetime.now(pytz.UTC)
def test_not_started(self):
"""
Test to return 0 if the exam attempt has not been started.
"""
attempt = {
'started_at': None,
'allowed_time_limit_mins': 10,
'time_remaining_seconds': None
}
time_remaining_seconds = get_time_remaining_for_attempt(attempt)
self.assertEqual(time_remaining_seconds, 0)
def test_get_time_remaining_started(self):
"""
Test to get the time remaining on an attempt after the exam has started.
"""
with freeze_time(self.now_utc):
attempt = {
'started_at': self.now_utc,
'allowed_time_limit_mins': 10,
'time_remaining_seconds': None
}
time_remaining_seconds = get_time_remaining_for_attempt(attempt)
self.assertEqual(time_remaining_seconds, 600)
class TestHumanizedTime(unittest.TestCase):
"""
Class to test the humanized_time utility function
"""
def test_humanized_time(self):
"""
tests the humanized_time utility function against different values.
"""
human_time = humanized_time(0)
self.assertEqual(human_time, "0 minutes")
human_time = humanized_time(1)
self.assertEqual(human_time, "1 minute")
human_time = humanized_time(10)
self.assertEqual(human_time, "10 minutes")
human_time = humanized_time(60)
self.assertEqual(human_time, "1 hour")
human_time = humanized_time(61)
self.assertEqual(human_time, "1 hour and 1 minute")
human_time = humanized_time(62)
self.assertEqual(human_time, "1 hour and 2 minutes")
human_time = humanized_time(120)
self.assertEqual(human_time, "2 hours")
human_time = humanized_time(121)
self.assertEqual(human_time, "2 hours and 1 minute")
human_time = humanized_time(150)
self.assertEqual(human_time, "2 hours and 30 minutes")
human_time = humanized_time(180)
self.assertEqual(human_time, "3 hours")
human_time = humanized_time(-60)
self.assertEqual(human_time, "error")
@ddt.ddt
class TestUtils(unittest.TestCase):
"""
Class to test misc utilities
"""
def test_emit_event(self):
"""
Call through to emit event to the analytics pipeline.
NOTE: We're just testing one specific case where the context is None
We get full coverage on other cases, via the test_api.py file
"""
# call without a context
_emit_event(
'foo.bar',
None,
{
'one': 'two'
}
)
@ddt.data(
*product(
[
ProctoredExamStudentAttemptStatus.started,
ProctoredExamStudentAttemptStatus.ready_to_submit,
],
[
ProctoredExamStudentAttemptStatus.created,
ProctoredExamStudentAttemptStatus.download_software_clicked,
ProctoredExamStudentAttemptStatus.ready_to_start,
]
)
)
@ddt.unpack
def test_is_reattempting_exam_from_in_progress_state(self, from_status, to_status):
"""Tests that re-attempting exam returns true while transiting from given statuses"""
self.assertTrue(is_reattempting_exam(from_status, to_status))
@ddt.data(
ProctoredExamStudentAttemptStatus.created,
ProctoredExamStudentAttemptStatus.download_software_clicked,
ProctoredExamStudentAttemptStatus.ready_to_start,
ProctoredExamStudentAttemptStatus.submitted,
ProctoredExamStudentAttemptStatus.verified,
)
def test_is_reattempting_exam_from_other_status(self, from_status):
"""Tests that re-attempting exam returns false while transiting from given status"""
self.assertFalse(
is_reattempting_exam(from_status, 'foo')
)
def test_obscured_user_id(self):
user_id = 32432455
expected_obscured_user_id = '9b82efd5d28f1a170b23b8f648c3093e75a0a0ca'
self.assertEqual(expected_obscured_user_id, obscured_user_id(user_id))
@ddt.data(
(1, 3, 1),
(None, 4, 4),
(2, None, 2),
(-1, -3, -1),
(None, -2, -2),
(-3, None, -3)
)
@ddt.unpack
def test_get_visibility_check_date(self, mock_due_offset, mock_end_offset, expected_offset):
cur_time = pytz.utc.localize(datetime.now())
expected_datetime = cur_time + timedelta(days=expected_offset)
mock_due = None
if mock_due_offset:
mock_due = cur_time + timedelta(days=mock_due_offset)
mock_course_end = None
if mock_end_offset:
mock_course_end = cur_time + timedelta(days=mock_end_offset)
mock_usage_key = '32fjkle2jf3'
mock_sequences = {
mock_usage_key: MockScheduleItemData(cur_time, mock_due)
}
mock_schedule = MockScheduleData(mock_sequences, mock_course_end)
with freeze_time(cur_time):
due_date = get_visibility_check_date(mock_schedule, mock_usage_key)
self.assertEqual(due_date, expected_datetime)
@ddt.data(
b"Hello World!",
b"1234567890123456",
b"12345678901234561234567890123456123456789012345601",
b"\xe9\xe1a\x13\x1bT5\xc8",
b"",
'Hello World'
)
def test_encryption(self, data):
aes_key = binascii.unhexlify(b'32fe72aaf2abb44de9e161131b5435c8d37cbdb6f5df242ae860b283115f2dae')
decoded = decode_and_decrypt(encrypt_and_encode(data, aes_key), aes_key)
# in the case that we are testing a string, ensure that we convert the decoded data to a string
if isinstance(data, str):
decoded = decoded.decode("utf-8")
self.assertEqual(decoded, data)