detour 0.0.10 → 0.0.11

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: 424e1945f8aaf1315085953f1795186ee0c7caf4
4
- data.tar.gz: 3415e4788d0c2ed9802532212a74a1b87837d888
3
+ metadata.gz: cf7115b71744ec2229a2d850f8b6a4efecd79d28
4
+ data.tar.gz: 0f5afa558a4412a10db629f0c448d4647c0959b3
5
5
  SHA512:
6
- metadata.gz: cdb2d36abb5bc62777410cb7d97043f8271537d224182081c4d6e0db4a2b8d774c030ddd33a1a3d27fe37ef21125f66ded5a77a00fb08d86599835eb37a136a3
7
- data.tar.gz: 2770754f7379de39c788f626c441869477905bb6e90ebcefe007efc596f48e5b4d543d7b2403688f93e4eac3b6a88e7dcdfc36f458c4fe3f21063b333d4609b5
6
+ metadata.gz: 8b37642c8dd68bd34f924dcc5438c847c9c4dde889a91e1d32afe5375b4de3aee2ff8d6c04c9b9fc34a892c7d79402cd5f7fdabb42bb4054ad15daa37152700e
7
+ data.tar.gz: a2f4afa256166f2f97b12f52bb0853c60a9e9674d2f83dd34b214caf30a7736042706ca9f2479b790f4fabb77219ba006778e38eeec72abe4374857497cd106a
@@ -1,38 +1,5 @@
1
1
  module Detour::Concerns
2
2
  module Matchers
3
- # Determines whether or not the given instance has had the feature rolled out
4
- # to it either via direct flagging-in, percentage, or by database or defined
5
- # group membership.
6
- #
7
- # @example
8
- # feature.match?(current_user)
9
- #
10
- # @param [ActiveRecord::Base] instance A record to be tested for feature
11
- # rollout.
12
- #
13
- # @return Whether or not the given instance has the feature rolled out to it.
14
- def match?(instance)
15
- match_id?(instance) ||
16
- match_percentage?(instance) ||
17
- match_database_groups?(instance) ||
18
- match_defined_groups?(instance)
19
- end
20
-
21
- # Determines whether or not the given instance has had the feature rolled out
22
- # to it via direct flagging-in.
23
- #
24
- # @example
25
- # feature.match_id?(current_user)
26
- #
27
- # @param [ActiveRecord::Base] instance A record to be tested for feature
28
- # rollout.
29
- #
30
- # @return Whether or not the given instance has the feature rolled out to it
31
- # via direct flagging-in.
32
- def match_id?(instance)
33
- flag_in_flags.where(flaggable_type: instance.class.to_s, flaggable_id: instance.id).any?
34
- end
35
-
36
3
  # Determines whether or not the given instance has had the feature rolled out
37
4
  # to it via percentage.
38
5
  #
@@ -71,10 +71,6 @@ module Detour::ActsAsFlaggable
71
71
  as: :flaggable,
72
72
  class_name: "Detour::OptOutFlag"
73
73
 
74
- has_many :features,
75
- through: :flag_in_flags,
76
- class_name: "Detour::Feature"
77
-
78
74
  if options[:find_by]
79
75
  @detour_flaggable_find_by = options[:find_by]
80
76
  end
@@ -83,7 +79,6 @@ module Detour::ActsAsFlaggable
83
79
  @detour_flaggable_find_by
84
80
  end
85
81
 
86
- extend Detour::Flaggable::ClassMethods
87
82
  include Detour::Flaggable
88
83
  end
89
84
  end
@@ -1,11 +1,30 @@
1
1
  module Detour::Flaggable
