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
@@ -10,8 +10,8 @@ describe Detour::FlaggableFlagsController do
10
10
  get :index, feature_name: flag.feature.name, flaggable_type: "users"
11
11
  end
12
12
 
13
- it "assigns the flag-in flags" do
14
- assigns(:flags).should eq [flag]
13
+ it "assigns the feature" do
14
+ assigns(:feature).should eq flag.feature
15
15
  end
16
16
 
17
17
  it "renders the index template" do
@@ -19,82 +19,45 @@ describe Detour::FlaggableFlagsController do
19
19
  end
20
20
  end
21
21
 
22
- describe "POST #create" do
23
- let!(:user) { create :user }
24
- let(:feature) { create :feature }
25
-
26
- context "when creating multiple flag-ins" do
27
- let!(:user2) { create :user, email: "another@example.com" }
28
-
29
- before do
30
- post :create, feature_name: feature.name, flaggable_type: user.class.table_name, ids: ids, format: :js
31
- end
22
+ describe "PUT #update" do
23
+ let(:flag) { create :flag_in_flag }
32
24
 
33
- context "when successful" do
34
- let(:ids) { [user.id.to_s, user2.id.to_s].join(",") }
25
+ before do
26
+ put :update, feature_name: flag.feature.name, flaggable_type: "users", feature: flag_params
27
+ end
35
28
 
36
- it "creates the flag-in" do
37
- feature.users_flag_ins.collect(&:flaggable).should eq [user, user2]
38
- end
29
+ context "when successful" do
30
+ let(:user) { create :user }
39
31
 
40
- it "sets a flash message" do
41
- flash[:notice].should eq "#{user.class.to_s.pluralize} #{user.id}, #{user2.id} have been flagged in to #{feature.name}"
42
- end
32
+ let(:flag_params) do
33
+ {
34
+ users_flag_ins_attributes: {
35
+ "1" => { flaggable_type: "User", flaggable_key: user.id, _destroy: 0 }
36
+ }
37
+ }
43
38
  end
44
39
 
45
- context "when unsuccessful" do
46
- let(:ids) { "foo" }
47
-
48
- it "renders the errors template" do
49
- response.should render_template "error"
50
- end
40
+ it "sets a flash message" do
41
+ flash[:notice].should eq "Your flag-ins have been updated"
51
42
  end
52
43
 
53
- context "when creating a single flag-in" do
54
- before do
55
- post :create, feature_name: feature.name, flaggable_type: user.class.table_name, ids: ids, format: :js
56
- end
57
-
58
- context "when successful" do
59
- let(:ids) { user.id.to_s }
60
-
61
- it "creates the flag-in" do
62
- feature.users_flag_ins.collect(&:flaggable).should eq [user]
63
- end
64
-
65
- it "sets a flash message" do
66
- flash[:notice].should eq "#{user.class} #{user.id} has been flagged in to #{feature.name}"
67
- end
68
- end
69
-
70
- context "when the flaggable can't be found" do
71
- let(:ids) { "foo" }
72
-
73
- it "renders the errors template" do
74
- response.should render_template "error"
75
- end
76
- end
44
+ it "redirect to the group" do
45
+ response.should redirect_to flag_in_flags_path(feature_name: flag.feature.name, flaggable_type: "users")
77
46
  end
78
47
  end
79
- end
80
-
81
- describe "DELETE #destroy" do
82
- let(:flag) { create :flag_in_flag }
83
-
84
- before do
85
- delete :destroy, feature_name: flag.feature.name, flaggable_type: "users", id: flag.id
86
- end
87
48
 
88
- it "destroys the flag" do
89
- expect { flag.reload }.to raise_error ActiveRecord::RecordNotFound
90
- end
91
-
92
- it "sets a flash message" do
93
- flash[:notice].should eq "#{flag.feature.name} flag-in for User #{flag.flaggable.id} has been deleted."
94
- end
49
+ context "when unsuccessful" do
50
+ let(:flag_params) do
51
+ {
52
+ users_flag_ins_attributes: {
53
+ "1" => { flaggable_type: "User", flaggable_key: nil, _destroy: 0 }
54
+ }
55
+ }
56
+ end
95
57
 
96
- it "redirects to the flag-ins index" do
97
- response.should redirect_to flag_in_flags_path flag.feature.name, "users"
58
+ it "renders the show template" do
59
+ response.should render_template :index
60
+ end
98
61
  end
