Example #1
0
    def test_that_subsidiary_models_are_created_when_new_model_is_saved(
            self) -> None:
        """Tests the _trusted_commit() method."""

        # SubtopicPage is created but not committed/saved.
        subtopic_page = subtopic_models.SubtopicPageModel(
            id=self.SUBTOPIC_PAGE_ID,
            topic_id='topic_id',
            page_contents={},
            page_contents_schema_version=(
                feconf.CURRENT_SUBTOPIC_PAGE_CONTENTS_SCHEMA_VERSION),
            language_code='en')
        # We check that subtopic page has not been saved before calling
        # commit().
        self.assertIsNone(
            subtopic_models.SubtopicPageModel.get(
                entity_id=self.SUBTOPIC_PAGE_ID, strict=False))
        # We call commit() expecting that _trusted_commit works fine
        # and saves subtopic page to datastore.
        subtopic_page.commit(committer_id=feconf.SYSTEM_COMMITTER_ID,
                             commit_message='Created new topic',
                             commit_cmds=[{
                                 'cmd': topic_domain.CMD_CREATE_NEW
                             }])
        # Now we check that subtopic page is not None and that actually
        # now subtopic page exists, that means that commit() worked fine.
        self.assertIsNotNone(
            subtopic_models.SubtopicPageModel.get(
                entity_id=self.SUBTOPIC_PAGE_ID, strict=False))
