def test_merges_old_and_new_client_data(self): original_client_data = {"a": 1, "b": 2} updated_client_data = {"b": 3} meta = FeatureFlagStoreMeta(self.now, original_client_data) meta.update(client_data=updated_client_data) self.assertEqual( { "a": original_client_data["a"], "b": updated_client_data["b"] }, meta.client_data, )
def test_when_asynch_is_false_sets_meta_in_primary_and_replicas(self): feature_name = self.txt() meta = FeatureFlagStoreMeta(datetime(2018, 5, 4)) self.store.create(feature_name, asynch=False) self.store.set_meta(feature_name, meta, asynch=False) self.assertTrue( all([ self.primary.get(feature_name).meta == meta.to_dict(), *[ replica.get(feature_name).meta == meta.to_dict() for replica in self.replicas ], ]))
def test_calls_rpc_client_with_correct_args(self): feature_name = self.txt() client_data = {self.txt(): self.txt()} created_date = self.date() meta = FeatureFlagStoreMeta( created_date, client_data, conditions=[Condition(foo__lte=99)], bucketer=ConsistentHashPercentageBucketer( key_whitelist=["baz"], percentage=LinearRampPercentage() ), ) self.store.set_meta(feature_name, meta) self.client.SetMeta.assert_called_once_with( feature_name, TFeatureFlagStoreMeta( created_date=meta.created_date, client_data=json.dumps(client_data), conditions=[ { "foo": [ TConditionCheck( variable="foo", value="99", operator=TConditionOperator(symbol="lte"), ) ] } ], bucketer=json.dumps(meta.bucketer.to_dict()), ), )
def test_returns_instance_of_class(self): name = self.txt() is_enabled = True meta = FeatureFlagStoreMeta(self.now, {}) item = FeatureFlagStoreItem(name, is_enabled, meta) serialized = item.serialize() deserialized = FeatureFlagStoreItem.deserialize(serialized) self.assertTrue(isinstance(deserialized, FeatureFlagStoreItem))
def test_sets_correct_is_enabled(self): name = self.txt() is_enabled = True meta = FeatureFlagStoreMeta(self.now, {}) item = FeatureFlagStoreItem(name, is_enabled, meta) serialized = item.serialize() deserialized = FeatureFlagStoreItem.deserialize(serialized) self.assertEqual(is_enabled, deserialized.is_enabled())
def test_sets_correct_client_data(self): name = self.txt() is_enabled = True client_data = {"foo": "bar"} meta = FeatureFlagStoreMeta(self.now, client_data) item = FeatureFlagStoreItem(name, is_enabled, meta) serialized = item.serialize() deserialized = FeatureFlagStoreItem.deserialize(serialized) self.assertEqual(client_data, deserialized.to_dict()["meta"]["client_data"])
def test_sets_created_date_correctly(self): feature_name = self.txt() self.fast.create(feature_name) meta = FeatureFlagStoreMeta(int(datetime.now().timestamp())) self.fast.set_meta(feature_name, meta) self.assertEqual(meta.created_date, self.fast.get(feature_name).meta["created_date"])
def test_returns_false_when_bucketer_returns_true_and_conditions_return_false( self ): # noqa: E501 # flag.is_enabled(user_id=1, is_admin=False) # False bucketer = MagicMock() bucketer.check.return_value = True condition = Condition(is_admin=True) meta = FeatureFlagStoreMeta(self.now, bucketer=bucketer, conditions=[condition]) item = FeatureFlagStoreItem(self.txt(), True, meta) self.assertFalse(item.is_enabled(is_admin=False))
def test_sets_client_data_correctly(self): feature_name = self.txt() self.store.create(feature_name) client_data = {self.txt(): self.txt()} meta = FeatureFlagStoreMeta(self.date(), client_data) self.store.set_meta(feature_name, meta) item = self.store.get(feature_name) self.assertEqual(client_data, item.meta["client_data"])
def test_sets_client_data_correctly(self): feature_name = self.txt() self.fast.create(feature_name) meta = FeatureFlagStoreMeta(int(datetime.now().timestamp()), client_data={self.txt(): self.txt}) self.fast.set_meta(feature_name, meta) self.assertEqual(meta.client_data, self.fast.get(feature_name).meta["client_data"])
def test_converts_metadata_properly(self): feature_name = self.txt() self.store.create(feature_name, is_enabled=True) item = self.store.get(feature_name) expected = FeatureFlagStoreMeta( created_date=self.meta.created_date, client_data=json.loads(self.meta.client_data), conditions=[Condition(foo__lte=99)], bucketer=ConsistentHashPercentageBucketer( key_whitelist=["baz"], percentage=LinearRampPercentage( initial_time=json.loads(self.meta.bucketer)["percentage"][ "initial_time" ] ), ), ) self.assertEqual(expected.to_dict(), item.meta)
def test_sets_conditions_correctly(self): feature_name = self.txt() self.fast.create(feature_name) condition = Condition(**{self.txt(): self.txt()}) meta = FeatureFlagStoreMeta(int(datetime.now().timestamp()), conditions=[condition]) self.fast.set_meta(feature_name, meta) self.assertEqual(condition.to_dict(), self.fast.get(feature_name).meta["conditions"][0])
def test_forwards_all_arguments_to_stores(self): feature_name = self.txt() meta = FeatureFlagStoreMeta(datetime(2018, 5, 4)) primary = MagicMock() replicas = [MagicMock(), MagicMock(), MagicMock()] store = ReplicatedFeatureFlagStore(primary, *replicas) store.create(feature_name, asynch=False) args = (feature_name, meta) kwargs = {} store.set_meta(*args, **kwargs) primary.set_meta.assert_called_once_with(*args, **kwargs) for replica in replicas: replica.set_meta.assert_called_once_with(*args, **kwargs)
def test_includes_correct_is_enabled_when_false(self): is_enabled = False item = FeatureFlagStoreItem( self.txt(), is_enabled, FeatureFlagStoreMeta(self.now, {}) ) self.assertEqual(is_enabled, item.to_dict()["is_enabled"])
def test_updates_created_date(self): later = self.now + 1 meta = FeatureFlagStoreMeta(self.now, {}) meta.update(created_date=later) self.assertEqual(later, meta.created_date)
def test_updates_client_data(self): updated_client_data = {self.txt(): self.txt()} meta = FeatureFlagStoreMeta(self.now, {}) meta.update(client_data=updated_client_data) self.assertEqual(updated_client_data, meta.client_data)
def test_updating_created_date_does_not_affect_client_data(self): later = self.now + 1 meta = FeatureFlagStoreMeta(self.now, {}) meta.update(created_date=later) self.assertEqual({}, meta.client_data)
def test_updating_client_data_does_not_affect_created_date(self): updated_client_data = {self.txt(): self.txt()} meta = FeatureFlagStoreMeta(self.now, {}) meta.update(client_data=updated_client_data) self.assertEqual(self.now, meta.created_date)
def test_contains_all_fields_from_json(self): name = self.txt() is_enabled = True meta = FeatureFlagStoreMeta(self.now, {}) item = FeatureFlagStoreItem(name, is_enabled, meta) self.assertEqual(json.dumps(item.to_dict()), item.serialize().decode("utf-8"))
def test_sets_conditions(self): conditions = [Condition(foo=1)] meta = FeatureFlagStoreMeta(self.now) meta.update(conditions=conditions) self.assertEqual(conditions, meta.conditions)
def test_includes_correct_feature_name(self): name = self.txt() meta = FeatureFlagStoreMeta(self.now, {}) item = FeatureFlagStoreItem(name, True, meta) self.assertEqual(name, item.to_dict()["feature_name"])
def test_will_not_crash_if_conditions_not_present(self): json = {"created_date": self.now, "client_data": {}} meta = FeatureFlagStoreMeta.from_dict(json) self.assertEqual([], meta.conditions)
def test_returns_true_if_bucketer_check_returns_true(self): bucketer = MagicMock() bucketer.check.return_value = True meta = FeatureFlagStoreMeta(self.now, bucketer=bucketer) item = FeatureFlagStoreItem(self.txt(), True, meta) self.assertTrue(item.is_enabled())
def test_is_true_if_all_of_many_conditions_are_matched(self): conditions = [Condition(foo=True), Condition(x=9)] meta = FeatureFlagStoreMeta(self.now, conditions=conditions) item = FeatureFlagStoreItem(self.txt(), True, meta) self.assertTrue(item.is_enabled(foo=True, x=9))
def test_is_false_if_conditions_are_not_matched(self): meta = FeatureFlagStoreMeta(self.now, conditions=[Condition(foo=True)]) item = FeatureFlagStoreItem(self.txt(), True, meta) self.assertFalse(item.is_enabled(foo=False))
def test_is_enabled_is_false(self): meta = FeatureFlagStoreMeta(self.now, {}) item = FeatureFlagStoreItem(self.txt(), False, meta) self.assertFalse(item.is_enabled())
def test_can_create_with_bucketer(self): bucketer = PercentageBucketer(percentage=Percentage(0.3)) json = {"created_date": self.now, "bucketer": bucketer.to_dict()} meta = FeatureFlagStoreMeta.from_dict(json) self.assertEqual(bucketer.to_dict(), meta.bucketer.to_dict())
def test_includes_correct_meta(self): client_data = {"foo": "bar"} meta = FeatureFlagStoreMeta(self.now, client_data) item = FeatureFlagStoreItem(self.txt(), True, meta) self.assertEqual(meta.to_dict(), item.to_dict()["meta"])
def test_includes_currect_bucketer(self): bucketer = PercentageBucketer(percentage=Percentage(0.3)) meta = FeatureFlagStoreMeta(self.now, bucketer=bucketer) self.assertEqual(bucketer.to_dict(), meta.to_dict()["bucketer"])
def test_is_base_64_encoded(self): name = self.txt() is_enabled = True meta = FeatureFlagStoreMeta(self.now, {}) item = FeatureFlagStoreItem(name, is_enabled, meta) self.assertTrue(isinstance(item.serialize().decode("utf-8"), str))