Commit a90370b4 by Vedran Karacic Committed by Afzal Wali Naushahi

Remove SITE_ID from settings.

Merge branches 'master' and 'vkaracic/LEARNER-1119' of https://github.com/edx/course-discovery into vkaracic/LEARNER-1119
parent cda1efbe
from django.conf import settings
from django.contrib.sites.models import Site
from django.test import RequestFactory
from course_discovery.apps.core.tests.factories import PartnerFactory, SiteFactory
class PartnerMixin(object):
class SiteMixin(object):
def setUp(self):
super(PartnerMixin, self).setUp()
Site.objects.all().delete()
self.site = SiteFactory(id=settings.SITE_ID)
super(SiteMixin, self).setUp()
domain = 'testserver.fake'
self.client = self.client_class(SERVER_NAME=domain)
self.site = SiteFactory(domain=domain)
self.partner = PartnerFactory(site=self.site)
self.request = RequestFactory(SERVER_NAME=self.site.domain).get('')
self.request.site = self.site
......@@ -21,7 +21,7 @@ from course_discovery.apps.api.serializers import (
ProgramSerializer, ProgramTypeSerializer, SeatSerializer, SubjectSerializer, TypeaheadCourseRunSearchSerializer,
TypeaheadProgramSearchSerializer, VideoSerializer
)
from course_discovery.apps.api.tests.mixins import PartnerMixin
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.catalogs.tests.factories import CatalogFactory
from course_discovery.apps.core.models import User
from course_discovery.apps.core.tests.factories import UserFactory
......@@ -97,7 +97,7 @@ class CatalogSerializerTests(ElasticsearchTestMixin, TestCase):
self.assertEqual(User.objects.filter(username=username).count(), 0) # pylint: disable=no-member
class MinimalCourseSerializerTests(PartnerMixin, TestCase):
class MinimalCourseSerializerTests(SiteMixin, TestCase):
serializer_class = MinimalCourseSerializer
def get_expected_data(self, course, request):
......
......@@ -12,7 +12,7 @@ from course_discovery.apps.api.serializers import (
CourseWithProgramsSerializer, FlattenedCourseRunWithCourseSerializer, MinimalProgramSerializer,
OrganizationSerializer, PersonSerializer, ProgramSerializer, ProgramTypeSerializer
)
from course_discovery.apps.api.tests.mixins import PartnerMixin
from course_discovery.apps.api.tests.mixins import SiteMixin
class SerializationMixin(object):
......@@ -92,5 +92,5 @@ class OAuth2Mixin(object):
)
class APITestCase(PartnerMixin, RestAPITestCase):
class APITestCase(SiteMixin, RestAPITestCase):
pass
......@@ -7,10 +7,9 @@ import ddt
import pytz
from lxml import etree
from rest_framework.reverse import reverse
from rest_framework.test import APITestCase
from course_discovery.apps.api.serializers import AffiliateWindowSerializer
from course_discovery.apps.api.v1.tests.test_views.mixins import SerializationMixin
from course_discovery.apps.api.v1.tests.test_views.mixins import APITestCase, SerializationMixin
from course_discovery.apps.catalogs.tests.factories import CatalogFactory
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.core.tests.mixins import ElasticsearchTestMixin
......@@ -46,8 +45,7 @@ class AffiliateWindowViewSetTests(ElasticsearchTestMixin, SerializationMixin, AP
def test_affiliate_with_supported_seats(self):
""" Verify that endpoint returns course runs for verified and professional seats only. """
with self.assertNumQueries(9):
response = self.client.get(self.affiliate_url)
response = self.client.get(self.affiliate_url)
self.assertEqual(response.status_code, 200)
root = ET.fromstring(response.content)
......
......@@ -8,10 +8,9 @@ import pytz
import responses
from django.contrib.auth import get_user_model
from rest_framework.reverse import reverse
from rest_framework.test import APITestCase
from course_discovery.apps.api.tests.jwt_utils import generate_jwt_header_for_user
from course_discovery.apps.api.v1.tests.test_views.mixins import OAuth2Mixin, SerializationMixin
from course_discovery.apps.api.v1.tests.test_views.mixins import APITestCase, OAuth2Mixin, SerializationMixin
from course_discovery.apps.catalogs.models import Catalog
from course_discovery.apps.catalogs.tests.factories import CatalogFactory
from course_discovery.apps.core.tests.factories import UserFactory
......@@ -31,6 +30,7 @@ class CatalogViewSetTests(ElasticsearchTestMixin, SerializationMixin, OAuth2Mixi
def setUp(self):
super(CatalogViewSetTests, self).setUp()
self.user = UserFactory(is_staff=True, is_superuser=True)
self.request.user = self.user
self.client.force_authenticate(self.user)
self.catalog = CatalogFactory(query='title:abc*')
enrollment_end = datetime.datetime.now(pytz.UTC) + datetime.timedelta(days=30)
......
......@@ -21,6 +21,7 @@ class CourseViewSetTests(SerializationMixin, APITestCase):
def setUp(self):
super(CourseViewSetTests, self).setUp()
self.user = UserFactory(is_staff=True, is_superuser=True)
self.request.user = self.user
self.client.login(username=self.user.username, password=USER_PASSWORD)
self.course = CourseFactory(partner=self.partner)
......
......@@ -13,6 +13,7 @@ class OrganizationViewSetTests(SerializationMixin, APITestCase):
def setUp(self):
super(OrganizationViewSetTests, self).setUp()
self.user = UserFactory(is_staff=True, is_superuser=True)
self.request.user = self.user
self.client.login(username=self.user.username, password=USER_PASSWORD)
def test_authentication(self):
......@@ -28,16 +29,14 @@ class OrganizationViewSetTests(SerializationMixin, APITestCase):
""" Asserts the response data (only) contains the expected organizations. """
actual = response.data
serializer_data = self.serialize_organization(organizations, many=many)
if many:
actual = actual['results']
actual = sorted(actual, key=lambda k: k['uuid'])
serializer_data = sorted(serializer_data, key=lambda k: k['uuid'])
self.assertEqual(actual, serializer_data)
self.assertCountEqual(actual, serializer_data)
def assert_list_uuid_filter(self, organizations, expected_query_count):
""" Asserts the list endpoint supports filtering by UUID. """
organizations = sorted(organizations, key=lambda o: o.created)
with self.assertNumQueries(expected_query_count):
uuids = ','.join([organization.uuid.hex for organization in organizations])
url = '{root}?uuids={uuids}'.format(root=self.list_path, uuids=uuids)
......@@ -60,7 +59,7 @@ class OrganizationViewSetTests(SerializationMixin, APITestCase):
""" Verify the endpoint returns a list of all organizations. """
OrganizationFactory.create_batch(3, partner=self.partner)
with self.assertNumQueries(8):
with self.assertNumQueries(7):
response = self.client.get(self.list_path)
self.assertEqual(response.status_code, 200)
......
......@@ -7,7 +7,8 @@ from rest_framework.reverse import reverse
from rest_framework.test import APITestCase
from testfixtures import LogCapture
from course_discovery.apps.api.v1.tests.test_views.mixins import PartnerMixin, SerializationMixin
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.api.v1.tests.test_views.mixins import SerializationMixin
from course_discovery.apps.api.v1.views.people import logger as people_logger
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.course_metadata.models import Person
......@@ -19,7 +20,7 @@ User = get_user_model()
@ddt.ddt
class PersonViewSetTests(SerializationMixin, PartnerMixin, APITestCase):
class PersonViewSetTests(SerializationMixin, SiteMixin, APITestCase):
""" Tests for the person resource. """
people_list_url = reverse('api:v1:person-list')
......
from django.urls import reverse
from rest_framework.test import APITestCase
from course_discovery.apps.api.v1.tests.test_views.mixins import SerializationMixin
from course_discovery.apps.api.v1.tests.test_views.mixins import APITestCase, SerializationMixin
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.course_metadata.models import ProgramType
from course_discovery.apps.course_metadata.tests.factories import ProgramTypeFactory
......
......@@ -24,6 +24,7 @@ class ProgramViewSetTests(SerializationMixin, APITestCase):
def setUp(self):
super(ProgramViewSetTests, self).setUp()
self.user = UserFactory(is_staff=True, is_superuser=True)
self.request.user = self.user
self.client.login(username=self.user.username, password=USER_PASSWORD)
# Clear the cache between test cases, so they don't interfere with each other.
......
......@@ -155,7 +155,9 @@ class CourseRunSearchViewSetTests(SerializationMixin, LoginMixin, ElasticsearchT
return course_run, response_data
def build_facet_url(self, params):
return 'http://testserver{path}?{query}'.format(path=self.faceted_path, query=urllib.parse.urlencode(params))
return 'http://testserver.fake{path}?{query}'.format(
path=self.faceted_path, query=urllib.parse.urlencode(params)
)
def test_invalid_query_facet(self):
""" Verify the endpoint returns HTTP 400 if an invalid facet is requested. """
......
......@@ -3,10 +3,11 @@ import json
from django.test import TestCase
from django.urls import reverse
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
class UserAutocompleteTests(TestCase):
class UserAutocompleteTests(SiteMixin, TestCase):
""" Tests for user autocomplete lookups."""
def setUp(self):
......
......@@ -3,12 +3,13 @@ from django.core.cache import cache
from django.urls import reverse
from rest_framework.test import APITestCase
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.models import UserThrottleRate
from course_discovery.apps.core.tests.factories import USER_PASSWORD, PartnerFactory, UserFactory
from course_discovery.apps.core.throttles import OverridableUserRateThrottle
class RateLimitingTest(APITestCase):
class RateLimitingTest(SiteMixin, APITestCase):
"""
Testing rate limiting of API calls.
"""
......
......@@ -9,33 +9,23 @@ from django.test.utils import override_settings
from django.urls import reverse
from django.utils.encoding import force_text
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.constants import Status
from course_discovery.apps.core.views import get_database_status
User = get_user_model()
class HealthTests(TestCase):
class HealthTests(SiteMixin, TestCase):
"""Tests of the health endpoint."""
def test_getting_database_ok_status(self):
"""Method should return the OK status."""
status = get_database_status()
self.assertEqual(status, Status.OK)
def test_getting_database_unavailable_status(self):
"""Method should return the unavailable status when a DatabaseError occurs."""
with mock.patch('django.db.backends.base.base.BaseDatabaseWrapper.cursor', side_effect=DatabaseError):
status = get_database_status()
self.assertEqual(status, Status.UNAVAILABLE)
def test_all_services_available(self):
"""Test that the endpoint reports when all services are healthy."""
self._assert_health(200, Status.OK, Status.OK)
@mock.patch('django.contrib.sites.middleware.get_current_site', mock.Mock(return_value=None))
def test_database_outage(self):
"""Test that the endpoint reports when the database is unavailable."""
with mock.patch('course_discovery.apps.core.views.get_database_status', return_value=Status.UNAVAILABLE):
with mock.patch('django.db.backends.base.base.BaseDatabaseWrapper.cursor', side_effect=DatabaseError):
self._assert_health(503, Status.UNAVAILABLE, Status.UNAVAILABLE)
def _assert_health(self, status_code, overall_status, database_status):
......@@ -54,7 +44,7 @@ class HealthTests(TestCase):
self.assertJSONEqual(force_text(response.content), expected_data)
class AutoAuthTests(TestCase):
class AutoAuthTests(SiteMixin, TestCase):
""" Auto Auth view tests. """
AUTO_AUTH_PATH = reverse('auto_auth')
......
......@@ -15,18 +15,6 @@ logger = logging.getLogger(__name__)
User = get_user_model()
def get_database_status():
"""Run a database query to see if the database is responsive."""
try:
cursor = connection.cursor()
cursor.execute("SELECT 1")
cursor.fetchone()
cursor.close()
return Status.OK
except DatabaseError:
return Status.UNAVAILABLE
@transaction.non_atomic_requests
def health(_):
"""Allows a load balancer to verify this service is up.
......@@ -44,7 +32,15 @@ def health(_):
>>> response.content
'{"overall_status": "OK", "detailed_status": {"database_status": "OK"}}'
"""
database_status = get_database_status()
try:
cursor = connection.cursor()
cursor.execute("SELECT 1")
cursor.fetchone()
cursor.close()
database_status = Status.OK
except DatabaseError:
database_status = Status.UNAVAILABLE
overall_status = Status.OK if (database_status == Status.OK) else Status.UNAVAILABLE
......
......@@ -11,6 +11,7 @@ from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support.wait import WebDriverWait
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.models import Partner
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.core.tests.helpers import make_image_file
......@@ -23,7 +24,7 @@ from course_discovery.apps.course_metadata.tests import factories
# pylint: disable=no-member
@ddt.ddt
class AdminTests(TestCase):
class AdminTests(SiteMixin, TestCase):
""" Tests Admin page."""
def setUp(self):
......@@ -190,7 +191,7 @@ class AdminTests(TestCase):
self.assertEqual(response.status_code, 200)
class ProgramAdminFunctionalTests(LiveServerTestCase):
class ProgramAdminFunctionalTests(SiteMixin, LiveServerTestCase):
""" Functional Tests for Admin page."""
# Required for access to initial data loaded in migrations (e.g., LanguageTags).
serialized_rollback = True
......@@ -224,7 +225,6 @@ class ProgramAdminFunctionalTests(LiveServerTestCase):
def setUp(self):
super().setUp()
# ContentTypeManager uses a cache to speed up ContentType retrieval. This
# cache persists across tests. This is fine in the context of a regular
# TestCase which uses a transaction to reset the database between tests.
......@@ -238,6 +238,9 @@ class ProgramAdminFunctionalTests(LiveServerTestCase):
# stale ContentType objects from being used.
ContentType.objects.clear_cache()
self.site.domain = self.live_server_url.strip('http://')
self.site.save()
self.course_runs = factories.CourseRunFactory.create_batch(2)
self.courses = [course_run.course for course_run in self.course_runs]
......@@ -349,7 +352,7 @@ class ProgramAdminFunctionalTests(LiveServerTestCase):
self.assertEqual(self.program.subtitle, subtitle)
class ProgramEligibilityFilterTests(TestCase):
class ProgramEligibilityFilterTests(SiteMixin, TestCase):
""" Tests for Program Eligibility Filter class. """
parameter_name = 'eligible_for_one_click_purchase'
......
......@@ -5,6 +5,7 @@ import ddt
from django.test import TestCase
from django.urls import reverse
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.course_metadata.tests.factories import (
CourseFactory, CourseRunFactory, OrganizationFactory, PersonFactory, PositionFactory
......@@ -16,7 +17,7 @@ from course_discovery.apps.publisher.tests import factories
@ddt.ddt
class AutocompleteTests(TestCase):
class AutocompleteTests(SiteMixin, TestCase):
""" Tests for autocomplete lookups."""
def setUp(self):
super(AutocompleteTests, self).setUp()
......@@ -118,7 +119,7 @@ class AutocompleteTests(TestCase):
@ddt.ddt
class AutoCompletePersonTests(TestCase):
class AutoCompletePersonTests(SiteMixin, TestCase):
"""
Tests for person autocomplete lookups
"""
......
......@@ -4,13 +4,14 @@ import ddt
from django.test import TestCase
from django.urls import reverse
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.ietf_language_tags.models import LanguageTag
# pylint: disable=no-member
@ddt.ddt
class AutocompleteTests(TestCase):
class AutocompleteTests(SiteMixin, TestCase):
""" Tests for autocomplete lookups."""
def setUp(self):
super(AutocompleteTests, self).setUp()
......
......@@ -40,7 +40,8 @@ class CourseUserRoleSerializer(serializers.ModelSerializer):
former_user = instance.user
instance = super(CourseUserRoleSerializer, self).update(instance, validated_data)
if not instance.role == PublisherUserRole.CourseTeam:
send_change_role_assignment_email(instance, former_user)
request = self.context['request']
send_change_role_assignment_email(instance, former_user, request.site)
return instance
......@@ -104,6 +105,7 @@ class CourseRunSerializer(serializers.ModelSerializer):
instance = super(CourseRunSerializer, self).update(instance, validated_data)
preview_url = validated_data.get('preview_url')
lms_course_id = validated_data.get('lms_course_id')
request = self.context['request']
if preview_url:
# Change ownership to CourseTeam.
......@@ -111,10 +113,10 @@ class CourseRunSerializer(serializers.ModelSerializer):
if waffle.switch_is_active('enable_publisher_email_notifications'):
if preview_url:
send_email_preview_page_is_available(instance)
send_email_preview_page_is_available(instance, site=request.site)
elif lms_course_id:
send_email_for_studio_instance_created(instance)
send_email_for_studio_instance_created(instance, site=request.site)
return instance
......@@ -167,7 +169,7 @@ class CourseStateSerializer(serializers.ModelSerializer):
state = validated_data.get('name')
request = self.context.get('request')
try:
instance.change_state(state=state, user=request.user)
instance.change_state(state=state, user=request.user, site=request.site)
except TransitionNotAllowed:
# pylint: disable=no-member
raise serializers.ValidationError(
......@@ -204,7 +206,7 @@ class CourseRunStateSerializer(serializers.ModelSerializer):
if state:
try:
instance.change_state(state=state, user=request.user)
instance.change_state(state=state, user=request.user, site=request.site)
except TransitionNotAllowed:
# pylint: disable=no-member
raise serializers.ValidationError(
......@@ -223,6 +225,6 @@ class CourseRunStateSerializer(serializers.ModelSerializer):
instance.save()
if waffle.switch_is_active('enable_publisher_email_notifications'):
send_email_preview_accepted(instance.course_run)
send_email_preview_accepted(instance.course_run, request.site)
return instance
......@@ -5,6 +5,7 @@ from django.test import RequestFactory, TestCase
from opaque_keys.edx.keys import CourseKey
from rest_framework.exceptions import ValidationError
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.core.tests.helpers import make_image_file
from course_discovery.apps.course_metadata.tests import toggle_switch
......@@ -20,7 +21,7 @@ from course_discovery.apps.publisher.tests.factories import (CourseFactory, Cour
OrganizationExtensionFactory, SeatFactory)
class CourseUserRoleSerializerTests(TestCase):
class CourseUserRoleSerializerTests(SiteMixin, TestCase):
serializer_class = CourseUserRoleSerializer
def setUp(self):
......@@ -28,6 +29,7 @@ class CourseUserRoleSerializerTests(TestCase):
self.request = RequestFactory()
self.course_user_role = CourseUserRoleFactory(role=PublisherUserRole.MarketingReviewer)
self.request.user = self.course_user_role.user
self.request.site = self.site
def get_expected_data(self):
""" Helper method which will return expected serialize data. """
......@@ -138,7 +140,7 @@ class CourseRunSerializerTests(TestCase):
"""
self.course_run.preview_url = ''
self.course_run.save()
serializer = self.serializer_class(self.course_run)
serializer = self.serializer_class(self.course_run, context={'request': self.request})
serializer.update(self.course_run, {'preview_url': 'https://example.com/abc/course'})
self.assertEqual(self.course_state.owner_role, PublisherUserRole.CourseTeam)
......@@ -246,13 +248,12 @@ class CourseRevisionSerializerTests(TestCase):
self.assertDictEqual(serializer.data, expected)
class CourseStateSerializerTests(TestCase):
class CourseStateSerializerTests(SiteMixin, TestCase):
serializer_class = CourseStateSerializer
def setUp(self):
super(CourseStateSerializerTests, self).setUp()
self.course_state = CourseStateFactory(name=CourseStateChoices.Draft)
self.request = RequestFactory()
self.user = UserFactory()
self.request.user = self.user
......@@ -289,14 +290,13 @@ class CourseStateSerializerTests(TestCase):
serializer.update(self.course_state, data)
class CourseRunStateSerializerTests(TestCase):
class CourseRunStateSerializerTests(SiteMixin, TestCase):
serializer_class = CourseRunStateSerializer
def setUp(self):
super(CourseRunStateSerializerTests, self).setUp()
self.run_state = CourseRunStateFactory(name=CourseRunStateChoices.Draft)
self.course_run = self.run_state.course_run
self.request = RequestFactory()
self.user = UserFactory()
self.request.user = self.user
CourseStateFactory(name=CourseStateChoices.Approved, course=self.course_run.course)
......
......@@ -4,7 +4,6 @@ from urllib.parse import quote
import ddt
from django.contrib.auth.models import Group
from django.contrib.sites.models import Site
from django.core import mail
from django.db import IntegrityError
from django.test import TestCase
......@@ -14,6 +13,7 @@ from mock import mock, patch
from opaque_keys.edx.keys import CourseKey
from testfixtures import LogCapture
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.core.tests.helpers import make_image_file
from course_discovery.apps.course_metadata.tests import toggle_switch
......@@ -28,7 +28,7 @@ from course_discovery.apps.publisher.tests import JSON_CONTENT_TYPE, factories
@ddt.ddt
class CourseRoleAssignmentViewTests(TestCase):
class CourseRoleAssignmentViewTests(SiteMixin, TestCase):
def setUp(self):
super(CourseRoleAssignmentViewTests, self).setUp()
......@@ -139,7 +139,7 @@ class CourseRoleAssignmentViewTests(TestCase):
self.assertEqual(len(mail.outbox), 1)
class OrganizationGroupUserViewTests(TestCase):
class OrganizationGroupUserViewTests(SiteMixin, TestCase):
def setUp(self):
super(OrganizationGroupUserViewTests, self).setUp()
......@@ -189,7 +189,7 @@ class OrganizationGroupUserViewTests(TestCase):
)
class UpdateCourseRunViewTests(TestCase):
class UpdateCourseRunViewTests(SiteMixin, TestCase):
def setUp(self):
super(UpdateCourseRunViewTests, self).setUp()
......@@ -313,7 +313,7 @@ class UpdateCourseRunViewTests(TestCase):
body = mail.outbox[0].body.strip()
self.assertIn(expected_body, body)
page_url = 'https://{host}{path}'.format(host=Site.objects.get_current().domain.strip('/'), path=object_path)
page_url = 'https://{host}{path}'.format(host=self.site.domain.strip('/'), path=object_path)
self.assertIn(page_url, body)
def test_update_preview_url(self):
......@@ -377,7 +377,7 @@ class UpdateCourseRunViewTests(TestCase):
self.assertEqual(len(mail.outbox), 0)
class CourseRevisionDetailViewTests(TestCase):
class CourseRevisionDetailViewTests(SiteMixin, TestCase):
def setUp(self):
super(CourseRevisionDetailViewTests, self).setUp()
......@@ -431,7 +431,7 @@ class CourseRevisionDetailViewTests(TestCase):
return self.client.get(path=course_revision_path)
class ChangeCourseStateViewTests(TestCase):
class ChangeCourseStateViewTests(SiteMixin, TestCase):
def setUp(self):
super(ChangeCourseStateViewTests, self).setUp()
......@@ -530,7 +530,7 @@ class ChangeCourseStateViewTests(TestCase):
body = mail.outbox[0].body.strip()
object_path = reverse('publisher:publisher_course_detail', kwargs={'pk': self.course.id})
page_url = 'https://{host}{path}'.format(host=Site.objects.get_current().domain.strip('/'), path=object_path)
page_url = 'https://{host}{path}'.format(host=self.site.domain.strip('/'), path=object_path)
self.assertIn(page_url, body)
def test_change_course_state_with_error(self):
......@@ -587,7 +587,7 @@ class ChangeCourseStateViewTests(TestCase):
self._assert_email_sent(course_team_user, subject)
class ChangeCourseRunStateViewTests(TestCase):
class ChangeCourseRunStateViewTests(SiteMixin, TestCase):
def setUp(self):
super(ChangeCourseRunStateViewTests, self).setUp()
......@@ -796,7 +796,7 @@ class ChangeCourseRunStateViewTests(TestCase):
self.assertIn('has been published', mail.outbox[0].body.strip())
class RevertCourseByRevisionTests(TestCase):
class RevertCourseByRevisionTests(SiteMixin, TestCase):
def setUp(self):
super(RevertCourseByRevisionTests, self).setUp()
......@@ -860,7 +860,7 @@ class RevertCourseByRevisionTests(TestCase):
return self.client.put(path=course_revision_path)
class CoursesAutoCompleteTests(TestCase):
class CoursesAutoCompleteTests(SiteMixin, TestCase):
""" Tests for course autocomplete."""
def setUp(self):
......@@ -927,7 +927,7 @@ class CoursesAutoCompleteTests(TestCase):
self.assertEqual(len(data['results']), expected_length)
class AcceptAllByRevisionTests(TestCase):
class AcceptAllByRevisionTests(SiteMixin, TestCase):
def setUp(self):
super(AcceptAllByRevisionTests, self).setUp()
......
......@@ -617,7 +617,7 @@ class CourseState(TimeStampedModel, ChangedByMixin):
# TODO: send email etc.
pass
def change_state(self, state, user):
def change_state(self, state, user, site=None):
"""
Change course workflow state and ownership also send emails if required.
"""
......@@ -632,12 +632,12 @@ class CourseState(TimeStampedModel, ChangedByMixin):
elif user_role.role == PublisherUserRole.CourseTeam:
self.change_owner_role(PublisherUserRole.MarketingReviewer)
if is_notifications_enabled:
emails.send_email_for_seo_review(self.course)
emails.send_email_for_seo_review(self.course, site)
self.review()
if is_notifications_enabled:
emails.send_email_for_send_for_review(self.course, user)
emails.send_email_for_send_for_review(self.course, user, site)
elif state == CourseStateChoices.Approved:
user_role = self.course.course_user_roles.get(user=user)
......@@ -646,7 +646,7 @@ class CourseState(TimeStampedModel, ChangedByMixin):
self.approved()
if is_notifications_enabled:
emails.send_email_for_mark_as_reviewed(self.course, user)
emails.send_email_for_mark_as_reviewed(self.course, user, site)
self.save()
......@@ -744,10 +744,10 @@ class CourseRunState(TimeStampedModel, ChangedByMixin):
pass
@transition(field=name, source=CourseRunStateChoices.Approved, target=CourseRunStateChoices.Published)
def published(self):
emails.send_course_run_published_email(self.course_run)
def published(self, site):
emails.send_course_run_published_email(self.course_run, site)
def change_state(self, state, user):
def change_state(self, state, user, site=None):
"""
Change course run workflow state and ownership also send emails if required.
"""
......@@ -763,7 +763,7 @@ class CourseRunState(TimeStampedModel, ChangedByMixin):
self.review()
if waffle.switch_is_active('enable_publisher_email_notifications'):
emails.send_email_for_send_for_review_course_run(self.course_run, user)
emails.send_email_for_send_for_review_course_run(self.course_run, user, site)
elif state == CourseRunStateChoices.Approved:
user_role = self.course_run.course.course_user_roles.get(user=user)
......@@ -772,11 +772,11 @@ class CourseRunState(TimeStampedModel, ChangedByMixin):
self.approved()
if waffle.switch_is_active('enable_publisher_email_notifications'):
emails.send_email_for_mark_as_reviewed_course_run(self.course_run, user)
emails.send_email_to_publisher(self.course_run, user)
emails.send_email_for_mark_as_reviewed_course_run(self.course_run, user, site)
emails.send_email_to_publisher(self.course_run, user, site)
elif state == CourseRunStateChoices.Published:
self.published()
self.published(site)
self.save()
......
......@@ -4,6 +4,7 @@ from django.test import TestCase
from django.urls import reverse
from guardian.shortcuts import get_group_perms
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory
from course_discovery.apps.publisher.choices import PublisherUserRole
......@@ -18,7 +19,7 @@ USER_PASSWORD = 'password'
# pylint: disable=no-member
class AdminTests(TestCase):
class AdminTests(SiteMixin, TestCase):
""" Tests Admin page."""
def setUp(self):
......@@ -81,7 +82,7 @@ class AdminTests(TestCase):
self.assertEqual(response.status_code, 200)
class OrganizationExtensionAdminTests(TestCase):
class OrganizationExtensionAdminTests(SiteMixin, TestCase):
""" Tests for OrganizationExtensionAdmin."""
def setUp(self):
......@@ -134,7 +135,7 @@ class OrganizationExtensionAdminTests(TestCase):
@ddt.ddt
class OrganizationUserRoleAdminTests(TestCase):
class OrganizationUserRoleAdminTests(SiteMixin, TestCase):
""" Tests for OrganizationUserRoleAdmin."""
def setUp(self):
......
......@@ -6,6 +6,7 @@ from django.urls import reverse
from django_fsm import TransitionNotAllowed
from guardian.shortcuts import assign_perm
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.core.tests.helpers import make_image_file
from course_discovery.apps.course_metadata.tests.factories import OrganizationFactory, PersonFactory
......@@ -510,7 +511,7 @@ class GroupOrganizationTests(TestCase):
@ddt.ddt
class CourseStateTests(TestCase):
class CourseStateTests(SiteMixin, TestCase):
""" Tests for the publisher `CourseState` model. """
@classmethod
......@@ -548,7 +549,7 @@ class CourseStateTests(TestCase):
"""
self.assertNotEqual(self.course_state.name, state)
self.course_state.change_state(state=state, user=self.user)
self.course_state.change_state(state=state, user=self.user, site=self.site)
self.assertEqual(self.course_state.name, state)
......@@ -561,7 +562,7 @@ class CourseStateTests(TestCase):
self.assertEqual(self.course_state.name, CourseStateChoices.Draft)
with self.assertRaises(TransitionNotAllowed):
self.course_state.change_state(state=CourseStateChoices.Review, user=self.user)
self.course_state.change_state(state=CourseStateChoices.Review, user=self.user, site=self.site)
def test_can_send_for_review(self):
"""
......@@ -644,7 +645,7 @@ class CourseStateTests(TestCase):
@ddt.ddt
class CourseRunStateTests(TestCase):
class CourseRunStateTests(SiteMixin, TestCase):
""" Tests for the publisher `CourseRunState` model. """
@classmethod
......@@ -703,7 +704,7 @@ class CourseRunStateTests(TestCase):
Verify that we can change course-run state according to workflow.
"""
self.assertNotEqual(self.course_run_state.name, state)
self.course_run_state.change_state(state=state, user=self.user)
self.course_run_state.change_state(state=state, user=self.user, site=self.site)
self.assertEqual(self.course_run_state.name, state)
def test_with_invalid_parent_course_state(self):
......
......@@ -394,14 +394,16 @@ class CourseEditView(mixins.PublisherPermissionMixin, UpdateView):
if latest_run and latest_run.course_run_state.name == CourseRunStateChoices.Published:
# If latest run of this course is published send an email to Publisher and don't change state.
send_email_for_published_course_run_editing(latest_run)
send_email_for_published_course_run_editing(latest_run, self.request.site)
else:
user_role = self.object.course_user_roles.get(user=user)
# Change course state to draft if marketing not yet reviewed or
# if marketing person updating the course.
if not self.object.course_state.marketing_reviewed or user_role.role == PublisherUserRole.MarketingReviewer:
if self.object.course_state.name != CourseStateChoices.Draft:
self.object.course_state.change_state(state=CourseStateChoices.Draft, user=user)
self.object.course_state.change_state(
state=CourseStateChoices.Draft, user=user, site=self.request.site
)
# Change ownership if user role not equal to owner role.
if self.object.course_state.owner_role != user_role.role:
......@@ -599,7 +601,7 @@ class CreateCourseRunView(mixins.LoginRequiredMixin, CreateView):
)
messages.success(request, success_msg)
emails.send_email_for_course_creation(parent_course, course_run)
emails.send_email_for_course_creation(parent_course, course_run, request.site)
return HttpResponseRedirect(reverse(self.success_url, kwargs={'pk': course_run.id}))
except Exception as error: # pylint: disable=broad-except
# pylint: disable=no-member
......@@ -740,10 +742,10 @@ class CourseRunEditView(mixins.LoginRequiredMixin, mixins.PublisherPermissionMix
course_run_state = course_run.course_run_state
if course_run_state.name not in immutable_states:
course_run_state.change_state(state=CourseStateChoices.Draft, user=user)
course_run_state.change_state(state=CourseStateChoices.Draft, user=user, site=request.site)
if course_run.lms_course_id and lms_course_id != course_run.lms_course_id:
emails.send_email_for_studio_instance_created(course_run)
emails.send_email_for_studio_instance_created(course_run, site=request.site)
# pylint: disable=no-member
messages.success(request, _('Course run updated successfully.'))
......@@ -757,7 +759,7 @@ class CourseRunEditView(mixins.LoginRequiredMixin, mixins.PublisherPermissionMix
course_run_state.change_owner_role(user_role)
if CourseRunStateChoices.Published == course_run_state.name:
send_email_for_published_course_run_editing(course_run)
send_email_for_published_course_run_editing(course_run, request.site)
return HttpResponseRedirect(reverse(self.success_url, kwargs={'pk': course_run.id}))
except Exception as e: # pylint: disable=broad-except
......
......@@ -3,6 +3,7 @@ import json
from django.test import TestCase
from rest_framework.reverse import reverse
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.publisher.tests import JSON_CONTENT_TYPE
from course_discovery.apps.publisher.tests.factories import CourseRunFactory
......@@ -11,7 +12,7 @@ from course_discovery.apps.publisher_comments.models import Comments
from course_discovery.apps.publisher_comments.tests.factories import CommentFactory
class PostCommentTests(TestCase):
class PostCommentTests(SiteMixin, TestCase):
def generate_data(self, obj):
"""Generate data for the form."""
......@@ -39,7 +40,7 @@ class PostCommentTests(TestCase):
self.assertEqual(comment.user_email, generated_data['email'])
class UpdateCommentTests(TestCase):
class UpdateCommentTests(SiteMixin, TestCase):
def setUp(self):
super(UpdateCommentTests, self).setUp()
......
from django.conf import settings
from django.contrib.sites.models import Site
from django.test import TestCase
from django.urls import reverse
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import USER_PASSWORD, UserFactory
from course_discovery.apps.publisher.tests import factories
from course_discovery.apps.publisher_comments.forms import CommentsAdminForm
from course_discovery.apps.publisher_comments.tests.factories import CommentFactory
class AdminTests(TestCase):
class AdminTests(SiteMixin, TestCase):
""" Tests Admin page and customize form."""
def setUp(self):
super(AdminTests, self).setUp()
self.user = UserFactory(is_staff=True, is_superuser=True)
self.client.login(username=self.user.username, password=USER_PASSWORD)
self.site = Site.objects.get(pk=settings.SITE_ID)
self.course = factories.CourseFactory()
self.comment = CommentFactory(content_object=self.course, user=self.user, site=self.site)
......
import ddt
import mock
from django.conf import settings
from django.contrib.sites.models import Site
from django.core import mail
from django.test import TestCase
from django.urls import reverse
from opaque_keys.edx.keys import CourseKey
from testfixtures import LogCapture
from course_discovery.apps.api.tests.mixins import SiteMixin
from course_discovery.apps.core.tests.factories import UserFactory
from course_discovery.apps.course_metadata.tests import toggle_switch
from course_discovery.apps.publisher.choices import PublisherUserRole
......@@ -20,7 +19,7 @@ from course_discovery.apps.publisher_comments.tests.factories import CommentFact
@ddt.ddt
class CommentsEmailTests(TestCase):
class CommentsEmailTests(SiteMixin, TestCase):
""" Tests for the e-mail functionality for course, course-run and seats. """
def setUp(self):
......@@ -30,8 +29,6 @@ class CommentsEmailTests(TestCase):
self.user_2 = UserFactory()
self.user_3 = UserFactory()
self.site = Site.objects.get(pk=settings.SITE_ID)
self.organization_extension = factories.OrganizationExtensionFactory()
self.seat = factories.SeatFactory()
......
......@@ -476,8 +476,6 @@ DISTINCT_COUNTS_QUERY_CACHE_WARMING_COUNT = 20
DEFAULT_PARTNER_ID = None
# See: https://docs.djangoproject.com/en/dev/ref/settings/#site-id
SITE_ID = 1
COMMENTS_APP = 'course_discovery.apps.publisher_comments'
TAGGIT_CASE_INSENSITIVE = True
......
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