flipper-api 0.16.0 → 0.16.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1fe848186acddf2d53ab3068d5f2ec2246ab688c
4
- data.tar.gz: 20c08ae092d4b61c9a1412778a55f84ca9602c1b
3
+ metadata.gz: debf12af06cb2052a93e762b577c84ca00947468
4
+ data.tar.gz: 80243f08329c85997012c0a2a0c436d22b9ccc4d
5
5
  SHA512:
6
- metadata.gz: 8e7e1c899f4a5cd09ac3e129e8e83d0085a46b1ccb4bd05a6d849ad4ccc7a4a158313a08d22201d644f4d35820d70482b248e1a81283f5434ccfc93e70b88863
7
- data.tar.gz: 4d367bab12c168329609aa4c9cac1b7098bd68d428d49d927c4c5ee22584864482877866a49d733c9a36fa4874d698b632277cff90ee027f800a0196343febbd
6
+ metadata.gz: d00f668b0162f64d431058bee93d475d9c24e79e01c495cb943d968654cb2f898cfb315fe649c1e1b1143ec0089296fc103ee1c7b666c78b2d3d2d3735aeb480
7
+ data.tar.gz: 0ca3db409714648246d2a8bb8641485502bd38188e39980208b708d758638657fa14e4ec18aebfbb6b46dbaffdc08676eca34b234c89d5d15fa897af58b76053
@@ -10,7 +10,7 @@ module Flipper
10
10
  def feature_name
11
11
  @feature_name ||= begin
12
12
  match = request.path_info.match(self.class.route_regex)
13
- match ? match[:feature_name] : nil
13
+ match ? Rack::Utils.unescape(match[:feature_name]) : nil
14
14
  end
15
15
  end
16
16
  private :feature_name
@@ -20,6 +20,7 @@ module Flipper
20
20
  @action_collection.add Api::V1::Actions::GroupsGate
21
21
  @action_collection.add Api::V1::Actions::BooleanGate
22
22
  @action_collection.add Api::V1::Actions::ClearFeature
23
+ @action_collection.add Api::V1::Actions::Actors
23
24
  @action_collection.add Api::V1::Actions::Feature
24
25
  @action_collection.add Api::V1::Actions::Features
25
26
  end
@@ -0,0 +1,39 @@
1
+ require 'flipper/api/action'
2
+ require 'flipper/api/v1/decorators/actor'
3
+
4
+ module Flipper
5
+ module Api
6
+ module V1
7
+ module Actions
8
+ class Actors < Api::Action
9
+ route %r{\A/actors/(?<flipper_id>.*)/?\Z}
10
+
11
+ def get
12
+ keys = params['keys']
13
+ features = if keys
14
+ names = keys.split(',')
15
+ if names.empty?
16
+ []
17
+ else
18
+ flipper.preload(names)
19
+ end
20
+ else
21
+ flipper.features
22
+ end
23
+
24
+ actor = Flipper::Actor.new(flipper_id)
25
+ decorated_actor = Decorators::Actor.new(actor, features)
26
+ json_response(decorated_actor.as_json)
27
+ end
28
+
29
+ private
30
+
31
+ def flipper_id
32
+ match = request.path_info.match(self.class.route_regex)
33
+ match ? match[:flipper_id] : nil
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,35 @@
1
+ module Flipper
2
+ module Api
3
+ module V1
4
+ module Decorators
5
+ class Actor < SimpleDelegator
6
+ # Public: the actor and features.
7
+ attr_reader :actor, :features
8
+
9
+ def initialize(actor, features)
10
+ @actor = actor
11
+ @features = features
12
+ end
13
+
14
+ def as_json
15
+ {
16
+ 'flipper_id' => actor.flipper_id,
17
+ 'features' => features_data,
18
+ }
19
+ end
20
+
21
+ private
22
+
23
+ def features_data
24
+ features.each_with_object({}) do |feature, features_hash|
25
+ features_hash[feature.name] = {
26
+ 'enabled' => feature.enabled?(actor),
27
+ }
28
+ features_hash
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.16.0'.freeze
2
+ VERSION = '0.16.1'.freeze
3
3
  end
