diff --git a/controllers/tour.py b/controllers/tour.py index 9f92b786..810ab9a9 100644 --- a/controllers/tour.py +++ b/controllers/tour.py @@ -217,6 +217,8 @@ def data(): tss_targets = {} for i, ts in enumerate(request.vars['tourstops']): ts = { + # All fields not otherwise specfied return to their default + **{k:db.tourstop.get(k).default for k in db.tourstop.fields if k not in ['created', 'updated']}, **ts_shared, **ts, # Deep-clone template_data, should always exist diff --git a/models/db.py b/models/db.py index 57c69a51..4068c6e6 100755 --- a/models/db.py +++ b/models/db.py @@ -772,10 +772,10 @@ Field('identifier', type='string', notnull=True), # Unique identifier for tourstop, for establishing symlinks Field('ord', type='integer', notnull=True), # The position of this tourstop in the tour, starting with 1 Field('ott', type='integer', notnull=False), # The OTT this tourstop points at. NULL => return to start - Field('secondary_ott', type='integer', notnull=True), # A second OTT when targeting a common ancestor + Field('secondary_ott', type='integer', notnull=True, default=0), # A second OTT when targeting a common ancestor Field('qs_opts', type='string', notnull=False, default=''), # QS-style options to apply to modify tourstop, e.g. into_node=true&initmark=... Field('author', type='text', notnull=True, default=''), # Author of tourstop (doesn't necessarily match tour in case of remix) - Field('transition_in', type='string', notnull=True, requires=IS_IN_SET(('fly', 'leap', 'fly_straight'))), # Transition to use when flying to stop + Field('transition_in', type='string', notnull=True, requires=IS_IN_SET(('fly', 'leap', 'fly_straight')), default='fly'), # Transition to use when flying to stop Field('fly_in_speed', type='double', notnull=False, default=1), # Speed relative to global_anim_speed Field('transition_in_wait', type='integer', notnull=False), # How long to wait before entering into transition Field('stop_wait', type='integer', notnull=False), # How long to wait at this stop (null => wait until "next" is pressed) @@ -783,7 +783,7 @@ Field('template_data', type='text', notnull=True, filter_in=lambda obj: json.dumps(obj), filter_out=lambda txt: json.loads(txt)), # JSON template data for tourstop - Field('lang', type='string', notnull=True, length=3), #the 'primary' 2 or 3 letter 'lang' code for this name (e.g. 'en', 'cmn'). See http://www.w3.org/International/articles/language-tags/ + Field('lang', type='string', notnull=True, length=3, default='en'), #the 'primary' 2 or 3 letter 'lang' code for this name (e.g. 'en', 'cmn'). See http://www.w3.org/International/articles/language-tags/ Field('checked_by', type='string'), # Who has checked the validity of this data? Field('checked_updated', 'datetime', default=None), # When did they do it? Field('visible_in_search', 'boolean', notnull=True, default=True), # Available in tourstop-search for remixing a tour? diff --git a/tests/unit/test_controllers_tour.py b/tests/unit/test_controllers_tour.py index abec1811..7b66a4e7 100644 --- a/tests/unit/test_controllers_tour.py +++ b/tests/unit/test_controllers_tour.py @@ -361,6 +361,71 @@ def test_data_shareddata(self): ] ) + def test_data_resettodefault(self): + """Removing values will reset them to their default""" + otts = util.find_unsponsored_otts(10) + + # Can insert a tour with a common ancestor pinpoint + t = self.tour_put('UT::TOUR', dict( + title="A unit test tour", + description="It's a nice tour", + author="UT::Author", + tourstop_shared=dict( + stop_wait=1234, + ), + tourstops=[ + dict( + ott=otts[0], + identifier="ott0", + stop_wait=3, + author="Frank", + ), + dict( + ott=otts[1], + identifier="ott1", + author="Gelda", + ), + ], + )) + # One entry uses default + self.assertEqual( + [ts['stop_wait'] for ts in self.tour_get('UT::TOUR')['tourstops']], + [3, 1234], + ) + # Both have an Author + self.assertEqual( + [ts['author'] for ts in self.tour_get('UT::TOUR')['tourstops']], + ['Frank', 'Gelda'], + ) + + # Clear author, stop_wait. Get set back to their DB defaults + t = self.tour_put('UT::TOUR', dict( + title="A unit test tour", + description="It's a nice tour", + author="UT::Author", + tourstop_shared=dict( + ), + tourstops=[ + dict( + ott=otts[0], + identifier="ott0", + stop_wait=3, + ), + dict( + ott=otts[1], + identifier="ott1", + ), + ], + )) + self.assertEqual( + [ts['stop_wait'] for ts in self.tour_get('UT::TOUR')['tourstops']], + [3, None], + ) + self.assertEqual( + [ts['author'] for ts in self.tour_get('UT::TOUR')['tourstops']], + ['', ''], + ) + def test_list(self): def t_list(tours, include_rest=""): return util.call_controller(