Exemplo n.º 1
0
 def test_get_filter_options_with_invalid_field_throws_exception(
         self) -> None:
     model_class = app_feedback_report_models.AppFeedbackReportModel
     invalid_filter = python_utils.create_enum('invalid_field') # type: ignore[no-untyped-call]
     with self.assertRaisesRegexp( # type: ignore[no-untyped-call]
         utils.InvalidInputException,
         'The field %s is not a valid field to filter reports on' % (
             invalid_filter.invalid_field.name)
     ):
         with self.swap(
             model_class, 'query',
             self._mock_query_filters_returns_empy_list):
             model_class.get_filter_options_for_field(
                 invalid_filter.invalid_field)
Exemplo n.º 2
0
from __future__ import absolute_import
from __future__ import unicode_literals

import inspect

from constants import constants
import feconf
import python_utils

# Valid model names.
NAMES = python_utils.create_enum(
    'activity', 'app_feedback_report', 'audit', 'base_model', 'beam_job',
    'blog', 'classifier', 'collection', 'config', 'email', 'exploration',
    'feedback', 'improvements', 'job', 'opportunity', 'question',
    'recommendations', 'skill', 'statistics', 'activity', 'audit', 'auth',
    'base_model', 'classifier', 'collection', 'config', 'email', 'exploration',
    'feedback', 'improvements', 'job', 'opportunity', 'question',
    'recommendations', 'skill', 'statistics', 'story', 'subtopic',
    'suggestion', 'topic', 'translation', 'user')

# Types of deletion policies. The pragma comment is needed because Enums are
# evaluated as classes in Python and they should use PascalCase, but using
# UPPER_CASE seems more appropriate here.
MODULES_WITH_PSEUDONYMIZABLE_CLASSES = (  # pylint: disable=invalid-name
    NAMES.app_feedback_report, NAMES.blog, NAMES.collection, NAMES.config,
    NAMES.exploration, NAMES.feedback, NAMES.question, NAMES.skill,
    NAMES.story, NAMES.subtopic, NAMES.suggestion, NAMES.topic)

GAE_PLATFORM = 'gae'
Exemplo n.º 3
0
BeamJobState = python_utils.create_enum(  # pylint: disable=invalid-name
    # The job is currently running.
    'RUNNING',
    # The job has been created but is not yet running. Jobs that are pending may
    # only transition to RUNNING, or FAILED.
    'PENDING',
    # The job has not yet started to run.
    'STOPPED',
    # The job has has been explicitly cancelled and is in the process of
    # stopping. Jobs that are cancelling may only transition to CANCELLED or
    # FAILED.
    'CANCELLING',
    # The job has has been explicitly cancelled. This is a terminal job state.
    # This state may only be set via a Cloud Dataflow jobs.update call, and only
    # if the job has not yet reached another terminal state.
    'CANCELLED',
    # The job is in the process of draining. A draining job has stopped pulling
    # from its input sources and is processing any data that remains in-flight.
    # This state may be set via a Cloud Dataflow jobs.update call, but only as a
    # transition from RUNNING. Jobs that are draining may only transition to
    # DRAINED, CANCELLED, or FAILED.
    'DRAINING',
    # The job has been drained. A drained job terminated by stopping pulling
    # from its input sources and processing any data that remained in-flight
    # when draining was requested. This state is a terminal state, may only be
    # set by the Cloud Dataflow service, and only as a transition from DRAINING.
    'DRAINED',
    # The job was successfully updated, meaning that this job was stopped and
    # another job was started, inheriting state from this one. This is a
    # terminal job state. This state may only be set by the Cloud Dataflow
    # service, and only as a transition from RUNNING.
    'UPDATED',
    # The job has successfully completed. This is a terminal job state. This
    # state may be set by the Cloud Dataflow service, as a transition from
    # RUNNING. It may also be set via a Cloud Dataflow jobs.update call, if the
    # job has not yet reached a terminal state.
    'DONE',
    # The job has has failed. This is a terminal job state. This state may only
    # be set by the Cloud Dataflow service, and only as a transition from
    # RUNNING.
    'FAILED',
    # The job's run state isn't specified.
    'UNKNOWN')
# limitations under the License.
"""Unit tests for platform_feature_services.py."""

from __future__ import absolute_import
from __future__ import unicode_literals

from constants import constants
from core.domain import caching_services
from core.domain import platform_feature_services as feature_services
from core.domain import platform_parameter_domain
from core.domain import platform_parameter_registry as registry
from core.tests import test_utils
import python_utils
import utils

PARAM_NAMES = python_utils.create_enum('feature_a', 'feature_b')  # pylint: disable=invalid-name
SERVER_MODES = platform_parameter_domain.SERVER_MODES
FEATURE_STAGES = platform_parameter_domain.FEATURE_STAGES


