BigW Consortium Gitlab

features_spec.rb 8.29 KB
Newer Older
1 2 3 4 5 6
require 'spec_helper'

describe API::Features do
  let(:user)  { create(:user) }
  let(:admin) { create(:admin) }

7 8 9 10 11 12 13
  before do
    Flipper.unregister_groups
    Flipper.register(:perf_team) do |actor|
      actor.respond_to?(:admin) && actor.admin?
    end
  end

14 15 16 17 18 19 20 21 22 23 24 25
  describe 'GET /features' do
    let(:expected_features) do
      [
        {
          'name' => 'feature_1',
          'state' => 'on',
          'gates' => [{ 'key' => 'boolean', 'value' => true }]
        },
        {
          'name' => 'feature_2',
          'state' => 'off',
          'gates' => [{ 'key' => 'boolean', 'value' => false }]
26 27 28 29 30 31 32 33
        },
        {
          'name' => 'feature_3',
          'state' => 'conditional',
          'gates' => [
            { 'key' => 'boolean', 'value' => false },
            { 'key' => 'groups', 'value' => ['perf_team'] }
          ]
34 35 36 37 38 39 40
        }
      ]
    end

    before do
      Feature.get('feature_1').enable
      Feature.get('feature_2').disable
41
      Feature.get('feature_3').enable Feature.group(:perf_team)
42 43 44 45 46
    end

    it 'returns a 401 for anonymous users' do
      get api('/features')

47
      expect(response).to have_gitlab_http_status(401)
48 49 50 51 52
    end

    it 'returns a 403 for users' do
      get api('/features', user)

53
      expect(response).to have_gitlab_http_status(403)
54 55 56 57 58
    end

    it 'returns the feature list for admins' do
      get api('/features', admin)

59
      expect(response).to have_gitlab_http_status(200)
60 61 62 63 64 65 66
      expect(json_response).to match_array(expected_features)
    end
  end

  describe 'POST /feature' do
    let(:feature_name) { 'my_feature' }

67 68 69
    context 'when the feature does not exist' do
      it 'returns a 401 for anonymous users' do
        post api("/features/#{feature_name}")
70

71
        expect(response).to have_gitlab_http_status(401)
72
      end
73

74 75
      it 'returns a 403 for users' do
        post api("/features/#{feature_name}", user)
76

77
        expect(response).to have_gitlab_http_status(403)
78
      end
79

80 81 82
      context 'when passed value=true' do
        it 'creates an enabled feature' do
          post api("/features/#{feature_name}", admin), value: 'true'
83

84
          expect(response).to have_gitlab_http_status(201)
85 86 87 88 89 90
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'on',
            'gates' => [{ 'key' => 'boolean', 'value' => true }])
        end

91 92
        it 'creates an enabled feature for the given Flipper group when passed feature_group=perf_team' do
          post api("/features/#{feature_name}", admin), value: 'true', feature_group: 'perf_team'
93

94
          expect(response).to have_gitlab_http_status(201)
95 96 97 98 99 100 101 102 103 104 105
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'conditional',
            'gates' => [
              { 'key' => 'boolean', 'value' => false },
              { 'key' => 'groups', 'value' => ['perf_team'] }
            ])
        end

        it 'creates an enabled feature for the given user when passed user=username' do
          post api("/features/#{feature_name}", admin), value: 'true', user: user.username
106

107
          expect(response).to have_gitlab_http_status(201)
108 109 110 111 112 113 114 115
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'conditional',
            'gates' => [
              { 'key' => 'boolean', 'value' => false },
              { 'key' => 'actors', 'value' => ["User:#{user.id}"] }
            ])
        end
116 117 118 119

        it 'creates an enabled feature for the given user and feature group when passed user=username and feature_group=perf_team' do
          post api("/features/#{feature_name}", admin), value: 'true', user: user.username, feature_group: 'perf_team'

120
          expect(response).to have_gitlab_http_status(201)
