Esempio n. 1
0
    def test_editable_collection_handler_put_can_access(self):
        """Check that editors can access put handler"""
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_config_property(
            config_domain.WHITELISTED_COLLECTION_EDITOR_USERNAMES,
            whitelisted_usernames)

        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.owner_id)
        rights_manager.assign_role_for_collection(
            self.admin_id, self.COLLECTION_ID, self.editor_id,
            rights_manager.ROLE_EDITOR)
        rights_manager.publish_collection(self.owner_id, self.COLLECTION_ID)

        self.login(self.EDITOR_EMAIL)

        # Call get handler to return the csrf token.
        response = self.testapp.get(
            '%s/%s' % (feconf.COLLECTION_URL_PREFIX,
                       self.COLLECTION_ID))
        csrf_token = self.get_csrf_token_from_response(response)

        json_response = self.put_json(
            '%s/%s' % (feconf.EDITABLE_COLLECTION_DATA_URL_PREFIX,
                       self.COLLECTION_ID),
            self.json_dict, csrf_token=csrf_token)

        self.assertEqual(self.COLLECTION_ID, json_response['collection']['id'])
        self.assertEqual(2, json_response['collection']['version'])
        self.logout()
Esempio n. 2
0
    def test_editable_collection_handler_put_can_access(self):
        """Check that editors can access put handler."""
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_collection_editors(whitelisted_usernames)

        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.owner_id)
        rights_manager.assign_role_for_collection(
            self.moderator, self.COLLECTION_ID, self.editor_id,
            rights_domain.ROLE_EDITOR)
        rights_manager.publish_collection(self.owner, self.COLLECTION_ID)

        self.login(self.EDITOR_EMAIL)

        # Call get handler to return the csrf token.
        csrf_token = self.get_new_csrf_token()
        json_response = self.put_json(
            '%s/%s' % (
                feconf.COLLECTION_EDITOR_DATA_URL_PREFIX,
                self.COLLECTION_ID),
            self.json_dict, csrf_token=csrf_token)

        self.assertEqual(self.COLLECTION_ID, json_response['collection']['id'])
        self.assertEqual(2, json_response['collection']['version'])

        self.logout()
Esempio n. 3
0
    def test_editable_collection_handler_put_cannot_access(self):
        """Check that non-editors cannot access editable put handler"""
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_config_property(
            config_domain.WHITELISTED_COLLECTION_EDITOR_USERNAMES,
            whitelisted_usernames)

        # Assign viewer role to collection.
        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.owner_id)
        rights_manager.assign_role_for_collection(
            self.admin_id, self.COLLECTION_ID, self.viewer_id,
            rights_manager.ROLE_VIEWER)
        rights_manager.publish_collection(self.owner_id, self.COLLECTION_ID)

        self.login(self.VIEWER_EMAIL)

        # Call get handler to return the csrf token.
        response = self.testapp.get(
            '%s/%s' % (feconf.COLLECTION_URL_PREFIX,
                       self.COLLECTION_ID))
        csrf_token = self.get_csrf_token_from_response(response)

        # Ensure viewers do not have access to the PUT Handler.
        json_response = self.put_json(
            '%s/%s' % (feconf.EDITABLE_COLLECTION_DATA_URL_PREFIX,
                       self.COLLECTION_ID),
            self.json_dict, expect_errors=True,
            csrf_token=csrf_token, expected_status_int=401)

        self.assertEqual(json_response['code'], 401)
        self.logout()
