예제 #1
0
    def process_apply_step(self, data):
        """
    Processes the "APPLY" step of a test script, applying a user action, and checking the
    resulting action group's return value (if present)
    """
        if "USER_ACTION" in data:
            user_actions = [useractions.from_repr(data.pop("USER_ACTION"))]
        else:
            user_actions = [
                useractions.from_repr(u) for u in data.pop("USER_ACTIONS")
            ]

        expected_call_counts = data.pop("CHECK_CALL_COUNTS", None)
        expected_actions = data.pop("ACTIONS", {})
        expected_actions.setdefault("stored", [])
        expected_actions.setdefault("calc", [])
        expected_actions.setdefault("undo", [])

        if data:
            raise ValueError("Unrecognized key %s in APPLY step" %
                             data.popitem()[0])

        self.call_counts.clear()
        out_actions = self.engine.apply_user_actions(user_actions)

        self.assertOutActions(out_actions, expected_actions)
        if expected_call_counts:
            self.assertEqual(self.call_counts, expected_call_counts)
        return out_actions
예제 #2
0
 def test_multiple_renames(self):
     # Combine several renames into one bundle.
     self.engine.apply_user_actions([
         useractions.from_repr(ua) for ua in (
             ['RenameColumn', 'Students', 'firstName', 'Given_Name'],
             ['RenameColumn', 'Students', 'lastName', 'Family_Name'],
             ['RenameTable', 'Students', 'Students2'],
             ['RenameColumn', 'Students2', 'schoolName', 'escuela'],
             ['RenameColumn', 'Schools', 'name', 'schoolName'],
         )
     ])
     self.assertTableData('_grist_ACLResources',
                          cols="subset",
                          data=[
                              ['id', 'tableId', 'colIds'],
                              [1, '*', '*'],
                              [2, 'Students2', 'Given_Name,Family_Name'],
                              [3, 'Students2', '*'],
                          ])
     self.assertTableData(
         '_grist_ACLRules',
         cols="subset",
         data=[
             [
                 'id', 'resource', 'aclFormula', 'permissionsText',
                 'userAttributes'
             ],
             [1, 1, '', '', json.dumps(user_attr1)],
             [
                 2, 2,
                 '( rec.escuela !=  # ünîcødé comment\n  user.School.schoolName)',
                 'none', ''
             ],
             [3, 3, '', 'all', ''],
         ])
예제 #3
0
  def test_useraction_failures(self):
    # Verify that when a useraction fails, we revert any changes already applied.

    self.load_sample(self.sample)

    # Simple failure: bad action (last argument should be a dict). It shouldn't cause any actions
    # in the first place, just raise an exception about the argument being an int.
    with self.assertRaisesRegexp(AttributeError, r"'int'"):
      self.apply_user_action(['AddColumn', 'Address', "A", 17])

    # Do some successful actions, just to make sure we know what they look like.
    self.engine.apply_user_actions([useractions.from_repr(ua) for ua in (
      ['AddColumn', 'Address', "B", {"isFormula": True}],
      ['UpdateRecord', 'Address', 11, {"city": "New York2"}],
    )])

    # More complicated: here some actions should succeed, but get reverted when a later one fails.
    with self.assertRaisesRegexp(AttributeError, r"'int'"):
      self.engine.apply_user_actions([useractions.from_repr(ua) for ua in (
        ['UpdateRecord', 'Address', 11, {"city": "New York3"}],
        ['AddColumn', 'Address', "C", {"isFormula": True}],
        ['AddColumn', 'Address', "D", 17]
      )])

    with self.assertRaisesRegexp(Exception, r"non-existent record #77"):
      self.engine.apply_user_actions([useractions.from_repr(ua) for ua in (
        ['UpdateRecord', 'Address', 11, {"city": "New York4"}],
        ['UpdateRecord', 'Address', 77, {"city": "Chicago"}],
      )])

    # Make sure that no columns got added except the intentionally successful one.
    self.assertTableData('_grist_Tables_column', cols="subset", data=[
      ["id",  "colId",      "type",         "isFormula",  "formula"],
      [21,     "city",       "Text",         False,        ""],
      [22,     "B",          "Any",          True,         ""],
    ], rows=lambda r: r.parentId.id == 1)

    # Make sure that no columns got added here either, and the only change to "New York" is the
    # one in the successful user-action.
    self.assertTableData('Address', cols="all", data=[
      ["id",  "city"      , "B"   ],
      [11,    "New York2" , None  ],
      [12,    "Colombia"  , None  ],
      [13,    "New Haven" , None  ],
      [14,    "West Haven", None  ],
    ])
