gristlabs_grist-core/sandbox/grist/test_display_cols.py
Alex Hall c0ca936c1e (core) Backend restrictions for raw data widgets
Summary:
Prevent most updates or removals of raw view sections and their fields in `useractions.py`. Only a fiew columns are allowed to be updated.

Removed the unused method `_UpdateViews` while I was at it.

Test Plan:
Added a Python test.

Tested manually that I can still make all expected changes, i.e. those allowed by the UI, e.g. reordering columns.

Reviewers: georgegevoian

Reviewed By: georgegevoian

Differential Revision: https://phab.getgrist.com/D3263
2022-02-15 22:04:32 +02:00

623 lines
29 KiB
Python

import logger
import testutil
import test_engine
from test_engine import Table, Column
log = logger.Logger(__name__, logger.INFO)
class TestUserActions(test_engine.EngineTestCase):
ref_sample = testutil.parse_test_sample({
# pylint: disable=line-too-long
"SCHEMA": [
[1, "Television", [
[21, "show", "Text", False, "", "", ""],
[22, "network", "Text", False, "", "", ""],
[23, "viewers", "Int", False, "", "", ""]
]]
],
"DATA": {
"Television": [
["id", "show" , "network", "viewers"],
[11, "Game of Thrones", "HBO" , 100],
[12, "Narcos" , "Netflix", 500],
[13, "Today" , "NBC" , 200],
[14, "Empire" , "Fox" , 300]],
}
})
def test_display_cols(self):
# Test the implementation of display columns which adds a column modified by
# a formula as a display version of the original column.
self.load_sample(self.ref_sample)
# Add a new table for People so that we get the associated views and fields.
self.apply_user_action(['AddTable', 'Favorites', [{'id': 'favorite', 'type':
'Ref:Television'}]])
self.apply_user_action(['BulkAddRecord', 'Favorites', [1,2,3,4,5], {
'favorite': [2, 4, 1, 4, 3]
}])
self.assertTables([
Table(1, "Television", 0, 0, columns=[
Column(21, "show", "Text", False, "", 0),
Column(22, "network", "Text", False, "", 0),
Column(23, "viewers", "Int", False, "", 0),
]),
Table(2, "Favorites", 1, 0, columns=[
Column(24, "manualSort", "ManualSortPos", False, "", 0),
Column(25, "favorite", "Ref:Television", False, "", 0),
]),
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 0],
[2, 25, 0],
])
self.assertTableData("Favorites", cols="subset", data=[
["id", "favorite"],
[1, 2],
[2, 4],
[3, 1],
[4, 4],
[5, 3]
])
# Add an extra view for the new table to test multiple fields at once
self.apply_user_action(['AddView', 'Favorites', 'raw_data', 'Extra View'])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 0],
[2, 25, 0],
[3, 25, 0],
])
# Set display formula for 'favorite' column.
# A "gristHelper_Display" column with the requested formula should be added and set as the
# displayCol of the favorite column.
self.apply_user_action(['SetDisplayFormula', 'Favorites', None, 25, '$favorite.show'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"]
])
# Set display formula for 'favorite' column fields.
# A single "gristHelper_Display2" column should be added with the requested formula, since both
# require the same formula. The fields' colRefs should be set to the new column.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 1, None, '$favorite.network'])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 3, None, '$favorite.network'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"],
[27, "gristHelper_Display2", 2, 0, "$favorite.network"],
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 25, 0],
[3, 25, 27],
])
# Change display formula for a field.
# Since the field is changing to use a formula not yet held by a display column,
# a new display column should be added with the desired formula.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 3, None, '$favorite.viewers'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"],
[27, "gristHelper_Display2", 2, 0, "$favorite.network"],
[28, "gristHelper_Display3", 2, 0, "$favorite.viewers"]
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 25, 0],
[3, 25, 28],
])
# Remove a field.
# This should also remove the display column used by that field, since it is not used
# by any other fields.
self.apply_user_action(['RemoveRecord', '_grist_Views_section_field', 3])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"],
[27, "gristHelper_Display2", 2, 0, "$favorite.network"],
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 25, 0],
])
# Add a new column with a formula.
self.apply_user_action(['AddColumn', 'Favorites', 'fav_viewers', {
'formula': '$favorite.viewers'
}])
# Add a field back for the favorites table and set its display formula to the
# same formula that the new column has. Make sure that the new column is NOT used as
# the display column.
self.apply_user_action(['AddRecord', '_grist_Views_section_field', None, {
'parentId': 3,
'colRef': 25
}])
self.apply_user_action(['SetDisplayFormula', 'Favorites', 6, None, '$favorite.viewers'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"],
[27, "gristHelper_Display2", 2, 0, "$favorite.network"],
[28, "fav_viewers", 2, 0, "$favorite.viewers"],
[29, "gristHelper_Display3", 2, 0, "$favorite.viewers"]
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 25, 0],
[3, 28, 0], # fav_viewers field
[4, 28, 0], # fav_viewers field
[5, 28, 0], # fav_viewers field
[6, 25, 29] # re-added field w/ display col
])
# Change the display formula for a field to be the same as the other field, then remove
# the field.
# The display column should not be removed since it is still in use.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 6, None, '$favorite.network'])
self.apply_user_action(['RemoveRecord', '_grist_Views_section_field', 6])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"],
[27, "gristHelper_Display2",2, 0, "$favorite.network"],
[28, "fav_viewers", 2, 0, "$favorite.viewers"],
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 27],
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Clear field display formula, then set it again.
# Clearing the display formula should remove the display column, since it is no longer
# used by any column or field.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 1, None, ''])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"],
[28, "fav_viewers", 2, 0, "$favorite.viewers"],
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 0],
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Setting the display formula should add another display column.
self.apply_user_action(['SetDisplayFormula', 'Favorites', 1, None, '$favorite.viewers'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display", 2, 0, "$favorite.show"],
[28, "fav_viewers", 2, 0, "$favorite.viewers"],
[29, "gristHelper_Display2",2, 0, "$favorite.viewers"],
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Change column display formula.
# This should re-use the current display column since it is only used by the column.
self.apply_user_action(['SetDisplayFormula', 'Favorites', None, 25, '$favorite.network'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[25, "favorite", 2, 26, ""],
[26, "gristHelper_Display",2, 0, "$favorite.network"],
[28, "fav_viewers", 2, 0, "$favorite.viewers"],
[29, "gristHelper_Display2",2, 0, "$favorite.viewers"],
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 25, 0],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
# Remove column.
# This should remove the display column used by the column.
self.apply_user_action(['RemoveColumn', "Favorites", "favorite"])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id >= 25), data=[
["id", "colId", "parentId", "displayCol", "formula"],
[28, "fav_viewers", 2, 0, "$favorite.viewers"]
])
self.assertTableData("_grist_Views_section_field", cols="subset", data=[
["id", "colRef", "displayCol"],
[3, 28, 0],
[4, 28, 0],
[5, 28, 0],
])
def test_display_col_removal(self):
# Test that when removing a column, we don't produce unnecessary calc actions for a display
# column that may also get auto-removed.
self.load_sample(self.ref_sample)
# Create a display column.
self.apply_user_action(['SetDisplayFormula', 'Television', None, 21, '$show.upper()'])
# Verify the state of columns and display columns.
self.assertTableData("_grist_Tables_column", cols="subset", data=[
["id", "colId", "type", "displayCol", "formula" ],
[21, "show", "Text", 24 , "" ],
[22, "network", "Text", 0 , "" ],
[23, "viewers", "Int", 0 , "" ],
[24, "gristHelper_Display", "Any", 0 , "$show.upper()"]
])
self.assertTableData("Television", cols="all", data=[
["id", "show" , "network", "viewers", "gristHelper_Display"],
[11, "Game of Thrones", "HBO" , 100, "GAME OF THRONES"],
[12, "Narcos" , "Netflix", 500, "NARCOS"],
[13, "Today" , "NBC" , 200, "TODAY"],
[14, "Empire" , "Fox" , 300, "EMPIRE"],
])
# Remove the column that has a displayCol referring to it.
out_actions = self.apply_user_action(['RemoveColumn', 'Television', 'show'])
# Verify that the resulting actions don't include any calc actions.
self.assertPartialOutActions(out_actions, {
"stored": [
["BulkRemoveRecord", "_grist_Tables_column", [21, 24]],
["RemoveColumn", "Television", "show"],
["RemoveColumn", "Television", "gristHelper_Display"],
],
"calc": []
})
# Verify the state of columns and display columns afterwards.
self.assertTableData("_grist_Tables_column", cols="subset", data=[
["id", "colId", "type", "displayCol", "formula" ],
[22, "network", "Text", 0 , "" ],
[23, "viewers", "Int", 0 , "" ],
])
self.assertTableData("Television", cols="all", data=[
["id", "network", "viewers" ],
[11, "HBO" , 100 ],
[12, "Netflix", 500 ],
[13, "NBC" , 200 ],
[14, "Fox" , 300 ],
])
def test_display_col_and_field_removal(self):
# When there are different displayCols associated with the column and with the field, removal
# takes more steps, and order of produced actions matters.
self.load_sample(self.ref_sample)
# Add a table for people, which includes an associated view.
self.apply_user_action(['AddTable', 'People', [
{'id': 'name', 'type': 'Text'},
{'id': 'favorite', 'type': 'Ref:Television',
'widgetOptions': '\"{\"alignment\":\"center\",\"visibleCol\":\"show\"}\"'},
]])
self.apply_user_action(['BulkAddRecord', 'People', [1,2,3], {
'name': ['Bob', 'Jim', 'Don'],
'favorite': [12, 11, 13]
}])
# Add a display formula for the 'favorite' column. A "gristHelper_Display" column with the
# requested formula should be added and set as the displayCol of the favorite column.
self.apply_user_action(['SetDisplayFormula', 'People', None, 26, '$favorite.show'])
# Set display formula for 'favorite' column field.
# A single "gristHelper_Display2" column should be added with the requested formula.
self.apply_user_action(['SetDisplayFormula', 'People', 2, None, '$favorite.network'])
expected_tables1 = [
Table(1, "Television", 0, 0, columns=[
Column(21, "show", "Text", False, "", 0),
Column(22, "network", "Text", False, "", 0),
Column(23, "viewers", "Int", False, "", 0),
]),
Table(2, "People", 1, 0, columns=[
Column(24, "manualSort", "ManualSortPos", False, "", 0),
Column(25, "name", "Text", False, "", 0),
Column(26, "favorite", "Ref:Television", False, "", 0),
Column(27, "gristHelper_Display", "Any", True, "$favorite.show", 0),
Column(28, "gristHelper_Display2", "Any", True, "$favorite.network", 0)
]),
]
expected_data1 = [
["id", "name", "favorite", "gristHelper_Display", "gristHelper_Display2"],
[1, "Bob", 12, "Narcos", "Netflix"],
[2, "Jim", 11, "Game of Thrones", "HBO"],
[3, "Don", 13, "Today", "NBC"]
]
self.assertTables(expected_tables1)
self.assertTableData("People", cols="subset", data=expected_data1)
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "parentId", "colRef", "displayCol"],
[1, 1, 25, 0],
[2, 1, 26, 28],
])
# Now remove the 'favorite' column.
out_actions = self.apply_user_action(['RemoveColumn', 'People', 'favorite'])
# The associated field and both displayCols should be gone.
self.assertTables([
expected_tables1[0],
Table(2, "People", 1, 0, columns=[
Column(24, "manualSort", "ManualSortPos", False, "", 0),
Column(25, "name", "Text", False, "", 0),
]),
])
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "parentId", "colRef", "displayCol"],
[1, 1, 25, 0],
])
# Verify that the resulting actions don't include any extraneous calc actions.
# pylint:disable=line-too-long
self.assertOutActions(out_actions, {
"stored": [
["BulkRemoveRecord", "_grist_Views_section_field", [2, 4]],
["BulkRemoveRecord", "_grist_Tables_column", [26, 27]],
["RemoveColumn", "People", "favorite"],
["RemoveColumn", "People", "gristHelper_Display"],
["RemoveRecord", "_grist_Tables_column", 28],
["RemoveColumn", "People", "gristHelper_Display2"],
],
"direct": [True, True, True, True, True, True],
"undo": [
["BulkUpdateRecord", "People", [1, 2, 3], {"gristHelper_Display2": ["Netflix", "HBO", "NBC"]}],
["BulkUpdateRecord", "People", [1, 2, 3], {"gristHelper_Display": ["Narcos", "Game of Thrones", "Today"]}],
["BulkAddRecord", "_grist_Views_section_field", [2, 4], {"colRef": [26, 26], "displayCol": [28, 0], "parentId": [1, 2], "parentPos": [2.0, 4.0]}],
["BulkAddRecord", "_grist_Tables_column", [26, 27], {"colId": ["favorite", "gristHelper_Display"], "displayCol": [27, 0], "formula": ["", "$favorite.show"], "isFormula": [False, True], "label": ["favorite", "gristHelper_Display"], "parentId": [2, 2], "parentPos": [6.0, 7.0], "type": ["Ref:Television", "Any"], "widgetOptions": ["\"{\"alignment\":\"center\",\"visibleCol\":\"show\"}\"", ""]}],
["BulkUpdateRecord", "People", [1, 2, 3], {"favorite": [12, 11, 13]}],
["AddColumn", "People", "favorite", {"formula": "", "isFormula": False, "type": "Ref:Television"}],
["AddColumn", "People", "gristHelper_Display", {"formula": "$favorite.show", "isFormula": True, "type": "Any"}],
["AddRecord", "_grist_Tables_column", 28, {"colId": "gristHelper_Display2", "formula": "$favorite.network", "isFormula": True, "label": "gristHelper_Display2", "parentId": 2, "parentPos": 8.0, "type": "Any"}],
["AddColumn", "People", "gristHelper_Display2", {"formula": "$favorite.network", "isFormula": True, "type": "Any"}],
],
})
# Now undo; expect the structure and values restored.
stored_actions = out_actions.get_repr()["stored"]
undo_actions = out_actions.get_repr()["undo"]
out_actions = self.apply_user_action(['ApplyUndoActions', undo_actions])
self.assertTables(expected_tables1)
self.assertTableData("People", cols="subset", data=expected_data1)
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "parentId", "colRef", "displayCol"],
[1, 1, 25, 0],
[2, 1, 26, 28],
])
self.assertPartialOutActions(out_actions, {
"stored": reversed(undo_actions),
})
def test_display_col_copying(self):
# Test that when switching types and using CopyFromColumn, displayCol is set/unset correctly.
self.load_sample(self.ref_sample)
# Add a new table for People so that we get the associated views and fields.
self.apply_user_action(['AddTable', 'Favorites', [
{'id': 'favorite', 'type': 'Ref:Television'},
{'id': 'favorite2', 'type': 'Text'}]])
self.apply_user_action(['BulkAddRecord', 'Favorites', [1,2,3,4,5], {
'favorite': [2, 4, 1, 4, 3]
}])
# Set a displayCol.
self.apply_user_action(['SetDisplayFormula', 'Favorites', None, 25, '$favorite.show'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id > 24), data=[
["id" , "colId" , "parentId", "displayCol", "type", "formula"],
[25 , "favorite" , 2 , 27 , "Ref:Television", ""],
[26 , "favorite2" , 2 , 0 , "Text", ""],
[27 , "gristHelper_Display" , 2 , 0 , "Any", "$favorite.show"],
])
# Copy 'favorite' to 'favorite2': displayCol should be set on the latter.
self.apply_user_action(['CopyFromColumn', 'Favorites', 'favorite', 'favorite2', None])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id > 24), data=[
["id" , "colId" , "parentId", "displayCol", "type", "formula"],
[25 , "favorite" , 2 , 27 , "Ref:Television", ""],
[26 , "favorite2" , 2 , 28 , "Ref:Television", ""],
[27 , "gristHelper_Display" , 2 , 0 , "Any", "$favorite.show"],
[28 , "gristHelper_Display2", 2 , 0 , "Any", "$favorite2.show"],
])
# SetDisplyFormula to a different formula: displayCol should get reused.
self.apply_user_action(['SetDisplayFormula', 'Favorites', None, 25, '$favorite.network'])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id > 24), data=[
["id" , "colId" , "parentId", "displayCol", "type", "formula"],
[25 , "favorite" , 2 , 27 , "Ref:Television", ""],
[26 , "favorite2" , 2 , 28 , "Ref:Television", ""],
[27 , "gristHelper_Display" , 2 , 0 , "Any", "$favorite.network"],
[28 , "gristHelper_Display2", 2 , 0 , "Any", "$favorite2.show"],
])
# Copy again; the destination displayCol should get adjusted but reused.
self.apply_user_action(['CopyFromColumn', 'Favorites', 'favorite', 'favorite2', None])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id > 24), data=[
["id" , "colId" , "parentId", "displayCol", "type", "formula"],
[25 , "favorite" , 2 , 27 , "Ref:Television", ""],
[26 , "favorite2" , 2 , 28 , "Ref:Television", ""],
[27 , "gristHelper_Display" , 2 , 0 , "Any", "$favorite.network"],
[28 , "gristHelper_Display2", 2 , 0 , "Any", "$favorite2.network"],
])
# If we change column type, the displayCol should get unset and deleted.
out_actions = self.apply_user_action(['ModifyColumn', 'Favorites', 'favorite',
{'type': 'Numeric'}])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id > 24), data=[
["id" , "colId" , "parentId", "displayCol", "type", "formula"],
[25 , "favorite" , 2 , 0 , "Numeric", ""],
[26 , "favorite2" , 2 , 28 , "Ref:Television", ""],
[28 , "gristHelper_Display2", 2 , 0 , "Any", "$favorite2.network"],
])
# Copy again; the destination displayCol should now get deleted too.
self.apply_user_action(['CopyFromColumn', 'Favorites', 'favorite', 'favorite2', None])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.id > 24), data=[
["id" , "colId" , "parentId", "displayCol", "type", "formula"],
[25 , "favorite" , 2 , 0 , "Numeric", ""],
[26 , "favorite2" , 2 , 0 , "Numeric", ""],
])
def test_display_col_table_rename(self):
self.load_sample(self.ref_sample)
# Add a table for people to get an associated view.
self.apply_user_action(['AddTable', 'People', [
{'id': 'name', 'type': 'Text'},
{'id': 'favorite', 'type': 'Ref:Television',
'widgetOptions': '\"{\"alignment\":\"center\",\"visibleCol\":\"show\"}\"'},
{'id': 'network', 'type': 'Any', 'isFormula': True,
'formula': 'Television.lookupOne(show=rec.favorite.show).network'}]])
self.apply_user_action(['BulkAddRecord', 'People', [1,2,3], {
'name': ['Bob', 'Jim', 'Don'],
'favorite': [12, 11, 13]
}])
# Add a display formula for the 'favorite' column.
# A "gristHelper_Display" column with the requested formula should be added and set as the
# displayCol of the favorite column.
self.apply_user_action(['SetDisplayFormula', 'People', None, 26, '$favorite.show'])
# Set display formula for 'favorite' column field.
# A single "gristHelper_Display2" column should be added with the requested formula.
self.apply_user_action(['SetDisplayFormula', 'People', 1, None, '$favorite.network'])
# Check that the tables are set up as expected.
self.assertTables([
Table(1, "Television", 0, 0, columns=[
Column(21, "show", "Text", False, "", 0),
Column(22, "network", "Text", False, "", 0),
Column(23, "viewers", "Int", False, "", 0),
]),
Table(2, "People", 1, 0, columns=[
Column(24, "manualSort", "ManualSortPos", False, "", 0),
Column(25, "name", "Text", False, "", 0),
Column(26, "favorite", "Ref:Television", False, "", 0),
Column(27, "network", "Any", True,
"Television.lookupOne(show=rec.favorite.show).network", 0),
Column(28, "gristHelper_Display", "Any", True, "$favorite.show", 0),
Column(29, "gristHelper_Display2", "Any", True, "$favorite.network", 0)
]),
])
self.assertTableData("People", cols="subset", data=[
["id", "name", "favorite", "network"],
[1, "Bob", 12, "Netflix"],
[2, "Jim", 11, "HBO"],
[3, "Don", 13, "NBC"]
])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.parentId.id == 2),
data=[
["id", "colId", "parentId", "displayCol", "formula"],
[24, "manualSort", 2, 0, ""],
[25, "name", 2, 0, ""],
[26, "favorite", 2, 28, ""],
[27, "network", 2, 0,
"Television.lookupOne(show=rec.favorite.show).network"],
[28, "gristHelper_Display", 2, 0, "$favorite.show"],
[29, "gristHelper_Display2", 2, 0, "$favorite.network"]
])
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 26, 0],
[3, 27, 0]
])
# Rename the referenced table.
out_actions = self.apply_user_action(['RenameTable', 'Television', 'Television2'])
# Verify the resulting actions.
# This tests a bug fix where table renames would cause widgetOptions and displayCols
# of columns referencing the renamed table to be unset. See https://phab.getgrist.com/T206.
# Ensure that no actions are generated to unset the widgetOptions and the displayCols of the
# field or column.
self.assertPartialOutActions(out_actions, {
"stored": [
["ModifyColumn", "People", "favorite", {"type": "Int"}],
["RenameTable", "Television", "Television2"],
["UpdateRecord", "_grist_Tables", 1, {"tableId": "Television2"}],
["ModifyColumn", "People", "favorite", {"type": "Ref:Television2"}],
["ModifyColumn", "People", "network",
{"formula": "Television2.lookupOne(show=rec.favorite.show).network"}],
["BulkUpdateRecord", "_grist_Tables_column", [26, 27], {
"formula": ["", "Television2.lookupOne(show=rec.favorite.show).network"],
"type": ["Ref:Television2", "Any"]
}]
],
"calc": []
})
# Verify that the tables have responded as expected to the change.
self.assertTables([
Table(1, "Television2", 0, 0, columns=[
Column(21, "show", "Text", False, "", 0),
Column(22, "network", "Text", False, "", 0),
Column(23, "viewers", "Int", False, "", 0),
]),
Table(2, "People", 1, 0, columns=[
Column(24, "manualSort", "ManualSortPos", False, "", 0),
Column(25, "name", "Text", False, "", 0),
Column(26, "favorite", "Ref:Television2", False, "", 0),
Column(27, "network", "Any", True,
"Television2.lookupOne(show=rec.favorite.show).network", 0),
Column(28, "gristHelper_Display", "Any", True, "$favorite.show", 0),
Column(29, "gristHelper_Display2", "Any", True, "$favorite.network", 0)
]),
])
self.assertTableData("People", cols="subset", data=[
["id", "name", "favorite", "network"],
[1, "Bob", 12, "Netflix"],
[2, "Jim", 11, "HBO"],
[3, "Don", 13, "NBC"]
])
self.assertTableData("_grist_Tables_column", cols="subset", rows=(lambda r: r.parentId.id == 2),
data=[
["id", "colId", "parentId", "displayCol", "formula"],
[24, "manualSort", 2, 0, ""],
[25, "name", 2, 0, ""],
[26, "favorite", 2, 28, ""],
[27, "network", 2, 0,
"Television2.lookupOne(show=rec.favorite.show).network"],
[28, "gristHelper_Display", 2, 0, "$favorite.show"],
[29, "gristHelper_Display2", 2, 0, "$favorite.network"]
])
self.assertTableData(
"_grist_Views_section_field", cols="subset", rows=lambda r: r.parentId.parentId, data=[
["id", "colRef", "displayCol"],
[1, 25, 29],
[2, 26, 0],
[3, 27, 0]
])