Exemple #1
0
    def test_state_class(self):
        """Test State Class."""
        state = State(id='The exploration hash id')

        # A new state should have a default name property.
        self.assertEqual(state.name, feconf.DEFAULT_STATE_NAME)

        state.put()
Exemple #2
0
    def add_state(self, state_name, state_id=None):
        """Adds a new state, and returns it. Commits changes."""
        if self._has_state_named(state_name):
            raise Exception('Duplicate state name %s' % state_name)

        state_id = state_id or State.get_new_id(state_name)
        new_state = State(id=state_id, name=state_name)
        new_state.put()

        self.state_ids.append(new_state.id)
        self.put()

        return new_state
Exemple #3
0
    def test_get_id_from_name(self):
        """Test converting state names to ids."""
        id_1 = '123'
        name_1 = 'State 1'
        self.exploration.add_state(name_1, state_id=id_1)

        self.assertEqual(
            State._get_id_from_name(name_1, self.exploration), id_1)

        with self.assertRaises(Exception):
            State._get_id_from_name('fake_name', self.exploration)

        self.assertEqual(
            State._get_id_from_name(feconf.END_DEST, self.exploration),
            feconf.END_DEST)
Exemple #4
0
def create_from_yaml(
    yaml_content, user_id, title, category, exploration_id=None,
        image_id=None):
    """Creates an exploration from a YAML text string."""
    exploration_dict = utils.dict_from_yaml(yaml_content)
    init_state_name = exploration_dict['states'][0]['name']

    exploration = Exploration.get(create_new(
        user_id, title, category, exploration_id=exploration_id,
        init_state_name=init_state_name, image_id=image_id))

    init_state = State.get_by_name(init_state_name, exploration)

    try:
        exploration.parameters = [Parameter(
            name=param['name'], obj_type=param['obj_type'],
            values=param['values']
        ) for param in exploration_dict['parameters']]

        state_list = []
        for state_description in exploration_dict['states']:
            state_name = state_description['name']
            state = (init_state if state_name == init_state_name
                     else exploration.add_state(state_name))
            state_list.append({'state': state, 'desc': state_description})

        for index, state in enumerate(state_list):
            modify_using_dict(exploration.id, state['state'].id, state['desc'])
    except Exception:
        exploration.delete()
        raise

    return exploration.id
Exemple #5
0
    def get_state_by_id(self, state_id, strict=True):
        """Returns a state of the exploration, given its id."""
        if state_id not in self.state_ids:
            raise Exception(
                'Invalid state id %s for exploration %s' % (state_id, self.id))

        return State.get(state_id, strict=strict)
Exemple #6
0
    def test_init_state_property(self):
        """Test the init_state property."""
        INIT_STATE_ID = 'init_state_id'
        INIT_STATE_NAME = 'init_state_name'

        init_state = State(id=INIT_STATE_ID, name=INIT_STATE_NAME)
        init_state.put()

        exploration = FakeExploration(owner_id='*****@*****.**')
        exploration.state_ids = ['init_state_id']
        self.assertEqual(exploration.init_state_id, INIT_STATE_ID)
        self.assertEqual(exploration.init_state.name, INIT_STATE_NAME)

        exploration.add_state('b')
        self.assertEqual(exploration.init_state_id, INIT_STATE_ID)
        self.assertEqual(exploration.init_state.name, INIT_STATE_NAME)
Exemple #7
0
    def test_state_operations(self):
        """Test adding, renaming and checking existence of states."""
        exploration = FakeExploration(owner_id='*****@*****.**')
        exploration.add_state('Initial state')

        self.assertEqual(len(exploration.state_ids), 1)

        default_state = State.get(exploration.state_ids[0])
        default_state_name = default_state.name
        exploration.rename_state(default_state.id, 'Renamed state')

        self.assertEqual(len(exploration.state_ids), 1)
        self.assertEqual(default_state.name, 'Renamed state')

        # Add a new state.
        second_state = exploration.add_state('State 2')
        self.assertEqual(len(exploration.state_ids), 2)

        # It is OK to rename a state to itself.
        exploration.rename_state(second_state.id, second_state.name)
        self.assertEqual(second_state.name, 'State 2')

        # But it is not OK to add or rename a state using a name that already
        # exists.
        with self.assertRaises(Exception):
            exploration.add_state('State 2')
        with self.assertRaises(Exception):
            exploration.rename_state(second_state.id, 'Renamed state')

        # The exploration now has exactly two states.
        self.assertFalse(exploration._has_state_named(default_state_name))
        self.assertTrue(exploration._has_state_named('Renamed state'))
        self.assertTrue(exploration._has_state_named('State 2'))