def _create_collection(committer_id, collection, commit_message, commit_cmds):
    """Ensures that rights for a new collection are saved first.

    This is because _save_collection() depends on the rights object being
    present to tell it whether to do strict validation or not.
    """
    # This line is needed because otherwise a rights object will be created,
    # but the creation of an collection object will fail.
    collection.validate(strict=False)
    rights_manager.create_new_collection_rights(collection.id, committer_id)
    model = collection_models.CollectionModel(
        id=collection.id,
        category=collection.category,
        title=collection.title,
        objective=collection.objective,
        language_code=collection.language_code,
        tags=collection.tags,
        schema_version=collection.schema_version,
        nodes=[
            collection_node.to_dict() for collection_node in collection.nodes
        ],
    )
    model.commit(committer_id, commit_message, commit_cmds)
    collection.version += 1
    create_collection_summary(collection.id, committer_id)
    def test_migrate_colections_failing_strict_validation(self):
        """Tests that the collection migration job migrates collections which
        do not pass strict validation.
        """
        # Save a collection without an objective or explorations in version 1.
        collection_title = 'A title'
        collection_category = 'A category'
        rights_manager.create_new_collection_rights(self.COLLECTION_ID,
                                                    self.albert_id)
        model = collection_models.CollectionModel(
            id=self.COLLECTION_ID,
            category=collection_title,
            title=collection_category,
            objective='',
            tags=[],
            schema_version=2,
        )
        model.commit(self.albert_id, 'Made a new collection!',
                     [{
                         'cmd': collection_services.CMD_CREATE_NEW,
                         'title': collection_title,
                         'category': collection_category,
                     }])

        # Start migration job on sample collection.
        job_id = (collection_jobs_one_off.CollectionMigrationJob.create_new())
        collection_jobs_one_off.CollectionMigrationJob.enqueue(job_id)

        # This running without errors indicates the collection is migrated.
        self.process_and_flush_pending_tasks()

        # Check the version number of the new model
        new_model = collection_models.CollectionModel.get(self.COLLECTION_ID)
        self.assertEqual(new_model.schema_version,
                         feconf.CURRENT_COLLECTION_SCHEMA_VERSION)
Esempio n. 6
0
def _create_collection(committer_id, collection, commit_message, commit_cmds):
    """Ensures that rights for a new collection are saved first.

    This is because _save_collection() depends on the rights object being
    present to tell it whether to do strict validation or not.
    """
    # This line is needed because otherwise a rights object will be created,
    # but the creation of an collection object will fail.
    collection.validate(strict=False)
    rights_manager.create_new_collection_rights(collection.id, committer_id)
    model = collection_models.CollectionModel(
        id=collection.id,
        category=collection.category,
        title=collection.title,
        objective=collection.objective,
        language_code=collection.language_code,
        tags=collection.tags,
        schema_version=collection.schema_version,
        nodes=[
            collection_node.to_dict() for collection_node in collection.nodes
        ],
    )
    model.commit(committer_id, commit_message, commit_cmds)
    collection.version += 1
    create_collection_summary(collection.id, committer_id)
