Skip to content
Snippets Groups Projects
Commit 2bf3e662 authored by Rick Reilly's avatar Rick Reilly
Browse files

Add ProgramEnrollment app and model for masters

parent 05a682f5
No related branches found
No related tags found
No related merge requests found
# -*- coding: utf-8 -*-
"""
Admin tool for the Program Enrollments models
"""
from __future__ import unicode_literals
from django.contrib import admin
from lms.djangoapps.program_enrollments.models import ProgramEnrollment
class ProgramEnrollmentAdmin(admin.ModelAdmin):
"""
Admin tool for the ProgramEnrollment model
"""
admin.site.register(ProgramEnrollment, ProgramEnrollmentAdmin)
# -*- coding: utf-8 -*-
"""
ProgramEnrollments Application Configuration
"""
from __future__ import unicode_literals
from django.apps import AppConfig
class ProgramEnrollmentsConfig(AppConfig):
"""
Application configuration for ProgramEnrollment
"""
name = 'lms.djangoapps.program_enrollments'
plugin_app = {
'url_config': {},
}
# -*- coding: utf-8 -*-
# Generated by Django 1.11.20 on 2019-04-09 19:32
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import model_utils.fields
import simple_history.models
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='HistoricalProgramEnrollment',
fields=[
('id', models.IntegerField(auto_created=True, blank=True, db_index=True, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('external_user_key', models.CharField(db_index=True, max_length=255, null=True)),
('program_uuid', models.UUIDField(db_index=True)),
('curriculum_uuid', models.UUIDField(db_index=True)),
('status', models.CharField(choices=[('enrolled', 'enrolled'), ('pending', 'pending'), ('suspended', 'suspended'), ('withdrawn', 'withdrawn')], max_length=9)),
('history_id', models.AutoField(primary_key=True, serialize=False)),
('history_date', models.DateTimeField()),
('history_change_reason', models.CharField(max_length=100, null=True)),
('history_type', models.CharField(choices=[('+', 'Created'), ('~', 'Changed'), ('-', 'Deleted')], max_length=1)),
('history_user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to=settings.AUTH_USER_MODEL)),
('user', models.ForeignKey(blank=True, db_constraint=False, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL)),
],
options={
'ordering': ('-history_date', '-history_id'),
'get_latest_by': 'history_date',
'verbose_name': 'historical program enrollment',
},
bases=(simple_history.models.HistoricalChanges, models.Model),
),
migrations.CreateModel(
name='ProgramEnrollment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('created', model_utils.fields.AutoCreatedField(default=django.utils.timezone.now, editable=False, verbose_name='created')),
('modified', model_utils.fields.AutoLastModifiedField(default=django.utils.timezone.now, editable=False, verbose_name='modified')),
('external_user_key', models.CharField(db_index=True, max_length=255, null=True)),
('program_uuid', models.UUIDField(db_index=True)),
('curriculum_uuid', models.UUIDField(db_index=True)),
('status', models.CharField(choices=[('enrolled', 'enrolled'), ('pending', 'pending'), ('suspended', 'suspended'), ('withdrawn', 'withdrawn')], max_length=9)),
('user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
]
# -*- coding: utf-8 -*-
"""
Django model specifications for the Program Enrollments API
"""
from __future__ import unicode_literals
from django.contrib.auth.models import User
from django.db import models
from model_utils.models import TimeStampedModel
from simple_history.models import HistoricalRecords
class ProgramEnrollment(TimeStampedModel): # pylint: disable=model-missing-unicode
"""
This is a model for Program Enrollments from the registrar service
.. pii: PII is found in the external key for a program enrollment
.. pii_types: other
.. pii_retirement: local_api
"""
STATUSES = (
('enrolled', 'enrolled'),
('pending', 'pending'),
('suspended', 'suspended'),
('withdrawn', 'withdrawn'),
)
class Meta(object):
app_label = "program_enrollments"
user = models.ForeignKey(
User,
null=True,
blank=True
)
external_user_key = models.CharField(
db_index=True,
max_length=255,
null=True
)
program_uuid = models.UUIDField(db_index=True, null=False)
curriculum_uuid = models.UUIDField(db_index=True, null=False)
status = models.CharField(max_length=9, choices=STATUSES)
historical_records = HistoricalRecords()
@classmethod
def retire_user(cls, user_id):
"""
With the parameter user_id, retire the external_user_key field
Return True if there is data that was retired
Return False if there is no matching data
"""
enrollments = cls.objects.filter(user=user_id)
if not enrollments:
return False
for enrollment in enrollments:
enrollment.historical_records.update(external_user_key=None)
enrollments.update(external_user_key=None)
return True
"""
Unit tests for ProgramEnrollment models.
"""
from __future__ import unicode_literals
from uuid import uuid4
from django.test import TestCase
from lms.djangoapps.program_enrollments.models import ProgramEnrollment
from student.tests.factories import UserFactory
class ProgramEnrollmentModelTests(TestCase):
"""
Tests for the ProgramEnrollment model.
"""
def setUp(self):
"""
Set up the test data used in the specific tests
"""
super(ProgramEnrollmentModelTests, self).setUp()
self.user = UserFactory.create()
self.enrollment = ProgramEnrollment.objects.create(
user=self.user,
external_user_key='abc',
program_uuid=uuid4(),
curriculum_uuid=uuid4(),
status='enrolled'
)
def test_user_retirement(self):
"""
Test that the external_user_key is uccessfully retired for a user's program enrollments and history.
"""
new_status = 'withdrawn'
self.enrollment.status = new_status
self.enrollment.save()
# Ensure that all the records had values for external_user_key
self.assertEquals(self.enrollment.external_user_key, 'abc')
self.assertTrue(self.enrollment.historical_records.all())
for record in self.enrollment.historical_records.all():
self.assertEquals(record.external_user_key, 'abc')
ProgramEnrollment.retire_user(self.user.id)
self.enrollment.refresh_from_db()
# Ensure those values are retired
self.assertEquals(self.enrollment.external_user_key, None)
self.assertTrue(self.enrollment.historical_records.all())
for record in self.enrollment.historical_records.all():
self.assertEquals(record.external_user_key, None)
# -*- coding: utf-8 -*-
"""
ProgramEnrollment Views
"""
from __future__ import unicode_literals
# from django.shortcuts import render
# Create your views here.
......@@ -82,7 +82,8 @@ setup(
"zendesk_proxy = openedx.core.djangoapps.zendesk_proxy.apps:ZendeskProxyConfig",
"instructor = lms.djangoapps.instructor.apps:InstructorConfig",
"password_policy = openedx.core.djangoapps.password_policy.apps:PasswordPolicyConfig",
"user_authn = openedx.core.djangoapps.user_authn.apps:UserAuthnConfig"
"user_authn = openedx.core.djangoapps.user_authn.apps:UserAuthnConfig",
"program_enrollments = lms.djangoapps.program_enrollments.apps:ProgramEnrollmentsConfig",
],
"cms.djangoapp": [
"announcements = openedx.features.announcements.apps:AnnouncementsConfig",
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment