detour 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +2 -1
- data/.travis.yml +6 -2
- data/Gemfile +5 -0
- data/README.md +41 -132
- data/Rake.md +108 -0
- data/Rakefile +21 -1
- data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
- data/app/assets/fonts/glyphicons-halflings-regular.svg +229 -0
- data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
- data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
- data/app/assets/images/detour/.gitkeep +0 -0
- data/app/assets/javascripts/detour/application.js +16 -0
- data/app/assets/javascripts/detour/bootstrap.js +2006 -0
- data/app/assets/javascripts/detour/delete_feature.js +13 -0
- data/app/assets/javascripts/detour/delete_flag.js +13 -0
- data/app/assets/javascripts/detour/modals.js +3 -0
- data/app/assets/javascripts/detour/tooltips.js +3 -0
- data/app/assets/stylesheets/detour/application.css +14 -0
- data/app/assets/stylesheets/detour/bootstrap.css +7112 -0
- data/app/assets/stylesheets/detour/main.css +49 -0
- data/app/controllers/detour/application_controller.rb +12 -0
- data/app/controllers/detour/features_controller.rb +19 -0
- data/app/controllers/detour/flaggable_flags_controller.rb +90 -0
- data/app/controllers/detour/flags_controller.rb +18 -0
- data/app/helpers/detour/application_helper.rb +32 -0
- data/app/helpers/detour/flaggable_flags_helper.rb +5 -0
- data/app/helpers/detour/flags_helper.rb +7 -0
- data/app/models/detour/concerns/countable_flag.rb +19 -0
- data/app/models/detour/concerns/flag_actions.rb +141 -0
- data/app/models/detour/concerns/matchers.rb +73 -0
- data/app/models/detour/feature.rb +81 -0
- data/{lib → app/models}/detour/flag.rb +8 -2
- data/app/models/detour/flag_in_flag.rb +12 -0
- data/app/models/detour/group_flag.rb +13 -0
- data/{lib → app/models}/detour/opt_out_flag.rb +4 -2
- data/app/models/detour/percentage_flag.rb +9 -0
- data/app/views/detour/application/index.html.erb +0 -0
- data/app/views/detour/features/_errors.html.erb +11 -0
- data/app/views/detour/features/_success.html.erb +1 -0
- data/app/views/detour/features/error.js.erb +5 -0
- data/app/views/detour/features/success.js.erb +1 -0
- data/app/views/detour/flaggable_flags/_errors.html.erb +11 -0
- data/app/views/detour/flaggable_flags/_flaggable_flag.html.erb +11 -0
- data/app/views/detour/flaggable_flags/error.js.erb +5 -0
- data/app/views/detour/flaggable_flags/index.html.erb +34 -0
- data/app/views/detour/flaggable_flags/success.js.erb +1 -0
- data/app/views/detour/flags/_feature_form.html.erb +38 -0
- data/app/views/detour/flags/index.html.erb +76 -0
- data/app/views/detour/shared/_nav.html.erb +28 -0
- data/app/views/detour/shared/_spacer_cells.html.erb +3 -0
- data/app/views/layouts/detour/application.html.erb +29 -0
- data/config/routes.rb +16 -0
- data/detour.gemspec +15 -14
- data/lib/detour/acts_as_flaggable.rb +42 -3
- data/lib/detour/configuration.rb +35 -0
- data/lib/detour/engine.rb +5 -0
- data/lib/detour/flag_form.rb +87 -0
- data/lib/detour/version.rb +1 -1
- data/lib/detour.rb +10 -14
- data/lib/generators/templates/migration.rb +2 -0
- data/lib/tasks/detour.rake +16 -16
- data/script/rails +8 -0
- data/spec/controllers/detour/application_controller_spec.rb +15 -0
- data/spec/controllers/detour/features_controller_spec.rb +51 -0
- data/spec/controllers/detour/flaggable_flags_controller_spec.rb +100 -0
- data/spec/controllers/detour/flags_controller_spec.rb +77 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +7 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/models/user.rb +5 -0
- data/spec/dummy/app/models/widget.rb +5 -0
- data/spec/dummy/app/views/application/index.html.erb +22 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config/application.rb +65 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +19 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/detour.rb +36 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/db/migrate/20131218015844_create_users.rb +10 -0
- data/spec/dummy/db/migrate/20131218023124_create_widgets.rb +9 -0
- data/spec/dummy/db/migrate/20131218055352_add_user_id_to_widgets.rb +6 -0
- data/spec/dummy/db/migrate/20131221052201_setup_detour.rb +32 -0
- data/spec/dummy/db/schema.rb +59 -0
- data/spec/dummy/db/seeds.rb +10 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/feature.rb +5 -0
- data/spec/factories/flag_in_flag.rb +6 -0
- data/spec/factories/group_flag.rb +7 -0
- data/spec/factories/opt_out_flag.rb +6 -0
- data/spec/factories/percentage_flag.rb +7 -0
- data/spec/factories/user.rb +6 -0
- data/spec/factories/widget.rb +5 -0
- data/spec/features/features_spec.rb +70 -0
- data/spec/features/flag_in_flags_spec.rb +118 -0
- data/spec/features/group_flags_spec.rb +49 -0
- data/spec/features/home_page_spec.rb +11 -0
- data/spec/features/opt_out_flags_spec.rb +105 -0
- data/spec/features/percentage_flags_spec.rb +63 -0
- data/spec/integration/group_rollout_spec.rb +1 -1
- data/spec/lib/detour/acts_as_flaggable_spec.rb +45 -0
- data/spec/lib/detour/configuration_spec.rb +23 -0
- data/spec/lib/detour/flag_form_spec.rb +84 -0
- data/spec/lib/{active_record/rollout → detour}/flaggable_spec.rb +19 -19
- data/spec/lib/tasks/{detour_rake_spec.rb → detour_spec.rb} +54 -54
- data/spec/{lib/active_record/rollout → models/detour}/feature_spec.rb +93 -67
- data/spec/models/detour/flag_in_flag_spec.rb +38 -0
- data/spec/{lib/active_record/rollout → models/detour}/flag_spec.rb +1 -1
- data/spec/models/detour/opt_out_flag_spec.rb +38 -0
- data/spec/{lib/active_record/rollout → models/detour}/percentage_flag_spec.rb +1 -1
- data/spec/spec_helper.rb +41 -21
- data/spec/support/shared_contexts/rake.rb +4 -14
- metadata +278 -95
- data/lib/detour/feature.rb +0 -312
- data/lib/detour/flaggable_flag.rb +0 -10
- data/lib/detour/group_flag.rb +0 -8
- data/lib/detour/percentage_flag.rb +0 -11
- data/spec/lib/active_record/rollout/acts_as_flaggable_spec.rb +0 -31
- data/spec/lib/active_record/rollout/flaggable_flag_spec.rb +0 -9
- data/spec/lib/active_record/rollout/opt_out_flag_spec.rb +0 -9
- data/spec/support/schema.rb +0 -13
- /data/lib/generators/{active_record_rollout_generator.rb → detour_generator.rb} +0 -0
- /data/lib/generators/templates/{active_record_rollout.rb → detour.rb} +0 -0
- /data/spec/{lib/active_record/rollout → models/detour}/group_flag_spec.rb +0 -0
|
@@ -12,151 +12,151 @@ end
|
|
|
12
12
|
describe "detour:destroy" do
|
|
13
13
|
include_context "rake"
|
|
14
14
|
|
|
15
|
-
let(:feature) {
|
|
15
|
+
let(:feature) { create :feature }
|
|
16
16
|
|
|
17
17
|
it "destroys the given feature" do
|
|
18
18
|
Detour::Feature.should_receive(:find_by_name!).with(feature.name).and_return(feature)
|
|
19
19
|
feature.should_receive(:destroy)
|
|
20
|
-
subject.invoke(
|
|
20
|
+
subject.invoke(feature.name)
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
describe "detour:activate" do
|
|
25
25
|
include_context "rake"
|
|
26
26
|
|
|
27
|
-
let(:user)
|
|
28
|
-
let
|
|
27
|
+
let(:user) { create :user }
|
|
28
|
+
let(:feature) { create :feature }
|
|
29
29
|
|
|
30
30
|
it "activates the feature for the record" do
|
|
31
|
-
Detour::Feature.should_receive(:add_record_to_feature).with(user,
|
|
32
|
-
subject.invoke(
|
|
31
|
+
Detour::Feature.should_receive(:add_record_to_feature).with(user, feature.name)
|
|
32
|
+
subject.invoke(feature.name, user.class.to_s, user.id.to_s)
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
it "does not require a class if defined_flaggable_class is set" do
|
|
36
|
-
Detour::Feature.should_receive(:add_record_to_feature).with(user,
|
|
37
|
-
Detour
|
|
38
|
-
expect { subject.invoke(
|
|
36
|
+
Detour::Feature.should_receive(:add_record_to_feature).with(user, feature.name)
|
|
37
|
+
Detour.config.default_flaggable_class_name = user.class.to_s
|
|
38
|
+
expect { subject.invoke(feature.name, user.id.to_s) }.to_not raise_error
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
describe "detour:deactivate" do
|
|
43
43
|
include_context "rake"
|
|
44
44
|
|
|
45
|
-
let(:user)
|
|
46
|
-
let
|
|
45
|
+
let(:user) { create :user }
|
|
46
|
+
let(:feature) { create :feature }
|
|
47
47
|
|
|
48
48
|
it "deactivates the feature for the record" do
|
|
49
|
-
Detour::Feature.should_receive(:remove_record_from_feature).with(user,
|
|
50
|
-
subject.invoke(
|
|
49
|
+
Detour::Feature.should_receive(:remove_record_from_feature).with(user, feature.name)
|
|
50
|
+
subject.invoke(feature.name, user.class.to_s, user.id.to_s)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it "does not require a class if defined_flaggable_class is set" do
|
|
54
|
-
Detour::Feature.should_receive(:remove_record_from_feature).with(user,
|
|
55
|
-
Detour
|
|
56
|
-
expect { subject.invoke(
|
|
54
|
+
Detour::Feature.should_receive(:remove_record_from_feature).with(user, feature.name)
|
|
55
|
+
Detour.config.default_flaggable_class_name = user.class.to_s
|
|
56
|
+
expect { subject.invoke(feature.name, user.id.to_s) }.to_not raise_error
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
describe "detour:opt_out" do
|
|
61
61
|
include_context "rake"
|
|
62
62
|
|
|
63
|
-
let(:user)
|
|
64
|
-
let
|
|
63
|
+
let(:user) { create :user }
|
|
64
|
+
let(:feature) { create :feature }
|
|
65
65
|
|
|
66
66
|
it "deactivates the feature for the record" do
|
|
67
|
-
Detour::Feature.should_receive(:opt_record_out_of_feature).with(user,
|
|
68
|
-
subject.invoke(
|
|
67
|
+
Detour::Feature.should_receive(:opt_record_out_of_feature).with(user, feature.name)
|
|
68
|
+
subject.invoke(feature.name, user.class.to_s, user.id.to_s)
|
|
69
69
|
end
|
|
70
70
|
|
|
71
71
|
it "does not require a class if defined_flaggable_class is set" do
|
|
72
|
-
Detour::Feature.should_receive(:opt_record_out_of_feature).with(user,
|
|
73
|
-
Detour
|
|
74
|
-
expect { subject.invoke(
|
|
72
|
+
Detour::Feature.should_receive(:opt_record_out_of_feature).with(user, feature.name)
|
|
73
|
+
Detour.config.default_flaggable_class_name = user.class.to_s
|
|
74
|
+
expect { subject.invoke(feature.name, user.id.to_s) }.to_not raise_error
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
describe "detour:un_opt_out" do
|
|
79
79
|
include_context "rake"
|
|
80
80
|
|
|
81
|
-
let(:user)
|
|
82
|
-
let
|
|
81
|
+
let(:user) { create :user }
|
|
82
|
+
let(:feature) { create :feature }
|
|
83
83
|
|
|
84
84
|
it "deactivates the feature for the record" do
|
|
85
|
-
Detour::Feature.should_receive(:un_opt_record_out_of_feature).with(user,
|
|
86
|
-
subject.invoke(
|
|
85
|
+
Detour::Feature.should_receive(:un_opt_record_out_of_feature).with(user, feature.name)
|
|
86
|
+
subject.invoke(feature.name, user.class.to_s, user.id.to_s)
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
it "does not require a class if defined_flaggable_class is set" do
|
|
90
|
-
Detour::Feature.should_receive(:un_opt_record_out_of_feature).with(user,
|
|
91
|
-
Detour
|
|
92
|
-
expect { subject.invoke(
|
|
90
|
+
Detour::Feature.should_receive(:un_opt_record_out_of_feature).with(user, feature.name)
|
|
91
|
+
Detour.config.default_flaggable_class_name = user.class.to_s
|
|
92
|
+
expect { subject.invoke(feature.name, user.id.to_s) }.to_not raise_error
|
|
93
93
|
end
|
|
94
94
|
end
|
|
95
95
|
|
|
96
96
|
describe "detour:activate_group" do
|
|
97
97
|
include_context "rake"
|
|
98
98
|
|
|
99
|
-
let
|
|
99
|
+
let(:feature) { create :feature }
|
|
100
100
|
|
|
101
101
|
it "activates the feature for the group" do
|
|
102
|
-
Detour::Feature.should_receive(:add_group_to_feature).with("User", "admins",
|
|
103
|
-
subject.invoke(
|
|
102
|
+
Detour::Feature.should_receive(:add_group_to_feature).with("User", "admins", feature.name)
|
|
103
|
+
subject.invoke(feature.name, "User", "admins")
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
it "does not require a class if defined_flaggable_class is set" do
|
|
107
|
-
Detour::Feature.should_receive(:add_group_to_feature).with("User", "admins",
|
|
108
|
-
Detour
|
|
109
|
-
expect { subject.invoke(
|
|
107
|
+
Detour::Feature.should_receive(:add_group_to_feature).with("User", "admins", feature.name)
|
|
108
|
+
Detour.config.default_flaggable_class_name = "User"
|
|
109
|
+
expect { subject.invoke(feature.name, "admins") }.to_not raise_error
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
describe "detour:deactivate_group" do
|
|
114
114
|
include_context "rake"
|
|
115
115
|
|
|
116
|
-
let
|
|
116
|
+
let(:feature) { create :feature }
|
|
117
117
|
|
|
118
118
|
it "deactivates the feature for the group" do
|
|
119
|
-
Detour::Feature.should_receive(:remove_group_from_feature).with("User", "admins",
|
|
120
|
-
subject.invoke(
|
|
119
|
+
Detour::Feature.should_receive(:remove_group_from_feature).with("User", "admins", feature.name)
|
|
120
|
+
subject.invoke(feature.name, "User", "admins")
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
it "does not require a class if defined_flaggable_class is set" do
|
|
124
|
-
Detour::Feature.should_receive(:remove_group_from_feature).with("User", "admins",
|
|
125
|
-
Detour
|
|
126
|
-
expect { subject.invoke(
|
|
124
|
+
Detour::Feature.should_receive(:remove_group_from_feature).with("User", "admins", feature.name)
|
|
125
|
+
Detour.config.default_flaggable_class_name = "User"
|
|
126
|
+
expect { subject.invoke(feature.name, "admins") }.to_not raise_error
|
|
127
127
|
end
|
|
128
128
|
end
|
|
129
129
|
|
|
130
130
|
describe "detour:activate_percentage" do
|
|
131
131
|
include_context "rake"
|
|
132
132
|
|
|
133
|
-
let
|
|
133
|
+
let(:feature) { create :feature }
|
|
134
134
|
|
|
135
135
|
it "activates the feature for the percentage" do
|
|
136
|
-
Detour::Feature.should_receive(:add_percentage_to_feature).with("User", 50,
|
|
137
|
-
subject.invoke(
|
|
136
|
+
Detour::Feature.should_receive(:add_percentage_to_feature).with("User", 50, feature.name)
|
|
137
|
+
subject.invoke(feature.name, "User", "50")
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
it "does not require a class if defined_flaggable_class is set" do
|
|
141
|
-
Detour::Feature.should_receive(:add_percentage_to_feature).with("User", 50,
|
|
142
|
-
Detour
|
|
143
|
-
expect { subject.invoke(
|
|
141
|
+
Detour::Feature.should_receive(:add_percentage_to_feature).with("User", 50, feature.name)
|
|
142
|
+
Detour.config.default_flaggable_class_name = "User"
|
|
143
|
+
expect { subject.invoke(feature.name, "50") }.to_not raise_error
|
|
144
144
|
end
|
|
145
145
|
end
|
|
146
146
|
|
|
147
147
|
describe "detour:deactivate_percentage" do
|
|
148
148
|
include_context "rake"
|
|
149
149
|
|
|
150
|
-
let
|
|
150
|
+
let(:feature) { create :feature }
|
|
151
151
|
|
|
152
152
|
it "deactivates the feature for the percentage" do
|
|
153
|
-
Detour::Feature.should_receive(:remove_percentage_from_feature).with("User",
|
|
154
|
-
subject.invoke(
|
|
153
|
+
Detour::Feature.should_receive(:remove_percentage_from_feature).with("User", feature.name)
|
|
154
|
+
subject.invoke(feature.name, "User")
|
|
155
155
|
end
|
|
156
156
|
|
|
157
157
|
it "does not require a class if defined_flaggable_class is set" do
|
|
158
|
-
Detour::Feature.should_receive(:remove_percentage_from_feature).with("User",
|
|
159
|
-
Detour
|
|
160
|
-
expect { subject.invoke(
|
|
158
|
+
Detour::Feature.should_receive(:remove_percentage_from_feature).with("User", feature.name)
|
|
159
|
+
Detour.config.default_flaggable_class_name = "User"
|
|
160
|
+
expect { subject.invoke(feature.name) }.to_not raise_error
|
|
161
161
|
end
|
|
162
162
|
end
|
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
|
2
2
|
require "fakefs/spec_helpers"
|
|
3
3
|
|
|
4
4
|
describe Detour::Feature do
|
|
5
|
-
it { should have_many(:
|
|
5
|
+
it { should have_many(:flag_in_flags) }
|
|
6
6
|
it { should have_many(:group_flags) }
|
|
7
7
|
it { should have_many(:percentage_flags) }
|
|
8
8
|
it { should have_many(:opt_out_flags) }
|
|
@@ -11,13 +11,13 @@ describe Detour::Feature do
|
|
|
11
11
|
it { should validate_uniqueness_of :name }
|
|
12
12
|
it { should allow_mass_assignment_of :name }
|
|
13
13
|
|
|
14
|
-
describe ".
|
|
14
|
+
describe ".with_lines" do
|
|
15
15
|
include FakeFS::SpecHelpers
|
|
16
16
|
|
|
17
|
-
let
|
|
17
|
+
let(:feature) { create :feature, name: "foo" }
|
|
18
18
|
|
|
19
19
|
before do
|
|
20
|
-
Detour
|
|
20
|
+
Detour.config.grep_dirs = ["/foo/**/*.rb"]
|
|
21
21
|
|
|
22
22
|
FileUtils.mkdir("/foo")
|
|
23
23
|
|
|
@@ -45,30 +45,22 @@ describe Detour::Feature do
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it "fetches lines for persisted features" do
|
|
48
|
-
persisted_feature = Detour::Feature.
|
|
48
|
+
persisted_feature = Detour::Feature.with_lines.detect { |f| f.name == feature.name }
|
|
49
49
|
persisted_feature.lines.should eq %w[/foo/bar.rb#L1 /foo/bar.rb#L7 /foo/baz.rb#L1]
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
it "fetches lines for un-persisted features" do
|
|
53
|
-
unpersisted_feature = Detour::Feature.
|
|
53
|
+
unpersisted_feature = Detour::Feature.with_lines.detect { |f| f.name == "bar" }
|
|
54
54
|
unpersisted_feature.lines.should eq %w[/foo/bar.rb#L4 /foo/baz.rb#L1 /foo/baz.rb#L3]
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
describe ".define_{klass}_group" do
|
|
59
|
-
let(:block) { Proc.new {} }
|
|
60
|
-
it "defines a group for the given class" do
|
|
61
|
-
Detour::Feature.should_receive(:define_group_for_class).with("User", :id_is_1)
|
|
62
|
-
Detour::Feature.define_user_group :id_is_1, block
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
58
|
describe ".add_record_to_feature" do
|
|
67
|
-
let(:user)
|
|
68
|
-
let
|
|
59
|
+
let(:user) { create :user }
|
|
60
|
+
let(:feature) { create :feature }
|
|
69
61
|
|
|
70
62
|
before do
|
|
71
|
-
Detour::Feature.add_record_to_feature user,
|
|
63
|
+
Detour::Feature.add_record_to_feature user, feature.name
|
|
72
64
|
end
|
|
73
65
|
|
|
74
66
|
it "creates a flag for the given instance and feature" do
|
|
@@ -77,12 +69,12 @@ describe Detour::Feature do
|
|
|
77
69
|
end
|
|
78
70
|
|
|
79
71
|
describe ".remove_record_from_feature" do
|
|
80
|
-
let(:user)
|
|
81
|
-
let
|
|
72
|
+
let(:user) { create :user }
|
|
73
|
+
let(:feature) { create :feature }
|
|
82
74
|
|
|
83
75
|
before do
|
|
84
|
-
Detour::Feature.add_record_to_feature user,
|
|
85
|
-
Detour::Feature.remove_record_from_feature user,
|
|
76
|
+
Detour::Feature.add_record_to_feature user, feature.name
|
|
77
|
+
Detour::Feature.remove_record_from_feature user, feature.name
|
|
86
78
|
end
|
|
87
79
|
|
|
88
80
|
it "creates a flag for the given instance and feature" do
|
|
@@ -91,41 +83,41 @@ describe Detour::Feature do
|
|
|
91
83
|
end
|
|
92
84
|
|
|
93
85
|
describe ".opt_record_out_of_feature" do
|
|
94
|
-
let(:user)
|
|
95
|
-
let
|
|
86
|
+
let(:user) { create :user }
|
|
87
|
+
let(:feature) { create :feature }
|
|
96
88
|
|
|
97
89
|
before do
|
|
98
|
-
Detour::Feature.add_percentage_to_feature
|
|
99
|
-
Detour::Feature.opt_record_out_of_feature user,
|
|
90
|
+
Detour::Feature.add_percentage_to_feature user.class.to_s, 100, feature.name
|
|
91
|
+
Detour::Feature.opt_record_out_of_feature user, feature.name
|
|
100
92
|
end
|
|
101
93
|
|
|
102
94
|
it "opts the record out of the feature" do
|
|
103
|
-
user.has_feature?(
|
|
95
|
+
user.has_feature?(feature.name).should be_false
|
|
104
96
|
end
|
|
105
97
|
end
|
|
106
98
|
|
|
107
99
|
describe ".un_opt_record_out_of_feature" do
|
|
108
|
-
let(:user)
|
|
109
|
-
let
|
|
100
|
+
let(:user) { create :user }
|
|
101
|
+
let(:feature) { create :feature }
|
|
110
102
|
|
|
111
103
|
before do
|
|
112
|
-
Detour::Feature.add_percentage_to_feature
|
|
113
|
-
Detour::Feature.opt_record_out_of_feature user,
|
|
114
|
-
Detour::Feature.un_opt_record_out_of_feature user,
|
|
104
|
+
Detour::Feature.add_percentage_to_feature user.class.to_s, 100, feature.name
|
|
105
|
+
Detour::Feature.opt_record_out_of_feature user, feature.name
|
|
106
|
+
Detour::Feature.un_opt_record_out_of_feature user, feature.name
|
|
115
107
|
end
|
|
116
108
|
|
|
117
109
|
it "opts the record out of the feature" do
|
|
118
|
-
user.has_feature?(
|
|
110
|
+
user.has_feature?(feature.name).should be_true
|
|
119
111
|
end
|
|
120
112
|
end
|
|
121
113
|
|
|
122
114
|
describe ".add_group_to_feature" do
|
|
123
|
-
let
|
|
115
|
+
let(:feature) { create :feature }
|
|
124
116
|
|
|
125
117
|
before do
|
|
126
|
-
Detour
|
|
118
|
+
Detour.config.define_user_group :bar do
|
|
127
119
|
end
|
|
128
|
-
Detour::Feature.add_group_to_feature "User", :bar,
|
|
120
|
+
Detour::Feature.add_group_to_feature "User", :bar, feature.name
|
|
129
121
|
end
|
|
130
122
|
|
|
131
123
|
it "creates a flag for the given group and feature" do
|
|
@@ -134,13 +126,13 @@ describe Detour::Feature do
|
|
|
134
126
|
end
|
|
135
127
|
|
|
136
128
|
describe ".remove_group_from_feature" do
|
|
137
|
-
let
|
|
129
|
+
let(:feature) { create :feature }
|
|
138
130
|
|
|
139
131
|
before do
|
|
140
|
-
Detour
|
|
132
|
+
Detour.config.define_user_group :bar do
|
|
141
133
|
end
|
|
142
|
-
Detour::Feature.add_group_to_feature "User", :bar,
|
|
143
|
-
Detour::Feature.remove_group_from_feature "User", :bar,
|
|
134
|
+
Detour::Feature.add_group_to_feature "User", :bar, feature.name
|
|
135
|
+
Detour::Feature.remove_group_from_feature "User", :bar, feature.name
|
|
144
136
|
end
|
|
145
137
|
|
|
146
138
|
it "destroys flags for the given group and feature" do
|
|
@@ -149,10 +141,10 @@ describe Detour::Feature do
|
|
|
149
141
|
end
|
|
150
142
|
|
|
151
143
|
describe ".add_percentage_to_feature" do
|
|
152
|
-
let
|
|
144
|
+
let(:feature) { create :feature }
|
|
153
145
|
|
|
154
146
|
before do
|
|
155
|
-
Detour::Feature.add_percentage_to_feature "User", 50,
|
|
147
|
+
Detour::Feature.add_percentage_to_feature "User", 50, feature.name
|
|
156
148
|
end
|
|
157
149
|
|
|
158
150
|
it "creates a flag for the given percentage and feature" do
|
|
@@ -161,11 +153,11 @@ describe Detour::Feature do
|
|
|
161
153
|
end
|
|
162
154
|
|
|
163
155
|
describe ".remove_percentage_from_feature" do
|
|
164
|
-
let
|
|
156
|
+
let(:feature) { create :feature }
|
|
165
157
|
|
|
166
158
|
before do
|
|
167
|
-
Detour::Feature.add_percentage_to_feature "User", 50,
|
|
168
|
-
Detour::Feature.remove_percentage_from_feature "User",
|
|
159
|
+
Detour::Feature.add_percentage_to_feature "User", 50, feature.name
|
|
160
|
+
Detour::Feature.remove_percentage_from_feature "User", feature.name
|
|
169
161
|
end
|
|
170
162
|
|
|
171
163
|
it "creates a flag for the given percentage and feature" do
|
|
@@ -173,20 +165,17 @@ describe Detour::Feature do
|
|
|
173
165
|
end
|
|
174
166
|
end
|
|
175
167
|
|
|
176
|
-
describe "
|
|
177
|
-
let(:
|
|
178
|
-
before do
|
|
179
|
-
Detour::Feature.send :define_group_for_class, "User", "user_id_1", &block
|
|
180
|
-
end
|
|
168
|
+
describe "#to_s" do
|
|
169
|
+
let(:feature) { create :feature }
|
|
181
170
|
|
|
182
|
-
it "
|
|
183
|
-
|
|
171
|
+
it "returns the name of the feature" do
|
|
172
|
+
feature.to_s.should eq feature.name
|
|
184
173
|
end
|
|
185
174
|
end
|
|
186
175
|
|
|
187
176
|
describe "#match?" do
|
|
188
|
-
let(:user)
|
|
189
|
-
let(:feature) {
|
|
177
|
+
let(:user) { create :user }
|
|
178
|
+
let(:feature) { create :feature }
|
|
190
179
|
|
|
191
180
|
it "checks if the user is flagged individually" do
|
|
192
181
|
feature.should_receive(:match_id?).with(user)
|
|
@@ -204,13 +193,50 @@ describe Detour::Feature do
|
|
|
204
193
|
end
|
|
205
194
|
end
|
|
206
195
|
|
|
196
|
+
describe "#flag_in_count_for" do
|
|
197
|
+
context "when a value does not exist" do
|
|
198
|
+
let(:feature) { create :feature }
|
|
199
|
+
|
|
200
|
+
it "returns 0" do
|
|
201
|
+
feature.flag_in_count_for("users").should eq 0
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context "when a value exists" do
|
|
206
|
+
let(:feature) { create :feature, flag_in_counts: { "users" => 10 } }
|
|
207
|
+
|
|
208
|
+
it "returns the value" do
|
|
209
|
+
feature.flag_in_count_for("users").should eq 10
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
describe "#opt_out_count_for" do
|
|
215
|
+
context "when a value does not exist" do
|
|
216
|
+
let(:feature) { create :feature }
|
|
217
|
+
|
|
218
|
+
it "returns 0" do
|
|
219
|
+
feature.opt_out_count_for("users").should eq 0
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
context "when a value exists" do
|
|
224
|
+
let(:feature) { create :feature, opt_out_counts: { "users" => 10 } }
|
|
225
|
+
|
|
226
|
+
it "returns the value" do
|
|
227
|
+
feature.opt_out_count_for("users").should eq 10
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
|
|
207
233
|
describe "#match_id?" do
|
|
208
|
-
let(:user)
|
|
209
|
-
let(:user2)
|
|
210
|
-
let
|
|
234
|
+
let(:user) { create :user }
|
|
235
|
+
let(:user2) { create :user }
|
|
236
|
+
let(:feature) { create :feature }
|
|
211
237
|
|
|
212
238
|
before do
|
|
213
|
-
Detour::Feature.add_record_to_feature user,
|
|
239
|
+
Detour::Feature.add_record_to_feature user, feature.name
|
|
214
240
|
end
|
|
215
241
|
|
|
216
242
|
context "when the feature exists for the instance" do
|
|
@@ -227,9 +253,9 @@ describe Detour::Feature do
|
|
|
227
253
|
end
|
|
228
254
|
|
|
229
255
|
describe "#match_percentage?" do
|
|
230
|
-
let(:user)
|
|
231
|
-
let(:feature) {
|
|
232
|
-
let!(:flag)
|
|
256
|
+
let(:user) { create :user }
|
|
257
|
+
let(:feature) { create :feature }
|
|
258
|
+
let!(:flag) { create :percentage_flag, feature: feature, flaggable_type: user.class.to_s, percentage: 50 }
|
|
233
259
|
|
|
234
260
|
context "when the user's ID matches `id % 10 < percentage / 10" do
|
|
235
261
|
it "returns true" do
|
|
@@ -247,14 +273,14 @@ describe Detour::Feature do
|
|
|
247
273
|
end
|
|
248
274
|
|
|
249
275
|
describe "#match_groups?" do
|
|
250
|
-
let
|
|
251
|
-
let
|
|
252
|
-
let
|
|
253
|
-
let(:feature) {
|
|
254
|
-
let!(:flag)
|
|
276
|
+
let(:user) { create :user, name: "foo" }
|
|
277
|
+
let(:user2) { create :user }
|
|
278
|
+
let(:widget) { create :widget }
|
|
279
|
+
let(:feature) { create :feature }
|
|
280
|
+
let!(:flag) { create :group_flag, feature: feature, flaggable_type: user.class.to_s, group_name: "foo_users" }
|
|
255
281
|
|
|
256
282
|
before do
|
|
257
|
-
Detour
|
|
283
|
+
Detour.config.define_user_group "foo_users" do |user|
|
|
258
284
|
user.name == "foo"
|
|
259
285
|
end
|
|
260
286
|
end
|
|
@@ -273,7 +299,7 @@ describe Detour::Feature do
|
|
|
273
299
|
|
|
274
300
|
context "when the instance is not of the type of the block" do
|
|
275
301
|
it "returns false" do
|
|
276
|
-
feature.match_groups?(
|
|
302
|
+
feature.match_groups?(widget).should be_false
|
|
277
303
|
end
|
|
278
304
|
end
|
|
279
305
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Detour::FlagInFlag do
|
|
4
|
+
it { should be_a Detour::Flag }
|
|
5
|
+
it { should belong_to :flaggable }
|
|
6
|
+
it { should validate_presence_of :flaggable }
|
|
7
|
+
it { should allow_mass_assignment_of :flaggable }
|
|
8
|
+
|
|
9
|
+
it "validates uniquness of feature_id on flaggable" do
|
|
10
|
+
user = create :user
|
|
11
|
+
flag = create :flag_in_flag, flaggable: user
|
|
12
|
+
flag2 = build :flag_in_flag, flaggable: user, feature: flag.feature
|
|
13
|
+
|
|
14
|
+
flag2.should_not be_valid
|
|
15
|
+
flag2.errors.full_messages.should eq ["Feature has already been taken"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "when creating" do
|
|
19
|
+
let(:flag) { create :flag_in_flag }
|
|
20
|
+
|
|
21
|
+
it "increments its feature's flag_in_count" do
|
|
22
|
+
flag.reload.feature.flag_in_count_for(flag.flaggable_type.tableize).should eq 1
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "when destroying" do
|
|
27
|
+
let!(:flag) { create :flag_in_flag }
|
|
28
|
+
let!(:flag2) { create :flag_in_flag, feature: flag.feature }
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
flag2.destroy
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "decrements its feature's flag_in_count" do
|
|
35
|
+
flag.reload.feature.flag_in_count_for(flag.flaggable_type.tableize).should eq 1
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
|
2
2
|
|
|
3
3
|
describe Detour::Flag do
|
|
4
4
|
it { should belong_to :feature }
|
|
5
|
-
it { should validate_presence_of :
|
|
5
|
+
it { should validate_presence_of :feature }
|
|
6
6
|
it { should validate_presence_of :flaggable_type }
|
|
7
7
|
it { should allow_mass_assignment_of :flaggable_type }
|
|
8
8
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Detour::OptOutFlag do
|
|
4
|
+
it { should be_a Detour::Flag }
|
|
5
|
+
it { should belong_to :flaggable }
|
|
6
|
+
it { should validate_presence_of :flaggable }
|
|
7
|
+
it { should allow_mass_assignment_of :flaggable }
|
|
8
|
+
|
|
9
|
+
it "validates uniquness of feature_id on flaggable" do
|
|
10
|
+
user = create :user
|
|
11
|
+
flag = create :opt_out_flag, flaggable: user
|
|
12
|
+
flag2 = build :opt_out_flag, flaggable: user, feature: flag.feature
|
|
13
|
+
|
|
14
|
+
flag2.should_not be_valid
|
|
15
|
+
flag2.errors.full_messages.should eq ["Feature has already been taken"]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe "when creating" do
|
|
19
|
+
let(:flag) { create :opt_out_flag }
|
|
20
|
+
|
|
21
|
+
it "increments its feature's opt_out_count" do
|
|
22
|
+
flag.reload.feature.opt_out_count_for(flag.flaggable_type.tableize).should eq 1
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe "when destroying" do
|
|
27
|
+
let!(:flag) { create :opt_out_flag }
|
|
28
|
+
let!(:flag2) { create :opt_out_flag, feature: flag.feature }
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
flag2.destroy
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "decrements its feature's opt_out_count" do
|
|
35
|
+
flag.reload.feature.opt_out_count_for(flag.flaggable_type.tableize).should eq 1
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
describe Detour::PercentageFlag do
|
|
4
|
-
subject {
|
|
4
|
+
subject { build :percentage_flag }
|
|
5
5
|
|
|
6
6
|
it { should be_a Detour::Flag }
|
|
7
7
|
it { should validate_numericality_of(:percentage).is_greater_than(0).is_less_than_or_equal_to(100) }
|