Esempio n. 7
0
    def test_editable_collection_handler_put_cannot_access(self):
        """Check that non-editors cannot access editable put handler."""
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_collection_editors(whitelisted_usernames)

        # Assign viewer role to collection.
        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.owner_id)
        rights_manager.assign_role_for_collection(
            self.moderator, self.COLLECTION_ID, self.viewer_id,
            rights_domain.ROLE_VIEWER)
        rights_manager.publish_collection(self.owner, self.COLLECTION_ID)

        self.login(self.VIEWER_EMAIL)

        # Call get handler to return the csrf token.
        csrf_token = self.get_new_csrf_token()

        # Ensure viewers do not have access to the PUT Handler.
        self.put_json(
            '%s/%s' % (
                feconf.COLLECTION_EDITOR_DATA_URL_PREFIX,
                self.COLLECTION_ID),
            self.json_dict, csrf_token=csrf_token,
            expected_status_int=401)

        self.logout()
    def test_cannot_put_long_commit_message(self):
        """Check that putting a long commit message is denied."""
        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.owner_id)
        rights_manager.publish_collection(self.owner, self.COLLECTION_ID)

        self.login(self.OWNER_EMAIL)

        long_message_dict = self.json_dict.copy()
        long_message_dict['commit_message'] = (
            'a' * (feconf.MAX_COMMIT_MESSAGE_LENGTH + 1))

        # Call get handler to return the csrf token.
        csrf_token = self.get_new_csrf_token()
        json_response = self.put_json(
            '%s/%s' % (
                feconf.COLLECTION_EDITOR_DATA_URL_PREFIX,
                self.COLLECTION_ID),
            long_message_dict, csrf_token=csrf_token, expected_status_int=400)

        self.assertEqual(
            json_response['error'],
            'Commit messages must be at most 1000 characters long.'
        )

        self.logout()
    def test_migrate_colections_failing_strict_validation(self):
        """Tests that the collection migration job migrates collections which
        do not pass strict validation.
        """
        # Save a collection without an objective or explorations in version 1.
        collection_title = 'A title'
        collection_category = 'A category'
        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.albert_id)
        model = collection_models.CollectionModel(
            id=self.COLLECTION_ID,
            category=collection_title,
            title=collection_category,
            objective='',
            tags=[],
            schema_version=2,
        )
        model.commit(self.albert_id, 'Made a new collection!', [{
            'cmd': collection_services.CMD_CREATE_NEW,
            'title': collection_title,
            'category': collection_category,
        }])

        # Start migration job on sample collection.
        job_id = (
            collection_jobs_one_off.CollectionMigrationJob.create_new())
        collection_jobs_one_off.CollectionMigrationJob.enqueue(job_id)

        # This running without errors indicates the collection is migrated.
        self.process_and_flush_pending_tasks()

        # Check the version number of the new model
        new_model = collection_models.CollectionModel.get(self.COLLECTION_ID)
        self.assertEqual(
            new_model.schema_version, feconf.CURRENT_COLLECTION_SCHEMA_VERSION)
Esempio n. 10
0
def _create_collection(committer_id, collection, commit_message, commit_cmds):
    """Creates a new collection, and ensures that rights for a new collection
    are saved first. This is because _save_collection() depends on the rights
    object being present to tell it whether to do strict validation or not.

    Args:
        committer_id: str. ID of the committer.
        collection: Collection. collection domain object.
        commit_message: str. A description of changes made to the collection.
        commit_cmds: list(dict). A list of change commands made to the given
            collection.
    """
    # This line is needed because otherwise a rights object will be created,
    # but the creation of an collection object will fail.
    collection.validate(strict=False)
    rights_manager.create_new_collection_rights(collection.id, committer_id)
    model = collection_models.CollectionModel(
        id=collection.id,
        category=collection.category,
        title=collection.title,
        objective=collection.objective,
        language_code=collection.language_code,
        tags=collection.tags,
        schema_version=collection.schema_version,
        collection_contents={
            'nodes': [
                collection_node.to_dict()
                for collection_node in collection.nodes
            ]
        },
    )
    model.commit(committer_id, commit_message, commit_cmds)
    collection.version += 1
    create_collection_summary(collection.id, committer_id)
Esempio n. 11
0
    def test_editable_collection_handler_put_cannot_access(self):
        """Check that non-editors cannot access editable put handler"""
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_collection_editors(whitelisted_usernames)

        # Assign viewer role to collection.
        rights_manager.create_new_collection_rights(self.COLLECTION_ID,
                                                    self.owner_id)
        rights_manager.assign_role_for_collection(self.admin,
                                                  self.COLLECTION_ID,
                                                  self.viewer_id,
                                                  rights_manager.ROLE_VIEWER)
        rights_manager.publish_collection(self.owner, self.COLLECTION_ID)

        self.login(self.VIEWER_EMAIL)

        # Call get handler to return the csrf token.
        response = self.testapp.get(
            '%s/%s' % (feconf.COLLECTION_URL_PREFIX, self.COLLECTION_ID))
        csrf_token = self.get_csrf_token_from_response(response)

        # Ensure viewers do not have access to the PUT Handler.
        json_response = self.put_json(
            '%s/%s' %
            (feconf.EDITABLE_COLLECTION_DATA_URL_PREFIX, self.COLLECTION_ID),
            self.json_dict,
            expect_errors=True,
            csrf_token=csrf_token,
            expected_status_int=401)

        self.assertEqual(json_response['code'], 401)
        self.logout()
