mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
534615dd50
Summary: - Replace logger module by the standard module 'logging'. - When a log message from the sandbox includes newlines (e.g. for tracebacks), keep those lines together in the Node log message. Previously each line was a different message, making it difficult to view tracebacks, particularly in prod where each line becomes a separate message object. - Fix assorted lint errors. Test Plan: Added a test for the log-line splitting and escaping logic. Reviewers: georgegevoian Reviewed By: georgegevoian Differential Revision: https://phab.getgrist.com/D3956
623 lines
29 KiB
Python
623 lines
29 KiB
Python
import logging
|
|
|
|
import testutil
|
|
import test_engine
|
|
from test_engine import Table, Column
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
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(['AddVisibleColumn', '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, False, False],
|
|
"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]
|
|
])
|