Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

controllers/tour: Reset unspecified fields to DB default #776 #814

Merged
merged 1 commit into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions controllers/tour.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions models/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,18 +772,18 @@
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)
Field('stop_wait_after_backward', type='integer', notnull=False), # How long to wait if entered by going back
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?
Expand Down
65 changes: 65 additions & 0 deletions tests/unit/test_controllers_tour.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down