Esempio n. 12
0
    def test_editable_collection_handler_put_can_access(self):
        """Check that editors can access put handler"""
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_config_property(
            config_domain.WHITELISTED_COLLECTION_EDITOR_USERNAMES,
            whitelisted_usernames)

        rights_manager.create_new_collection_rights(self.COLLECTION_ID,
                                                    self.owner_id)
        rights_manager.assign_role_for_collection(self.admin_id,
                                                  self.COLLECTION_ID,
                                                  self.editor_id,
                                                  rights_manager.ROLE_EDITOR)
        rights_manager.publish_collection(self.owner_id, self.COLLECTION_ID)

        self.login(self.EDITOR_EMAIL)

        # Call get handler to return the csrf token.
        response = self.testapp.get(
            '%s/%s' % (feconf.COLLECTION_URL_PREFIX, self.COLLECTION_ID))
        csrf_token = self.get_csrf_token_from_response(response)

        json_response = self.put_json(
            '%s/%s' %
            (feconf.EDITABLE_COLLECTION_DATA_URL_PREFIX, self.COLLECTION_ID),
            self.json_dict,
            csrf_token=csrf_token)

        self.assertEqual(self.COLLECTION_ID, json_response['collection']['id'])
        self.assertEqual(2, json_response['collection']['version'])
        self.logout()
Esempio n. 13
0
    def test_migration_job_migrates_collection_nodes(self):
        """Tests that the collection migration job migrates content from
        nodes to collection_contents if collection_contents is empty.
        """
        with self.swap(collection_models, 'CollectionModel',
                       MockCollectionModel):
            # Create an exploration to put in the collection.
            self.save_new_default_exploration(self.EXP_ID, self.albert_id)
            node = collection_domain.CollectionNode.create_default_node(
                self.EXP_ID)

            # Create a collection directly using the model, so that the
            # collection nodes are stored in the 'nodes' property rather
            # than the 'collection_contents' property.
            collection_title = 'A title'
            collection_category = 'A category'
            rights_manager.create_new_collection_rights(
                self.COLLECTION_ID, self.albert_id)
            model = collection_models.CollectionModel(
                id=self.COLLECTION_ID,
                category=collection_category,
                title=collection_title,
                objective='An objective',
                tags=[],
                schema_version=2,
                nodes=[{
                    'exploration_id': self.EXP_ID,
                    'prerequisite_skills': [],
                    'acquired_skills': []
                }],
            )
            model.commit(self.albert_id, 'Made a new collection!',
                         [{
                             'cmd': collection_services.CMD_CREATE_NEW,
                             'title': collection_title,
                             'category': collection_category,
                         }])

            # Save a collection summary object for indexing. The explicit commit
            # does not create a summary object, which is needed for the
            # job to update the index after updating the collection.
            (collection_services.
             regenerate_collection_summary_with_new_contributor(
                 model.id, self.albert_id))

            # Check that collection_contents is empty.
            self.assertEqual(model.collection_contents, {})

            # Run the job. This should populate collection_contents.
            job_id = (collection_jobs_one_off.CollectionMigrationOneOffJob.
                      create_new())
            collection_jobs_one_off.CollectionMigrationOneOffJob.enqueue(
                job_id)
            self.process_and_flush_pending_mapreduce_tasks()

            new_model = collection_models.CollectionModel.get(
                self.COLLECTION_ID)
            self.assertEqual(new_model.collection_contents,
                             {'nodes': [node.to_dict()]})