2
- module ClassMethods
3
- # Finds a record by the field set by the :find_by param in
4
- # `acts_as_flaggable`. If no :find_by param was provided, :id is used.
5
- #
6
- # @param [String,Integer] value The value to find the record by.
7
- def flaggable_find!(value)
8
- send("find_by_#{@detour_flaggable_find_by}!", value)
2
+ extend ActiveSupport::Concern
3
+
4
+ # Returns an array of all features rolled out to the given record.
5
+ #
6
+ # @example
7
+ # user.features
8
+ #
9
+ # @return [Array] An array of {Detour::Feature}s.
10
+ def features
11
+ @features ||= begin
12
+ @features = []
13
+
14
+ opt_out_ids = opt_out_flags.map(&:feature_id) + [-1] # prevents "NOT IN (NULL)"
15
+ table_name = self.class.table_name
16
+
17
+ database_group_features = Detour::Feature.joins(:"#{table_name}_database_group_flags" => :memberships).where("detour_memberships" => { member_id: self.id }).where("'detour_features'.id NOT IN (?)", opt_out_ids)
18
+ @features.concat database_group_features
19
+
20
+ defined_group_features = Detour::Feature.joins(:"#{table_name}_defined_group_flags").where("'detour_features'.id NOT IN (?)", opt_out_ids)
21
+ @features.concat defined_group_features.select { |feature| feature.match_defined_groups?(self) }
22
+
23
+ percentage_group_features = Detour::Feature.joins(:"#{table_name}_percentage_flag").where("'detour_features'.id NOT IN (?)", opt_out_ids)
24
+ @features.concat percentage_group_features.select { |feature| feature.match_percentage?(self) }
25
+
26
+ flag_in_features = Detour::Feature.joins(:"#{table_name}_flag_ins").where("'detour_features'.id NOT IN (?)", opt_out_ids)
27
+ @features.concat flag_in_features
9
28
  end
10
29
  end
11
30
 
@@ -22,26 +41,20 @@ module Detour::Flaggable
22
41
  # @param [Proc] &block A block to be called if the user is flagged in to the
23
42
  # feature.
24
43
  def has_feature?(feature_name, &block)
25
- if detour_features.include? feature_name.to_s
26
- match = true
27
- else
28
- feature = Detour::Feature.find_by_name(feature_name)
29
- return false unless feature
30
-
31
- opt_out = opt_out_flags.find_by_feature_id(feature.id)
32
- return false if opt_out
33
-
34
- match = feature.match? self
35
-
36
- if match
37
- detour_features << feature.name.to_s
38
- end
39
- end
40
-
41
- match
44
+ features.map(&:name).include? feature_name.to_s
42
45
  end
43
46
 
44
47
  def detour_features
45
48
  @detour_features ||= []
46
49
  end
50
+
51
+ included do
52
+ # Finds a record by the field set by the :find_by param in
53
+ # `acts_as_flaggable`. If no :find_by param was provided, :id is used.
54
+ #
55
+ # @param [String,Integer] value The value to find the record by.
56
+ def self.flaggable_find!(value)
57
+ send("find_by_#{@detour_flaggable_find_by}!", value)
58
+ end
59
+ end
47
60
  end
@@ -1,3 +1,3 @@
1
1
  module Detour
2
- VERSION = "0.0.10"
2
+ VERSION = "0.0.11"
3
3
  end
@@ -1,5 +1,6 @@
1
1
  FactoryGirl.define do
2
+
2
3
  factory :feature, class: "Detour::Feature" do
3
- name "foo_feature"
4
+ sequence(:name) { |n| "#{n}_feature" }
4
5
  end
5
6
  end
@@ -5,7 +5,6 @@ describe Detour::ActsAsFlaggable do
5
5
 
6
6
  it { should have_many :flag_in_flags }
7
7
  it { should have_many :opt_out_flags }
8
- it { should have_many(:features).through(:flag_in_flags) }
9
8
 
10
9
  it "includes Detour::Flaggable" do
11
10
  subject.class.ancestors.should include Detour::Flaggable
