diff --git a/grails-app/conf/Config.groovy b/grails-app/conf/Config.groovy index f127d85..f437439 100644 --- a/grails-app/conf/Config.groovy +++ b/grails-app/conf/Config.groovy @@ -1,5 +1,9 @@ // configuration for plugin testing - will not be included in the plugin zip +featuresConfig { + allowToggling = true +} + features { alwaysOn { enabled = true diff --git a/grails-app/controllers/uk/co/desirableobjects/featureswitch/FeatureSwitchAdminController.groovy b/grails-app/controllers/uk/co/desirableobjects/featureswitch/FeatureSwitchAdminController.groovy index 4e9ad0e..6d6a355 100644 --- a/grails-app/controllers/uk/co/desirableobjects/featureswitch/FeatureSwitchAdminController.groovy +++ b/grails-app/controllers/uk/co/desirableobjects/featureswitch/FeatureSwitchAdminController.groovy @@ -27,20 +27,32 @@ class FeatureSwitchAdminController { } - def toggle(String feature) { - - grailsApplication.config.features[feature].enabled = !grailsApplication.config.features[feature].enabled - redirect action: 'switches' + private def modifyFeature(String feature, boolean enabled, Closure renderSuccess) { + if (grailsApplication.config.featuresConfig.allowToggling) { + grailsApplication.config.features[feature].enabled = enabled + renderSuccess() + } else { + response.status = 403 + render "Modifying features at run time has been disabled" + } + } + def toggle(String feature) { + boolean toggled = !grailsApplication.config.features[feature].enabled + modifyFeature feature, toggled, { + redirect action: 'switches' + } } def enable(String feature) { - grailsApplication.config.features[feature].enabled = true - render text: [(feature): 'enabled'] as JSON + modifyFeature feature, true, { + render text: [(feature): 'enabled'] as JSON + } } def disable(String feature) { - grailsApplication.config.features[feature].enabled = false - render text: [(feature): 'disabled'] as JSON + modifyFeature feature, false, { + render text: [(feature): 'disabled'] as JSON + } } } diff --git a/test/unit/uk/co/desirableobjects/featureswitch/FeatureSwitchAdminControllerSpec.groovy b/test/unit/uk/co/desirableobjects/featureswitch/FeatureSwitchAdminControllerSpec.groovy new file mode 100644 index 0000000..c23bbe7 --- /dev/null +++ b/test/unit/uk/co/desirableobjects/featureswitch/FeatureSwitchAdminControllerSpec.groovy @@ -0,0 +1,32 @@ +package uk.co.desirableobjects.featureswitch + +import spock.lang.Specification +import grails.test.mixin.TestFor +import spock.lang.Unroll + +@Unroll +@TestFor(FeatureSwitchAdminController) +class FeatureSwitchAdminControllerSpec extends Specification { + + def "ability to toggle features can be disabled" (boolean allowToggling, boolean startState, Closure endpoint, boolean endState, int responseCode) { + given: + def featureName = "theFeature" + grailsApplication.config.features[featureName].enabled = startState + and: + grailsApplication.config.featuresConfig.allowToggling = allowToggling + when: + endpoint(featureName) + then: + response.status == responseCode + and: + grailsApplication.config.features[featureName].enabled == endState + where: + allowToggling | startState | endpoint | endState | responseCode + false | true | {controller.disable(it)} | true | 403 + false | false | {controller.enable(it)} | false | 403 + false | true | {controller.toggle(it)} | true | 403 + true | true | {controller.disable(it)} | false | 200 + true | false | {controller.enable(it)} | true | 200 + true | true | {controller.toggle(it)} | false | 302 + } +}