Commit 7008beb1 by Simon Chen

Add the correct alias to the created course about page

Also, do not create course about page if we already have it on the drupal side
LEARNER-2461
parent 7360a79d
...@@ -10,6 +10,7 @@ import waffle ...@@ -10,6 +10,7 @@ import waffle
from django.db import models, transaction from django.db import models, transaction
from django.db.models.query_utils import Q from django.db.models.query_utils import Q
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django_extensions.db.fields import AutoSlugField from django_extensions.db.fields import AutoSlugField
from django_extensions.db.models import TimeStampedModel from django_extensions.db.models import TimeStampedModel
...@@ -632,6 +633,11 @@ class CourseRun(TimeStampedModel): ...@@ -632,6 +633,11 @@ class CourseRun(TimeStampedModel):
publisher = CourseRunMarketingSitePublisher(self.course.partner) publisher = CourseRunMarketingSitePublisher(self.course.partner)
previous_obj = CourseRun.objects.get(id=self.id) if self.id else None previous_obj = CourseRun.objects.get(id=self.id) if self.id else None
if not self.slug:
# If we are publishing this object to marketing site,
# let's make sure slug is defined
self.slug = slugify(self.title)
with transaction.atomic(): with transaction.atomic():
super(CourseRun, self).save(*args, **kwargs) super(CourseRun, self).save(*args, **kwargs)
publisher.publish_obj(self, previous_obj=previous_obj) publisher.publish_obj(self, previous_obj=previous_obj)
......
...@@ -9,6 +9,7 @@ from course_discovery.apps.course_metadata.choices import CourseRunStatus, Progr ...@@ -9,6 +9,7 @@ from course_discovery.apps.course_metadata.choices import CourseRunStatus, Progr
from course_discovery.apps.course_metadata.exceptions import ( from course_discovery.apps.course_metadata.exceptions import (
AliasCreateError, AliasCreateError,
AliasDeleteError, AliasDeleteError,
FormRetrievalError,
NodeCreateError, NodeCreateError,
NodeDeleteError, NodeDeleteError,
NodeEditError, NodeEditError,
...@@ -107,6 +108,12 @@ class BaseMarketingSitePublisherTests(MarketingSitePublisherTestMixin): ...@@ -107,6 +108,12 @@ class BaseMarketingSitePublisherTests(MarketingSitePublisherTestMixin):
with pytest.raises(NodeLookupError): with pytest.raises(NodeLookupError):
self.publisher.node_id(self.obj) self.publisher.node_id(self.obj)
responses.reset()
self.mock_api_client()
self.mock_node_retrieval(self.publisher.node_lookup_field, lookup_value, exists=False)
node_id = self.publisher.node_id(self.obj)
assert node_id is None
@responses.activate @responses.activate
def test_create_node(self): def test_create_node(self):
""" """
...@@ -200,10 +207,34 @@ class CourseRunMarketingSitePublisherTests(MarketingSitePublisherTestMixin): ...@@ -200,10 +207,34 @@ class CourseRunMarketingSitePublisherTests(MarketingSitePublisherTestMixin):
self.obj = CourseRunFactory() self.obj = CourseRunFactory()
@mock.patch.object(CourseRunMarketingSitePublisher, 'serialize_obj', return_value='data') @mock.patch.object(CourseRunMarketingSitePublisher, 'serialize_obj', return_value='data')
@mock.patch.object(CourseRunMarketingSitePublisher, 'create_node') @mock.patch.object(CourseRunMarketingSitePublisher, 'node_id', return_value=None)
def test_publish_obj_create(self, mock_create_node, *args): # pylint: disable=unused-argument @mock.patch.object(CourseRunMarketingSitePublisher, 'create_node', return_value='node_id')
@mock.patch.object(CourseRunMarketingSitePublisher, 'update_node_alias')
def test_publish_obj_create_successful(
self,
mock_update_node_alias,
mock_create_node,
*args
): # pylint: disable=unused-argument
self.publisher.publish_obj(self.obj) self.publisher.publish_obj(self.obj)
mock_create_node.assert_called_with('data') mock_create_node.assert_called_with('data')
mock_update_node_alias.assert_called_with(self.obj, 'node_id', None)
@mock.patch.object(CourseRunMarketingSitePublisher, 'serialize_obj', return_value='data')
@mock.patch.object(CourseRunMarketingSitePublisher, 'node_id', return_value='node_id')
@mock.patch.object(CourseRunMarketingSitePublisher, 'create_node')
@mock.patch.object(CourseRunMarketingSitePublisher, 'update_node_alias')
def test_publish_obj_not_create_if_exists(
self,
mock_update_node_alias,
mock_create_node,
mock_node_id,
*args
): # pylint: disable=unused-argument
self.publisher.publish_obj(self.obj)
mock_node_id.assert_called_with(self.obj)
assert not mock_create_node.called
assert not mock_update_node_alias.called
@mock.patch.object(CourseRunMarketingSitePublisher, 'node_id', return_value='node_id') @mock.patch.object(CourseRunMarketingSitePublisher, 'node_id', return_value='node_id')
@mock.patch.object(CourseRunMarketingSitePublisher, 'serialize_obj', return_value='data') @mock.patch.object(CourseRunMarketingSitePublisher, 'serialize_obj', return_value='data')
...@@ -250,6 +281,59 @@ class CourseRunMarketingSitePublisherTests(MarketingSitePublisherTestMixin): ...@@ -250,6 +281,59 @@ class CourseRunMarketingSitePublisherTests(MarketingSitePublisherTestMixin):
assert actual == expected assert actual == expected
@responses.activate
def test_update_node_alias(self):
"""
Verify that the publisher attempts to create a new alias associated with the new course_run,
and that appropriate exceptions are raised for non-200 status codes.
"""
# No previous object is provided. Create a new node and make sure
# title alias created, by default, based on the title is deleted
# and a new alias based on marketing slug is created.
self.mock_api_client()
self.mock_get_alias_form()
self.mock_get_delete_form(self.obj.slug)
self.mock_delete_alias()
self.mock_get_delete_form(self.obj.slug)
self.mock_add_alias()
self.publisher.update_node_alias(self.obj, self.node_id, None)
assert responses.calls[-1].request.url == '{}/add'.format(self.publisher.alias_api_base)
responses.reset()
# Same scenario, but this time a non-200 status code is returned during
# alias creation. An exception should be raised.
self.mock_api_client()
self.mock_get_alias_form()
self.mock_get_delete_form(self.obj.slug)
self.mock_delete_alias()
self.mock_get_delete_form(self.obj.slug)
self.mock_add_alias(status=500)
with pytest.raises(AliasCreateError):
self.publisher.update_node_alias(self.obj, self.node_id, None)
responses.reset()
# In this case, similate the fact that alias form retrival returned error
# FormRetrievalError should be raised
self.mock_api_client()
self.mock_get_delete_form(self.obj.slug)
self.mock_get_alias_form(status=500)
with pytest.raises(FormRetrievalError):
self.publisher.update_node_alias(self.obj, self.node_id, None)
def test_alias(self):
"""
Verify that aliases are constructed correctly.
"""
actual = self.publisher.alias(self.obj)
expected = 'course/{slug}'.format(slug=self.obj.slug)
assert actual == expected
class ProgramMarketingSitePublisherTests(MarketingSitePublisherTestMixin): class ProgramMarketingSitePublisherTests(MarketingSitePublisherTestMixin):
""" """
......
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