class PlatformFeatureServiceTest(test_utils.GenericTestBase):
    """Test for the platform feature services."""
    def setUp(self):
        super(PlatformFeatureServiceTest, self).setUp()

        self.signup(self.OWNER_EMAIL, self.OWNER_USERNAME)
        self.user_id = self.get_user_id_from_email(self.OWNER_EMAIL)

        registry.Registry.parameter_registry.clear()
        # Parameter names that might be used in following tests.
        param_names = ['feature_a', 'feature_b']
Exemplo n.º 5
0
UNTICKETED_ANDROID_REPORTS_STATS_TICKET_ID = (
    app_feedback_report_models.UNTICKETED_ANDROID_REPORTS_STATS_TICKET_ID)

MAXIMUM_TICKET_NAME_LENGTH = 100
MINIMUM_ANDROID_SDK_VERSION = 2
# Timezone offsets in hours, corresponding to the range of timezone difference
# from GMT.
TIMEZONE_MINIMUM_OFFSET = -12
TIMEZONE_MAXIMUM_OFFSET = 14
REPORT_ID_DELIMITER = '.'
TICKET_ID_DELIMITER = '.'
STATS_ID_DELIMITER = ':'
ANDROID_VERSION_NAME_DELIMITER = '-'

# Ignoring the untyped call error because python_utils is untyped.
REPORT_TYPE = python_utils.create_enum(
    'suggestion', 'issue', 'crash')  # type: ignore[no-untyped-call]
CATEGORY = python_utils.create_enum(  # type: ignore[no-untyped-call]
    'feature_suggestion', 'language_suggestion', 'other_suggestion',
    'lesson_question_issue', 'language_general_issue', 'language_audio_issue',
    'language_text_issue', 'topics_issue', 'profile_issue', 'other_issue',
    'lesson_player_crash', 'practice_questions_crash', 'options_page_crash',
    'profile_page_crash', 'other_crash')
ENTRY_POINT = python_utils.create_enum(  # type: ignore[no-untyped-call]
    'navigation_drawer', 'lesson_player', 'revision_card', 'crash')
STATS_PARAMETER_NAMES = python_utils.create_enum(  # type: ignore[no-untyped-call]
    'platform', 'report_type', 'country_locale_code', 'entry_point_name',
    'text_language_code', 'audio_language_code', 'android_sdk_version',
    'version_name')
ANDROID_TEXT_SIZE = python_utils.create_enum(  # type: ignore[no-untyped-call]
    'text_size_unspecified', 'small_text_size', 'medium_text_size',
    'large_text_size', 'extra_large_text_size')
Exemplo n.º 6
0
 def test_enum_for_invalid_attribute(self):
     enums = python_utils.create_enum('first', 'second', 'third')
     with self.assertRaisesRegexp(AttributeError, 'fourth'):
         getattr(enums, 'fourth')
Exemplo n.º 7
0
 def test_create_enum_method_and_check_its_names(self):
     """Test create_enum method."""
     enums = python_utils.create_enum('first', 'second', 'third')
     self.assertEqual(enums.first.name, 'first')
     self.assertEqual(enums.second.name, 'second')
     self.assertEqual(enums.third.name, 'third')
Exemplo n.º 8
0
 def test_create_platform_parameter_with_invalid_type_failure(self):
     _data_type = python_utils.create_enum('invalid')
     with self.assertRaisesRegexp(Exception,
                                  'Unsupported data type \'invalid\''):
         registry.Registry.create_platform_parameter(
             PARAM_NAMES.parameter_a, 'test', _data_type.invalid)
Exemplo n.º 9
0
from __future__ import unicode_literals  # pylint: disable=import-only-modules

from core.domain import caching_services
from core.domain import platform_parameter_domain as parameter_domain
from core.domain import platform_parameter_registry as registry
from core.platform import models
from core.tests import test_utils
import feconf
import python_utils
import utils

(config_models, ) = models.Registry.import_models([models.NAMES.config])

DATA_TYPES = parameter_domain.DATA_TYPES  # pylint: disable=invalid-name
FEATURE_STAGES = parameter_domain.FEATURE_STAGES  # pylint: disable=invalid-name
PARAM_NAMES = python_utils.create_enum('parameter_a')  # pylint: disable=invalid-name


class PlatformParameterRegistryTests(test_utils.GenericTestBase):
    """Tests for the platform parameter Registry."""
    def setUp(self):
        super(PlatformParameterRegistryTests, self).setUp()

        self.original_param_registry = registry.Registry.parameter_registry
        registry.Registry.parameter_registry.clear()

        # Parameter names that might be used in following tests.
        parameter_names = ('parameter_a', 'parameter_b')
        caching_services.delete_multi(
            caching_services.CACHE_NAMESPACE_PLATFORM_PARAMETER, None,
            parameter_names)
Exemplo n.º 10
0
# limitations under the License.
"""Domain objects for platform parameters."""

from __future__ import absolute_import
from __future__ import unicode_literals