Esempio n. 14
0
    def test_migrate_collections_failing_strict_validation(self):
        """Tests that the collection migration job migrates collections which
        do not pass strict validation.
        """
        # Save a collection without an objective or explorations in version 1.
        with self.swap(
            collection_models,
            'CollectionModel',
            MockCollectionModel):
            collection_title = 'A title'
            collection_category = 'A category'
            # Create an exploration to put in the collection.
            self.save_new_default_exploration(self.EXP_ID, self.albert_id)
            rights_manager.create_new_collection_rights(
                self.COLLECTION_ID, self.albert_id)
            model = collection_models.CollectionModel(
                id=self.COLLECTION_ID,
                category=collection_title,
                title=collection_category,
                objective='',
                tags=[],
                nodes=[{
                    'exploration_id': self.EXP_ID,
                    'prerequisite_skills': [],
                    'acquired_skills': []
                }],
                schema_version=2,
            )
            model.commit(self.albert_id, 'Made a new collection!', [{
                'cmd': collection_services.CMD_CREATE_NEW,
                'title': collection_title,
                'category': collection_category,
            }])

            # Save a collection summary object for indexing. The explicit commit
            # does not create a summary object, which is needed for the
            # job to update the index after updating the collection.
            (
                collection_services
                .regenerate_collection_summary_with_new_contributor(
                    model.id, self.albert_id))

            # Start migration job on sample collection.
            job_id = (
                collection_jobs_one_off.CollectionMigrationOneOffJob
                .create_new())
            collection_jobs_one_off.CollectionMigrationOneOffJob.enqueue(job_id)

            # This running without errors indicates the collection is migrated.
            self.process_and_flush_pending_mapreduce_tasks()

            # Check the version number of the new model.
            new_model = collection_models.CollectionModel.get(
                self.COLLECTION_ID)
            self.assertEqual(
                new_model.schema_version,
                feconf.CURRENT_COLLECTION_SCHEMA_VERSION)
Esempio n. 15
0
    def test_editable_collection_handler_put_with_invalid_payload_version(
            self):
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_collection_editors(whitelisted_usernames)

        rights_manager.create_new_collection_rights(self.COLLECTION_ID,
                                                    self.owner_id)
        rights_manager.assign_role_for_collection(self.moderator,
                                                  self.COLLECTION_ID,
                                                  self.editor_id,
                                                  rights_domain.ROLE_EDITOR)
        rights_manager.publish_collection(self.owner, self.COLLECTION_ID)

        self.login(self.EDITOR_EMAIL)

        # Call get handler to return the csrf token.
        csrf_token = self.get_new_csrf_token()

        # Raises error as version is None.
        sample_change_list = [{
            'cmd': 'edit_collection_property',
            'property_name': 'title',
            'new_value': 'A new title'
        }]
        json_response = self.put_json(
            '%s/%s' %
            (feconf.COLLECTION_EDITOR_DATA_URL_PREFIX, self.COLLECTION_ID), {
                'version': None,
                'change_list': sample_change_list
            },
            csrf_token=csrf_token,
            expected_status_int=400)

        self.assertEqual(json_response['error'],
                         'Invalid POST request: a version must be specified.')

        # Raises error as version from payload does not match the collection
        # version.
        json_response = self.put_json(
            '%s/%s' %
            (feconf.COLLECTION_EDITOR_DATA_URL_PREFIX, self.COLLECTION_ID), {
                'version': 2,
                'change_list': sample_change_list
            },
            csrf_token=csrf_token,
            expected_status_int=400)

        self.assertEqual(
            json_response['error'],
            'Trying to update version 1 of collection from version 2, '
            'which is too old. Please reload the page and try again.')

        self.logout()