Exemple #8
0
    def add_state(self, state_name):
        """Adds a new state, and returns it."""
        if self._has_state_named(state_name):
            raise Exception('Duplicate state name %s' % state_name)

        state = State.create(self, state_name)
        self.states.append(state.key)
        self.put()

        return state
Exemple #9
0
def create_new(
    user_id, title, category, exploration_id=None,
        init_state_name=feconf.DEFAULT_STATE_NAME, image_id=None):
    """Creates, saves and returns a new exploration id."""
    # Generate a new exploration id, if one wasn't passed in.
    exploration_id = exploration_id or ExplorationModel.get_new_id(title)

    state_id = State.get_new_id(init_state_name)
    new_state = State(id=state_id, name=init_state_name)
    new_state.put()

    # Note that demo explorations do not have owners, so user_id may be None.
    exploration = ExplorationModel(
        id=exploration_id, title=title, category=category,
        image_id=image_id, state_ids=[state_id],
        editor_ids=[user_id] if user_id else [])

    exploration.put()

    return exploration.id
Exemple #10
0
    def test_create_and_get_state(self):
        """Test creation and retrieval of states."""
        id_1 = '123'
        name_1 = 'State 1'
        state_1 = self.exploration.add_state(name_1, state_id=id_1)

        fetched_state_1 = self.exploration.get_state_by_id(id_1)
        self.assertEqual(fetched_state_1, state_1)

        fetched_state_by_name_1 = State.get_by_name(name_1, self.exploration)
        self.assertEqual(fetched_state_by_name_1, state_1)

        # Test the failure cases.
        id_2 = 'fake_id'
        name_2 = 'fake_name'
        with self.assertRaises(Exception):
            self.exploration.get(id_2)

        fetched_state_by_name_2 = State.get_by_name(
            name_2, self.exploration, strict=False)
        self.assertIsNone(fetched_state_by_name_2)
        with self.assertRaises(Exception):
            State.get_by_name(name_2, self.exploration, strict=True)
        # The default behavior is to fail noisily.
        with self.assertRaises(Exception):
            State.get_by_name(name_2, self.exploration)
Exemple #11
0
    def create(cls, user, title, category, exploration_id=None,
               init_state_name=feconf.DEFAULT_STATE_NAME, image_id=None):
        """Creates and returns a new exploration."""
        # Generate a new exploration id, if one wasn't passed in.
        exploration_id = exploration_id or cls.get_new_id(title)

        # Temporarily create a fake initial state key.
        state_id = State.get_new_id(init_state_name)
        fake_state_key = ndb.Key(Exploration, exploration_id, State, state_id)

        # Note that demo explorations do not have owners, so user may be None.
        exploration = cls(
            id=exploration_id, title=title, init_state=fake_state_key,
            category=category, image_id=image_id, states=[fake_state_key],
            editors=[user] if user else [])
        exploration.put()

        # Finally, create the initial state and check that it has the right key.
        new_init_state = State.create(
            exploration, init_state_name, state_id=state_id)
        assert fake_state_key == new_init_state.key

        return exploration
Exemple #12
0
    def create_from_yaml(
        cls, yaml_file, user, title, category, exploration_id=None,
            image_id=None):
        """Creates an exploration from a YAML file."""
        exploration_dict = utils.dict_from_yaml(yaml_file)
        init_state_name = exploration_dict['states'][0]['name']

        exploration = cls.create(
            user, title, category, exploration_id=exploration_id,
            init_state_name=init_state_name, image_id=image_id)

        init_state = State.get_by_name(init_state_name, exploration)

        try:
            for param in exploration_dict['parameters']:
                exploration.parameters.append(Parameter(
                    name=param['name'], obj_type=param['obj_type'],
                    values=param['values'])
                )

            state_list = []
            exploration_states = exploration_dict['states']
            for state_description in exploration_states:
                state_name = state_description['name']
                state = (init_state if state_name == init_state_name
                         else exploration.add_state(state_name))
                state_list.append({'state': state, 'desc': state_description})

            for index, state in enumerate(state_list):
                State.modify_using_dict(
                    exploration, state['state'], state['desc'])
        except Exception:
            exploration.delete()
            raise

        return exploration