import json
import re

from constants import constants
from core.domain import change_domain
import feconf
import python_utils
import utils

SERVER_MODES = python_utils.create_enum('dev', 'test', 'prod')  # pylint: disable=invalid-name
FEATURE_STAGES = SERVER_MODES  # pylint: disable=invalid-name
DATA_TYPES = python_utils.create_enum('bool', 'string', 'number')  # pylint: disable=invalid-name

ALLOWED_SERVER_MODES = [SERVER_MODES.dev, SERVER_MODES.test, SERVER_MODES.prod]
ALLOWED_FEATURE_STAGES = [
    FEATURE_STAGES.dev, FEATURE_STAGES.test, FEATURE_STAGES.prod
]
ALLOWED_PLATFORM_TYPES = constants.PLATFORM_PARAMETER_ALLOWED_PLATFORM_TYPES
ALLOWED_BROWSER_TYPES = constants.PLATFORM_PARAMETER_ALLOWED_BROWSER_TYPES
ALLOWED_APP_VERSION_FLAVORS = (
    constants.PLATFORM_PARAMETER_ALLOWED_APP_VERSION_FLAVORS)

APP_VERSION_WITH_HASH_REGEXP = re.compile(
    constants.PLATFORM_PARAMETER_APP_VERSION_WITH_HASH_REGEXP)
APP_VERSION_WITHOUT_HASH_REGEXP = re.compile(
Exemplo n.º 11
0
from core.platform import models
import feconf
from jobs import job_utils
from jobs.decorators import validation_decorators
from jobs.types import base_validation_errors
import python_utils

import apache_beam as beam

(base_models, exp_models) = models.Registry.import_models(
    [models.NAMES.base_model, models.NAMES.exploration])

BASE_MODEL_ID_PATTERN = r'^[A-Za-z0-9-_]{1,%s}$' % base_models.ID_LENGTH
MAX_CLOCK_SKEW_SECS = datetime.timedelta(seconds=1)

VALIDATION_MODES = python_utils.create_enum('neutral', 'strict', 'non_strict')  # pylint: disable=invalid-name


class ValidateDeletedModel(beam.DoFn):
    """DoFn to check whether models marked for deletion are stale.

    Doesn't use the AuditsExisting decorator because it audits deleted models,
    not existing ones.
    """
    def process(self, input_model):
        """Yields audit errors that are discovered in the input model.

        Args:
            input_model: datastore_services.Model. Entity to validate.

        Yields:
Exemplo n.º 12
0
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Definition of platform parameters."""

from __future__ import absolute_import  # pylint: disable=import-only-modules
from __future__ import unicode_literals  # pylint: disable=import-only-modules

from core.domain import platform_parameter_domain
from core.domain import platform_parameter_registry as registry
import python_utils

Registry = registry.Registry
FEATURE_STAGES = platform_parameter_domain.FEATURE_STAGES  # pylint: disable=invalid-name
DATA_TYPES = platform_parameter_domain.DATA_TYPES  # pylint: disable=invalid-name

PARAM_NAMES = python_utils.create_enum(  # pylint: disable=invalid-name
    'dummy_feature', 'dummy_parameter')

# Platform parameters should all be defined below.

Registry.create_feature_flag(
    PARAM_NAMES.dummy_feature,
    'This is a dummy feature flag.',
    FEATURE_STAGES.dev,
)

Registry.create_platform_parameter(PARAM_NAMES.dummy_parameter,
                                   'This is a dummy platform parameter.',
                                   DATA_TYPES.string)
Exemplo n.º 13
0
    from mypy_imports import datastore_services

(base_models, ) = models.Registry.import_models([models.NAMES.base_model])

datastore_services = models.Registry.import_datastore_services()

PLATFORM_CHOICE_ANDROID = 'android'
PLATFORM_CHOICE_WEB = 'web'
PLATFORM_CHOICES = [PLATFORM_CHOICE_ANDROID, PLATFORM_CHOICE_WEB]
GITHUB_REPO_CHOICES = PLATFORM_CHOICES

# The model field names that can be filtered / sorted for when maintainers
# triage feedback reports.
FILTER_FIELD_NAMES = python_utils.create_enum(  # type: ignore[no-untyped-call]
    'platform', 'report_type', 'entry_point', 'submitted_on',
    'android_device_model', 'android_sdk_version', 'text_language_code',
    'audio_language_code', 'platform_version',
    'android_device_country_locale_code')

# An ID used for stats model entities tracking all unticketed reports.
UNTICKETED_ANDROID_REPORTS_STATS_TICKET_ID = (
    'unticketed_android_reports_stats_ticket_id')


class AppFeedbackReportModel(base_models.BaseModel):
    """Model for storing feedback reports sent from learners.

    Instances of this model contain information about learner's device and Oppia
    app settings, as well as information provided by the user in the feedback
    report.