Esempio n. 16
0
    def test_migration_job_skips_collection_failing_validation(self):
        """Tests that the collection migration job skips the collection
        failing validation and does not attempt to migrate.
        """
        # Create a collection directly using the model and with an
        # invalid language code.
        collection_title = 'A title'
        collection_category = 'A category'
        collection_language_code = 'abc'
        collection_schema_version = 2
        rights_manager.create_new_collection_rights(self.COLLECTION_ID,
                                                    self.albert_id)
        model = collection_models.CollectionModel(
            id=self.COLLECTION_ID,
            category=collection_title,
            title=collection_category,
            language_code=collection_language_code,
            objective='An objective',
            tags=[],
            schema_version=collection_schema_version)
        model.commit(self.albert_id, 'Made a new collection!',
                     [{
                         'cmd': collection_services.CMD_CREATE_NEW,
                         'title': collection_title,
                         'category': collection_category,
                     }])

        # Start migration job on sample collection.
        job_id = (
            collection_jobs_one_off.CollectionMigrationOneOffJob.create_new())
        collection_jobs_one_off.CollectionMigrationOneOffJob.enqueue(job_id)

        # This running without errors indicates the collection failing
        # validation is being ignored.
        self.process_and_flush_pending_tasks()

        # Check that the version number of the new model is same as old model.
        new_model = collection_models.CollectionModel.get(self.COLLECTION_ID)
        self.assertEqual(new_model.schema_version, collection_schema_version)

        output = (collection_jobs_one_off.CollectionMigrationOneOffJob.
                  get_output(job_id))
        expected = [[
            u'validation_error',
            [
                u'Collection %s failed validation: Invalid '
                u'language code: %s' %
                (self.COLLECTION_ID, collection_language_code)
            ]
        ]]
        self.assertEqual(expected, [ast.literal_eval(x) for x in output])
    def test_migration_job_migrates_collection_nodes(self):
        """Tests that the collection migration job migrates content from
        nodes to collection_contents if collection_contents is empty.
        """
        # Create an exploration to put in the collection.
        self.save_new_default_exploration(self.EXP_ID, self.albert_id)
        node = collection_domain.CollectionNode.create_default_node(
            self.EXP_ID)

        # Create a collection directly using the model, so that the collection
        # nodes are stored in the 'nodes' property rather than the
        # 'collection_contents' property.
        collection_title = 'A title'
        collection_category = 'A category'
        rights_manager.create_new_collection_rights(self.COLLECTION_ID,
                                                    self.albert_id)
        model = collection_models.CollectionModel(
            id=self.COLLECTION_ID,
            category=collection_category,
            title=collection_title,
            objective='An objective',
            tags=[],
            schema_version=2,
            nodes=[{
                'exploration_id': self.EXP_ID,
                'prerequisite_skills': [],
                'acquired_skills': []
            }],
        )
        model.commit(self.albert_id, 'Made a new collection!',
                     [{
                         'cmd': collection_services.CMD_CREATE_NEW,
                         'title': collection_title,
                         'category': collection_category,
                     }])

        # Check that collection_contents is empty
        self.assertEqual(model.collection_contents, {})

        # Run the job. This should populate collection_contents.
        job_id = (collection_jobs_one_off.CollectionMigrationJob.create_new())
        collection_jobs_one_off.CollectionMigrationJob.enqueue(job_id)
        self.process_and_flush_pending_tasks()

        new_model = collection_models.CollectionModel.get(self.COLLECTION_ID)
        self.assertEqual(new_model.collection_contents, {
            'nodes': [node.to_dict()],
            'skills': {},
            'next_skill_id': 0
        })