예제 #4
0
  def apply_user_action(self, user_action_repr, is_undo=False):
    if not is_undo:
      log.debug("Applying user action %r" % (user_action_repr,))
      if self._undo_state_tracker is not None:
        doc_state = self.getFullEngineData()

    self.call_counts.clear()
    out_actions = self.engine.apply_user_actions([useractions.from_repr(user_action_repr)])
    out_actions.calls = self.call_counts.copy()

    if not is_undo and self._undo_state_tracker is not None:
      self._undo_state_tracker.append((doc_state, out_actions.undo[:]))
    return out_actions
예제 #5
0
 def apply_user_actions(action_reprs, user=None):
     action_group = eng.apply_user_actions(
         [useractions.from_repr(u) for u in action_reprs], user)
     return eng.acl_split(action_group).to_json_obj()
예제 #6
0
    def setUp(self):
        super(TestACLRenames, self).setUp()

        self.load_sample(testsamples.sample_students)

        # Add column to Schools to use with User Attribute.
        self.engine.apply_user_actions([
            useractions.from_repr(ua) for ua in (
                ['AddColumn', 'Schools', 'LiasonEmail', {
                    'type': 'Text'
                }],
                [
                    'AddRecord', '_grist_ACLResources', -1, {
                        'tableId': '*',
                        'colIds': '*'
                    }
                ],
                [
                    'AddRecord', '_grist_ACLRules', None, {
                        'resource': -1,
                        'userAttributes': json.dumps(user_attr1),
                    }
                ],
                [
                    'AddRecord', '_grist_ACLResources', -2, {
                        'tableId': 'Students',
                        'colIds': 'firstName,lastName'
                    }
                ],
                [
                    'AddRecord', '_grist_ACLResources', -3, {
                        'tableId': 'Students',
                        'colIds': '*'
                    }
                ],
                [
                    'AddRecord',
                    '_grist_ACLRules',
                    None,
                    {
                        'resource': -2,
                        # Include comments and unicode to check that renaming respects all that.
                        'aclFormula':
                        '( rec.schoolName !=  # ünîcødé comment\n  user.School.name)',
                        'permissionsText': 'none',
                    }
                ],
                [
                    'AddRecord', '_grist_ACLRules', None, {
                        'resource': -3,
                        'permissionsText': 'all'
                    }
                ],
            )
        ])

        # Here's what we expect to be in the ACL tables (for reference in tests below).
        self.assertTableData('_grist_ACLResources',
                             cols="subset",
                             data=[
                                 ['id', 'tableId', 'colIds'],
                                 [1, '*', '*'],
                                 [2, 'Students', 'firstName,lastName'],
                                 [3, 'Students', '*'],
                             ])
        self.assertTableData(
            '_grist_ACLRules',
            cols="subset",
            data=[
                [
                    'id', 'resource', 'aclFormula', 'permissionsText',
                    'userAttributes'
                ],
                [1, 1, '', '', json.dumps(user_attr1)],
                [
                    2, 2,
                    '( rec.schoolName !=  # ünîcødé comment\n  user.School.name)',
                    'none', ''
                ],
                [3, 3, '', 'all', ''],
            ])
