feat: only enable verified name feature if Name Affirmation is installed

This commit is contained in:
Bianca Severino
2022-02-18 09:19:15 -05:00
parent 9fa7b8b704
commit 76f9756f92
14 changed files with 188 additions and 56 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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