Commit 0334df1e by Clinton Blackburn

Fixed bug with Studio API course run team update endpoint

We now iterate over the given team members and create them individually, rather than in bulk. This avoids uniqueness errors that arise when we attempt a bulk create operation with an existing row.

LEARNER-2468
parent 55df6570
......@@ -3,12 +3,12 @@ from django.contrib.auth import get_user_model
from django.db import transaction
from rest_framework import serializers
from rest_framework.fields import empty
from xmodule.modulestore.django import modulestore
from cms.djangoapps.contentstore.views.course import create_new_course, get_course_and_check_access, rerun_course
from contentstore.views.assets import update_course_run_asset
from openedx.core.lib.courses import course_image_url
from student.models import CourseAccessRole
from xmodule.modulestore.django import modulestore
IMAGE_TYPES = {
'image/jpeg': 'jpg',
......@@ -116,11 +116,15 @@ class CourseRunSerializer(CourseRunTeamSerializerMixin, serializers.Serializer):
if not self.partial:
CourseAccessRole.objects.filter(course_id=instance.id).delete()
# TODO In the future we can optimize by getting users in a single query.
CourseAccessRole.objects.bulk_create([
CourseAccessRole(course_id=instance.id, role=member['role'], user=User.objects.get(username=member['user']))
for member in team
])
# We iterate here, instead of using a bulk operation, to avoid uniqueness errors that arise
# when using `bulk_create` with existing data. Given the relatively small number of team members
# in a course, this is not worth optimizing at this time.
for member in team:
CourseAccessRole.objects.update_or_create(
course_id=instance.id,
user=User.objects.get(username=member['user']),
defaults={'role': member['role']}
)
class CourseRunCreateSerializer(CourseRunSerializer):
......
......@@ -140,23 +140,32 @@ class CourseRunViewSetTests(ModuleStoreTestCase):
role = 'staff'
start = datetime.datetime.now(pytz.UTC).replace(microsecond=0)
course_run = CourseFactory(start=start, end=None, enrollment_start=None, enrollment_end=None)
CourseAccessRole.objects.create(course_id=course_run.id, role=role, user=UserFactory())
assert CourseAccessRole.objects.filter(course_id=course_run.id).count() == 1
user = UserFactory()
# The request should only update or create new team members
existing_user = UserFactory()
CourseAccessRole.objects.create(course_id=course_run.id, role=role, user=existing_user)
new_user = UserFactory()
CourseAccessRole.objects.create(course_id=course_run.id, role=role, user=new_user)
assert CourseAccessRole.objects.filter(course_id=course_run.id).count() == 2
data = {
'team': [
{
'user': user.username,
'user': existing_user.username,
'role': role,
}
},
{
'user': new_user.username,
'role': role,
},
],
}
url = reverse('api:v1:course_run-detail', kwargs={'pk': str(course_run.id)})
response = self.client.patch(url, data, format='json')
assert response.status_code == 200
self.assert_access_role(course_run, user, role)
self.assert_access_role(course_run, existing_user, role)
self.assert_access_role(course_run, new_user, role)
self.assert_course_access_role_count(course_run, 2)
course_run = modulestore().get_course(course_run.id)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment