detour 0.0.3 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +2 -25
  3. data/app/assets/javascripts/detour/add_fields.js +7 -0
  4. data/app/assets/javascripts/detour/delete_feature.js +9 -11
  5. data/app/assets/javascripts/detour/delete_flag.js +9 -11
  6. data/app/assets/javascripts/detour/delete_group.js +5 -0
  7. data/app/assets/javascripts/detour/feature_lines.js +23 -0
  8. data/app/assets/javascripts/detour/modals.js +1 -0
  9. data/app/assets/stylesheets/detour/main.css +12 -0
  10. data/app/controllers/detour/features_controller.rb +3 -2
  11. data/app/controllers/detour/flaggable_flags_controller.rb +9 -77
  12. data/app/controllers/detour/groups_controller.rb +39 -0
  13. data/app/helpers/detour/application_helper.rb +11 -0
  14. data/app/helpers/detour/flaggable_flags_helper.rb +20 -0
  15. data/app/helpers/detour/flags_helper.rb +5 -1
  16. data/app/models/detour/concerns/keepable.rb +21 -0
  17. data/app/models/detour/concerns/matchers.rb +28 -9
  18. data/app/models/detour/database_group_flag.rb +30 -0
  19. data/app/models/detour/defined_group.rb +21 -0
  20. data/app/models/detour/defined_group_flag.rb +28 -0
  21. data/app/models/detour/feature.rb +4 -3
  22. data/app/models/detour/flag_in_flag.rb +1 -8
  23. data/app/models/detour/flaggable_flag.rb +24 -0
  24. data/app/models/detour/group.rb +17 -0
  25. data/app/models/detour/membership.rb +41 -0
  26. data/app/models/detour/opt_out_flag.rb +1 -8
  27. data/app/views/detour/flaggable_flags/_flaggable_flag_fields.html.erb +19 -0
  28. data/app/views/detour/flaggable_flags/index.html.erb +13 -26
  29. data/app/views/detour/flags/_feature_form.html.erb +12 -3
  30. data/app/views/detour/flags/index.html.erb +7 -2
  31. data/app/views/detour/groups/_group.html.erb +3 -0
  32. data/app/views/detour/groups/_membership_fields.html.erb +19 -0
  33. data/app/views/detour/groups/index.html.erb +21 -0
  34. data/app/views/detour/groups/show.html.erb +41 -0
  35. data/app/views/detour/memberships/_membership.html.erb +4 -0
  36. data/app/views/detour/{features → shared}/_errors.html.erb +2 -2
  37. data/app/views/detour/shared/_nav.html.erb +1 -0
  38. data/app/views/detour/shared/error.js.erb +5 -0
  39. data/config/locales/en.yml +11 -0
  40. data/config/routes.rb +8 -7
  41. data/detour.gemspec +1 -0
  42. data/lib/detour/acts_as_flaggable.rb +19 -4
  43. data/lib/detour/configuration.rb +1 -1
  44. data/lib/detour/flag_form.rb +53 -34
  45. data/lib/detour/flaggable.rb +0 -19
  46. data/lib/detour/version.rb +1 -1
  47. data/lib/generators/templates/migration.rb +21 -1
  48. data/lib/tasks/.gitkeep +0 -0
  49. data/spec/controllers/detour/flaggable_flags_controller_spec.rb +30 -67
  50. data/spec/controllers/detour/groups_controller_spec.rb +107 -0
  51. data/spec/dummy/db/migrate/20131221052201_setup_detour.rb +21 -1
  52. data/spec/dummy/db/schema.rb +20 -1
  53. data/spec/factories/database_group_flag.rb +7 -0
  54. data/spec/factories/{group_flag.rb → defined_group_flag.rb} +1 -1
  55. data/spec/factories/group.rb +10 -0
  56. data/spec/factories/membership.rb +6 -0
  57. data/spec/features/database_group_flags_spec.rb +50 -0
  58. data/spec/features/database_groups_spec.rb +174 -0
  59. data/spec/features/defined_group_flags_spec.rb +67 -0
  60. data/spec/features/features_spec.rb +44 -0
  61. data/spec/features/flag_in_flags_spec.rb +22 -60
  62. data/spec/features/opt_out_flags_spec.rb +34 -59
  63. data/spec/integration/group_rollout_spec.rb +2 -2
  64. data/spec/lib/detour/acts_as_flaggable_spec.rb +12 -3
  65. data/spec/lib/detour/configuration_spec.rb +6 -2
  66. data/spec/lib/detour/flag_form_spec.rb +0 -11
  67. data/spec/lib/detour/flaggable_spec.rb +1 -54
  68. data/spec/models/detour/database_group_flag_spec.rb +29 -0
  69. data/spec/models/detour/defined_group_spec.rb +21 -0
  70. data/spec/models/detour/feature_spec.rb +57 -119
  71. data/spec/models/detour/flag_in_flag_spec.rb +1 -4
  72. data/spec/models/detour/flaggable_flag_spec.rb +25 -0
  73. data/spec/models/detour/group_flag_spec.rb +1 -1
  74. data/spec/models/detour/membership_spec.rb +58 -0
  75. data/spec/models/detour/opt_out_flag_spec.rb +1 -4
  76. data/spec/spec_helper.rb +4 -0
  77. metadata +97 -81
  78. data/app/models/detour/concerns/flag_actions.rb +0 -141
  79. data/app/models/detour/group_flag.rb +0 -13
  80. data/app/views/detour/features/_success.html.erb +0 -1
  81. data/app/views/detour/features/error.js.erb +0 -5
  82. data/lib/tasks/detour.rake +0 -119
  83. data/spec/features/group_flags_spec.rb +0 -49
  84. data/spec/integration/flag_rollout_spec.rb +0 -27
  85. data/spec/lib/tasks/detour_spec.rb +0 -162
  86. /data/app/views/detour/{features → shared}/success.js.erb +0 -0