99
62
  end
100
63
  end
@@ -0,0 +1,107 @@
1
+ require "spec_helper"
2
+
3
+ describe Detour::GroupsController do
4
+ routes { Detour::Engine.routes }
5
+
6
+ describe "GET #index" do
7
+ let!(:group) { create :group }
8
+
9
+ before do
10
+ get :index
11
+ end
12
+
13
+ it "assigns the groups" do
14
+ assigns(:groups).should eq [group]
15
+ end
16
+
17
+ it "renders the index template" do
18
+ response.should render_template "groups/index"
19
+ end
20
+ end
21
+
22
+ describe "GET #show" do
23
+ let!(:group) { create :group }
24
+
25
+ before do
26
+ get :show, id: group.to_param
27
+ end
28
+
29
+ it "assigns the groups" do
30
+ assigns(:group).should eq group
31
+ end
32
+
33
+ it "renders the show template" do
34
+ response.should render_template "groups/show"
35
+ end
36
+ end
37
+
38
+ describe "POST #create" do
39
+ before do
40
+ post :create, format: :js, group: group_params
41
+ end
42
+
43
+ context "when successful" do
44
+ let(:group_params) { { name: "Foo Group", flaggable_type: "User" } }
45
+
46
+ it "sets a flash message" do
47
+ flash[:notice].should eq "Your group has been successfully created."
48
+ end
49
+
50
+ it "renders the success template" do
51
+ response.should render_template "success"
52
+ end
53
+ end
54
+
55
+ context "when unsuccessful" do
56
+ let(:group_params) { { name: "" } }
57
+
58
+ it "renders the errors template" do
59
+ response.should render_template "error"
60
+ end
61
+ end
62
+ end
63
+
64
+ describe "PUT #update" do
65
+ let(:group) { create :group }
66
+
67
+ before do
68
+ put :update, id: group.to_param, group: group_params
69
+ end
70
+
71
+ context "when successful" do
72
+ let(:group_params) { { name: "New Group Name" } }
73
+
74
+ it "sets a flash message" do
75
+ flash[:notice].should eq "Your group has been successfully updated."
76
+ end
77
+
78
+ it "redirect to the group" do
79
+ response.should redirect_to group_path group
80
+ end
81
+ end
82
+
83
+ context "when unsuccessful" do
84
+ let(:group_params) { { name: "" } }
85
+
86
+ it "renders the show template" do
87
+ response.should render_template "show"
88
+ end
89
+ end
90
+ end
91
+
92
+ describe "DELETE #destroy" do
93
+ let(:group) { create :group }
94
+
95
+ before do
96
+ delete :destroy, id: group.to_param
97
+ end
98
+
99
+ it "sets a flash message" do
100
+ flash[:notice].should eq "Group \"#{group.name}\" has been deleted."
101
+ end
102
+
103
+ it "redirects to the groups path" do
104
+ response.should redirect_to groups_path
105
+ end
106
+ end
107
+ end
@@ -2,7 +2,6 @@ class SetupDetour < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :detour_features do |t|
4
4
  t.string :name
5
- t.integer :failure_count, default: 0
6
5
  t.text :flag_in_counts, default: "{}"
7
6
  t.text :opt_out_counts, default: "{}"
8
7
  t.timestamps
@@ -15,6 +14,7 @@ class SetupDetour < ActiveRecord::Migration
15
14
  t.integer :feature_id
16
15
  t.integer :flaggable_id
17
16
  t.string :flaggable_type
17
+ t.integer :group_id
18
18
  t.string :group_name
19
19
  t.integer :percentage
20
20
  t.timestamps
@@ -22,11 +22,31 @@ class SetupDetour < ActiveRecord::Migration
22
22
 
23
23
  add_index :detour_flags, :type
24
24
  add_index :detour_flags, :feature_id
25
+ add_index :detour_flags, :group_id
26
+ add_index :detour_flags,
27
+ [:type, :feature_id, :group_id]
25
28
  add_index :detour_flags,
26
29
  [:type, :feature_id, :flaggable_type, :flaggable_id],
27
30
  name: "flag_type_feature_flaggable_type_id"
28
31
  add_index :detour_flags,
29
32
  [:type, :feature_id, :flaggable_type],
30
33
  name: "flag_type_feature_flaggable_type"