Esempio n. 18
0
    def test_one_collection_model_with_nodes(self):
        with self.swap(collection_models, 'CollectionModel',
                       MockCollectionModel):
            self.save_new_default_exploration(self.EXP_ID, self.albert_id)
            rights_manager.create_new_collection_rights(
                self.COLLECTION_ID, self.albert_id)
            original_collection_model = (collection_models.CollectionModel(
                id=self.COLLECTION_ID,
                category='category1',
                title='title1',
                objective='An objective',
                tags=[],
                schema_version=2,
                nodes=[{
                    'prerequisite_skills': [],
                    'acquired_skills': [],
                    'exploration_id': self.EXP_ID,
                }],
            ))
            original_collection_model.commit(
                self.albert_id, 'Made a new collection!',
                [{
                    'cmd': collection_services.CMD_CREATE_NEW,
                    'title': 'title1',
                    'category': 'category1',
                }])

            self.assertIsNotNone(original_collection_model.nodes)
            self.assertIn('nodes', original_collection_model._values)  # pylint: disable=protected-access
            self.assertIn('nodes', original_collection_model._properties)  # pylint: disable=protected-access

            output = self._run_one_off_job()
            self.assertItemsEqual([['SUCCESS_REMOVED - CollectionModel', 1]],
                                  output)

            migrated_collection_model = (
                collection_models.CollectionModel.get_by_id(
                    self.COLLECTION_ID))

            self.assertNotIn('nodes', migrated_collection_model._values)  # pylint: disable=protected-access
            self.assertNotIn('nodes', migrated_collection_model._properties)  # pylint: disable=protected-access

            output = self._run_one_off_job()
            self.assertItemsEqual(
                [['SUCCESS_ALREADY_REMOVED - CollectionModel', 1]], output)
    def test_migration_job_migrates_collection_nodes(self):
        """Tests that the collection migration job migrates content from
        nodes to collection_contents if collection_contents is empty.
        """
        # Create an exploration to put in the collection.
        self.save_new_default_exploration(self.EXP_ID, self.albert_id)
        node = collection_domain.CollectionNode.create_default_node(self.EXP_ID)

        # Create a collection directly using the model, so that the collection
        # nodes are stored in the 'nodes' property rather than the
        # 'collection_contents' property.
        collection_title = 'A title'
        collection_category = 'A category'
        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.albert_id)
        model = collection_models.CollectionModel(
            id=self.COLLECTION_ID,
            category=collection_category,
            title=collection_title,
            objective='An objective',
            tags=[],
            schema_version=2,
            nodes=[node.to_dict()],
        )
        model.commit(self.albert_id, 'Made a new collection!', [{
            'cmd': collection_services.CMD_CREATE_NEW,
            'title': collection_title,
            'category': collection_category,
        }])

        # Check that collection_contents is empty
        self.assertEqual(model.collection_contents, {})

        # Run the job. This should populate collection_contents.
        job_id = (
            collection_jobs_one_off.CollectionMigrationJob.create_new())
        collection_jobs_one_off.CollectionMigrationJob.enqueue(job_id)
        self.process_and_flush_pending_tasks()

        new_model = collection_models.CollectionModel.get(self.COLLECTION_ID)
        self.assertEqual(
            new_model.collection_contents, {'nodes': [node.to_dict()]})
Esempio n. 20
0
    def test_editable_collection_handler_put_can_access(self):
        """Check that editors can access put handler."""
        whitelisted_usernames = [self.EDITOR_USERNAME, self.VIEWER_USERNAME]
        self.set_collection_editors(whitelisted_usernames)

        rights_manager.create_new_collection_rights(
            self.COLLECTION_ID, self.owner_id)
        rights_manager.assign_role_for_collection(
            self.admin, self.COLLECTION_ID, self.editor_id,
            rights_manager.ROLE_EDITOR)
        rights_manager.publish_collection(self.owner, self.COLLECTION_ID)

        self.login(self.EDITOR_EMAIL)

        # Call get handler to return the csrf token.
        response = self.get_html_response(
            '%s/%s' % (
                feconf.COLLECTION_URL_PREFIX,
                self.COLLECTION_ID))
        csrf_token = self.get_csrf_token_from_response(response)

        json_response = self.put_json(
            '%s/%s' % (
                feconf.COLLECTION_EDITOR_DATA_URL_PREFIX,
                self.COLLECTION_ID),
            self.json_dict, csrf_token=csrf_token)

        self.assertEqual(self.COLLECTION_ID, json_response['collection']['id'])
        self.assertEqual(2, json_response['collection']['version'])

        # Check that title is changed.
        response = self.get_html_response(
            '%s/%s' % (
                feconf.COLLECTION_EDITOR_URL_PREFIX,
                self.COLLECTION_ID))
        response.mustcontain(self.json_dict['change_list'][0]['new_value'])
        self.logout()