def test_not_equal(self): context_1 = context.Context(self.tk, **self.kws) kws2 = copy.deepcopy(self.kws) kws2["task"] = {"id":45, "type": "Task"} context_2 = context.Context(self.tk, **kws2) self.assertFalse(context_1 == context_2) self.assertTrue(context_1 != context_2)
def test_not_equal_with_none(self): context_1 = context.Context(self.tk, **self.kws) kws2 = copy.deepcopy(self.kws) kws2["entity"] = None context_2 = context.Context(self.tk, **kws2) self.assertFalse(context_1 == context_2) self.assertTrue(context_1 != context_2)
def test_equal(self): kws1 = copy.deepcopy(self.kws) kws1["entity"]["foo"] = "foo" context_1 = context.Context(self.tk, **kws1) kws2 = copy.deepcopy(self.kws) # other differing fields in the dictionary should be ignored kws2["entity"]["foo"] = "bar" context_2 = context.Context(self.tk, **kws2) self.assertTrue(context_1 == context_2) self.assertFalse(context_1 != context_2)
def test_additional_entities_not_equal(self): kws1 = copy.deepcopy(self.kws) kws1["additional_entities"] = [ {"type":"Asset", "id":123}, {"type":"Sequence", "id":456} ] context_1 = context.Context(self.tk, **kws1) kws2 = copy.deepcopy(self.kws) kws1["additional_entities"] = [ {"type":"Asset", "id":789}, {"type":"Sequence", "id":456} ] context_2 = context.Context(self.tk, **kws2) self.assertFalse(context_1 == context_2) self.assertTrue(context_1 != context_2)
def setUp(self): """Sets up entities in mocked shotgun database and creates Mock objects to pass in as callbacks to Schema.create_folders. The mock objects are then queried to see what paths the code attempted to create. """ super(TestShotgunRegisterPublish, self).setUp() self.setup_fixtures() self.storage = {"type": "LocalStorage", "id": 1, "code": "Tank"} self.tank_type_1 = {"type": "TankType", "id": 1, "code": "Maya Scene"} # Add these to mocked shotgun self.add_to_sg_mock_db([self.storage, self.tank_type_1]) self.shot = { "type": "Shot", "name": "shot_name", "id": 2, "project": self.project } self.step = {"type": "Step", "name": "step_name", "id": 4} context_data = { "tk": self.tk, "project": self.project, "entity": self.shot, "step": self.step, } self.context = context.Context(**context_data) self.path = os.path.join(self.project_root, "foo", "bar") self.name = "Test Publish" self.version = 1
def test_lazy_load_user(self, get_current_user): get_current_user.return_value = self.current_user # bug ticket 20272 context_1 = context.Context(self.tk, **self.kws) kws2 = self.kws.copy() # force seed the user for one of the contexts kws2["user"] = {"id": self.current_user["id"], "type": self.current_user["type"], "name": self.current_user["name"]} # the other context should pick up the context # automatically by the equals operator context_2 = context.Context(self.tk, **kws2) self.assertTrue(context_1 == context_2) self.assertFalse(context_1 != context_2)
def setUp(self): super(TestAsTemplateFields, self).setUp() # create a context obj using predefined data kws = {} kws["tk"] = self.tk kws["project"] = self.project kws["entity"] = self.shot kws["step"] = self.step self.ctx = context.Context(**kws) # create a template with which to filter self.keys = { "Sequence": StringKey("Sequence"), "Shot": StringKey("Shot"), "Step": StringKey("Step"), "static_key": StringKey("static_key"), "shotgun_field": StringKey("shotgun_field", shotgun_entity_type="Shot", shotgun_field_name="shotgun_field") } template_def = "/sequence/{Sequence}/{Shot}/{Step}/work" self.template = TemplatePath(template_def, self.keys, self.project_root)
def test_static_ambiguous(self): """ Tests that in case that static values are amiguous, no value is returned for that key. """ # Set up a shot with different static values in paths shot = {"type": "Shot", "id": 3, "name": "shot_3"} shot_path_1 = os.path.join(self.project_root, "static_1", "shot_3") shot_path_2 = os.path.join(self.project_root, "static_2", "shot_3") self.add_production_path(shot_path_1, shot) self.add_production_path(shot_path_2, shot) template_def = "/{static_key}/{Shot}" template = TemplatePath(template_def, self.keys, self.project_root) # Create context for this shot kws = {} kws["tk"] = self.tk kws["project"] = self.project kws["entity"] = shot kws["step"] = self.step ctx = context.Context(**kws) result = ctx.as_template_fields(template) # Check for non-entity value self.assertIsNone(result["static_key"])
def setUp(self): super(TestMultiRoot, self).setUp() self.setup_multi_root_fixtures() self.shot = {"type": "Shot", "name": "shot_name", "id": 2, "project": self.project} self.step = {"type": "Step", "name": "step_name", "id": 4} context_data = { "tk": self.tk, "project": self.project, "entity": self.shot, "step": self.step, } self.context = context.Context(**context_data) self.path = os.path.join(self.project_root, "foo", "bar") self.name = "Test Publish" self.version = 1 # mock server caps so we can test local storage mapping for publishes class server_capsMock: def __init__(self): self.version = (7, 0, 1) self.mockgun.server_caps = server_capsMock() # Prevents an actual connection to a Shotgun site. self._server_caps_mock = patch("tank_vendor.shotgun_api3.Shotgun.server_caps") self._server_caps_mock.start() self.addCleanup(self._server_caps_mock.stop)
def setUp(self): super(TestUser, self).setUp() kws1 = {} kws1["tk"] = self.tk kws1["project"] = self.project kws1["entity"] = self.shot kws1["step"] = self.step self.context = context.Context(**kws1)
def test_additional_entities_equal(self): kws1 = copy.deepcopy(self.kws) kws1["additional_entities"] = [ {"type":"Asset", "id":123, "foo":"bar"}, {"type":"Sequence", "id":456, "foo":"bar"} ] context_1 = context.Context(self.tk, **kws1) kws2 = copy.deepcopy(self.kws) kws2["additional_entities"] = [ # Only type & id difference should matter {"type":"Sequence", "id":456, "bar":"foo"}, {"type":"Asset", "id":123, "bar":"foo"}, # None entries should be ignored None, # and ok to have the same entity twice {"type":"Sequence", "id":456, "bar":"foo"} ] context_2 = context.Context(self.tk, **kws2) self.assertTrue(context_1 == context_2) self.assertFalse(context_1 != context_2)
def setUp(self): """Sets up entities in mocked shotgun database and creates Mock objects to pass in as callbacks to Schema.create_folders. The mock objects are then queried to see what paths the code attempted to create. """ super(TestShotgunRegisterPublish, self).setUp() self.setup_fixtures() self.storage = { "type": "LocalStorage", "id": 1, "code": "Tank" } self.storage_2 = { "type": "LocalStorage", "id": 2, "code": "my_other_storage", "mac_path": "/tmp/nix", "windows_path": r"x:\tmp\win", "linux_path": "/tmp/nix" } self.storage_3 = { "type": "LocalStorage", "id": 3, "code": "unc paths", "windows_path": r"\\server\share", } # Add these to mocked shotgun self.add_to_sg_mock_db([self.storage, self.storage_2, self.storage_3]) self.shot = {"type": "Shot", "name": "shot_name", "id": 2, "project": self.project} self.step = {"type": "Step", "name": "step_name", "id": 4} context_data = { "tk": self.tk, "project": self.project, "entity": self.shot, "step": self.step, } self.context = context.Context(**context_data) self.path = os.path.join(self.project_root, "foo", "bar") self.name = "Test Publish" self.version = 1
def test_serialize_with_user(self): """ Make sure the user is serialized and restored. """ tank.set_authenticated_user(self._user) ctx = context.Context(**self.kws) ctx_str = tank.Context.serialize(ctx) # Reset the current user to later check if it is restored. tank.set_authenticated_user(None) # Unserializing should restore the user. tank.Context.deserialize(ctx_str) self._assert_same_user(tank.get_authenticated_user(), self._user)
def test_bad_path_cache_entry(self): """ Test that as_template_fields() doesn't return incorrect entity fields when entries in the path cache for an entity are invalid/out-of-date. This can happen if the folder schema/templates are modified after folders have already been created/the path cache has already been populated. For example, given the following path cache: Type | Id | Name | Path ---------------------------------------------------- Sequence | 001 | Seq_001 | /Seq_001 Shot | 002 | Shot_A | /Seq_001/Shot_A Step | 003 | Lighting | /Seq_001/Shot_A/Lighting Step | 003 | Lighting | /Seq_001/blah/Shot_B/Lighting <- this is out of date! Shot | 004 | Shot_B | /Seq_001/blah/Shot_B <- this is out of date! This test ensures that searching for a context containing Step 'Lighting' and Shot 'Shot_B' doesn't return fields for Shot 'Shot_A' by mistake. This would previously happen because the last two entries are out-of-date but the code still managed to find an entry for the Step which it then used to find the (wrong) value of the Shot field. """ # build a new Shot entity and context: test_shot = { "type": "Shot", "code": "shot_bad", "id": 16, "sg_sequence": self.seq, "project": self.project } kws = { "tk": self.tk, "project": self.project, "entity": test_shot, "step": self.step } test_ctx = context.Context(**kws) # add some bad data for this new Shot to the path cache: bad_shot_path = os.path.join(self.seq_path, "bad", "shot_bad") self.add_production_path(bad_shot_path, test_shot) bad_shot_step_path = os.path.join(bad_shot_path, "step_short_name") self.add_production_path(bad_shot_step_path, self.step) # query the template fields: result = test_ctx.as_template_fields(self.template) # check the result: expected_result = {"Step": "step_short_name"} self.assertEquals(result, expected_result)
def test_serialize_without_user(self): """ Make sure the user is not serialized and not restored. """ tank.set_authenticated_user(self._user) ctx = context.Context(**self.kws) ctx_str = tank.Context.serialize(ctx) # Change the current user to make sure that the deserialize operation doesn't # change it back to the original user. other_user = ShotgunAuthenticator().create_script_user( "script_user", "script_key", "https://abc.shotgunstudio.com") tank.set_authenticated_user(other_user) # The unserialized context shouldn't have changed the current user. tank.Context.deserialize(ctx_str) self._assert_same_user(tank.get_authenticated_user(), other_user)
def test_validate_parameter(self): """ Test that the validate parameter behaves correctly when all context fields are found for a template and when they are not. """ # test a context that should resolve a full set of fields: fields = self.ctx.as_template_fields(self.template, validate=True) expected_fields = { "Sequence": "Seq", "Shot": "shot_code", "Step": "step_short_name" } self.assertEquals(fields, expected_fields) # test a context that shouldn't resolve a full set of fields. For this, we create # a new shot and add it to the path cache but we don't add the Step to ensure the # Step key isn't found. other_shot = { "type": "Shot", "code": "shot_other", "id": 16, "sg_sequence": self.seq, "project": self.project } kws = { "tk": self.tk, "project": self.project, "entity": other_shot, "step": self.step } other_shot_path = os.path.join(self.seq_path, "shot_other") self.add_production_path(other_shot_path, other_shot) test_ctx = context.Context(**kws) # check that running with validate=False returns the expected fields: fields = test_ctx.as_template_fields(self.template, validate=False) expected_fields = {"Sequence": "Seq", "Shot": "shot_other"} self.assertEquals(fields, expected_fields) # now check that when validate=True, a TankError is raised: self.assertRaises(TankError, test_ctx.as_template_fields, self.template, True)
def test_non_primary_entity_paths(self): """ Test case that entities have paths in path cache which have roots other than the primary project root. """ # Template using alt root template_def = "/sequence/{Sequence}/{Shot}/{Step}/work" template = TemplatePath(template_def, self.keys, self.alt_root_1) expected_step_name = "step_short_name" expected_shot_name = "shot_code" ctx = context.Context( tk=self.tk, project=self.project, entity=self.shot, step=self.step, ) result = ctx.as_template_fields(template) self.assertEquals(expected_step_name, result['Step']) self.assertEquals(expected_shot_name, result['Shot'])
def test_static(self): """ Tests that values for keys which do not map to entities are found. """ # Set up a shot with static value in path shot = {"type": "Shot", "id": 3, "name": "shot_3"} shot_path = os.path.join(self.project_root, "static", "shot_3") self.add_production_path(shot_path, shot) template_def = "/{static_key}/{Shot}" template = TemplatePath(template_def, self.keys, self.project_root) # Create context for this shot kws = {} kws["tk"] = self.tk kws["project"] = self.project kws["entity"] = shot kws["step"] = self.step ctx = context.Context(**kws) result = ctx.as_template_fields(template) # Check for non-entity value self.assertEquals("static", result["static_key"])
def test_equal_custom(self): context_1 = context.Context(**self.kws) serialized = tank.context.serialize(context_1) context_2 = tank.context.deserialize(serialized) self.assertTrue(context_1 == context_2)
def test_equal_yml(self): context_1 = context.Context(**self.kws) serialized = yaml.dump(context_1) context_2 = yaml.load(serialized) self.assertTrue(context_1 == context_2)
def test_empty_context(self): empty_context = context.Context(self.tk) result = context.create_empty(self.tk) self.assertTrue(empty_context, result)
def test_not_context(self): context_1 = context.Context(self.tk, **self.kws) not_context = object() self.assertFalse(context_1 == not_context) self.assertTrue(context_1 != not_context)
def test_equal(self): context_1 = context.Context(**self.kws) context_2 = context.Context(**self.kws) self.assertTrue(context_1 == context_2) self.assertFalse(context_1 != context_2)