34
+
35
+ create_table :detour_groups do |t|
36
+ t.string :name
37
+ t.string :flaggable_type
38
+ t.timestamps
39
+ end
40
+
41
+ create_table :detour_memberships do |t|
42
+ t.integer :group_id
43
+ t.string :member_type
44
+ t.integer :member_id
45
+ t.timestamps
46
+ end
47
+
48
+ add_index :detour_memberships, [:group_id, :member_type, :member_id],
49
+ name: :detour_memberships_membership_index,
50
+ unique: true
31
51
  end
32
52
  end
@@ -15,7 +15,6 @@ ActiveRecord::Schema.define(:version => 20131221052201) do
15
15
 
16
16
  create_table "detour_features", :force => true do |t|
17
17
  t.string "name"
18
- t.integer "failure_count", :default => 0
19
18
  t.text "flag_in_counts", :default => "{}"
20
19
  t.text "opt_out_counts", :default => "{}"
21
20
  t.datetime "created_at", :null => false
@@ -29,6 +28,7 @@ ActiveRecord::Schema.define(:version => 20131221052201) do
29
28
  t.integer "feature_id"
30
29
  t.integer "flaggable_id"
31
30
  t.string "flaggable_type"
31
+ t.integer "group_id"
32
32
  t.string "group_name"
33
33
  t.integer "percentage"
34
34
  t.datetime "created_at", :null => false
@@ -36,10 +36,29 @@ ActiveRecord::Schema.define(:version => 20131221052201) do
36
36
  end
37
37
 
38
38
  add_index "detour_flags", ["feature_id"], :name => "index_detour_flags_on_feature_id"
39
+ add_index "detour_flags", ["group_id"], :name => "index_detour_flags_on_group_id"
39
40
  add_index "detour_flags", ["type", "feature_id", "flaggable_type", "flaggable_id"], :name => "flag_type_feature_flaggable_type_id"
40
41
  add_index "detour_flags", ["type", "feature_id", "flaggable_type"], :name => "flag_type_feature_flaggable_type"
42
+ add_index "detour_flags", ["type", "feature_id", "group_id"], :name => "index_detour_flags_on_type_and_feature_id_and_group_id"
41
43
  add_index "detour_flags", ["type"], :name => "index_detour_flags_on_type"
42
44
 
45
+ create_table "detour_groups", :force => true do |t|
46
+ t.string "name"
47
+ t.string "flaggable_type"
48
+ t.datetime "created_at", :null => false
49
+ t.datetime "updated_at", :null => false
50
+ end
51
+
52
+ create_table "detour_memberships", :force => true do |t|
53
+ t.integer "group_id"
54
+ t.string "member_type"
55
+ t.integer "member_id"
56
+ t.datetime "created_at", :null => false
57
+ t.datetime "updated_at", :null => false
58
+ end
59
+
60
+ add_index "detour_memberships", ["group_id", "member_type", "member_id"], :name => "detour_memberships_membership_index", :unique => true
61
+
43
62
  create_table "users", :force => true do |t|
44
63
  t.string "email"
45
64
  t.string "name"
@@ -0,0 +1,7 @@
1
+ FactoryGirl.define do
2
+ factory :database_group_flag, class: "Detour::DatabaseGroupFlag" do
3
+ feature
4
+ flaggable_type "User"
5
+ group
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  FactoryGirl.define do
2
- factory :group_flag, class: "Detour::GroupFlag" do
2
+ factory :defined_group_flag, class: "Detour::DefinedGroupFlag" do
3
3
  feature
4
4
  flaggable_type "User"
5
5
  group_name "foo users"