예제 #7
0
    def test_temp_row_ids(self):
        self.load_sample(testsamples.sample_students)

        out_actions = self.engine.apply_user_actions([
            useractions.from_repr(ua) for ua in (
                # Add a mix of records with or without temp rowIds.
                ['AddRecord', 'Address', None, {
                    'city': 'A'
                }],
                ['AddRecord', 'Address', -1, {
                    'city': 'B'
                }],
                [
                    'BulkAddRecord', 'Address', [-3, None, -7, -10], {
                        'city': ['C', 'D', 'E', 'F']
                    }
                ],

                # -3 translates to C; the new record of -1 applies to a different table, so doesn't affect
                # its translation to city A.
                [
                    'AddRecord', 'Schools', -1, {
                        'address': -3,
                        'name': 'SUNY C'
                    }
                ],

                # Add a mix of records referring to new, existing, or null rows.
                [
                    'BulkAddRecord', 'Schools', [None, None, None, None, None],
                    {
                        'address': [-1, 11, 0, -3, -7],
                        'name':
                        ['SUNY A', 'NYU', 'Xavier', 'Suny C2', 'Suny E'],
                    }
                ],

                # Try a few updates too.
                ['UpdateRecord', 'Schools', 1, {
                    'address': -7
                }],
                [
                    'BulkUpdateRecord', 'Schools', [2, 3, 4], {
                        'address': [-3, -1, 11]
                    }
                ],

                # Later temp rowIds override previous one. Here, -3 was already used.
                ['AddRecord', 'Address', -3, {
                    'city': 'G'
                }],
                [
                    'AddRecord', 'Schools', None, {
                        'address': -3,
                        'name': 'SUNY G'
                    }
                ],
            )
        ])

        # Test that we get the correct resulting data.
        self.assertTableData(
            'Address',
            cols="subset",
            data=[
                ["id", "city"],
                [11, "New York"],
                [12, "Colombia"],
                [13, "New Haven"],
                [14, "West Haven"],
                [15, "A"],
                [16, "B"],  # was -1
                [17, "C"],  # was -3
                [18, "D"],
                [19, "E"],  # was -7
                [20, "F"],  # was -10
                [21, "G"],  # was -3
            ])
        self.assertTableData('Schools',
                             cols="subset",
                             data=[
                                 ["id", "name", "address"],
                                 [1, "Columbia", 19],
                                 [2, "Columbia", 17],
                                 [3, "Yale", 16],
                                 [4, "Yale", 11],
                                 [5, "SUNY C", 17],
                                 [6, "SUNY A", 16],
                                 [7, "NYU", 11],
                                 [8, "Xavier", 0],
                                 [9, "Suny C2", 17],
                                 [10, "Suny E", 19],
                                 [11, "SUNY G", 21],
                             ])

        # Test that the actions above got properly translated.
        # These are same as above, except for the translated rowIds.
        self.assertPartialOutActions(
            out_actions,
            {
                "stored": [
                    ['AddRecord', 'Address', 15, {
                        'city': 'A'
                    }],
                    ['AddRecord', 'Address', 16, {
                        'city': 'B'
                    }],
                    [
                        'BulkAddRecord', 'Address', [17, 18, 19, 20], {
                            'city': ['C', 'D', 'E', 'F']
                        }
                    ],
                    [
                        'AddRecord', 'Schools', 5, {
                            'address': 17,
                            'name': 'SUNY C'
                        }
                    ],
                    [
                        'BulkAddRecord', 'Schools', [6, 7, 8, 9, 10], {
                            'address': [16, 11, 0, 17, 19],
                            'name':
                            ['SUNY A', 'NYU', 'Xavier', 'Suny C2', 'Suny E'],
                        }
                    ],
                    ['UpdateRecord', 'Schools', 1, {
                        'address': 19
                    }],
                    [
                        'BulkUpdateRecord', 'Schools', [2, 3, 4], {
                            'address': [17, 16, 11]
                        }
                    ],
                    ['AddRecord', 'Address', 21, {
                        'city': 'G'
                    }],
                    [
                        'AddRecord', 'Schools', 11, {
                            'address': 21,
                            'name': 'SUNY G'
                        }
                    ],

                    # Calculated values (for Students; lookups on schools named "Columbia" and "Yale")
                    [
                        "BulkUpdateRecord", "Students", [1, 2, 3, 4, 6], {
                            "schoolCities": [
                                "E:C", "B:New York", "E:C", "B:New York",
                                "B:New York"
                            ]
                        }
                    ],
                ]
            })