Example #2
0
def save_subtopic_page(committer_id: str,
                       subtopic_page: subtopic_page_domain.SubtopicPage,
                       commit_message: str,
                       change_list: List[change_domain.BaseChange]) -> None:
    """Validates a subtopic page and commits it to persistent storage. If
    successful, increments the version number of the incoming subtopic page
    domain object by 1.

    Args:
        committer_id: str. ID of the given committer.
        subtopic_page: SubtopicPage. The subtopic page domain object to be
            saved.
        commit_message: str. The commit message.
        change_list: list(SubtopicPageChange). List of changes applied to a
            subtopic page.

    Raises:
        Exception. Received invalid change list.
        Exception. The subtopic page model and the incoming subtopic page domain
            object have different version numbers.
    """
    if not change_list:
        raise Exception(
            'Unexpected error: received an invalid change list when trying to '
            'save topic %s: %s' % (subtopic_page.id, change_list))
    subtopic_page.validate()  # type: ignore[no-untyped-call]

    subtopic_page_model = subtopic_models.SubtopicPageModel.get(
        subtopic_page.id, strict=False)
    if subtopic_page_model is None:
        subtopic_page_model = subtopic_models.SubtopicPageModel(
            id=subtopic_page.id)
    else:
        if subtopic_page.version > subtopic_page_model.version:
            raise Exception(
                'Unexpected error: trying to update version %s of topic '
                'from version %s. Please reload the page and try again.' %
                (subtopic_page_model.version, subtopic_page.version))

        if subtopic_page.version < subtopic_page_model.version:
            raise Exception(
                'Trying to update version %s of topic from version %s, '
                'which is too old. Please reload the page and try again.' %
                (subtopic_page_model.version, subtopic_page.version))

    subtopic_page_model.topic_id = subtopic_page.topic_id
    subtopic_page_model.page_contents = subtopic_page.page_contents.to_dict()
    subtopic_page_model.language_code = subtopic_page.language_code
    subtopic_page_model.page_contents_schema_version = (
        subtopic_page.page_contents_schema_version)
    change_dicts = [change.to_dict() for change in change_list]
    subtopic_page_model.commit(committer_id, commit_message, change_dicts)
    subtopic_page.version += 1
    def test_migrate_page_contents_from_v2_to_v3_schema(self) -> None:
        current_schema_version_swap = self.swap(
            feconf, 'CURRENT_SUBTOPIC_PAGE_CONTENTS_SCHEMA_VERSION', 3)
        html_content = ('<oppia-noninteractive-svgdiagram '
                        'svg_filename-with-value="&quot;img1.svg&quot;"'
                        ' alt-with-value="&quot;Image&quot;">'
                        '</oppia-noninteractive-svgdiagram>')
        expected_html_content = (
            '<oppia-noninteractive-image alt-with-value=\'\"Image\"\''
            ' caption-with-value="&amp;quot;&amp;quot;" '
            'filepath-with-value=\'\"img1.svg\"\'>'
            '</oppia-noninteractive-image>')
        written_translations_dict = {
            'translations_mapping': {
                'content1': {
                    'en': {
                        'data_format': 'html',
                        'translation': html_content,
                        'needs_update': True
                    },
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Hey!',
                        'needs_update': False
                    }
                },
                'feedback_1': {
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Testing!',
                        'needs_update': False
                    },
                    'en': {
                        'data_format': 'html',
                        'translation': 'hello!',
                        'needs_update': False
                    }
                }
            }
        }
        written_translations_dict_math = {
            'translations_mapping': {
                'content1': {
                    'en': {
                        'data_format': 'html',
                        'translation': expected_html_content,
                        'needs_update': True
                    },
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Hey!',
                        'needs_update': False
                    }
                },
                'feedback_1': {
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Testing!',
                        'needs_update': False
                    },
                    'en': {
                        'data_format': 'html',
                        'translation': 'hello!',
                        'needs_update': False
                    }
                }
            }
        }
        recorded_voiceovers = {
            'voiceovers_mapping': {
                'content': {
                    'en': {
                        'filename': 'test.mp3',
                        'file_size_bytes': 100,
                        'needs_update': False,
                        'duration_secs': 7.213
                    }
                }
            }
        }
        page_contents_dict = {
            'subtitled_html': {
                'content_id': 'content',
                'html': html_content
            },
            'recorded_voiceovers': recorded_voiceovers,
            'written_translations': written_translations_dict
        }
        expected_page_contents_dict = {
            'subtitled_html': {
                'content_id': 'content',
                'html': expected_html_content
            },
            'recorded_voiceovers': recorded_voiceovers,
            'written_translations': written_translations_dict_math
        }

        subtopic_page_id = subtopic_models.SubtopicPageModel.get_new_id('')
        subtopic_page_model = subtopic_models.SubtopicPageModel(
            id=subtopic_page_id,
            topic_id=self.TOPIC_ID,
            page_contents=page_contents_dict,
            page_contents_schema_version=2,
            language_code='en')
        self.assertEqual(subtopic_page_model.page_contents_schema_version, 2)

        with current_schema_version_swap:
            subtopic_page = subtopic_page_services.get_subtopic_page_from_model(
                subtopic_page_model)

        self.assertEqual(subtopic_page.page_contents_schema_version, 3)
        self.assertEqual(subtopic_page.page_contents.to_dict(),
                         expected_page_contents_dict)
    def test_migrate_page_contents_from_v3_to_v4_schema(self) -> None:
        current_schema_version_swap = self.swap(
            feconf, 'CURRENT_SUBTOPIC_PAGE_CONTENTS_SCHEMA_VERSION', 4)
        expected_html_content = ('<p>1 × 3 😕 😊</p>')
        html_content = ('<p>1 × 3 😕 😊</p>')
        written_translations_dict = {
            'translations_mapping': {
                'content1': {
                    'en': {
                        'data_format': 'html',
                        'translation': html_content,
                        'needs_update': True
                    },
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Hey!',
                        'needs_update': False
                    }
                },
                'feedback_1': {
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Testing!',
                        'needs_update': False
                    },
                    'en': {
                        'data_format': 'html',
                        'translation': 'hello!',
                        'needs_update': False
                    }
                }
            }
        }
        written_translations_dict_math = {
            'translations_mapping': {
                'content1': {
                    'en': {
                        'data_format': 'html',
                        'translation': expected_html_content,
                        'needs_update': True
                    },
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Hey!',
                        'needs_update': False
                    }
                },
                'feedback_1': {
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Testing!',
                        'needs_update': False
                    },
                    'en': {
                        'data_format': 'html',
                        'translation': 'hello!',
                        'needs_update': False
                    }
                }
            }
        }
        recorded_voiceovers = {
            'voiceovers_mapping': {
                'content': {
                    'en': {
                        'filename': 'test.mp3',
                        'file_size_bytes': 100,
                        'needs_update': False,
                        'duration_secs': 7.213
                    }
                }
            }
        }
        page_contents_dict = {
            'subtitled_html': {
                'content_id': 'content',
                'html': html_content
            },
            'recorded_voiceovers': recorded_voiceovers,
            'written_translations': written_translations_dict
        }
        expected_page_contents_dict = {
            'subtitled_html': {
                'content_id': 'content',
                'html': expected_html_content
            },
            'recorded_voiceovers': recorded_voiceovers,
            'written_translations': written_translations_dict_math
        }

        subtopic_page_id = subtopic_models.SubtopicPageModel.get_new_id('')
        subtopic_page_model = subtopic_models.SubtopicPageModel(
            id=subtopic_page_id,
            topic_id=self.TOPIC_ID,
            page_contents=page_contents_dict,
            page_contents_schema_version=3,
            language_code='en')
        self.assertEqual(subtopic_page_model.page_contents_schema_version, 3)

        with current_schema_version_swap:
            subtopic_page = subtopic_page_services.get_subtopic_page_from_model(
                subtopic_page_model)

        self.assertEqual(subtopic_page.page_contents_schema_version, 4)
        self.assertEqual(subtopic_page.page_contents.to_dict(),
                         expected_page_contents_dict)
    def test_migrate_page_contents_from_v1_to_v2_schema(self) -> None:
        current_schema_version_swap = self.swap(
            feconf, 'CURRENT_SUBTOPIC_PAGE_CONTENTS_SCHEMA_VERSION', 2)
        html_content = (
            '<p>Value</p><oppia-noninteractive-math raw_latex-with-value="&a'
            'mp;quot;+,-,-,+&amp;quot;"></oppia-noninteractive-math>')
        expected_html_content = (
            '<p>Value</p><oppia-noninteractive-math math_content-with-value='
            '"{&amp;quot;raw_latex&amp;quot;: &amp;quot;+,-,-,+&amp;quot;, &'
            'amp;quot;svg_filename&amp;quot;: &amp;quot;&amp;quot;}"></oppia'
            '-noninteractive-math>')
        written_translations_dict = {
            'translations_mapping': {
                'content1': {
                    'en': {
                        'data_format': 'html',
                        'translation': html_content,
                        'needs_update': True
                    },
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Hey!',
                        'needs_update': False
                    }
                },
                'feedback_1': {
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Testing!',
                        'needs_update': False
                    },
                    'en': {
                        'data_format': 'html',
                        'translation': 'hello!',
                        'needs_update': False
                    }
                }
            }
        }
        written_translations_dict_math = {
            'translations_mapping': {
                'content1': {
                    'en': {
                        'data_format': 'html',
                        'translation': expected_html_content,
                        'needs_update': True
                    },
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Hey!',
                        'needs_update': False
                    }
                },
                'feedback_1': {
                    'hi': {
                        'data_format': 'html',
                        'translation': 'Testing!',
                        'needs_update': False
                    },
                    'en': {
                        'data_format': 'html',
                        'translation': 'hello!',
                        'needs_update': False
                    }
                }
            }
        }
        recorded_voiceovers = {
            'voiceovers_mapping': {
                'content': {
                    'en': {
                        'filename': 'test.mp3',
                        'file_size_bytes': 100,
                        'needs_update': False,
                        'duration_secs': 7.213
                    }
                }
            }
        }
        page_contents_dict = {
            'subtitled_html': {
                'content_id': 'content',
                'html': html_content
            },
            'recorded_voiceovers': recorded_voiceovers,
            'written_translations': written_translations_dict
        }
        expected_page_contents_dict = {
            'subtitled_html': {
                'content_id': 'content',
                'html': expected_html_content
            },
            'recorded_voiceovers': recorded_voiceovers,
            'written_translations': written_translations_dict_math
        }

        subtopic_page_id = subtopic_models.SubtopicPageModel.get_new_id('')
        subtopic_page_model = subtopic_models.SubtopicPageModel(
            id=subtopic_page_id,
            topic_id=self.TOPIC_ID,
            page_contents=page_contents_dict,
            page_contents_schema_version=1,
            language_code='en')
        self.assertEqual(subtopic_page_model.page_contents_schema_version, 1)

        with current_schema_version_swap:
            subtopic_page = subtopic_page_services.get_subtopic_page_from_model(
                subtopic_page_model)

        self.assertEqual(subtopic_page.page_contents_schema_version, 2)
        self.assertEqual(subtopic_page.page_contents.to_dict(),
                         expected_page_contents_dict)