121 122 123 124 125 126 127 128 129
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'conditional',
            'gates' => [
              { 'key' => 'boolean', 'value' => false },
              { 'key' => 'groups', 'value' => ['perf_team'] },
              { 'key' => 'actors', 'value' => ["User:#{user.id}"] }
            ])
        end
130 131 132 133 134
      end

      it 'creates a feature with the given percentage if passed an integer' do
        post api("/features/#{feature_name}", admin), value: '50'

135
        expect(response).to have_gitlab_http_status(201)
136 137 138 139 140 141 142 143
        expect(json_response).to eq(
          'name' => 'my_feature',
          'state' => 'conditional',
          'gates' => [
            { 'key' => 'boolean', 'value' => false },
            { 'key' => 'percentage_of_time', 'value' => 50 }
          ])
      end
144 145 146 147 148 149 150 151 152
    end

    context 'when the feature exists' do
      let(:feature) { Feature.get(feature_name) }

      before do
        feature.disable # This also persists the feature on the DB
      end

153 154 155
      context 'when passed value=true' do
        it 'enables the feature' do
          post api("/features/#{feature_name}", admin), value: 'true'
156

157
          expect(response).to have_gitlab_http_status(201)
158 159 160 161 162 163
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'on',
            'gates' => [{ 'key' => 'boolean', 'value' => true }])
        end

164 165
        it 'enables the feature for the given Flipper group when passed feature_group=perf_team' do
          post api("/features/#{feature_name}", admin), value: 'true', feature_group: 'perf_team'
166

167
          expect(response).to have_gitlab_http_status(201)
168 169 170 171 172 173 174 175 176 177 178 179
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'conditional',
            'gates' => [
              { 'key' => 'boolean', 'value' => false },
              { 'key' => 'groups', 'value' => ['perf_team'] }
            ])
        end

        it 'enables the feature for the given user when passed user=username' do
          post api("/features/#{feature_name}", admin), value: 'true', user: user.username

180
          expect(response).to have_gitlab_http_status(201)
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'conditional',
            'gates' => [
              { 'key' => 'boolean', 'value' => false },
              { 'key' => 'actors', 'value' => ["User:#{user.id}"] }
            ])
        end
      end

      context 'when feature is enabled and value=false is passed' do
        it 'disables the feature' do
          feature.enable
          expect(feature).to be_enabled

          post api("/features/#{feature_name}", admin), value: 'false'

198
          expect(response).to have_gitlab_http_status(201)
199 200 201 202 203 204
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'off',
            'gates' => [{ 'key' => 'boolean', 'value' => false }])
        end

205
        it 'disables the feature for the given Flipper group when passed feature_group=perf_team' do
206 207 208
          feature.enable(Feature.group(:perf_team))
          expect(Feature.get(feature_name).enabled?(admin)).to be_truthy

209
          post api("/features/#{feature_name}", admin), value: 'false', feature_group: 'perf_team'
210

211
          expect(response).to have_gitlab_http_status(201)
212 213 214 215 216 217 218 219 220 221 222 223
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'off',
            'gates' => [{ 'key' => 'boolean', 'value' => false }])
        end

        it 'disables the feature for the given user when passed user=username' do
          feature.enable(user)
          expect(Feature.get(feature_name).enabled?(user)).to be_truthy

          post api("/features/#{feature_name}", admin), value: 'false', user: user.username

224
          expect(response).to have_gitlab_http_status(201)
225 226 227 228 229
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'off',
            'gates' => [{ 'key' => 'boolean', 'value' => false }])
        end
230 231 232 233 234 235 236 237 238 239
      end

      context 'with a pre-existing percentage value' do
        before do
          feature.enable_percentage_of_time(50)
        end

        it 'updates the percentage of time if passed an integer' do
          post api("/features/#{feature_name}", admin), value: '30'

240
          expect(response).to have_gitlab_http_status(201)
241 242 243 244 245 246 247
          expect(json_response).to eq(
            'name' => 'my_feature',
            'state' => 'conditional',
            'gates' => [
              { 'key' => 'boolean', 'value' => false },
              { 'key' => 'percentage_of_time', 'value' => 30 }
            ])
248 249 250 251 252
        end
      end
    end
  end
end