@@ -0,0 +1,10 @@
1
+ FactoryGirl.define do
2
+ sequence :name do |n|
3
+ "Group #{n}"
4
+ end
5
+
6
+ factory :group, class: "Detour::Group" do
7
+ flaggable_type "User"
8
+ name
9
+ end
10
+ end
@@ -0,0 +1,6 @@
1
+ FactoryGirl.define do
2
+ factory :membership, class: "Detour::Membership" do
3
+ association :member, factory: :user
4
+ group
5
+ end
6
+ end
@@ -0,0 +1,50 @@
1
+ require "spec_helper"
2
+
3
+ describe "creating database group flags" do
4
+ let!(:feature) { create :feature }
5
+ let!(:group) { create :group, flaggable_type: "User" }
6
+ let(:checkbox) { "features[#{feature.name}][users_database_group_flags_attributes[#{group.name}]][to_keep]" }
7
+
8
+ before do
9
+ visit "/detour/flags/users"
10
+ check checkbox
11
+ end
12
+
13
+ it "creates the database group flag" do
14
+ click_button "Save Changes"
15
+ feature.reload.users_database_group_flags.map(&:group).should eq [group]
16
+ end
17
+
18
+ context "when there are errors in other fields" do
19
+ it "preserves the database group flag option" do
20
+ fill_in "features[#{feature.name}][users_percentage_flag_attributes][percentage]", with: 101
21
+ click_button "Save Changes"
22
+ page.find("input[type='checkbox'][name='#{checkbox}']").should be_checked
23
+ end
24
+ end
25
+ end
26
+
27
+ describe "removing database group flags" do
28
+ let!(:feature) { create :feature }
29
+ let(:group) { create :group, flaggable_type: "User" }
30
+ let!(:group_flag) { create :database_group_flag, feature: feature, group: group, flaggable_type: "User" }
31
+ let(:checkbox) { "features[#{feature.name}][users_database_group_flags_attributes[#{group.name}]][to_keep]" }
32
+
33
+ before do
34
+ visit "/detour/flags/users"
35
+ uncheck checkbox
36
+ end
37
+
38
+ it "removes the database group flag" do
39
+ click_button "Save Changes"
40
+ feature.reload.users_database_group_flags.should be_empty
41
+ end
42
+
43
+ context "when there are errors in other fields" do
44
+ it "preserves the database group flag option" do
45
+ fill_in "features[#{feature.name}][users_percentage_flag_attributes][percentage]", with: 101
46
+ click_button "Save Changes"
47
+ page.find("input[type='checkbox'][name='#{checkbox}']").should_not be_checked
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,174 @@
1
+ require "spec_helper"
2
+
3
+ describe "listing groups" do
4
+ let!(:group) { create :group }
5
+
6
+ before do
7
+ visit "/detour/groups"
8
+ end
9
+
10
+ it "lists every group" do
11
+ within "ul li.group" do
12
+ page.should have_content group.name
13
+ end
14
+ end
15
+ end
16
+
17
+ describe "showing a group" do
18
+ let(:user) { create :user }
19
+ let(:group) { create :group }
20
+
21
+ before do
22
+ User.instance_variable_set "@detour_flaggable_find_by", :email
23
+ create :membership, group: group, member: user
24
+ visit "/detour/groups/#{group.to_param}"
25
+ end
26
+
27
+ it "lists every membership" do
28
+ page.find("input[name=member_identifier]").value.should eq user.email
29
+ end
30
+ end
31
+
32
+ describe "creating a group", js: true do
33
+ before do
34
+ visit "/detour/groups"
35
+ page.find("[data-target='#create-group']").click
36
+ end
37
+
38
+ context "when successful" do
39
+ before do
40
+ fill_in "group[name]", with: "New Group"
41
+ select "User", from: "group[flaggable_type]"
42
+ click_button "Create Group"
43
+ end
44
+
45
+ it "displays a flash message" do
46
+ page.should have_content "Your group has been successfully created."
47
+ end
48
+
49
+ it "shows the newly created group" do
50
+ within "ul li.group" do
51
+ page.should have_content "New Group"
52
+ end
53
+ end
54
+ end
55
+
56
+ context "when unsuccessful" do
57
+ before do
58
+ click_button "Create Group"
59
+ end
60
+
61
+ it "displays error messages" do
62
+ page.should have_content "Name can't be blank"
63
+ end
64
+ end
65
+ end
66
+
67
+ describe "updating a group" do
68
+ let(:group) { create :group }
69
+
70
+ before do
71
+ visit "/detour/groups/#{group.to_param}"
72
+ end
73
+
74
+ context "when successful" do
75
+ before do
76
+ fill_in "group[name]", with: "New Group Name"
77
+ click_button "Update Group"
78
+ end
79
+
80
+ it "displays a flash message" do
81
+ page.should have_content "Your group has been successfully updated."
82
+ end
83
+
84
+ it "shows the newly updated group" do
85
+ within "h1" do
86
+ page.should have_content "New Group Name"
87
+ end
88
+ end
89
+ end
90
+
91
+ context "when unsuccessful" do
92
+ before do
93
+ fill_in "group[name]", with: ""
94
+ click_button "Update Group"
95
+ end
96
+
97
+ it "displays error messages" do
98
+ page.should have_content "Name can't be blank"
99
+ end
100
+ end
101
+ end
102
+
103
+ describe "adding a member to a group", js: true do
104
+ let(:group) { create :group }
105
+ let!(:user) { create :user }
106
+
107
+ before do
108
+ User.instance_variable_set "@detour_flaggable_find_by", :email
109
+ visit "/detour/groups/#{group.to_param}"
110
+ page.find(".add-fields").click
111
+ end
112
+
113
+ context "when successful" do
114
+ before do
115
+ name = page.find("##{page.all("label")[-2][:for]}")[:name]
116
+ fill_in name, with: user.email
117
+ click_button "Update Group"
118
+ end
119
+
120
+ it "displays a flash message" do
121
+ page.should have_content "Your group has been successfully updated."
122
+ end
123
+
124
+ it "shows the newly added member" do
125
+ page.find("input[type='text'][disabled]").value.should eq user.email
126
+ end
127
+ end
128
+
129
+ context "when unsuccessful" do
130
+ before do
131
+ click_button "Update Group"
132
+ end
133
+
134
+ it "displays error messages" do
135
+ page.should have_content "Memberships user \"\" could not be found"
136
+ end
137
+ end
138
+ end
139
+
140
+ describe "removing a member from a group" do
141
+ let(:group) { create :group }
142
+ let(:user) { create :user }
143
+ let!(:membership) { create :membership, group: group, member: user }
144
+
145
+ before do
146
+ User.instance_variable_set "@detour_flaggable_find_by", :email
147
+ visit "/detour/groups/#{group.to_param}"
148
+ name = page.find("##{page.all("label").last[:for]}")[:name]
149
+ check name
150
+ click_button "Update Group"
151
+ end
152
+
153
+ it "does not show the removed member" do
154
+ page.should_not have_selector "label[for='group_memberships_attributes_0_member_key']"
155
+ end
156
+ end
157
+
158
+ describe "destroying a group", js: true do
159
+ let!(:group) { create :group }
160
+
161
+ before do
162
+ visit "/detour/groups/#{group.to_param}"
163
+ click_button "Delete Group"
164
+ page.find(".modal a").click
165
+ end
166
+
167
+ it "shows a flash message" do
168
+ page.should have_content "Group \"#{group.name}\" has been deleted"
169
+ end
170
+
171
+ it "shows the remaining groups" do
172
+ page.should_not have_selector ".group"
173
+ end
174
+ end
@@ -0,0 +1,67 @@
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
+ let(:checkbox) { "features[#{feature.name}][users_defined_group_flags_attributes[admins]][to_keep]" }
19
+
20
+ before do
21
+ Detour.config.define_user_group :admins do |user|
22
+ end
23
+
24
+ visit "/detour/flags/users"
25
+ check checkbox
26
+ end
27
+
28
+ it "creates the group flag" do
29
+ click_button "Save Changes"
30
+ feature.reload.users_defined_group_flags.first.group_name.should eq "admins"
31
+ end
32
+
33
+ context "when there are errors in other fields" do
34
+ it "preserves the database group flag option" do
35
+ fill_in "features[#{feature.name}][users_percentage_flag_attributes][percentage]", with: 101
36
+ click_button "Save Changes"
37
+ page.find("input[type='checkbox'][name='#{checkbox}']").should be_checked
38
+ end
39
+ end
40
+ end
41
+
42
+ describe "removing defined group flags" do
43
+ let(:feature) { create :feature }
44
+ let!(:group_flag) { create :defined_group_flag, feature: feature, group_name: "admins" }
45
+ let(:checkbox) { "features[#{feature.name}][users_defined_group_flags_attributes[admins]][to_keep]" }
46
+
47
+ before do
48
+ Detour.config.define_user_group :admins do |user|
49
+ end
50
+
51
+ visit "/detour/flags/users"
52
+ uncheck checkbox
53
+ end
54
+
55
+ it "creates the group flag" do
56
+ click_button "Save Changes"
57
+ feature.reload.users_defined_group_flags.should be_empty
58
+ end
59
+
60
+ context "when there are errors in other fields" do
61
+ it "preserves the database group flag option" do
62
+ fill_in "features[#{feature.name}][users_percentage_flag_attributes][percentage]", with: 101
63
+ click_button "Save Changes"
64
+ page.find("input[type='checkbox'][name='#{checkbox}']").should_not be_checked
65
+ end
66
+ end
67
+ end