@@ -1,7 +1,37 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Detour::Flaggable do
4
- subject { User.new }
4
+ subject { create :user }
5
+
6
+ describe "#features" do
7
+ let(:feature1) { create :feature }
8
+ let(:feature2) { create :feature }
9
+ let(:feature3) { create :feature }
10
+ let(:feature4) { create :feature }
11
+ let(:feature5) { create :feature }
12
+ let(:membership) { create :membership, member: subject }
13
+ let(:defined_group) { Detour::DefinedGroup.new "foo", ->(user){true} }
14
+
15
+ before do
16
+ Detour.config.defined_groups["User"] = { foo: defined_group }
17
+ create :flag_in_flag, flaggable: subject, feature: feature1
18
+ create :percentage_flag, flaggable_type: "User", feature: feature2
19
+ create :database_group_flag, flaggable_type: "User", feature: feature3, group: membership.group
20
+ create :database_group_flag, flaggable_type: "User", feature: feature4, group: membership.group
21
+ create :opt_out_flag, flaggable: subject, feature: feature4
22
+ create :defined_group_flag, flaggable_type: "User", feature: feature5, group_name: "foo"
23
+ end
24
+
25
+ it "finds every feature for a record" do
26
+ subject.features.sort.should eq [feature1, feature2, feature3, feature5].sort
27
+ end
28
+
29
+ it "is memoized" do
30
+ subject.features
31
+ Detour::Feature.stub(:joins) { raise "I was called" }
32
+ subject.features
33
+ end
34
+ end
5
35
 
6
36
  describe "#flaggable_find!" do
7
37
  context "when a non-default find_by is not specified" do
@@ -27,17 +57,6 @@ describe Detour::Flaggable do
27
57
  let(:user) { create :user }
28
58
  let(:feature) { create :feature }
29
59
 
30
- it "memoizes found features" do
31
- Detour::Feature.stub(:find_by_name) { feature }
32
- feature.flag_in_flags.create(flaggable: user)
33
-
34
- feature.should_receive(:match?).with(user).and_return(true)
35
- user.has_feature?(feature.name)
36
-
37
- feature.should_not_receive(:match?).with(user)
38
- user.has_feature?(feature.name)
39
- end
40
-
41
60
  context "when the user is not flagged in" do
42
61
  it "returns false" do
43
62
  user.has_feature?(feature.name).should be_false
@@ -97,31 +97,6 @@ describe Detour::Feature do
97
97
  end
98
98
  end
99
99
 
100
- describe "#match?" do
101
- let(:user) { create :user }
102
- let(:feature) { create :feature }
103
-
104
- it "checks if the user is flagged individually" do
105
- feature.should_receive(:match_id?).with(user)
106
- feature.match?(user)
107
- end
108
-
109
- it "checks if the user is flagged as part of a percentage" do
110
- feature.should_receive(:match_percentage?).with(user)
111
- feature.match?(user)
112
- end
113
-
114
- it "checks if the user is flagged as part of a database group" do
115
- feature.should_receive(:match_database_groups?).with(user)
116
- feature.match?(user)
117
- end
118
-
119
- it "checks if the user is flagged as part of a defined group" do
120
- feature.should_receive(:match_defined_groups?).with(user)
121
- feature.match?(user)
122
- end
123
- end
124
-
125
100
  describe "#flag_in_count_for" do
126
101
  context "when a value does not exist" do
127
102
  let(:feature) { create :feature }
@@ -158,29 +133,6 @@ describe Detour::Feature do
158
133
  end
159
134
  end
160
135
 
161
-
162
- describe "#match_id?" do
163
- let(:user) { create :user }
164
- let(:user2) { create :user }
165
- let(:feature) { create :feature }
166
-
167
- before do
168
- create(:flag_in_flag, flaggable: user, feature: feature)
169
- end
170
-
171
- context "when the feature exists for the instance" do
172
- it "returns true" do
173
- feature.match_id?(user).should be_true
174
- end
175
- end
176
-
177
- context "when the feature does not exist for the instance" do
178
- it "returns false" do
179
- feature.match_id?(user2).should be_false
180
- end
181
- end
182
- end
183
-
184
136
  describe "#match_percentage?" do
185
137
  let(:user) { create :user }
186
138
  let(:feature) { create :feature }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: detour
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Clem