feat: only enable verified name feature if Name Affirmation is installed
This commit is contained in:
@@ -18,7 +18,6 @@ from django.db.models import Count
|
||||
from django.dispatch import receiver
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from edx_name_affirmation.api import get_verified_name, should_use_verified_name_for_certs
|
||||
from model_utils import Choices
|
||||
from model_utils.models import TimeStampedModel
|
||||
from opaque_keys.edx.django.models import CourseKeyField
|
||||
@@ -33,6 +32,7 @@ from lms.djangoapps.certificates.data import CertificateStatuses
|
||||
from lms.djangoapps.instructor_task.models import InstructorTask
|
||||
from openedx.core.djangoapps.signals.signals import COURSE_CERT_AWARDED, COURSE_CERT_CHANGED, COURSE_CERT_REVOKED
|
||||
from openedx.core.djangoapps.xmodule_django.models import NoneToEmptyManager
|
||||
from openedx.features.name_affirmation_api.utils import get_name_affirmation_service
|
||||
|
||||
from openedx_events.learning.data import CourseData, UserData, UserPersonalData, CertificateData # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from openedx_events.learning.signals import CERTIFICATE_CHANGED, CERTIFICATE_CREATED, CERTIFICATE_REVOKED # lint-amnesty, pylint: disable=wrong-import-order
|
||||
@@ -435,9 +435,10 @@ class GeneratedCertificate(models.Model):
|
||||
a circular dependency.
|
||||
"""
|
||||
name_to_use = student_api.get_name(user.id)
|
||||
name_affirmation_service = get_name_affirmation_service()
|
||||
|
||||
if should_use_verified_name_for_certs(user):
|
||||
verified_name_obj = get_verified_name(user, is_verified=True)
|
||||
if name_affirmation_service and name_affirmation_service.should_use_verified_name_for_certs(user):
|
||||
verified_name_obj = name_affirmation_service.get_verified_name(user, is_verified=True)
|
||||
if verified_name_obj:
|
||||
name_to_use = verified_name_obj.verified_name
|
||||
|
||||
|
||||
@@ -3,10 +3,7 @@ Tests for certificate generation
|
||||
"""
|
||||
import ddt
|
||||
import logging # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from unittest import mock # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
from edx_name_affirmation.api import create_verified_name, create_verified_name_config
|
||||
from edx_name_affirmation.statuses import VerifiedNameStatus
|
||||
from unittest import mock, skipUnless # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
from common.djangoapps.course_modes.models import CourseMode
|
||||
from common.djangoapps.student.models import UserProfile
|
||||
@@ -16,12 +13,14 @@ from lms.djangoapps.certificates.data import CertificateStatuses
|
||||
from lms.djangoapps.certificates.generation import generate_course_certificate
|
||||
from lms.djangoapps.certificates.models import GeneratedCertificate
|
||||
from lms.djangoapps.certificates.tests.factories import GeneratedCertificateFactory
|
||||
from openedx.features.name_affirmation_api.utils import get_name_affirmation_service
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
PROFILE_NAME_METHOD = 'common.djangoapps.student.models_api.get_name'
|
||||
name_affirmation_service = get_name_affirmation_service()
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -193,9 +192,10 @@ class CertificateTests(EventTestMixin, ModuleStoreTestCase):
|
||||
assert cert.grade == self.grade
|
||||
assert cert.name == ''
|
||||
|
||||
@ddt.data((True, VerifiedNameStatus.APPROVED),
|
||||
(True, VerifiedNameStatus.DENIED),
|
||||
(False, VerifiedNameStatus.PENDING))
|
||||
@skipUnless(name_affirmation_service is not None, 'Requires Name Affirmation')
|
||||
@ddt.data((True, 'approved'),
|
||||
(True, 'denied'),
|
||||
(False, 'pending'))
|
||||
@ddt.unpack
|
||||
def test_generation_verified_name(self, should_use_verified_name_for_certs, status):
|
||||
"""
|
||||
@@ -204,8 +204,11 @@ class CertificateTests(EventTestMixin, ModuleStoreTestCase):
|
||||
their profile name.
|
||||
"""
|
||||
verified_name = 'Jonathan Doe'
|
||||
create_verified_name(self.u, verified_name, self.name, status=status)
|
||||
create_verified_name_config(self.u, use_verified_name_for_certs=should_use_verified_name_for_certs)
|
||||
name_affirmation_service.create_verified_name(self.u, verified_name, self.name, status=status)
|
||||
name_affirmation_service.create_verified_name_config(
|
||||
self.u,
|
||||
use_verified_name_for_certs=should_use_verified_name_for_certs
|
||||
)
|
||||
|
||||
GeneratedCertificateFactory(
|
||||
user=self.u,
|
||||
@@ -220,7 +223,7 @@ class CertificateTests(EventTestMixin, ModuleStoreTestCase):
|
||||
|
||||
cert = GeneratedCertificate.objects.get(user=self.u, course_id=self.key)
|
||||
|
||||
if should_use_verified_name_for_certs and status == VerifiedNameStatus.APPROVED:
|
||||
if should_use_verified_name_for_certs and status == 'approved':
|
||||
assert cert.name == verified_name
|
||||
else:
|
||||
assert cert.name == self.name
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import json
|
||||
from unittest.mock import patch
|
||||
from unittest import mock
|
||||
from unittest import mock, skipUnless
|
||||
|
||||
import ddt
|
||||
import pytest
|
||||
@@ -12,8 +12,6 @@ from django.core.exceptions import ValidationError
|
||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||
from django.test import TestCase
|
||||
from django.test.utils import override_settings
|
||||
from edx_name_affirmation.api import create_verified_name, create_verified_name_config
|
||||
from edx_name_affirmation.statuses import VerifiedNameStatus
|
||||
from opaque_keys.edx.locator import CourseKey, CourseLocator
|
||||
from openedx_events.tests.utils import OpenEdxEventsTestMixin
|
||||
from path import Path as path
|
||||
@@ -39,6 +37,7 @@ from lms.djangoapps.certificates.tests.factories import (
|
||||
)
|
||||
from lms.djangoapps.instructor_task.tests.factories import InstructorTaskFactory
|
||||
from openedx.core.djangoapps.content.course_overviews.tests.factories import CourseOverviewFactory
|
||||
from openedx.features.name_affirmation_api.utils import get_name_affirmation_service
|
||||
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
@@ -53,6 +52,8 @@ TEST_DATA_DIR = 'common/test/data/'
|
||||
PLATFORM_ROOT = TEST_DIR.parent.parent.parent.parent
|
||||
TEST_DATA_ROOT = PLATFORM_ROOT / TEST_DATA_DIR
|
||||
|
||||
name_affirmation_service = get_name_affirmation_service()
|
||||
|
||||
|
||||
class ExampleCertificateTest(TestCase, OpenEdxEventsTestMixin):
|
||||
"""Tests for the ExampleCertificate model. """
|
||||
@@ -624,9 +625,10 @@ class GeneratedCertificateTest(SharedModuleStoreTestCase, OpenEdxEventsTestMixin
|
||||
|
||||
self._assert_event_data(mock_emit_certificate_event, expected_event_data)
|
||||
|
||||
@ddt.data((True, VerifiedNameStatus.APPROVED),
|
||||
(True, VerifiedNameStatus.DENIED),
|
||||
(False, VerifiedNameStatus.PENDING))
|
||||
@skipUnless(name_affirmation_service is not None, 'Requires Name Affirmation')
|
||||
@ddt.data((True, 'approved'),
|
||||
(True, 'denied'),
|
||||
(False, 'pending'))
|
||||
@ddt.unpack
|
||||
def test_invalidate_with_verified_name(self, should_use_verified_name_for_certs, status):
|
||||
"""
|
||||
@@ -634,8 +636,11 @@ class GeneratedCertificateTest(SharedModuleStoreTestCase, OpenEdxEventsTestMixin
|
||||
"""
|
||||
verified_name = 'Jonathan Doe'
|
||||
profile = UserProfile.objects.get(user=self.user)
|
||||
create_verified_name(self.user, verified_name, profile.name, status=status)
|
||||
create_verified_name_config(self.user, use_verified_name_for_certs=should_use_verified_name_for_certs)
|
||||
name_affirmation_service.create_verified_name(self.user, verified_name, profile.name, status=status)
|
||||
name_affirmation_service.create_verified_name_config(
|
||||
self.user,
|
||||
use_verified_name_for_certs=should_use_verified_name_for_certs
|
||||
)
|
||||
|
||||
cert = GeneratedCertificateFactory.create(
|
||||
status=CertificateStatuses.downloadable,
|
||||
@@ -649,7 +654,7 @@ class GeneratedCertificateTest(SharedModuleStoreTestCase, OpenEdxEventsTestMixin
|
||||
cert.invalidate(mode=mode, source=source)
|
||||
|
||||
cert = GeneratedCertificate.objects.get(user=self.user, course_id=self.course_key)
|
||||
if should_use_verified_name_for_certs and status == VerifiedNameStatus.APPROVED:
|
||||
if should_use_verified_name_for_certs and status == 'approved':
|
||||
assert cert.name == verified_name
|
||||
else:
|
||||
assert cert.name == profile.name
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
import datetime
|
||||
from unittest import skipUnless
|
||||
from unittest.mock import patch
|
||||
from urllib.parse import urlencode
|
||||
from uuid import uuid4
|
||||
@@ -11,8 +12,6 @@ from django.conf import settings
|
||||
from django.test.client import Client, RequestFactory
|
||||
from django.test.utils import override_settings
|
||||
from django.urls import reverse
|
||||
from edx_name_affirmation.api import create_verified_name, create_verified_name_config
|
||||
from edx_name_affirmation.statuses import VerifiedNameStatus
|
||||
from edx_toggles.toggles.testutils import override_waffle_switch
|
||||
from organizations import api as organizations_api
|
||||
|
||||
@@ -51,6 +50,7 @@ from openedx.core.djangoapps.site_configuration.tests.test_util import (
|
||||
from openedx.core.djangolib.js_utils import js_escaped_string
|
||||
from openedx.core.djangolib.testing.utils import CacheIsolationTestCase
|
||||
from openedx.core.lib.tests.assertions.events import assert_event_matches
|
||||
from openedx.features.name_affirmation_api.utils import get_name_affirmation_service
|
||||
from xmodule.data import CertificatesDisplayBehaviors # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
|
||||
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
|
||||
@@ -66,6 +66,8 @@ FEATURES_WITH_CERTS_DISABLED['CERTIFICATES_HTML_VIEW'] = False
|
||||
FEATURES_WITH_CUSTOM_CERTS_ENABLED = FEATURES_WITH_CERTS_ENABLED.copy()
|
||||
FEATURES_WITH_CUSTOM_CERTS_ENABLED['CUSTOM_CERTIFICATE_TEMPLATES_ENABLED'] = True
|
||||
|
||||
name_affirmation_service = get_name_affirmation_service()
|
||||
|
||||
|
||||
class CommonCertificatesTestCase(ModuleStoreTestCase):
|
||||
"""
|
||||
@@ -1613,10 +1615,11 @@ class CertificatesViewsTests(CommonCertificatesTestCase, CacheIsolationTestCase)
|
||||
)
|
||||
)
|
||||
|
||||
@skipUnless(name_affirmation_service is not None, 'Requires Name Affirmation')
|
||||
@override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED)
|
||||
@ddt.data((True, VerifiedNameStatus.APPROVED),
|
||||
(True, VerifiedNameStatus.DENIED),
|
||||
(False, VerifiedNameStatus.PENDING))
|
||||
@ddt.data((True, 'approved'),
|
||||
(True, 'denied'),
|
||||
(False, 'pending'))
|
||||
@ddt.unpack
|
||||
def test_certificate_view_verified_name(self, should_use_verified_name_for_certs, status):
|
||||
"""
|
||||
@@ -1624,8 +1627,16 @@ class CertificatesViewsTests(CommonCertificatesTestCase, CacheIsolationTestCase)
|
||||
their verified name will appear on the certificate rather than their profile name.
|
||||
"""
|
||||
verified_name = 'Jonathan Doe'
|
||||
create_verified_name(self.user, verified_name, self.user.profile.name, status=status)
|
||||
create_verified_name_config(self.user, use_verified_name_for_certs=should_use_verified_name_for_certs)
|
||||
name_affirmation_service.create_verified_name(
|
||||
self.user,
|
||||
verified_name,
|
||||
self.user.profile.name,
|
||||
status=status
|
||||
)
|
||||
name_affirmation_service.create_verified_name_config(
|
||||
self.user,
|
||||
use_verified_name_for_certs=should_use_verified_name_for_certs
|
||||
)
|
||||
|
||||
self._add_course_certificates(count=1, signatory_count=1)
|
||||
test_url = get_certificate_url(
|
||||
@@ -1635,7 +1646,7 @@ class CertificatesViewsTests(CommonCertificatesTestCase, CacheIsolationTestCase)
|
||||
)
|
||||
|
||||
response = self.client.get(test_url, HTTP_HOST='test.localhost')
|
||||
if should_use_verified_name_for_certs and status == VerifiedNameStatus.APPROVED:
|
||||
if should_use_verified_name_for_certs and status == 'approved':
|
||||
self.assertContains(response, verified_name)
|
||||
self.assertNotContains(response, self.user.profile.name)
|
||||
else:
|
||||
|
||||
@@ -4,8 +4,6 @@ Certificates utilities
|
||||
from datetime import datetime
|
||||
import logging
|
||||
|
||||
from edx_name_affirmation.api import get_verified_name, should_use_verified_name_for_certs
|
||||
|
||||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
from eventtracking import tracker
|
||||
@@ -16,6 +14,7 @@ from common.djangoapps.student import models_api as student_api
|
||||
from lms.djangoapps.certificates.data import CertificateStatuses
|
||||
from lms.djangoapps.certificates.models import GeneratedCertificate
|
||||
from openedx.core.djangoapps.content.course_overviews.api import get_course_overview_or_none
|
||||
from openedx.features.name_affirmation_api.utils import get_name_affirmation_service
|
||||
from xmodule.data import CertificatesDisplayBehaviors # lint-amnesty, pylint: disable=wrong-import-order
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -240,9 +239,10 @@ def get_preferred_certificate_name(user):
|
||||
name, or an empty string if it doesn't exist.
|
||||
"""
|
||||
name_to_use = student_api.get_name(user.id)
|
||||
name_affirmation_service = get_name_affirmation_service()
|
||||
|
||||
if should_use_verified_name_for_certs(user):
|
||||
verified_name_obj = get_verified_name(user, is_verified=True)
|
||||
if name_affirmation_service and name_affirmation_service.should_use_verified_name_for_certs(user):
|
||||
verified_name_obj = name_affirmation_service.get_verified_name(user, is_verified=True)
|
||||
if verified_name_obj:
|
||||
name_to_use = verified_name_obj.verified_name
|
||||
|
||||
|
||||
Reference in New Issue
Block a user