@@ -0,0 +1,105 @@
1
+ require 'helper'
2
+
3
+ RSpec.describe Flipper::Api::V1::Actions::Actors do
4
+ let(:app) { build_api(flipper) }
5
+ let(:actor) { Flipper::Actor.new('User123') }
6
+
7
+ describe 'GET /actors/:flipper_id' do
8
+ before do
9
+ flipper[:my_feature_1].enable
10
+ flipper[:my_feature_2].disable
11
+ flipper[:my_feature_3].enable_actor(actor)
12
+ end
13
+
14
+ context 'when no feature is specified' do
15
+ before do
16
+ get "/actors/#{actor.flipper_id}"
17
+ end
18
+
19
+ it 'responds with success' do
20
+ expect(last_response.status).to eq(200)
21
+ end
22
+
23
+ it 'returns all features' do
24
+ expected_response = {
25
+ 'flipper_id' => 'User123',
26
+ 'features' => {
27
+ 'my_feature_1' => {
28
+ 'enabled' => true,
29
+ },
30
+ 'my_feature_2' => {
31
+ 'enabled' => false,
32
+ },
33
+ 'my_feature_3' => {
34
+ 'enabled' => true,
35
+ },
36
+ },
37
+ }
38
+
39
+ expect(json_response).to eq(expected_response)
40
+ end
41
+ end
42
+
43
+ context 'when features are specified' do
44
+ before do
45
+ get "/actors/#{actor.flipper_id}", keys: "my_feature_2,my_feature_3"
46
+ end
47
+
48
+ it 'responds with success' do
49
+ expect(last_response.status).to eq(200)
50
+ end
51
+
52
+ it 'returns all specified features' do
53
+ expected_response = {
54
+ 'flipper_id' => 'User123',
55
+ 'features' => {
56
+ 'my_feature_2' => {
57
+ 'enabled' => false,
58
+ },
59
+ 'my_feature_3' => {
60
+ 'enabled' => true,
61
+ },
62
+ },
63
+ }
64
+
65
+ expect(json_response).to eq(expected_response)
66
+ end
67
+ end
68
+
69
+ context 'when non-existent features are specified' do
70
+ before do
71
+ get "/actors/#{actor.flipper_id}", keys: "my_feature_3,not_a_feature"
72
+ end
73
+
74
+ it 'responds with success' do
75
+ expect(last_response.status).to eq(200)
76
+ end
77
+
78
+ it 'returns false for a non-existent feature' do
79
+ expected_response = {
80
+ 'flipper_id' => 'User123',
81
+ 'features' => {
82
+ 'my_feature_3' => {
83
+ 'enabled' => true,
84
+ },
85
+ 'not_a_feature' => {
86
+ 'enabled' => false,
87
+ },
88
+ },
89
+ }
90
+
91
+ expect(json_response).to eq(expected_response)
92
+ end
93
+ end
94
+
95
+ context 'when flipper id is missing' do
96
+ before do
97
+ get "/actors"
98
+ end
99
+
100
+ it 'responds with a 404' do
101
+ expect(last_response.status).to eq(404)
102
+ end
103
+ end
104
+ end
105
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.0
4
+ version: 0.16.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-01 00:00:00.000000000 Z
11
+ date: 2019-02-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -36,14 +36,14 @@ dependencies:
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.16.0
39
+ version: 0.16.1
40
40
  type: :runtime
41
41
  prerelease: false
42
42
  version_requirements: !ruby/object:Gem::Requirement
43
43
  requirements:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
- version: 0.16.0
46
+ version: 0.16.1
47
47
  description: Rack middleware that provides an API for the flipper gem.
48
48
  email:
49
49
  - nunemaker@gmail.com
@@ -60,6 +60,7 @@ files:
60
60
  - lib/flipper/api/error_response.rb
61
61
  - lib/flipper/api/json_params.rb
62
62
  - lib/flipper/api/middleware.rb
63
+ - lib/flipper/api/v1/actions/actors.rb
63
64
  - lib/flipper/api/v1/actions/actors_gate.rb
64
65
  - lib/flipper/api/v1/actions/boolean_gate.rb
65
66
  - lib/flipper/api/v1/actions/clear_feature.rb
@@ -68,12 +69,14 @@ files:
68
69
  - lib/flipper/api/v1/actions/groups_gate.rb
69
70
  - lib/flipper/api/v1/actions/percentage_of_actors_gate.rb
70
71
  - lib/flipper/api/v1/actions/percentage_of_time_gate.rb
72
+ - lib/flipper/api/v1/decorators/actor.rb
71
73
  - lib/flipper/api/v1/decorators/feature.rb
72
74
  - lib/flipper/api/v1/decorators/gate.rb
73
75
  - lib/flipper/version.rb
74
76
  - spec/flipper/api/action_spec.rb
75
77
  - spec/flipper/api/json_params_spec.rb
76
78
  - spec/flipper/api/v1/actions/actors_gate_spec.rb
79
+ - spec/flipper/api/v1/actions/actors_spec.rb
77
80
  - spec/flipper/api/v1/actions/boolean_gate_spec.rb
78
81
  - spec/flipper/api/v1/actions/clear_feature_spec.rb
79
82
  - spec/flipper/api/v1/actions/feature_spec.rb
@@ -111,6 +114,7 @@ test_files:
111
114
  - spec/flipper/api/action_spec.rb
112
115
  - spec/flipper/api/json_params_spec.rb
113
116
  - spec/flipper/api/v1/actions/actors_gate_spec.rb
117
+ - spec/flipper/api/v1/actions/actors_spec.rb
114
118
  - spec/flipper/api/v1/actions/boolean_gate_spec.rb
115
119
  - spec/flipper/api/v1/actions/clear_feature_spec.rb
116
120
  - spec/flipper/api/v1/actions/feature_spec.rb