Commit 8e407444 by Bill DeRusha Committed by GitHub

Merge pull request #163 from edx/awais786/ECOM-4908-add-models-course-about

ECOM-4892
parents fe9e1736 c1e5b031
from django.contrib import admin from django.contrib import admin
from course_discovery.apps.course_metadata.models import ( from course_discovery.apps.course_metadata.models import (
Seat, Image, Video, LevelType, Subject, Prerequisite, ExpectedLearningItem, Course, CourseRun, Organization, Person, Seat, Image, Video, LevelType, Subject, Prerequisite, ExpectedLearningItem, Expertise,
Course, CourseRun, CourseRunSocialNetwork, MajorWork, Organization, Person, PersonSocialNetwork,
CourseOrganization, SyllabusItem, Program CourseOrganization, SyllabusItem, Program
) )
...@@ -56,9 +57,9 @@ for model in (Organization, Person,): ...@@ -56,9 +57,9 @@ for model in (Organization, Person,):
admin.site.register(model, KeyNameAdmin) admin.site.register(model, KeyNameAdmin)
# Register children of AbstractNamedModel # Register children of AbstractNamedModel
for model in (LevelType, Subject, Prerequisite,): for model in (LevelType, Subject, Prerequisite, Expertise, MajorWork):
admin.site.register(model, NamedModelAdmin) admin.site.register(model, NamedModelAdmin)
# Register remaining models using basic ModelAdmin classes # Register remaining models using basic ModelAdmin classes
for model in (Image, Video, ExpectedLearningItem, SyllabusItem): for model in (Image, Video, ExpectedLearningItem, SyllabusItem, PersonSocialNetwork, CourseRunSocialNetwork):
admin.site.register(model) admin.site.register(model)
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import sortedm2m.fields
import django_extensions.db.fields
class Migration(migrations.Migration):
dependencies = [
('course_metadata', '0006_auto_20160719_2052'),
]
operations = [
migrations.CreateModel(
name='CourseRunSocialNetwork',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('created', django_extensions.db.fields.CreationDateTimeField(verbose_name='created', auto_now_add=True)),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('type', models.CharField(choices=[('facebook', 'Facebook'), ('twitter', 'Twitter'), ('blog', 'Blog'), ('others', 'Others')], db_index=True, max_length=15)),
('value', models.CharField(max_length=500)),
('course_run', models.ForeignKey(related_name='course_run_networks', to='course_metadata.CourseRun')),
],
options={
'verbose_name_plural': 'CourseRun SocialNetwork',
},
),
migrations.CreateModel(
name='Expertise',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('created', django_extensions.db.fields.CreationDateTimeField(verbose_name='created', auto_now_add=True)),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('name', models.CharField(unique=True, max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='MajorWork',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('created', django_extensions.db.fields.CreationDateTimeField(verbose_name='created', auto_now_add=True)),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('name', models.CharField(unique=True, max_length=255)),
],
options={
'abstract': False,
},
),
migrations.CreateModel(
name='PersonSocialNetwork',
fields=[
('id', models.AutoField(primary_key=True, verbose_name='ID', auto_created=True, serialize=False)),
('created', django_extensions.db.fields.CreationDateTimeField(verbose_name='created', auto_now_add=True)),
('modified', django_extensions.db.fields.ModificationDateTimeField(auto_now=True, verbose_name='modified')),
('type', models.CharField(choices=[('facebook', 'Facebook'), ('twitter', 'Twitter'), ('blog', 'Blog'), ('others', 'Others')], db_index=True, max_length=15)),
('value', models.CharField(max_length=500)),
],
options={
'verbose_name_plural': 'Person SocialNetwork',
},
),
migrations.AddField(
model_name='course',
name='learner_testimonial',
field=models.CharField(help_text='A quote from a learner in the course, demonstrating the value of taking the course', null=True, blank=True, max_length=50),
),
migrations.AddField(
model_name='course',
name='number',
field=models.CharField(help_text='Course number format e.g CS002x, BIO1.1x, BIO1.2x', null=True, blank=True, max_length=50),
),
migrations.AddField(
model_name='historicalcourse',
name='learner_testimonial',
field=models.CharField(help_text='A quote from a learner in the course, demonstrating the value of taking the course', null=True, blank=True, max_length=50),
),
migrations.AddField(
model_name='historicalcourse',
name='number',
field=models.CharField(help_text='Course number format e.g CS002x, BIO1.1x, BIO1.2x', null=True, blank=True, max_length=50),
),
migrations.AddField(
model_name='historicalperson',
name='email',
field=models.EmailField(null=True, blank=True, max_length=255),
),
migrations.AddField(
model_name='historicalperson',
name='username',
field=models.CharField(null=True, blank=True, max_length=255),
),
migrations.AddField(
model_name='person',
name='email',
field=models.EmailField(null=True, blank=True, max_length=255),
),
migrations.AddField(
model_name='person',
name='username',
field=models.CharField(null=True, blank=True, max_length=255),
),
migrations.AddField(
model_name='personsocialnetwork',
name='person',
field=models.ForeignKey(related_name='person_networks', to='course_metadata.Person'),
),
migrations.AddField(
model_name='person',
name='expertises',
field=sortedm2m.fields.SortedManyToManyField(related_name='person_expertise', help_text=None, blank=True, to='course_metadata.Expertise'),
),
migrations.AddField(
model_name='person',
name='major_works',
field=sortedm2m.fields.SortedManyToManyField(related_name='person_works', help_text=None, blank=True, to='course_metadata.MajorWork'),
),
migrations.AlterUniqueTogether(
name='personsocialnetwork',
unique_together=set([('person', 'type')]),
),
migrations.AlterUniqueTogether(
name='courserunsocialnetwork',
unique_together=set([('course_run', 'type')]),
),
]
...@@ -55,6 +55,30 @@ class AbstractMediaModel(TimeStampedModel): ...@@ -55,6 +55,30 @@ class AbstractMediaModel(TimeStampedModel):
abstract = True abstract = True
class AbstractSocialNetworkModel(TimeStampedModel):
""" SocialNetwork model. """
FACEBOOK = 'facebook'
TWITTER = 'twitter'
BLOG = 'blog'
OTHERS = 'others'
SOCIAL_NETWORK_CHOICES = (
(FACEBOOK, _('Facebook')),
(TWITTER, _('Twitter')),
(BLOG, _('Blog')),
(OTHERS, _('Others')),
)
type = models.CharField(max_length=15, choices=SOCIAL_NETWORK_CHOICES, db_index=True)
value = models.CharField(max_length=500)
def __str__(self):
return '{type}: {value}'.format(type=self.type, value=self.value)
class Meta(object):
abstract = True
class Image(AbstractMediaModel): class Image(AbstractMediaModel):
""" Image model. """ """ Image model. """
height = models.IntegerField(null=True, blank=True) height = models.IntegerField(null=True, blank=True)
...@@ -91,6 +115,16 @@ class SyllabusItem(AbstractValueModel): ...@@ -91,6 +115,16 @@ class SyllabusItem(AbstractValueModel):
parent = models.ForeignKey('self', blank=True, null=True, related_name='children') parent = models.ForeignKey('self', blank=True, null=True, related_name='children')
class Expertise(AbstractNamedModel):
""" Expertise model. """
pass
class MajorWork(AbstractNamedModel):
""" MajorWork model. """
pass
class Organization(TimeStampedModel): class Organization(TimeStampedModel):
""" Organization model. """ """ Organization model. """
key = models.CharField(max_length=255, unique=True) key = models.CharField(max_length=255, unique=True)
...@@ -113,6 +147,10 @@ class Person(TimeStampedModel): ...@@ -113,6 +147,10 @@ class Person(TimeStampedModel):
bio = models.TextField(null=True, blank=True) bio = models.TextField(null=True, blank=True)
profile_image = models.ForeignKey(Image, null=True, blank=True) profile_image = models.ForeignKey(Image, null=True, blank=True)
organizations = models.ManyToManyField(Organization, blank=True) organizations = models.ManyToManyField(Organization, blank=True)
email = models.EmailField(max_length=255, null=True, blank=True)
username = models.CharField(max_length=255, null=True, blank=True)
expertises = SortedManyToManyField(Expertise, blank=True, related_name='person_expertise')
major_works = SortedManyToManyField(MajorWork, blank=True, related_name='person_works')
history = HistoricalRecords() history = HistoricalRecords()
...@@ -137,6 +175,17 @@ class Course(TimeStampedModel): ...@@ -137,6 +175,17 @@ class Course(TimeStampedModel):
image = models.ForeignKey(Image, default=None, null=True, blank=True) image = models.ForeignKey(Image, default=None, null=True, blank=True)
video = models.ForeignKey(Video, default=None, null=True, blank=True) video = models.ForeignKey(Video, default=None, null=True, blank=True)
marketing_url = models.URLField(max_length=255, null=True, blank=True) marketing_url = models.URLField(max_length=255, null=True, blank=True)
learner_testimonial = models.CharField(
max_length=50, null=True, blank=True, help_text=_(
"A quote from a learner in the course, demonstrating the value of taking the course"
)
)
number = models.CharField(
max_length=50, null=True, blank=True, help_text=_(
"Course number format e.g CS002x, BIO1.1x, BIO1.2x"
)
)
history = HistoricalRecords() history = HistoricalRecords()
objects = CourseQuerySet.as_manager() objects = CourseQuerySet.as_manager()
...@@ -437,3 +486,27 @@ class Program(TimeStampedModel): ...@@ -437,3 +486,27 @@ class Program(TimeStampedModel):
def __str__(self): def __str__(self):
return self.title return self.title
class PersonSocialNetwork(AbstractSocialNetworkModel):
""" Person Social Network model. """
person = models.ForeignKey(Person, related_name='person_networks')
class Meta(object):
verbose_name_plural = 'Person SocialNetwork'
unique_together = (
('person', 'type'),
)
class CourseRunSocialNetwork(AbstractSocialNetworkModel):
""" CourseRun Social Network model. """
course_run = models.ForeignKey(CourseRun, related_name='course_run_networks')
class Meta(object):
verbose_name_plural = 'CourseRun SocialNetwork'
unique_together = (
('course_run', 'type'),
)
...@@ -9,7 +9,8 @@ from pytz import UTC ...@@ -9,7 +9,8 @@ from pytz import UTC
from course_discovery.apps.core.models import Currency from course_discovery.apps.core.models import Currency
from course_discovery.apps.course_metadata.models import ( from course_discovery.apps.course_metadata.models import (
Course, CourseRun, Organization, Person, Image, Video, Subject, Seat, Prerequisite, LevelType, Program Course, CourseRun, Organization, Person, Image, Video, Subject, Seat, Prerequisite, LevelType, Program,
AbstractSocialNetworkModel, CourseRunSocialNetwork, PersonSocialNetwork
) )
from course_discovery.apps.ietf_language_tags.models import LanguageTag from course_discovery.apps.ietf_language_tags.models import LanguageTag
...@@ -148,3 +149,22 @@ class ProgramFactory(factory.django.DjangoModelFactory): ...@@ -148,3 +149,22 @@ class ProgramFactory(factory.django.DjangoModelFactory):
category = 'xseries' category = 'xseries'
status = 'unpublished' status = 'unpublished'
marketing_slug = factory.Sequence(lambda n: 'test-slug-{}'.format(n)) # pylint: disable=unnecessary-lambda marketing_slug = factory.Sequence(lambda n: 'test-slug-{}'.format(n)) # pylint: disable=unnecessary-lambda
class AbstractSocialNetworkModelFactory(factory.DjangoModelFactory):
type = FuzzyChoice([name for name, __ in AbstractSocialNetworkModel.SOCIAL_NETWORK_CHOICES])
value = FuzzyText()
class PersonSocialNetworkFactory(AbstractSocialNetworkModelFactory):
person = factory.SubFactory(PersonFactory)
class Meta:
model = PersonSocialNetwork
class CourseRunSocialNetworkFactory(AbstractSocialNetworkModelFactory):
course_run = factory.SubFactory(CourseRunFactory)
class Meta:
model = CourseRunSocialNetwork
...@@ -3,6 +3,7 @@ import datetime ...@@ -3,6 +3,7 @@ import datetime
import ddt import ddt
import mock import mock
import pytz import pytz
from django.db import IntegrityError
from django.conf import settings from django.conf import settings
from django.test import TestCase from django.test import TestCase
...@@ -257,3 +258,47 @@ class ProgramTests(TestCase): ...@@ -257,3 +258,47 @@ class ProgramTests(TestCase):
""" Verify the property returns None if the Program has no marketing_slug set. """ """ Verify the property returns None if the Program has no marketing_slug set. """
program = factories.ProgramFactory(marketing_slug='') program = factories.ProgramFactory(marketing_slug='')
self.assertIsNone(program.marketing_url) self.assertIsNone(program.marketing_url)
class PersonSocialNetworkTests(TestCase):
"""Tests of the PersonSocialNetwork model."""
def setUp(self):
super(PersonSocialNetworkTests, self).setUp()
self.network = factories.PersonSocialNetworkFactory()
self.person = factories.PersonFactory()
def test_str(self):
"""Verify that a person-social-network is properly converted to a str."""
self.assertEqual(
str(self.network), '{type}: {value}'.format(type=self.network.type, value=self.network.value)
)
def test_unique_constraint(self):
"""Verify that a person-social-network does not allow multiple accounts for same
social network.
"""
factories.PersonSocialNetworkFactory(person=self.person, type='facebook')
with self.assertRaises(IntegrityError):
factories.PersonSocialNetworkFactory(person=self.person, type='facebook')
class CourseSocialNetworkTests(TestCase):
"""Tests of the CourseSocialNetwork model."""
def setUp(self):
super(CourseSocialNetworkTests, self).setUp()
self.network = factories.CourseRunSocialNetworkFactory()
self.course_run = factories.CourseRunFactory()
def test_str(self):
"""Verify that a course-social-network is properly converted to a str."""
self.assertEqual(
str(self.network), '{type}: {value}'.format(type=self.network.type, value=self.network.value)
)
def test_unique_constraint(self):
"""Verify that a course-social-network does not allow multiple accounts for same
social network.
"""
factories.CourseRunSocialNetworkFactory(course_run=self.course_run, type='facebook')
with self.assertRaises(IntegrityError):
factories.CourseRunSocialNetworkFactory(course_run=self.course_run, type='facebook')
from django.contrib import admin
from course_discovery.apps.publisher.models import Course, CourseRun, Seat
admin.site.register(Course)
admin.site.register(CourseRun)
admin.site.register(Seat)
import logging
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django_extensions.db.models import TimeStampedModel
from simple_history.models import HistoricalRecords
from sortedm2m.fields import SortedManyToManyField
from course_discovery.apps.core.models import User, Currency
from course_discovery.apps.course_metadata.models import LevelType, Subject, Person, Organization
from course_discovery.apps.course_metadata.models import CourseRun as CourseMetadataCourseRun
from course_discovery.apps.ietf_language_tags.models import LanguageTag
logger = logging.getLogger(__name__)
class ChangedByMixin(object):
changed_by = models.ForeignKey(User, null=True, blank=True)
class Course(TimeStampedModel, ChangedByMixin):
""" Publisher Course model. It contains fields related to the course intake form."""
title = models.CharField(max_length=255, default=None, null=True, blank=True)
number = models.CharField(max_length=50, null=True, blank=True)
short_description = models.CharField(max_length=255, default=None, null=True, blank=True)
full_description = models.TextField(default=None, null=True, blank=True)
organizations = models.ManyToManyField(Organization, blank=True, related_name='publisher_courses')
level_type = models.ForeignKey(LevelType, default=None, null=True, blank=True, related_name='publisher_courses')
expected_learnings = models.TextField(default=None, null=True, blank=True)
syllabus = models.TextField(default=None, null=True, blank=True)
prerequisites = models.TextField(default=None, null=True, blank=True)
learner_testimonial = models.CharField(max_length=50, null=True, blank=True)
primary_subject = models.ForeignKey(Subject, related_name='publisher_courses_primary')
secondary_subject = models.ForeignKey(Subject, related_name='publisher_courses_secondary')
tertiary_subject = models.ForeignKey(Subject, related_name='publisher_courses_tertiary')
history = HistoricalRecords()
def __str__(self):
return self.title
class CourseRun(TimeStampedModel, ChangedByMixin):
""" Publisher CourseRun model. It contains fields related to the course run intake form."""
PRIORITY_LEVEL_1 = 'L1'
PRIORITY_LEVEL_2 = 'L2'
PRIORITY_LEVEL_3 = 'L3'
PRIORITY_LEVEL_4 = 'L4'
PRIORITY_LEVEL_5 = 'L5'
PRIORITY_LEVELS = (
(PRIORITY_LEVEL_1, _('Level 1')),
(PRIORITY_LEVEL_2, _('Level 2')),
(PRIORITY_LEVEL_3, _('Level 3')),
(PRIORITY_LEVEL_4, _('Level 4')),
(PRIORITY_LEVEL_5, _('Level 5')),
)
course = models.ForeignKey(Course)
lms_course_id = models.CharField(max_length=255, unique=True, null=True, blank=True)
start = models.DateTimeField(null=True, blank=True)
end = models.DateTimeField(null=True, blank=True)
enrollment_start = models.DateTimeField(null=True, blank=True)
enrollment_end = models.DateTimeField(null=True, blank=True)
certificate_generation = models.DateTimeField(null=True, blank=True)
pacing_type = models.CharField(
max_length=255, choices=CourseMetadataCourseRun.PACING_CHOICES, db_index=True, null=True, blank=True
)
staff = SortedManyToManyField(Person, blank=True, related_name='publisher_course_runs_staffed')
min_effort = models.PositiveSmallIntegerField(
null=True, blank=True,
help_text=_('Estimated minimum number of hours per week needed to complete a course run.'))
max_effort = models.PositiveSmallIntegerField(
null=True, blank=True,
help_text=_('Estimated maximum number of hours per week needed to complete a course run.'))
language = models.ForeignKey(LanguageTag, null=True, blank=True, related_name='publisher_course_runs')
transcript_languages = models.ManyToManyField(
LanguageTag, blank=True, related_name='publisher_transcript_course_runs'
)
length = models.PositiveIntegerField(
null=True, blank=True, help_text=_("Length of course, in number of weeks")
)
sponsor = models.ManyToManyField(Organization, blank=True, related_name='publisher_course_runs')
is_re_run = models.BooleanField(default=False)
is_xseries = models.BooleanField(default=False)
xseries_name = models.CharField(max_length=255)
is_micromasters = models.BooleanField(default=False)
micromasters_name = models.CharField(max_length=255)
contacted_partner_manager = models.BooleanField(default=False)
seo_review = models.TextField(
default=None, null=True, blank=True, help_text=_("SEO review on your course title and short description")
)
keywords = models.TextField(
default=None, blank=True, help_text=_("Please add top 10 comma separated keywords for your course content")
)
notes = models.TextField(
default=None, null=True, blank=True, help_text=_(
"Please add any additional notes or special instructions for the course About Page."
)
)
target_content = models.BooleanField(default=False)
priority = models.CharField(
max_length=5, choices=PRIORITY_LEVELS, null=True, blank=True
)
course_team_admins = models.TextField(
default=None, blank=True, null=True, help_text=_("Comma separated list of edX usernames or emails of admins.")
)
course_team_additional_staff = models.TextField(
default=None, blank=True, null=True, help_text=_(
"Comma separated list of edX usernames or emails of additional staff."
)
)
history = HistoricalRecords()
def __str__(self):
return '{course}: {start_date}'.format(course=self.course.title, start_date=self.start)
class Seat(TimeStampedModel, ChangedByMixin):
""" Seat model. """
HONOR = 'honor'
AUDIT = 'audit'
VERIFIED = 'verified'
PROFESSIONAL = 'professional'
NO_ID_PROFESSIONAL = 'no-id-professional'
CREDIT = 'credit'
SEAT_TYPE_CHOICES = (
(HONOR, _('Honor')),
(AUDIT, _('Audit')),
(VERIFIED, _('Verified')),
(PROFESSIONAL, _('Professional (with ID verification)')),
(NO_ID_PROFESSIONAL, _('Professional (no ID verifiation)')),
(CREDIT, _('Credit')),
)
PRICE_FIELD_CONFIG = {
'decimal_places': 2,
'max_digits': 10,
'null': False,
'default': 0.00,
}
course_run = models.ForeignKey(CourseRun, related_name='seats')
type = models.CharField(max_length=63, choices=SEAT_TYPE_CHOICES)
price = models.DecimalField(**PRICE_FIELD_CONFIG)
currency = models.ForeignKey(Currency, related_name='publisher_seats')
upgrade_deadline = models.DateTimeField(null=True, blank=True)
credit_provider = models.CharField(max_length=255, null=True, blank=True)
credit_hours = models.IntegerField(null=True, blank=True)
history = HistoricalRecords()
def __str__(self):
return '{course}: {type}'.format(course=self.course_run.course.title, type=self.type)
from datetime import datetime
import factory
from factory.fuzzy import FuzzyText, FuzzyChoice, FuzzyDecimal, FuzzyDateTime, FuzzyInteger
from pytz import UTC
from course_discovery.apps.core.models import Currency
from course_discovery.apps.course_metadata.tests import factories
from course_discovery.apps.course_metadata.models import CourseRun as CourseMetadataCourseRun
from course_discovery.apps.ietf_language_tags.models import LanguageTag
from course_discovery.apps.publisher.models import Course, CourseRun, Seat
class CourseFactory(factory.DjangoModelFactory):
title = FuzzyText(prefix="Test çօմɾʂҽ ")
short_description = FuzzyText(prefix="Test çօմɾʂҽ short description")
full_description = FuzzyText(prefix="Test çօմɾʂҽ FULL description")
number = FuzzyText()
prerequisites = "prereq 1, prereq 2, prereq 3"
expected_learnings = "learning 1, learning 2, learning 3"
syllabus = "week 1: awesomeness"
learner_testimonial = "Best course ever!"
level_type = factory.SubFactory(factories.LevelTypeFactory)
primary_subject = factory.SubFactory(factories.SubjectFactory)
secondary_subject = factory.SubFactory(factories.SubjectFactory)
tertiary_subject = factory.SubFactory(factories.SubjectFactory)
class Meta:
model = Course
class CourseRunFactory(factory.DjangoModelFactory):
course = factory.SubFactory(CourseFactory)
start = FuzzyDateTime(datetime(2014, 1, 1, tzinfo=UTC))
end = FuzzyDateTime(datetime(2014, 1, 1, tzinfo=UTC)).end_dt
enrollment_start = FuzzyDateTime(datetime(2014, 1, 1, tzinfo=UTC))
enrollment_end = FuzzyDateTime(datetime(2014, 1, 1, tzinfo=UTC)).end_dt
certificate_generation = FuzzyDateTime(datetime(2014, 1, 1, tzinfo=UTC))
min_effort = FuzzyInteger(1, 10)
max_effort = FuzzyInteger(10, 20)
language = factory.Iterator(LanguageTag.objects.all())
pacing_type = FuzzyChoice([name for name, __ in CourseMetadataCourseRun.PACING_CHOICES])
length = FuzzyInteger(1, 10)
seo_review = "test-seo-review"
keywords = "Test1, Test2, Test3"
notes = "Testing notes"
class Meta:
model = CourseRun
class SeatFactory(factory.DjangoModelFactory):
type = FuzzyChoice([name for name, __ in Seat.SEAT_TYPE_CHOICES])
price = FuzzyDecimal(0.0, 650.0)
currency = factory.Iterator(Currency.objects.all())
upgrade_deadline = FuzzyDateTime(datetime(2014, 1, 1, tzinfo=UTC))
course_run = factory.SubFactory(CourseRunFactory)
class Meta:
model = Seat
# pylint: disable=no-member
from django.test import TestCase
from course_discovery.apps.publisher.tests import factories
class CourseRunTests(TestCase):
""" Tests for the publisher `CourseRun` model. """
def setUp(self):
super(CourseRunTests, self).setUp()
self.course_run = factories.CourseRunFactory()
def test_str(self):
""" Verify casting an instance to a string returns a string containing the course title and start date. """
self.assertEqual(
str(self.course_run),
'{title}: {date}'.format(
title=self.course_run.course.title, date=self.course_run.start
)
)
class CourseTests(TestCase):
""" Tests for the publisher `Course` model. """
def setUp(self):
super(CourseTests, self).setUp()
self.course = factories.CourseFactory()
def test_str(self):
""" Verify casting an instance to a string returns a string containing the course title. """
self.assertEqual(str(self.course), self.course.title)
class SeatTests(TestCase):
""" Tests for the publisher `Seat` model. """
def setUp(self):
super(SeatTests, self).setUp()
self.seat = factories.SeatFactory()
def test_str(self):
""" Verify casting an instance to a string returns a string containing the course title and seat type. """
self.assertEqual(
str(self.seat),
'{course}: {type}'.format(
course=self.seat.course_run.course.title, type=self.seat.type
)
)
...@@ -51,10 +51,10 @@ PROJECT_APPS = ( ...@@ -51,10 +51,10 @@ PROJECT_APPS = (
'course_discovery.apps.catalogs', 'course_discovery.apps.catalogs',
'course_discovery.apps.course_metadata', 'course_discovery.apps.course_metadata',
'course_discovery.apps.edx_haystack_extensions', 'course_discovery.apps.edx_haystack_extensions',
'course_discovery.apps.publisher',
) )
INSTALLED_APPS += THIRD_PARTY_APPS INSTALLED_APPS += THIRD_PARTY_APPS
INSTALLED_APPS += PROJECT_APPS INSTALLED_APPS += PROJECT_APPS
......
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