edx-enterprise-data 9.0.0__py3-none-any.whl → 9.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. {edx_enterprise_data-9.0.0.dist-info → edx_enterprise_data-9.1.0.dist-info}/METADATA +4 -3
  2. {edx_enterprise_data-9.0.0.dist-info → edx_enterprise_data-9.1.0.dist-info}/RECORD +22 -23
  3. {edx_enterprise_data-9.0.0.dist-info → edx_enterprise_data-9.1.0.dist-info}/WHEEL +1 -1
  4. enterprise_data/__init__.py +1 -1
  5. enterprise_data/admin_analytics/constants.py +0 -16
  6. enterprise_data/admin_analytics/database/queries/fact_engagement_admin_dash.py +90 -0
  7. enterprise_data/admin_analytics/database/queries/fact_enrollment_admin_dash.py +83 -4
  8. enterprise_data/admin_analytics/database/tables/fact_engagement_admin_dash.py +116 -0
  9. enterprise_data/admin_analytics/database/tables/fact_enrollment_admin_dash.py +97 -3
  10. enterprise_data/api/v1/serializers.py +1 -55
  11. enterprise_data/api/v1/urls.py +14 -17
  12. enterprise_data/api/v1/views/analytics_completions.py +150 -0
  13. enterprise_data/api/v1/views/analytics_engagements.py +106 -351
  14. enterprise_data/api/v1/views/analytics_enrollments.py +3 -6
  15. enterprise_data/renderers.py +22 -7
  16. enterprise_data/tests/admin_analytics/mock_analytics_data.py +12 -90
  17. enterprise_data/tests/admin_analytics/mock_enrollments.py +0 -66
  18. enterprise_data/tests/admin_analytics/test_analytics_engagements.py +120 -240
  19. enterprise_data/tests/admin_analytics/test_analytics_enrollments.py +12 -81
  20. enterprise_data/tests/admin_analytics/test_enterprise_completions.py +105 -120
  21. enterprise_data/admin_analytics/completions_utils.py +0 -261
  22. enterprise_data/api/v1/views/enterprise_completions.py +0 -200
  23. {edx_enterprise_data-9.0.0.dist-info → edx_enterprise_data-9.1.0.dist-info}/LICENSE +0 -0
  24. {edx_enterprise_data-9.0.0.dist-info → edx_enterprise_data-9.1.0.dist-info}/top_level.txt +0 -0
@@ -8,28 +8,13 @@ from rest_framework import status
8
8
  from rest_framework.reverse import reverse
9
9
  from rest_framework.test import APITransactionTestCase
10
10
 
11
- from enterprise_data.admin_analytics.constants import EngagementChart, ResponseType
12
- from enterprise_data.api.v1.serializers import AdvanceAnalyticsEngagementStatsSerializer as EngagementSerializer
13
- from enterprise_data.tests.admin_analytics.mock_analytics_data import (
14
- ENGAGEMENT_STATS_CSVS,
15
- ENGAGEMENTS,
16
- engagements_csv_content,
17
- engagements_dataframe,
18
- enrollments_dataframe,
19
- )
11
+ from enterprise_data.admin_analytics.constants import ResponseType
12
+ from enterprise_data.tests.admin_analytics.mock_analytics_data import ENGAGEMENTS
20
13
  from enterprise_data.tests.mixins import JWTTestMixin
21
14
  from enterprise_data.tests.test_utils import UserFactory
22
15
  from enterprise_data_roles.constants import ENTERPRISE_DATA_ADMIN_ROLE
23
16
  from enterprise_data_roles.models import EnterpriseDataFeatureRole, EnterpriseDataRoleAssignment
24
17
 
25
- INVALID_CALCULATION_ERROR = (
26
- f"Calculation must be one of {EngagementSerializer.CALCULATION_CHOICES}"
27
- )
28
- INVALID_GRANULARITY_ERROR = (
29
- f"Granularity must be one of {EngagementSerializer.GRANULARITY_CHOICES}"
30
- )
31
- INVALID_CSV_ERROR1 = f"chart_type must be one of {EngagementSerializer.CHART_TYPES}"
32
-
33
18
 
34
19
  @ddt.ddt
35
20
  class TestIndividualEngagementsAPI(JWTTestMixin, APITransactionTestCase):
@@ -49,161 +34,136 @@ class TestIndividualEngagementsAPI(JWTTestMixin, APITransactionTestCase):
49
34
  )
50
35
  self.client.force_authenticate(user=self.user)
51
36
 
52
- self.enterprise_uuid = "ee5e6b3a-069a-4947-bb8d-d2dbc323396c"
37
+ self.enterprise_uuid = 'ee5e6b3a-069a-4947-bb8d-d2dbc323396c'
53
38
  self.set_jwt_cookie()
54
39
 
55
40
  self.url = reverse(
56
- "v1:enterprise-admin-analytics-engagements",
41
+ 'v1:enterprise-admin-analytics-engagements',
57
42
  kwargs={"enterprise_uuid": self.enterprise_uuid},
58
43
  )
59
44
 
60
- fetch_max_enrollment_datetime_patcher = patch(
61
- 'enterprise_data.admin_analytics.utils.fetch_max_enrollment_datetime',
62
- return_value=datetime.now()
45
+ get_enrollment_date_range_patcher = patch(
46
+ 'enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_enrollment_date_range',
47
+ return_value=(datetime.now(), datetime.now())
63
48
  )
64
49
 
65
- fetch_max_enrollment_datetime_patcher.start()
66
- self.addCleanup(fetch_max_enrollment_datetime_patcher.stop)
67
-
68
- def verify_engagement_data(self, results, results_count):
69
- """Verify the received engagement data."""
70
- attrs = [
71
- "email",
72
- "course_title",
73
- "activity_date",
74
- "course_subject",
75
- ]
76
-
77
- assert len(results) == results_count
78
-
79
- filtered_data = []
80
- for engagement in ENGAGEMENTS:
81
- for result in results:
82
- if engagement["email"] == result["email"]:
83
- data = {attr: engagement[attr] for attr in attrs}
84
- data["learning_time_hours"] = round(engagement["learning_time_seconds"] / 3600, 1)
85
- filtered_data.append(data)
86
- break
87
-
88
- received_data = sorted(results, key=lambda x: x["email"])
89
- expected_data = sorted(filtered_data, key=lambda x: x["email"])
90
- assert received_data == expected_data
50
+ get_enrollment_date_range_patcher.start()
51
+ self.addCleanup(get_enrollment_date_range_patcher.stop)
91
52
 
92
- @patch(
93
- "enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_enrollments_data"
94
- )
95
- @patch(
96
- "enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_engagements_data"
97
- )
98
- def test_get(self, mock_fetch_and_cache_engagements_data, mock_fetch_and_cache_enrollments_data):
53
+ @patch('enterprise_data.api.v1.views.analytics_engagements.FactEngagementAdminDashTable.get_engagement_count')
54
+ @patch('enterprise_data.api.v1.views.analytics_engagements.FactEngagementAdminDashTable.get_all_engagements')
55
+ def test_get(self, mock_get_all_engagements, mock_get_engagement_count):
99
56
  """
100
57
  Test the GET method for the AdvanceAnalyticsIndividualEngagementsView works.
101
58
  """
102
- mock_fetch_and_cache_enrollments_data.return_value = enrollments_dataframe()
103
- mock_fetch_and_cache_engagements_data.return_value = engagements_dataframe()
59
+ mock_get_all_engagements.return_value = ENGAGEMENTS
60
+ mock_get_engagement_count.return_value = len(ENGAGEMENTS)
104
61
 
105
- response = self.client.get(self.url, {"page_size": 2})
62
+ response = self.client.get(self.url + '?page_size=2')
106
63
  assert response.status_code == status.HTTP_200_OK
107
64
  data = response.json()
108
- assert data["next"] == f"http://testserver{self.url}?page=2&page_size=2"
109
- assert data["previous"] is None
110
- assert data["current_page"] == 1
111
- assert data["num_pages"] == 5
112
- assert data["count"] == 9
113
- self.verify_engagement_data(data["results"], 2)
114
-
115
- response = self.client.get(self.url, {"page_size": 2, "page": 2})
65
+ assert data['next'] == f"http://testserver{self.url}?page=2&page_size=2"
66
+ assert data['previous'] is None
67
+ assert data['current_page'] == 1
68
+ assert data['num_pages'] == 6
69
+ assert data['count'] == 12
70
+
71
+ response = self.client.get(self.url + '?page_size=2&page=2')
116
72
  assert response.status_code == status.HTTP_200_OK
117
73
  data = response.json()
118
- assert data["next"] == f"http://testserver{self.url}?page=3&page_size=2"
119
- assert data["previous"] == f"http://testserver{self.url}?page_size=2"
120
- assert data["current_page"] == 2
121
- assert data["num_pages"] == 5
122
- assert data["count"] == 9
123
- self.verify_engagement_data(data["results"], 2)
124
-
125
- response = self.client.get(self.url, {"page_size": 2, "page": 5})
74
+ assert data['next'] == f"http://testserver{self.url}?page=3&page_size=2"
75
+ assert data['previous'] == f"http://testserver{self.url}?page_size=2"
76
+ assert data['current_page'] == 2
77
+ assert data['num_pages'] == 6
78
+ assert data['count'] == 12
79
+
80
+ response = self.client.get(self.url + '?page_size=2&page=6')
126
81
  assert response.status_code == status.HTTP_200_OK
127
82
  data = response.json()
128
- assert data["next"] is None
129
- assert data["previous"] == f"http://testserver{self.url}?page=4&page_size=2"
130
- assert data["current_page"] == 5
131
- assert data["num_pages"] == 5
132
- assert data["count"] == 9
133
- self.verify_engagement_data(data["results"], 1)
134
-
135
- response = self.client.get(self.url, {"page_size": 9})
83
+ assert data['next'] is None
84
+ assert data['previous'] == f"http://testserver{self.url}?page=5&page_size=2"
85
+ assert data['current_page'] == 6
86
+ assert data['num_pages'] == 6
87
+ assert data['count'] == 12
88
+
89
+ response = self.client.get(self.url + '?page_size=12')
136
90
  assert response.status_code == status.HTTP_200_OK
137
91
  data = response.json()
138
- assert data["next"] is None
139
- assert data["previous"] is None
140
- assert data["current_page"] == 1
141
- assert data["num_pages"] == 1
142
- assert data["count"] == 9
143
- self.verify_engagement_data(data["results"], 9)
144
-
145
- @patch(
146
- "enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_enrollments_data"
147
- )
148
- @patch(
149
- "enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_engagements_data"
150
- )
151
- def test_get_csv(self, mock_fetch_and_cache_engagements_data, mock_fetch_and_cache_enrollments_data):
92
+ assert data['next'] is None
93
+ assert data['previous'] is None
94
+ assert data['current_page'] == 1
95
+ assert data['num_pages'] == 1
96
+ assert data['count'] == 12
97
+
98
+ @patch('enterprise_data.api.v1.views.analytics_engagements.FactEngagementAdminDashTable.get_engagement_count')
99
+ @patch('enterprise_data.api.v1.views.analytics_engagements.FactEngagementAdminDashTable.get_all_engagements')
100
+ def test_get_csv(self, mock_get_all_engagements, mock_get_engagement_count):
152
101
  """
153
102
  Test the GET method for the AdvanceAnalyticsIndividualEngagementsView return correct CSV data.
154
103
  """
155
- mock_fetch_and_cache_enrollments_data.return_value = enrollments_dataframe()
156
- mock_fetch_and_cache_engagements_data.return_value = engagements_dataframe()
157
- start_date = enrollments_dataframe().enterprise_enrollment_date.min().strftime('%Y/%m/%d')
158
- end_date = datetime.now().strftime('%Y/%m/%d')
104
+ mock_get_all_engagements.return_value = ENGAGEMENTS[0:4]
105
+ mock_get_engagement_count.return_value = 4
106
+
159
107
  response = self.client.get(self.url, {"response_type": ResponseType.CSV.value})
160
108
  assert response.status_code == status.HTTP_200_OK
161
109
 
162
110
  # verify the response headers
163
111
  assert response["Content-Type"] == "text/csv"
164
- filename = f"""Individual Engagements, {start_date} - {end_date}.csv"""
165
- assert (
166
- response["Content-Disposition"] == f'attachment; filename="{filename}"'
167
- )
168
112
 
169
113
  # verify the response content
170
- content = b"".join(response.streaming_content)
171
- assert content == engagements_csv_content()
114
+ content = b"".join(response.streaming_content).decode().splitlines()
115
+ assert len(content) == 5
116
+
117
+ # Verify CSV header.
118
+ assert 'email,course_title,course_subject,enroll_type,activity_date,learning_time_hours' == content[0]
119
+
120
+ # verify the content
121
+ assert (
122
+ 'padillamichelle@example.org,Synergized reciprocal encoding,business-management,certificate,2021-08-05,'
123
+ '1.0344444444444445'
124
+ in content
125
+ )
126
+ assert (
127
+ 'yallison@example.org,Synergized reciprocal encoding,business-management,certificate,2021-07-27,'
128
+ '1.2041666666666666'
129
+ in content
130
+ )
131
+ assert (
132
+ 'weaverpatricia@example.net,Synergized reciprocal encoding,business-management,certificate,2021-08-05,'
133
+ '2.6225'
134
+ in content
135
+ )
136
+ assert (
137
+ 'seth57@example.org,Synergized reciprocal encoding,business-management,certificate,2021-08-21,'
138
+ '2.7494444444444444'
139
+ in content
140
+ )
172
141
 
173
142
  @ddt.data(
174
143
  {
175
- "params": {"start_date": 1},
176
- "error": {
177
- "start_date": [
178
- "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
144
+ 'params': {'start_date': 1},
145
+ 'error': {
146
+ 'start_date': [
147
+ 'Date has wrong format. Use one of these formats instead: YYYY-MM-DD.'
179
148
  ]
180
149
  },
181
150
  },
182
151
  {
183
- "params": {"end_date": 2},
184
- "error": {
185
- "end_date": [
186
- "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
152
+ 'params': {'end_date': 2},
153
+ 'error': {
154
+ 'end_date': [
155
+ 'Date has wrong format. Use one of these formats instead: YYYY-MM-DD.'
187
156
  ]
188
157
  },
189
158
  },
190
159
  {
191
- "params": {"start_date": "2024-01-01", "end_date": "2023-01-01"},
192
- "error": {
193
- "non_field_errors": [
194
- "start_date should be less than or equal to end_date."
160
+ 'params': {"start_date": "2024-01-01", "end_date": "2023-01-01"},
161
+ 'error': {
162
+ 'non_field_errors': [
163
+ 'start_date should be less than or equal to end_date.'
195
164
  ]
196
165
  },
197
166
  },
198
- {
199
- "params": {"calculation": "invalid"},
200
- "error": {"calculation": [INVALID_CALCULATION_ERROR]},
201
- },
202
- {
203
- "params": {"granularity": "invalid"},
204
- "error": {"granularity": [INVALID_GRANULARITY_ERROR]},
205
- },
206
- {"params": {"chart_type": "invalid"}, "error": {"chart_type": [INVALID_CSV_ERROR1]}},
207
167
  )
208
168
  @ddt.unpack
209
169
  def test_get_invalid_query_params(self, params, error):
@@ -233,152 +193,72 @@ class TestEngagementStatsAPI(JWTTestMixin, APITransactionTestCase):
233
193
  )
234
194
  self.client.force_authenticate(user=self.user)
235
195
 
236
- self.enterprise_uuid = "ee5e6b3a-069a-4947-bb8d-d2dbc323396c"
196
+ self.enterprise_uuid = 'ee5e6b3a-069a-4947-bb8d-d2dbc323396c'
237
197
  self.set_jwt_cookie()
238
198
 
239
199
  self.url = reverse(
240
- "v1:enterprise-admin-analytics-engagements-stats",
241
- kwargs={"enterprise_uuid": self.enterprise_uuid},
200
+ 'v1:enterprise-admin-analytics-engagements-stats',
201
+ kwargs={'enterprise_uuid': self.enterprise_uuid},
242
202
  )
243
203
 
244
- fetch_max_enrollment_datetime_patcher = patch(
245
- 'enterprise_data.admin_analytics.utils.fetch_max_enrollment_datetime',
246
- return_value=datetime.now()
204
+ get_enrollment_date_range_patcher = patch(
205
+ 'enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_enrollment_date_range',
206
+ return_value=(datetime.now(), datetime.now())
247
207
  )
248
208
 
249
- fetch_max_enrollment_datetime_patcher.start()
250
- self.addCleanup(fetch_max_enrollment_datetime_patcher.stop)
251
-
252
- def verify_engagement_data(self, results):
253
- """Verify the received engagement data."""
254
- attrs = [
255
- "email",
256
- "course_title",
257
- "activity_date",
258
- "course_subject",
259
- ]
260
-
261
- filtered_data = []
262
- for engagement in ENGAGEMENTS:
263
- for result in results:
264
- if engagement["email"] == result["email"]:
265
- data = {attr: engagement[attr] for attr in attrs}
266
- data["learning_time_hours"] = round(engagement["learning_time_seconds"] / 3600, 1)
267
- filtered_data.append(data)
268
- break
269
-
270
- received_data = sorted(results, key=lambda x: x["email"])
271
- expected_data = sorted(filtered_data, key=lambda x: x["email"])
272
- assert received_data == expected_data
209
+ get_enrollment_date_range_patcher.start()
210
+ self.addCleanup(get_enrollment_date_range_patcher.stop)
273
211
 
274
212
  @patch(
275
- "enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_enrollments_data"
213
+ 'enterprise_data.api.v1.views.analytics_engagements.FactEngagementAdminDashTable.'
214
+ 'get_engagement_time_series_data'
215
+ )
216
+ @patch(
217
+ 'enterprise_data.api.v1.views.analytics_engagements.FactEngagementAdminDashTable.get_top_courses_by_engagement'
276
218
  )
277
219
  @patch(
278
- "enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_engagements_data"
220
+ 'enterprise_data.api.v1.views.analytics_engagements.FactEngagementAdminDashTable.get_top_subjects_by_engagement'
279
221
  )
280
- def test_get(self, mock_fetch_and_cache_engagements_data, mock_fetch_and_cache_enrollments_data):
222
+ def test_get(self, mock_get_top_subjects_by_engagement, mock_get_top_courses_by_engagement, mock_get_time_series):
281
223
  """
282
224
  Test the GET method for the AdvanceAnalyticsEnrollmentStatsView works.
283
225
  """
284
- mock_fetch_and_cache_enrollments_data.return_value = enrollments_dataframe()
285
- mock_fetch_and_cache_engagements_data.return_value = engagements_dataframe()
226
+ mock_get_top_subjects_by_engagement.return_value = []
227
+ mock_get_top_courses_by_engagement.return_value = []
228
+ mock_get_time_series.return_value = []
286
229
 
287
230
  response = self.client.get(self.url)
288
231
  assert response.status_code == status.HTTP_200_OK
289
232
  data = response.json()
290
- assert data == {
291
- 'engagements_over_time': [
292
- {'activity_date': '2021-07-19T00:00:00', 'enroll_type': 'certificate', 'sum': 0.0},
293
- {'activity_date': '2021-07-26T00:00:00', 'enroll_type': 'certificate', 'sum': 4.4},
294
- {'activity_date': '2021-07-27T00:00:00', 'enroll_type': 'certificate', 'sum': 1.2},
295
- {'activity_date': '2021-08-05T00:00:00', 'enroll_type': 'certificate', 'sum': 3.6},
296
- {'activity_date': '2021-08-21T00:00:00', 'enroll_type': 'certificate', 'sum': 2.7},
297
- {'activity_date': '2021-09-02T00:00:00', 'enroll_type': 'certificate', 'sum': 1.3},
298
- {'activity_date': '2021-09-21T00:00:00', 'enroll_type': 'certificate', 'sum': 1.5},
299
- {'activity_date': '2022-05-17T00:00:00', 'enroll_type': 'certificate', 'sum': 0.0}
300
- ],
301
- 'top_courses_by_engagement': [
302
- {
303
- 'course_key': 'Kcpr+XoR30',
304
- 'course_title': 'Assimilated even-keeled focus group',
305
- 'enroll_type': 'certificate',
306
- 'count': 0.0
307
- },
308
- {
309
- 'course_key': 'luGg+KNt30',
310
- 'course_title': 'Synergized reciprocal encoding',
311
- 'enroll_type': 'certificate',
312
- 'count': 14.786944444444444
313
- }
314
- ],
315
- 'top_subjects_by_engagement': [
316
- {
317
- 'course_subject': 'business-management',
318
- 'enroll_type': 'certificate',
319
- 'count': 14.786944444444444
320
- },
321
- {
322
- 'course_subject': 'engineering',
323
- 'enroll_type': 'certificate',
324
- 'count': 0.0
325
- }
326
- ]
327
- }
328
-
329
- @patch("enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_enrollments_data")
330
- @patch("enterprise_data.api.v1.views.analytics_engagements.fetch_and_cache_engagements_data")
331
- @ddt.data(
332
- EngagementChart.ENGAGEMENTS_OVER_TIME.value,
333
- EngagementChart.TOP_COURSES_BY_ENGAGEMENTS.value,
334
- EngagementChart.TOP_SUBJECTS_BY_ENGAGEMENTS.value,
335
- )
336
- def test_get_csv(self, chart_type, mock_fetch_and_cache_engagements_data, mock_fetch_and_cache_enrollments_data):
337
- """
338
- Test that AdvanceAnalyticsEngagementStatsView return correct CSV data.
339
- """
340
- mock_fetch_and_cache_enrollments_data.return_value = enrollments_dataframe()
341
- mock_fetch_and_cache_engagements_data.return_value = engagements_dataframe()
342
- response = self.client.get(self.url, {"response_type": ResponseType.CSV.value, "chart_type": chart_type})
343
- assert response.status_code == status.HTTP_200_OK
344
- assert response["Content-Type"] == "text/csv"
345
- # verify the response content
346
- assert response.content == ENGAGEMENT_STATS_CSVS[chart_type]
233
+ assert 'engagement_over_time' in data
234
+ assert 'top_courses_by_engagement' in data
235
+ assert 'top_subjects_by_engagement' in data
347
236
 
348
237
  @ddt.data(
349
238
  {
350
- "params": {"start_date": 1},
351
- "error": {
352
- "start_date": [
353
- "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
239
+ 'params': {'start_date': 1},
240
+ 'error': {
241
+ 'start_date': [
242
+ 'Date has wrong format. Use one of these formats instead: YYYY-MM-DD.'
354
243
  ]
355
244
  },
356
245
  },
357
246
  {
358
- "params": {"end_date": 2},
359
- "error": {
360
- "end_date": [
361
- "Date has wrong format. Use one of these formats instead: YYYY-MM-DD."
247
+ 'params': {'end_date': 2},
248
+ 'error': {
249
+ 'end_date': [
250
+ 'Date has wrong format. Use one of these formats instead: YYYY-MM-DD.'
362
251
  ]
363
252
  },
364
253
  },
365
254
  {
366
- "params": {"start_date": "2024-01-01", "end_date": "2023-01-01"},
367
- "error": {
368
- "non_field_errors": [
369
- "start_date should be less than or equal to end_date."
255
+ 'params': {'start_date': '2024-01-01', 'end_date': '2023-01-01'},
256
+ 'error': {
257
+ 'non_field_errors': [
258
+ 'start_date should be less than or equal to end_date.'
370
259
  ]
371
260
  },
372
261
  },
373
- {
374
- "params": {"calculation": "invalid"},
375
- "error": {"calculation": [INVALID_CALCULATION_ERROR]},
376
- },
377
- {
378
- "params": {"granularity": "invalid"},
379
- "error": {"granularity": [INVALID_GRANULARITY_ERROR]},
380
- },
381
- {"params": {"chart_type": "invalid"}, "error": {"chart_type": [INVALID_CSV_ERROR1]}},
382
262
  )
383
263
  @ddt.unpack
384
264
  def test_get_invalid_query_params(self, params, error):
@@ -8,27 +8,18 @@ from rest_framework.reverse import reverse
8
8
  from rest_framework.test import APITransactionTestCase
9
9
 
10
10
  from enterprise_data.admin_analytics.constants import ResponseType
11
- from enterprise_data.api.v1.serializers import AdvanceAnalyticsEnrollmentStatsSerializer as EnrollmentStatsSerializer
12
- from enterprise_data.api.v1.serializers import AdvanceAnalyticsQueryParamSerializer
13
11
  from enterprise_data.tests.admin_analytics.mock_analytics_data import ENROLLMENTS
14
12
  from enterprise_data.tests.mixins import JWTTestMixin
15
13
  from enterprise_data.tests.test_utils import UserFactory
16
14
  from enterprise_data_roles.constants import ENTERPRISE_DATA_ADMIN_ROLE
17
15
  from enterprise_data_roles.models import EnterpriseDataFeatureRole, EnterpriseDataRoleAssignment
18
16
 
19
- INVALID_CALCULATION_ERROR = (
20
- f"Calculation must be one of {AdvanceAnalyticsQueryParamSerializer.CALCULATION_CHOICES}"
21
- )
22
- INVALID_GRANULARITY_ERROR = (
23
- f"Granularity must be one of {AdvanceAnalyticsQueryParamSerializer.GRANULARITY_CHOICES}"
24
- )
25
- INVALID_RESPONSE_TYPE_ERROR = f"response_type must be one of {AdvanceAnalyticsQueryParamSerializer.RESPONSE_TYPES}"
26
- INVALID_CHART_TYPE_ERROR = f"chart_type must be one of {EnrollmentStatsSerializer.CHART_TYPES}"
27
-
28
17
 
29
18
  @ddt.ddt
30
19
  class TestIndividualEnrollmentsAPI(JWTTestMixin, APITransactionTestCase):
31
- """Tests for AdvanceAnalyticsIndividualEnrollmentsView."""
20
+ """
21
+ Tests for AdvanceAnalyticsIndividualEnrollmentsView.
22
+ """
32
23
 
33
24
  def setUp(self):
34
25
  """
@@ -52,36 +43,13 @@ class TestIndividualEnrollmentsAPI(JWTTestMixin, APITransactionTestCase):
52
43
  kwargs={"enterprise_uuid": self.enterprise_uuid},
53
44
  )
54
45
 
55
- fetch_max_enrollment_datetime_patcher = patch(
46
+ get_enrollment_date_range_patcher = patch(
56
47
  'enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_enrollment_date_range',
57
48
  return_value=(datetime.now(), datetime.now())
58
49
  )
59
50
 
60
- fetch_max_enrollment_datetime_patcher.start()
61
- self.addCleanup(fetch_max_enrollment_datetime_patcher.stop)
62
-
63
- def verify_enrollment_data(self, results, results_count):
64
- """Verify the received enrollment data."""
65
- attrs = [
66
- 'email',
67
- 'course_title',
68
- 'course_subject',
69
- 'enroll_type',
70
- 'enterprise_enrollment_date',
71
- ]
72
-
73
- assert len(results) == results_count
74
-
75
- filtered_data = []
76
- for enrollment in ENROLLMENTS:
77
- for result in results:
78
- if enrollment["email"] == result["email"]:
79
- filtered_data.append({attr: enrollment[attr] for attr in attrs})
80
- break
81
-
82
- received_data = sorted(results, key=lambda x: x["email"])
83
- expected_data = sorted(filtered_data, key=lambda x: x["email"])
84
- assert received_data == expected_data
51
+ get_enrollment_date_range_patcher.start()
52
+ self.addCleanup(get_enrollment_date_range_patcher.stop)
85
53
 
86
54
  @patch('enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_enrollment_count')
87
55
  @patch('enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_all_enrollments')
@@ -200,15 +168,6 @@ class TestIndividualEnrollmentsAPI(JWTTestMixin, APITransactionTestCase):
200
168
  ]
201
169
  },
202
170
  },
203
- {
204
- "params": {"calculation": "invalid"},
205
- "error": {"calculation": [INVALID_CALCULATION_ERROR]},
206
- },
207
- {
208
- "params": {"granularity": "invalid"},
209
- "error": {"granularity": [INVALID_GRANULARITY_ERROR]},
210
- },
211
- {"params": {"response_type": "invalid"}, "error": {"response_type": [INVALID_RESPONSE_TYPE_ERROR]}},
212
171
  )
213
172
  @ddt.unpack
214
173
  def test_get_invalid_query_params(self, params, error):
@@ -222,7 +181,9 @@ class TestIndividualEnrollmentsAPI(JWTTestMixin, APITransactionTestCase):
222
181
 
223
182
  @ddt.ddt
224
183
  class TestEnrollmentStatsAPI(JWTTestMixin, APITransactionTestCase):
225
- """Tests for AdvanceAnalyticsEnrollmentStatsView."""
184
+ """
185
+ Tests for AdvanceAnalyticsEnrollmentStatsView.
186
+ """
226
187
 
227
188
  def setUp(self):
228
189
  """
@@ -246,34 +207,13 @@ class TestEnrollmentStatsAPI(JWTTestMixin, APITransactionTestCase):
246
207
  kwargs={"enterprise_uuid": self.enterprise_uuid},
247
208
  )
248
209
 
249
- fetch_max_enrollment_datetime_patcher = patch(
210
+ get_enrollment_date_range_patcher = patch(
250
211
  'enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.get_enrollment_date_range',
251
212
  return_value=(datetime.now(), datetime.now())
252
213
  )
253
214
 
254
- fetch_max_enrollment_datetime_patcher.start()
255
- self.addCleanup(fetch_max_enrollment_datetime_patcher.stop)
256
-
257
- def verify_enrollment_data(self, results):
258
- """Verify the received enrollment data."""
259
- attrs = [
260
- "email",
261
- "course_title",
262
- "course_subject",
263
- "enroll_type",
264
- "enterprise_enrollment_date",
265
- ]
266
-
267
- filtered_data = []
268
- for enrollment in ENROLLMENTS:
269
- for result in results:
270
- if enrollment["email"] == result["email"]:
271
- filtered_data.append({attr: enrollment[attr] for attr in attrs})
272
- break
273
-
274
- received_data = sorted(results, key=lambda x: x["email"])
275
- expected_data = sorted(filtered_data, key=lambda x: x["email"])
276
- assert received_data == expected_data
215
+ get_enrollment_date_range_patcher.start()
216
+ self.addCleanup(get_enrollment_date_range_patcher.stop)
277
217
 
278
218
  @patch(
279
219
  'enterprise_data.api.v1.views.analytics_enrollments.FactEnrollmentAdminDashTable.'
@@ -331,15 +271,6 @@ class TestEnrollmentStatsAPI(JWTTestMixin, APITransactionTestCase):
331
271
  ]
332
272
  },
333
273
  },
334
- {
335
- "params": {"calculation": "invalid"},
336
- "error": {"calculation": [INVALID_CALCULATION_ERROR]},
337
- },
338
- {
339
- "params": {"granularity": "invalid"},
340
- "error": {"granularity": [INVALID_GRANULARITY_ERROR]},
341
- },
342
- {"params": {"chart_type": "invalid"}, "error": {"chart_type": [INVALID_CHART_TYPE_ERROR]}},
343
274
  )
344
275
  @ddt.unpack
345
276
  def test_get_invalid_query_params(self, params, error):