def get_state_for_frontend(state, exploration): """Returns a representation of the given state for the frontend.""" state_repr = exp_services.export_state_to_dict(exploration.id, state.id) modified_state_dict = exp_services.export_state_internals_to_dict( exploration.id, state.id, human_readable_dests=True) # TODO(sll): The following is for backwards-compatibility and should be # deleted later. rules = {} for handler in state_repr['widget']['handlers']: rules[handler['name']] = handler['rules'] for item in rules[handler['name']]: if item['name'] == 'Default': item['rule'] = 'Default' else: item['rule'] = InteractiveWidget.get( state.widget.widget_id).get_readable_name( handler['name'], item['name'] ) state_repr['widget']['rules'] = rules state_repr['widget']['id'] = state_repr['widget']['widget_id'] state_repr['yaml'] = utils.yaml_from_dict(modified_state_dict) return state_repr
def _pre_put_hook(self): """Ensures that the widget and at least one handler for it exists.""" # Every state should have an interactive widget. if not self.widget: self.widget = self.get_default_widget() elif not self.widget.handlers: self.widget.handlers = [self.get_default_handler()] # TODO(sll): Do other validation. # Add the corresponding AnswerHandler classifiers for easy reference. widget = InteractiveWidget.get(self.widget.widget_id) for curr_handler in self.widget.handlers: for w_handler in widget.handlers: if w_handler.name == curr_handler.name: curr_handler.classifier = w_handler.classifier
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
def test_parameterized_widget(self): """Test that parameterized widgets are correctly handled.""" self.assertEqual(InteractiveWidget.objects.count(), 0) Classifier.load_default_classifiers() InteractiveWidget.load_default_widgets() MUSIC_STAFF_ID = 'interactive-MusicStaff' widget = InteractiveWidget.get(MUSIC_STAFF_ID) self.assertEqual(widget.id, MUSIC_STAFF_ID) self.assertEqual(widget.name, 'Music staff') code = InteractiveWidget.get_raw_code(MUSIC_STAFF_ID) self.assertIn('GLOBALS.noteToGuess = JSON.parse(\'\\"', code) code = InteractiveWidget.get_raw_code(MUSIC_STAFF_ID, {'noteToGuess': 'abc'}) self.assertIn('GLOBALS.noteToGuess = JSON.parse(\'abc\');', code) # The get_with_params() method cannot be called directly on Widget. # It must be called on a subclass. with self.assertRaises(AttributeError): parameterized_widget_dict = Widget.get_with_params( MUSIC_STAFF_ID, {'noteToGuess': 'abc'}) with self.assertRaises(NotImplementedError): parameterized_widget_dict = Widget._get_with_params( MUSIC_STAFF_ID, {'noteToGuess': 'abc'}) parameterized_widget_dict = InteractiveWidget.get_with_params( MUSIC_STAFF_ID, {'noteToGuess': 'abc'}) self.assertItemsEqual(parameterized_widget_dict.keys(), [ 'id', 'name', 'category', 'description', 'template', 'static_template', 'params', 'handlers', 'raw']) self.assertEqual(parameterized_widget_dict['id'], MUSIC_STAFF_ID) self.assertIn('GLOBALS.noteToGuess = JSON.parse(\'abc\');', parameterized_widget_dict['raw']) self.assertEqual(parameterized_widget_dict['params'], {'noteToGuess': 'abc'}) InteractiveWidget.delete_all_widgets()