detour 0.0.3 → 0.0.5

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.
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