def test_feature_page_submit_change_to_empty(self): """Correctly handle submitting an empty value.""" # Zope has the quirk of conflating empty with absent; make sure we # handle it properly. browser = self.getUserBrowserAsAdmin() browser.open(self.getFeatureRulesEditURL()) new_value = '' textarea = browser.getControl(name="field.feature_rules") textarea.value = new_value browser.getControl(name="field.comment").value = 'comment' browser.getControl(name="field.actions.change").click() self.assertThat(list(StormFeatureRuleSource().getAllRulesAsTuples()), Equals([]))
def make_script_feature_controller(script_name): """Create a `FeatureController` for the named script. You can then install this feature controller using `install_feature_controller`. """ # Avoid circular import. from lp.services.features.flags import FeatureController from lp.services.features.rulesource import StormFeatureRuleSource from lp.services.features.scopes import ScopesForScript return FeatureController( ScopesForScript(script_name).lookup, StormFeatureRuleSource())
def test_getFeatureFlag_ignores_relevant_feature_controller(self): # getFeatureFlag should only consider the scopes it is asked to # consider, not any that happen to be active due to the XML-RPC # request itself. flag_name = u'flag' scope_name = u'scope' self.installFeatureController( FeatureController( MultiScopeHandler([DefaultScope(), FixedScope(scope_name)]).lookup, StormFeatureRuleSource())) set_feature_flag(flag_name, u'1', scope_name) self.assertEqual(None, self.endpoint.getFeatureFlag(flag_name))
def getFeatureFlag(self, flag_name, active_scopes=()): scopes = list(default_scopes) for scope_name in active_scopes: if scope_name.startswith('user:'******'user:'):]) if person is not None: scopes.append(TeamScope(lambda: person)) else: scopes.append(FixedScope(scope_name)) flag_name = unicode(flag_name) controller = FeatureController( MultiScopeHandler(scopes).lookup, StormFeatureRuleSource()) return controller.getFlag(flag_name)
def __init__(self, scope_check_callback, rule_source=None): """Construct a new view of the features for a set of scopes. :param scope_check_callback: Given a scope name, says whether it's active or not. :param rule_source: Instance of StormFeatureRuleSource or similar. """ self._known_scopes = Memoize(scope_check_callback) self._known_flags = Memoize(self._checkFlag) # rules are read from the database the first time they're needed self._rules = None self.scopes = ScopeDict(self) if rule_source is None: rule_source = StormFeatureRuleSource() self.rule_source = rule_source self._current_scopes = Memoize(self._findCurrentScope)
def test_feature_page_submit_changes(self): """Submitted changes show up in the db.""" browser = self.getUserBrowserAsAdmin() browser.open(self.getFeatureRulesEditURL()) new_value = 'beta_user some_key 10 some value with spaces' textarea = browser.getControl(name="field.feature_rules") textarea.value = new_value browser.getControl(name="field.comment").value = 'Bob is testing.' browser.getControl(name="field.actions.change").click() self.assertThat( list(StormFeatureRuleSource().getAllRulesAsTuples()), Equals([ ('beta_user', 'some_key', 10, 'some value with spaces'), ])) changes = list(ChangeLog.get()) self.assertEqual(1, len(changes)) self.assertEqual('+beta_user\tsome_key\t10\tsome value with spaces', changes[0].diff) self.assertEqual('Bob is testing.', changes[0].comment) self.assertEqual(self.user, changes[0].person)
def setUp(self): """Set the feature flags that this fixture is responsible for.""" super(FeatureFixture, self).setUp() rule_source = StormFeatureRuleSource() self.addCleanup(rule_source.setAllRules, rule_source.getAllRulesAsTuples()) rule_source.setAllRules(self.makeNewRules()) original_controller = get_relevant_feature_controller() def scope_lookup(scope_name): request = get_current_browser_request() return ScopesFromRequest(request).lookup(scope_name) if self.override_scope_lookup: scope_lookup = self.override_scope_lookup install_feature_controller(FeatureController(scope_lookup, rule_source)) self.addCleanup(install_feature_controller, original_controller)
def test_setAllRulesFromText(self): # We will overwrite existing data. source = StormFeatureRuleSource() source.setAllRules(test_rules_list) source.setAllRulesFromText(""" flag1 beta_user 200 alpha flag1 default 100 gamma with spaces flag2 default 0\ton """) self.assertEquals( { 'flag1': [ ('beta_user', 200, 'alpha'), ('default', 100, 'gamma with spaces'), ], 'flag2': [ ('default', 0, 'on'), ], }, source.getAllRulesAsDict())
def populateStore(self): StormFeatureRuleSource().setAllRules(testdata)
def makeSource(self): return StormFeatureRuleSource()
def start_request(event): """Register FeatureController.""" event.request.features = FeatureController( ScopesFromRequest(event.request).lookup, StormFeatureRuleSource()) install_feature_controller(event.request.features)
def makeRuleSource(self, rules): rule_source = StormFeatureRuleSource() self.addCleanup(dbadmin(rule_source.setAllRules), dbadmin(rule_source.getAllRulesAsTuples)()) dbadmin(rule_source.setAllRules)(rules) return rule_source
def test_getAllRulesAsTuples(self): source = StormFeatureRuleSource() source.setAllRules(test_rules_list) self.assertEquals(test_rules_list, list(source.getAllRulesAsTuples()))