Exemple #13
0
def modify_using_dict(exploration_id, state_id, sdict):
    """Modifies the properties of a state using values from a dict."""
    exploration = Exploration.get(exploration_id)
    state = exploration.get_state_by_id(state_id)

    state.content = [
        Content(type=item['type'], value=item['value'])
        for item in sdict['content']
    ]

    state.param_changes = []
    for pc in sdict['param_changes']:
        instance = get_or_create_param(
            exploration_id, pc['name'], obj_type=pc['obj_type'])
        instance.values = pc['values']
        state.param_changes.append(instance)

    wdict = sdict['widget']
    state.widget = WidgetInstance(
        widget_id=wdict['widget_id'], sticky=wdict['sticky'],
        params=wdict['params'], handlers=[])

    # Augment the list of parameters in state.widget with the default widget
    # params.
    for wp in InteractiveWidget.get(wdict['widget_id']).params:
        if wp.name not in wdict['params']:
            state.widget.params[wp.name] = wp.value

    for handler in wdict['handlers']:
        handler_rules = [Rule(
            name=rule['name'],
            inputs=rule['inputs'],
            dest=State._get_id_from_name(rule['dest'], exploration),
            feedback=rule['feedback']
        ) for rule in handler['rules']]

        state.widget.handlers.append(AnswerHandlerInstance(
            name=handler['name'], rules=handler_rules))

    state.put()
    return state
Exemple #14
0
 def _has_state_named(self, state_name):
     """Checks if a state with the given name exists in this exploration."""
     state = State.query(ancestor=self.key).filter(
         State.name == state_name).count(limit=1)
     return bool(state)
Exemple #15
0
    def test_exploration_class(self):
        """Test the Exploration model class."""
        exploration = ExplorationModel(id='The exploration hash id')

        # A new exploration should have a default title property.
        self.assertEqual(exploration.title, 'New exploration')

        # A new exploration should have a default is_public property.
        self.assertEqual(exploration.is_public, False)

        state = State(id='The state hash id')
        state.put()

        # The 'state_ids' property must be a list of strings.
        with self.assertRaises(SyntaxError):
            exploration.state_ids = 'A string'
            exploration.put()
        with self.assertRaises(ValidationError):
            exploration.state_ids = [state]
            exploration.put()
        exploration.state_ids = [state.id]

        # An Exploration must have a category.
        with self.assertRaises(ValidationError):
            exploration.put()
        exploration.category = 'The category'

        # The 'parameters' property must be a list of Parameter objects.
        with self.assertRaises(ValidationError):
            exploration.parameters = 'A string'
            exploration.put()
        exploration.parameters = []
        parameter = Parameter(name='theParameter', obj_type='Int')
        with self.assertRaises(AttributeError):
            exploration.parameters = [parameter.key]
        exploration.parameters = [parameter]

        # The 'is_public' property must be a boolean.
        with self.assertRaises(ValidationError):
            exploration.is_public = 'true'
            exploration.put()
        exploration.is_public = True

        # The 'image_id' property must be a string.
        # TODO: This fails now because of the behaviour of CharField
        image = Image(id='The image')
        with self.assertRaises(ValidationError):
            exploration.image_id = image
            exploration.put()
        exploration.image_id = 'A string'

        exploration.editor_ids = ['A user id']

        # Put and retrieve the exploration.
        exploration.put()

        retrieved_exploration = Exploration.get('The exploration hash id')
        self.assertEqual(retrieved_exploration.category, 'The category')
        self.assertEqual(retrieved_exploration.title, 'New exploration')
        self.assertEqual(retrieved_exploration.state_ids, [state.id])
        self.assertEqual(retrieved_exploration.parameters, [parameter])
        self.assertEqual(retrieved_exploration.is_public, True)
        self.assertEqual(retrieved_exploration.image_id, 'A string')
        self.assertEqual(retrieved_exploration.editor_ids, ['A user id'])