@@ -1,119 +0,0 @@
1
- namespace :detour do
2
- desc "Create a feature"
3
- task :create, [:feature] => :environment do |task, args|
4
- Detour::Feature.find_or_create_by_name! args[:feature]
5
- end
6
-
7
- desc "Destroy a feature"
8
- task :destroy, [:feature] => :environment do |task, args|
9
- feature = Detour::Feature.find_by_name! args[:feature]
10
- feature.destroy
11
- end
12
-
13
- desc "Activate a feature for a record"
14
- task :activate, [:feature, :flaggable_type, :flaggable_id] => :environment do |task, args|
15
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
16
- klass = Detour.config.default_flaggable_class_name.constantize
17
- record_locator = args[:flaggable_type]
18
- else
19
- klass = args[:flaggable_type].constantize
20
- record_locator = args[:flaggable_id]
21
- end
22
-
23
- record = klass.flaggable_find! record_locator
24
-
25
- Detour::Feature.add_record_to_feature record, args[:feature]
26
- end
27
-
28
- desc "Deactivate a feature for a record"
29
- task :deactivate, [:feature, :flaggable_type, :flaggable_id] => :environment do |task, args|
30
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
31
- klass = Detour.config.default_flaggable_class_name.constantize
32
- record_locator = args[:flaggable_type]
33
- else
34
- klass = args[:flaggable_type].constantize
35
- record_locator = args[:flaggable_id]
36
- end
37
-
38
- record = klass.flaggable_find! record_locator
39
- Detour::Feature.remove_record_from_feature record, args[:feature]
40
- end
41
-
42
- desc "Opt a record out of a feature"
43
- task :opt_out, [:feature, :flaggable_type, :flaggable_id] => :environment do |task, args|
44
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
45
- klass = Detour.config.default_flaggable_class_name.constantize
46
- record_locator = args[:flaggable_type]
47
- else
48
- klass = args[:flaggable_type].constantize
49
- record_locator = args[:flaggable_id]
50
- end
51
-
52
- record = klass.flaggable_find! record_locator
53
- Detour::Feature.opt_record_out_of_feature record, args[:feature]
54
- end
55
-
56
- desc "Remove an opt out of a record from a feature"
57
- task :un_opt_out, [:feature, :flaggable_type, :flaggable_id] => :environment do |task, args|
58
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
59
- klass = Detour.config.default_flaggable_class_name.constantize
60
- record_locator = args[:flaggable_type]
61
- else
62
- klass = args[:flaggable_type].constantize
63
- record_locator = args[:flaggable_id]
64
- end
65
-
66
- record = klass.flaggable_find! record_locator
67
- Detour::Feature.un_opt_record_out_of_feature record, args[:feature]
68
- end
69
-
70
- desc "Activate a feature for a group"
71
- task :activate_group, [:feature, :flaggable_type, :group_name] => :environment do |task, args|
72
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
73
- klass = Detour.config.default_flaggable_class_name
74
- group_name = args[:flaggable_type]
75
- else
76
- klass = args[:flaggable_type]
77
- group_name = args[:group_name]
78
- end
79
-
80
- Detour::Feature.add_group_to_feature klass, group_name, args[:feature]
81
- end
82
-
83
- desc "Deactivate a feature for a group"
84
- task :deactivate_group, [:feature, :flaggable_type, :group_name] => :environment do |task, args|
85
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
86
- klass = Detour.config.default_flaggable_class_name
87
- group_name = args[:flaggable_type]
88
- else
89
- klass = args[:flaggable_type]
90
- group_name = args[:group_name]
91
- end
92
-
93
- Detour::Feature.remove_group_from_feature klass, group_name, args[:feature]
94
- end
95
-
96
- desc "Activate a feature for a percentage"
97
- task :activate_percentage, [:feature, :flaggable_type, :percentage] => :environment do |task, args|
98
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
99
- klass = Detour.config.default_flaggable_class_name
100
- percentage = args[:flaggable_type]
101
- else
102
- klass = args[:flaggable_type]
103
- percentage = args[:percentage]
104
- end
105
-
106
- Detour::Feature.add_percentage_to_feature klass, percentage.to_i, args[:feature]
107
- end
108
-
109
- desc "Deactivate a feature for a percentage"
110
- task :deactivate_percentage, [:feature, :flaggable_type] => :environment do |task, args|
111
- if args.to_a.length < 3 && Detour.config.default_flaggable_class_name
112
- klass = Detour.config.default_flaggable_class_name
113
- else
114
- klass = args[:flaggable_type]
115
- end
116
-
117
- Detour::Feature.remove_percentage_from_feature klass, args[:feature]
118
- end
119
- end
@@ -1,49 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "listing defined groups" do
4
- before do
5
- Detour.config.define_user_group :admins do |user|
6
- end
7
-
8
- visit "/detour/flags/users"
9
- end
10
-
11
- it "displays the defined groups" do
12
- page.should have_content "admins"
13
- end
14
- end
15
-
16
- describe "creating defined group flags" do
17
- let!(:feature) { create :feature }
18
-
19
- before do
20
- Detour.config.define_user_group :admins do |user|
21
- end
22
-
23
- visit "/detour/flags/users"
24
- check "features[#{feature.name}][users_group_flags_attributes[admins]][to_keep]"
25
- click_button "Save Changes"
26
- end
27
-
28
- it "creates the group flag" do
29
- feature.reload.users_group_flags.first.group_name.should eq "admins"
30
- end
31
- end
32
-
33
- describe "removing defined group flags" do
34
- let(:feature) { create :feature }
35
- let!(:group_flag) { create :group_flag, feature: feature, group_name: "admins" }
36
-
37
- before do
38
- Detour.config.define_user_group :admins do |user|
39
- end
40
-
41
- visit "/detour/flags/users"
42
- uncheck "features[#{feature.name}][users_group_flags_attributes[admins]][to_keep]"
43
- click_button "Save Changes"
44
- end
45
-
46
- it "creates the group flag" do
47
- feature.reload.users_group_flags.should be_empty
48
- end
49
- end
@@ -1,27 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "flag rollouts" do
4
- let(:user) { User.create }
5
- let(:feature) { Detour::Feature.create(name: "foo") }
6
-
7
- describe "creating a flag rollout" do
8
- before do
9
- Detour::Feature.add_record_to_feature user, feature.name
10
- end
11
-
12
- it "sets the feature on the user" do
13
- feature.match_id?(user).should be_true
14
- end
15
- end
16
-
17
- describe "removing a flag rollout" do
18
- before do
19
- Detour::Feature.add_record_to_feature user, feature.name
20
- Detour::Feature.remove_record_from_feature user, feature.name
21
- end
22
-
23
- it "removes the feature from the user" do
24
- feature.match_id?(user).should be_false
25
- end
26
- end
27
- end
@@ -1,162 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe "detour:create" do
4
- include_context "rake"
5
-
6
- it "creates the given feature" do
7
- Detour::Feature.should_receive(:find_or_create_by_name!).with("foo")
8
- subject.invoke("foo")
9
- end
10
- end
11
-
12
- describe "detour:destroy" do
13
- include_context "rake"
14
-
15
- let(:feature) { create :feature }
16
-
17
- it "destroys the given feature" do
18
- Detour::Feature.should_receive(:find_by_name!).with(feature.name).and_return(feature)
19
- feature.should_receive(:destroy)
20
- subject.invoke(feature.name)
21
- end
22
- end
23
-
24
- describe "detour:activate" do
25
- include_context "rake"
26
-
27
- let(:user) { create :user }
28
- let(:feature) { create :feature }
29
-
30
- it "activates the feature for the record" do
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
- end
34
-
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, 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
- end
40
- end
41
-
42
- describe "detour:deactivate" do
43
- include_context "rake"
44
-
45
- let(:user) { create :user }
46
- let(:feature) { create :feature }
47
-
48
- it "deactivates the feature for the record" do
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
- end
52
-
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, 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
- end
58
- end
59
-
60
- describe "detour:opt_out" do
61
- include_context "rake"
62
-
63
- let(:user) { create :user }
64
- let(:feature) { create :feature }
65
-
66
- it "deactivates the feature for the record" do
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
- end
70
-
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, 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
- end
76
- end
77
-
78
- describe "detour:un_opt_out" do
79
- include_context "rake"
80
-
81
- let(:user) { create :user }
82
- let(:feature) { create :feature }
83
-
84
- it "deactivates the feature for the record" do
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
- end
88
-
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, 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
- end
94
- end
95
-
96
- describe "detour:activate_group" do
97
- include_context "rake"
98
-
99
- let(:feature) { create :feature }
100
-
101
- it "activates the feature for the group" do
102
- Detour::Feature.should_receive(:add_group_to_feature).with("User", "admins", feature.name)
103
- subject.invoke(feature.name, "User", "admins")
104
- end
105
-
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", feature.name)
108
- Detour.config.default_flaggable_class_name = "User"
109
- expect { subject.invoke(feature.name, "admins") }.to_not raise_error
110
- end
111
- end
112
-
113
- describe "detour:deactivate_group" do
114
- include_context "rake"
115
-
116
- let(:feature) { create :feature }
117
-
118
- it "deactivates the feature for the group" do
119
- Detour::Feature.should_receive(:remove_group_from_feature).with("User", "admins", feature.name)
120
- subject.invoke(feature.name, "User", "admins")
121
- end
122
-
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", feature.name)
125
- Detour.config.default_flaggable_class_name = "User"
126
- expect { subject.invoke(feature.name, "admins") }.to_not raise_error
127
- end
128
- end
129
-
130
- describe "detour:activate_percentage" do
131
- include_context "rake"
132
-
133
- let(:feature) { create :feature }
134
-
135
- it "activates the feature for the percentage" do
136
- Detour::Feature.should_receive(:add_percentage_to_feature).with("User", 50, feature.name)
137
- subject.invoke(feature.name, "User", "50")
138
- end
139
-
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, feature.name)
142
- Detour.config.default_flaggable_class_name = "User"
143
- expect { subject.invoke(feature.name, "50") }.to_not raise_error
144
- end
145
- end
146
-
147
- describe "detour:deactivate_percentage" do
148
- include_context "rake"
149
-
150
- let(:feature) { create :feature }
151
-
152
- it "deactivates the feature for the percentage" do
153
- Detour::Feature.should_receive(:remove_percentage_from_feature).with("User", feature.name)
154
- subject.invoke(feature.name, "User")
155
- end
156
-
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", feature.name)
159
- Detour.config.default_flaggable_class_name = "User"
160
- expect { subject.invoke(feature.name) }.to_not raise_error
161
- end
162
- end