cullender 0.0.1

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 (107) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +34 -0
  5. data/app/assets/javascripts/cullender/application.js +13 -0
  6. data/app/assets/javascripts/cullender/rules.js +46 -0
  7. data/app/assets/stylesheets/cullender/application.css +13 -0
  8. data/app/assets/stylesheets/cullender/rules.css.scss +15 -0
  9. data/app/controllers/cullender/rules_controller.rb +68 -0
  10. data/app/controllers/cullender_controller.rb +105 -0
  11. data/app/helpers/cullender/rules_helper.rb +136 -0
  12. data/app/models/cullender/rule.rb +204 -0
  13. data/app/views/cullender/rules/_form.html.erb +20 -0
  14. data/app/views/cullender/rules/_trigger_fields.html.erb +19 -0
  15. data/app/views/cullender/rules/create.js.erb +3 -0
  16. data/app/views/cullender/rules/index.html.erb +25 -0
  17. data/app/views/cullender/rules/new.html.erb +1 -0
  18. data/app/views/cullender/rules/show.html.erb +3 -0
  19. data/config/locales/en.yml +12 -0
  20. data/config/routes.rb +4 -0
  21. data/lib/cullender.rb +96 -0
  22. data/lib/cullender/controllers/filter_logic.rb +89 -0
  23. data/lib/cullender/controllers/scoped_views.rb +17 -0
  24. data/lib/cullender/core_ext/hash.rb +1 -0
  25. data/lib/cullender/core_ext/hash/deep_delete.rb +13 -0
  26. data/lib/cullender/engine.rb +15 -0
  27. data/lib/cullender/engine/routes.rb +306 -0
  28. data/lib/cullender/mapping.rb +139 -0
  29. data/lib/cullender/version.rb +3 -0
  30. data/lib/generators/cullender/cullender_generator.rb +66 -0
  31. data/lib/generators/cullender/install_generator.rb +18 -0
  32. data/lib/generators/cullender/orm_helpers.rb +32 -0
  33. data/lib/generators/cullender/templates/cullender.rb +3 -0
  34. data/lib/generators/cullender/templates/cullender_migration.rb +13 -0
  35. data/lib/tasks/cullender_tasks.rake +4 -0
  36. data/spec/controllers/cullender/rules_controller_spec.rb +180 -0
  37. data/spec/cullender/controllers/filter_logic_spec.rb +233 -0
  38. data/spec/dummy/README.rdoc +28 -0
  39. data/spec/dummy/Rakefile +6 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +17 -0
  41. data/spec/dummy/app/assets/stylesheets/application.css +14 -0
  42. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  43. data/spec/dummy/app/controllers/events_controller.rb +60 -0
  44. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  45. data/spec/dummy/app/models/event.rb +16 -0
  46. data/spec/dummy/app/views/cullender/rules/_form.html.erb +33 -0
  47. data/spec/dummy/app/views/cullender/rules/index.html.erb +24 -0
  48. data/spec/dummy/app/views/cullender/rules/new.html.erb +1 -0
  49. data/spec/dummy/app/views/cullender/rules/show.html.erb +3 -0
  50. data/spec/dummy/app/views/events/_form.html.erb +21 -0
  51. data/spec/dummy/app/views/events/edit.html.erb +6 -0
  52. data/spec/dummy/app/views/events/index.html.erb +27 -0
  53. data/spec/dummy/app/views/events/new.html.erb +5 -0
  54. data/spec/dummy/app/views/events/show.html.erb +10 -0
  55. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  56. data/spec/dummy/bin/bundle +3 -0
  57. data/spec/dummy/bin/rails +4 -0
  58. data/spec/dummy/bin/rake +4 -0
  59. data/spec/dummy/config.ru +4 -0
  60. data/spec/dummy/config/application.rb +23 -0
  61. data/spec/dummy/config/boot.rb +9 -0
  62. data/spec/dummy/config/database.yml +25 -0
  63. data/spec/dummy/config/environment.rb +5 -0
  64. data/spec/dummy/config/environments/development.rb +27 -0
  65. data/spec/dummy/config/environments/production.rb +80 -0
  66. data/spec/dummy/config/environments/test.rb +36 -0
  67. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  68. data/spec/dummy/config/initializers/cullender.rb +3 -0
  69. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  70. data/spec/dummy/config/initializers/inflections.rb +16 -0
  71. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  72. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  73. data/spec/dummy/config/initializers/session_store.rb +3 -0
  74. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  75. data/spec/dummy/config/locales/cullender.en.yml +12 -0
  76. data/spec/dummy/config/locales/en.yml +23 -0
  77. data/spec/dummy/config/routes.rb +5 -0
  78. data/spec/dummy/db/development.sqlite3 +0 -0
  79. data/spec/dummy/db/migrate/123344556676_create_cullender_tables.rb +12 -0
  80. data/spec/dummy/db/schema.rb +24 -0
  81. data/spec/dummy/db/test.sqlite3 +0 -0
  82. data/spec/dummy/log/development.log +9987 -0
  83. data/spec/dummy/log/test.log +19786 -0
  84. data/spec/dummy/public/404.html +27 -0
  85. data/spec/dummy/public/422.html +26 -0
  86. data/spec/dummy/public/500.html +26 -0
  87. data/spec/dummy/public/favicon.ico +0 -0
  88. data/spec/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  89. data/spec/dummy/tmp/cache/assets/development/sprockets/268a828ee4997cf5c19106e5f00fcfb8 +0 -0
  90. data/spec/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  91. data/spec/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  92. data/spec/dummy/tmp/cache/assets/development/sprockets/56b2eb9b46b9aca7e86b5132ddf0d9de +0 -0
  93. data/spec/dummy/tmp/cache/assets/development/sprockets/750887406b3e8dacb2b03f986330932d +0 -0
  94. data/spec/dummy/tmp/cache/assets/development/sprockets/750b42e431d194c41f5b1cde4a257e47 +0 -0
  95. data/spec/dummy/tmp/cache/assets/development/sprockets/921642fe740290e9e5e88a706e5a562c +0 -0
  96. data/spec/dummy/tmp/cache/assets/development/sprockets/a967ed3fc5f8406f3ff72180775f1b40 +0 -0
  97. data/spec/dummy/tmp/cache/assets/development/sprockets/ae74bf4fc3fd20e7f7b98860b8ef0f74 +0 -0
  98. data/spec/dummy/tmp/cache/assets/development/sprockets/c7dbd1f5acc2d5bc078363f4f3c70c54 +0 -0
  99. data/spec/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  100. data/spec/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  101. data/spec/dummy/tmp/cache/assets/development/sprockets/d995daf8d6f36c27b6e9d1b4672eaf1e +0 -0
  102. data/spec/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  103. data/spec/helpers/cullender/rules_helper_spec.rb +360 -0
  104. data/spec/models/cullender/rule_spec.rb +425 -0
  105. data/spec/requests/rules_spec.rb +19 -0
  106. data/spec/spec_helper.rb +60 -0
  107. metadata +319 -0
@@ -0,0 +1,3 @@
1
+ module Cullender
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,66 @@
1
+ require 'generators/cullender/orm_helpers'
2
+
3
+ module Cullender
4
+ module Generators
5
+ class CullenderGenerator < Rails::Generators::NamedBase
6
+ include Rails::Generators::Migration
7
+ include Cullender::Generators::OrmHelpers
8
+ source_root File.expand_path('../templates', __FILE__)
9
+
10
+ argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
11
+ desc "Generates a model with the given NAME (if one does not exist) with cullender " <<
12
+ "configuration plus a migration file and cullender routes."
13
+
14
+ class_option :routes, :desc => "Generate routes", :type => :boolean, :default => true
15
+
16
+
17
+ def add_cullender_routes
18
+ cullender_route = "cullender_for :#{plural_name}"
19
+ cullender_route << %Q(, :class_name => "#{class_name}") if class_name.include?("::")
20
+ cullender_route << %Q(, :skip => :all) unless options.routes?
21
+ route cullender_route
22
+ end
23
+
24
+
25
+ def copy_cullender_rules_migration
26
+ migration_template "cullender_migration.rb", "db/migrate/create_cullender_tables"
27
+ end
28
+
29
+ # def copy_cullender_migration
30
+ # if (behavior == :invoke && model_exists?) || (behavior == :revoke && migration_exists?(table_name))
31
+ # migration_template "migration_existing.rb", "db/migrate/add_cullender_to_#{table_name}"
32
+ # else
33
+ # migration_template "migration.rb", "db/migrate/create_cullender_for_#{table_name}"
34
+ # end
35
+ # end
36
+
37
+ # def inject_cullender_content
38
+ # content = model_contents + <<CONTENT
39
+ # # Setup accessible (or protected) attributes for your model
40
+ # attr_accessible :email, :password, :password_confirmation, :remember_me
41
+ # CONTENT
42
+
43
+ # class_path = if namespaced?
44
+ # class_name.to_s.split("::")
45
+ # else
46
+ # [class_name]
47
+ # end
48
+
49
+ # indent_depth = class_path.size - 1
50
+ # content = content.split("\n").map { |line| " " * indent_depth + line } .join("\n") << "\n"
51
+
52
+ # inject_into_class(model_path, class_path.last, content) if model_exists?
53
+ # end
54
+
55
+
56
+ def migration_data
57
+ <<RUBY
58
+ t.string :name
59
+ t.boolean :enabled
60
+ t.text :triggers
61
+ RUBY
62
+ end
63
+
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,18 @@
1
+ module Cullender
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path('../templates', __FILE__)
5
+
6
+ desc "Creates a Cullender initializer and copy locale files to your application."
7
+
8
+
9
+ def create_initializer_file
10
+ template "cullender.rb", "config/initializers/cullender.rb"
11
+ end
12
+
13
+ def copy_locale
14
+ copy_file "../../../../config/locales/en.yml", "config/locales/cullender.en.yml"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ module Cullender
2
+ module Generators
3
+ module OrmHelpers
4
+ def model_contents
5
+ <<-CONTENT
6
+ # Include default devise modules. Others available are:
7
+ # :token_authenticatable, :confirmable,
8
+ # :lockable, :timeoutable and :omniauthable
9
+ devise :database_authenticatable, :registerable,
10
+ :recoverable, :rememberable, :trackable, :validatable
11
+
12
+ CONTENT
13
+ end
14
+
15
+ def model_exists?
16
+ File.exists?(File.join(destination_root, model_path))
17
+ end
18
+
19
+ def migration_exists?(table_name)
20
+ Dir.glob("#{File.join(destination_root, migration_path)}/[0-9]*_*.rb").grep(/\d+_add_devise_to_#{table_name}.rb$/).first
21
+ end
22
+
23
+ def migration_path
24
+ @migration_path ||= File.join("db", "migrate")
25
+ end
26
+
27
+ def model_path
28
+ @model_path ||= File.join("app", "models", "#{file_path}.rb")
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,3 @@
1
+ Cullender.setup do |config|
2
+
3
+ end
@@ -0,0 +1,13 @@
1
+ class CreateCullenderTables < ActiveRecord::Migration
2
+ def change
3
+ create_table :rules do |t|
4
+ <%= migration_data -%>
5
+
6
+ <% attributes.each do |attribute| -%>
7
+ t.<%= attribute.type %> :<%= attribute.name %>
8
+ <% end -%>
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :cullender do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,180 @@
1
+ require 'spec_helper'
2
+
3
+ # This spec was generated by rspec-rails when you ran the scaffold generator.
4
+ # It demonstrates how one might use RSpec to specify the controller code that
5
+ # was generated by Rails when you ran the scaffold generator.
6
+ #
7
+ # It assumes that the implementation code is generated by the rails scaffold
8
+ # generator. If you are using any extension libraries to generate different
9
+ # controller code, this generated spec may or may not pass.
10
+ #
11
+ # It only uses APIs available in rails and/or rspec-rails. There are a number
12
+ # of tools you can use to make these specs even more expressive, but we're
13
+ # sticking to rails and rspec-rails APIs to keep things simple and stable.
14
+ #
15
+ # Compared to earlier versions of this generator, there is very limited use of
16
+ # stubs and message expectations in this spec. Stubs are only used when there
17
+ # is no simpler way to get a handle on the object needed for the example.
18
+ # Message expectations are only used when there is no simpler way to specify
19
+ # that an instance is receiving a specific message.
20
+
21
+ describe Cullender::RulesController do
22
+ before(:each) do
23
+ @request.env["cullender.mapping"] = Cullender.mappings[:event]
24
+ Cullender::Rule.reset_callbacks(:create)
25
+ end
26
+ # This should return the minimal set of attributes required to create a valid
27
+ # Rule. As you add validations to Rule, be sure to
28
+ # update the return value of this method accordingly.
29
+ def valid_attributes
30
+ {name: "MyRule"}
31
+ end
32
+
33
+ # This should return the minimal set of values that should be in the session
34
+ # in order to pass any filters (e.g. authentication) defined in
35
+ # RulesController. Be sure to keep this updated too.
36
+ def valid_session
37
+ {}
38
+ end
39
+
40
+ describe "GET index" do
41
+ before(:each) do
42
+ @rule = Cullender::Rule.create(valid_attributes)
43
+ get :index, {:use_route => :cullender}, valid_session
44
+ end
45
+
46
+ it "assigns all rules as @rules" do
47
+ assigns(:rules).should eq([@rule])
48
+ end
49
+
50
+ end
51
+
52
+
53
+ describe "GET new" do
54
+ it "assigns a new rule as @rule" do
55
+ get :new, {:use_route => :cullender}, valid_session
56
+ assigns(:rule).should be_a_new(Cullender::Rule)
57
+ end
58
+ end
59
+
60
+ describe "GET show" do
61
+ it "assigns the requested rule as @rule" do
62
+ rule = Cullender::Rule.create(valid_attributes)
63
+ get :show, {:id => rule.to_param, :use_route => :cullender}, valid_session
64
+ assigns(:rule).should eq(rule)
65
+ end
66
+ end
67
+
68
+ describe "POST create" do
69
+ context "with valid params" do
70
+ it "creates a new Rule" do
71
+ expect {
72
+ post :create, {:rule => valid_attributes, :use_route => :cullender}, valid_session
73
+ }.to change(Cullender::Rule, :count).by(1)
74
+ end
75
+
76
+ it "assigns a newly created rule as @rule" do
77
+ post :create, {:rule => valid_attributes, :use_route => :cullender}, valid_session
78
+ assigns(:rule).should be_a(Cullender::Rule)
79
+ assigns(:rule).should be_persisted
80
+ end
81
+
82
+ it "redirects to the rules_url" do
83
+ post :create, {:rule => valid_attributes, :use_route => :cullender}, valid_session
84
+ response.should redirect_to({"controller"=>controller.params[:controller], "action"=>"index", :use_route => :cullender})
85
+ end
86
+ end
87
+
88
+ context "with invalid params" do
89
+ it "assigns a newly created but unsaved rule as @rule" do
90
+ # Trigger the behavior that occurs when invalid params are submitted
91
+ Cullender::Rule.any_instance.stub(:save).and_return(false)
92
+ post :create, {:rule => {:name => "asd"}, :use_route => :cullender}, valid_session
93
+ assigns(:rule).should be_a_new(Cullender::Rule)
94
+ end
95
+
96
+ it "re-renders the 'new' template" do
97
+ # Trigger the behavior that occurs when invalid params are submitted
98
+ Cullender::Rule.any_instance.stub(:save).and_return(false)
99
+ post :create, {:rule => {:name => "asd"}, :use_route => :cullender}, valid_session
100
+ response.should render_template("new")
101
+ end
102
+ end
103
+ end
104
+
105
+ describe "PUT update" do
106
+ before(:each) do
107
+ controller.stub(:clean_ids).and_return(nil)
108
+ Cullender::Rule.reset_callbacks(:update)
109
+ end
110
+ context "with valid params" do
111
+ it "updates the requested rule" do
112
+ rule = Cullender::Rule.create(valid_attributes)
113
+ # Assuming there are no other rules in the database, this
114
+ # specifies that the Rule created on the previous line
115
+ # receives the :update_attributes message with whatever params are
116
+ # submitted in the request.
117
+
118
+ Cullender::Rule.any_instance.should_receive(:update_attributes).with({'name' => 'New Name'})
119
+ put :update, {:id => rule.to_param, :rule => {'name' => 'New Name'}, :use_route => :cullender}, valid_session
120
+ end
121
+
122
+ it "assigns the requested rule as @rule" do
123
+ rule = Cullender::Rule.create(valid_attributes)
124
+ put :update, {:id => rule.to_param, :rule => valid_attributes, :use_route => :cullender}, valid_session
125
+ assigns(:rule).should eq(rule)
126
+ end
127
+
128
+ it "redirects to the rules page" do
129
+ rule = Cullender::Rule.create(valid_attributes)
130
+ put :update, {:id => rule.to_param, :rule => valid_attributes, :use_route => :cullender}, valid_session
131
+ response.should redirect_to({"controller"=>controller.params[:controller], "action"=>"index", :use_route => :cullender})
132
+ end
133
+ end
134
+
135
+ context "with invalid params" do
136
+ it "assigns the rule as @rule" do
137
+ rule = Cullender::Rule.create(valid_attributes)
138
+ # Trigger the behavior that occurs when invalid params are submitted
139
+ Cullender::Rule.any_instance.stub(:save).and_return(false)
140
+ put :update, {:id => rule.to_param, :rule => {:name => "asd"}, :use_route => :cullender}, valid_session
141
+ assigns(:rule).should eq(rule)
142
+ end
143
+
144
+ it "re-renders the 'show' template" do
145
+ rule = Cullender::Rule.create(valid_attributes)
146
+ # Trigger the behavior that occurs when invalid params are submitted
147
+ Cullender::Rule.any_instance.stub(:save).and_return(false)
148
+ put :update, {:id => rule.to_param, :rule => {:name => "asd"}, :use_route => :cullender}, valid_session
149
+ response.should render_template("show")
150
+ end
151
+ end
152
+ end
153
+
154
+ describe "DELETE destroy" do
155
+ before(:each)do
156
+ @factory = Cullender::Rule.create(valid_attributes)
157
+ Cullender::Rule.reset_callbacks(:destroy)
158
+ end
159
+ it "destroys the requested model" do
160
+ expect {
161
+ delete :destroy, {:id => @factory.to_param, :use_route => :cullender}, valid_session
162
+ }.to change(@factory.class, :count).by(-1)
163
+ end
164
+
165
+ it "redirects to the index url" do
166
+ delete :destroy, {:id => @factory.to_param, :use_route => :cullender}, valid_session
167
+ if defined?(@redirect)
168
+ response.should redirect_to(@redirect)
169
+ else
170
+ response.should redirect_to({"controller"=>controller.params[:controller], "action"=>"index", :use_route => :cullender})
171
+ end
172
+ end
173
+
174
+ it "returns a flash message that says that the model has been destroyed" do
175
+ delete :destroy, {:id => @factory.to_param, :use_route => :cullender}, valid_session
176
+ controller.flash[:notice].should eql("Rule was successfully destroyed.")
177
+ end
178
+ end
179
+
180
+ end
@@ -0,0 +1,233 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Cullender::Controllers::FilterLogic" do
4
+
5
+ before(:each) do
6
+ @object = Object.new
7
+ @object.extend(Cullender::Controllers::FilterLogic)
8
+ end
9
+
10
+
11
+ def add_or_filter(key, params, field, should_raise = false)
12
+ if params.present? && params.has_key?(key)
13
+ if should_raise
14
+ params[key] = {1 => params[key], 2 => add_operator(field)}
15
+ else
16
+ idx = params[key].keys.last.to_i + 1
17
+ params[key].deep_merge!({idx => add_operator(field)})
18
+ end
19
+ else
20
+ if should_raise
21
+ params[key] = add_operator(field)
22
+ else
23
+ params[key] = add_operator(field)
24
+ end
25
+ end
26
+ end
27
+ describe "#add_or_filter" do
28
+ context "with filter(s) defined" do
29
+ context "OR with the base" do
30
+ context "with only one group" do
31
+ before(:each) do
32
+ @hash = {"f" => {"some_field" => {"o" => nil}}}
33
+ @object.add_or_filter("f", @hash, "new_field", true)
34
+ end
35
+ it "moves the existing group to a higher level" do
36
+ @hash["f"].should have_key(1)
37
+ @hash["f"][1].should have_key("some_field")
38
+ end
39
+ it "adds the filter to a new group" do
40
+ @hash["f"].should have_key(2)
41
+ @hash["f"][2].should have_key("new_field")
42
+ end
43
+ end
44
+ context "with many groups" do
45
+ before(:each) do
46
+ @hash = {"f" => {1 => {"some_field1" => {"o" => nil}}, 2 => {"some_field2" => {"o" => nil}}}}
47
+ @object.add_or_filter("f", @hash, "new_field", true)
48
+ end
49
+ it "moves the existing group to a higher level" do
50
+ @hash["f"].should have_key(1)
51
+ @hash["f"][1][1].should have_key("some_field1")
52
+ @hash["f"][1][2].should have_key("some_field2")
53
+ end
54
+ it "adds the filter to a new group" do
55
+ @hash["f"].should have_key(2)
56
+ @hash["f"][2].should have_key("new_field")
57
+ end
58
+ end
59
+ end
60
+ context "OR with other groups at the same level" do
61
+ before(:each) do
62
+ @hash = {"f" => {1 => {"some_field1" => {"o" => nil}}, 2 => {"some_field2" => {"o" => nil}}}}
63
+ @object.add_or_filter("f", @hash, "new_field", false)
64
+ end
65
+ it "keeps the existing group at the higher level" do
66
+ @hash["f"].should have_key(1)
67
+ @hash["f"][1].should have_key("some_field1")
68
+ @hash["f"][2].should have_key("some_field2")
69
+ end
70
+ it "adds the filter to as a new group" do
71
+ @hash["f"].should have_key(3)
72
+ @hash["f"][3].should have_key("new_field")
73
+ end
74
+ end
75
+ end
76
+ context "with filter(s) undefined" do
77
+ before(:each) do
78
+ @hash = {}
79
+ @object.add_or_filter("f", @hash, "my_field")
80
+ end
81
+ it "creates a new filter hash with the field" do
82
+ @hash.should have_key("f")
83
+ @hash["f"].should have_key("my_field")
84
+ end
85
+ end
86
+ end
87
+
88
+ # def add_and_filter(params, field)
89
+ # if params.has_key?("f")
90
+ # params["f"].deep_merge!(add_operator(field))
91
+ # else
92
+ # params["f"] = add_operator(field)
93
+ # end
94
+ # end
95
+ describe "#add_and_filter" do
96
+ context "with existing filter(s)" do
97
+ context "that are deeply nested" do
98
+ before(:each) do
99
+ @params = { "f" => {1 => {"field1" => {"o" => nil}, "field2" => {"o" => nil}}, 2 => {1 => {"field3" => {"o" => nil}}}, "field4" => {"o" => nil}}}
100
+ end
101
+ it "adds a new field with 1 deep if the key doesn't exist" do
102
+ @object.add_and_filter("f", @params, { 1 => "field3"})
103
+ @params["f"][1].should have(3).keys
104
+ @params["f"][1].should have_key("field3")
105
+ end
106
+ it "adds a new field with 2 deep if the key doesn't exist" do
107
+ @object.add_and_filter( "f", @params, {2 => {1 => "field2"}})
108
+ @params["f"][2][1].should have(2).keys
109
+ @params["f"][2][1].should have_key("field2")
110
+ end
111
+ it "doesn't add a new field if the key already exists" do
112
+ @object.add_and_filter("f", @params, { 1 => "field2"})
113
+ @params["f"][1].should have(2).keys
114
+ end
115
+ end
116
+ context "that are not nested" do
117
+ before(:each) do
118
+ @params = { "f" => {"field1" => {"o" => nil}, "field2" => {"o" => nil}}}
119
+ end
120
+ it "adds a new field if the key doesn't exist" do
121
+ @object.add_and_filter("f", @params, "field3")
122
+ @params["f"].should have(3).keys
123
+ @params["f"].should have_key("field3")
124
+ end
125
+ end
126
+ end
127
+ context "without existing filter(s)" do
128
+ before(:each) do
129
+ @hash = {}
130
+ @object.add_and_filter("f", @hash, "my_field")
131
+ end
132
+ it "creates a new filter hash with the field" do
133
+ @hash.should have_key("f")
134
+ @hash["f"].should have_key("my_field")
135
+ end
136
+ end
137
+ end
138
+
139
+ describe "#remove_and_filter" do
140
+ context "with a filter present" do
141
+ it "deletes the part of hash specified by a string" do
142
+ params = {"f" => {"field" => {"o" => nil}}}
143
+ params["f"].should_receive(:delete).with("field")
144
+ @object.remove_and_filter("f", params, "field")
145
+ end
146
+ it "deletes the part of hash specified by a hash" do
147
+ params = {"f" => { 1 => {"field" => {"o" => nil}}}}
148
+ params["f"].should_receive(:deep_delete).with({1 => {"field" => nil}})
149
+ @object.remove_and_filter("f", params, {1 => {"field" => nil}})
150
+ end
151
+ end
152
+ context "without a filter present" do
153
+ it "does nothing" do
154
+ params = {"f" => {"field" => {"o" => nil}}}
155
+ params.stub(:has_key?).with("f").and_return(false)
156
+ params["f"].should_not_receive(:deep_delete)
157
+ @object.remove_and_filter("f", params, "field")
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+ describe "#add_operator" do
164
+ it "returns a hash with an operator indexed by the specified string" do
165
+ @object.add_operator("index").should eql({"index" => {"o" => nil}})
166
+ end
167
+ it "returns a hash with an operator indexed by the specified hash" do
168
+ @object.add_operator({0 => "index"}).should eql({0 => {"index" => {"o" => nil}}})
169
+ end
170
+ end
171
+
172
+ describe "#apply_filter_actions" do
173
+ context "add OR" do
174
+ context "with no params" do
175
+ it "raise new field", :current => true do
176
+ params = {"or"=>{"raise_field"=>"name", "raise"=>"OR"}}
177
+ flag = @object.apply_filter_actions("triggers", {"name" => "dsafdasg"}, params)
178
+ flag.should be_true
179
+ end
180
+ end
181
+ context "with 'field' present" do
182
+ before(:each) do
183
+ @params = {"or" => {"field" => "myfield", "commit" => "OR"}}
184
+ end
185
+ it "adds an or filter" do
186
+ @object.should_receive(:add_or_filter).with("name", {"name" => {}}, "myfield", false)
187
+ @object.apply_filter_actions("name", {"name" => {}}, @params)
188
+ end
189
+ end
190
+ context "without 'field' present" do
191
+ before(:each) do
192
+ @params = {"or" => {"field" => nil, "commit" => "OR"}}
193
+ end
194
+ it "does not add an or filter" do
195
+ @object.should_not_receive(:add_or_filter)
196
+ @object.apply_filter_actions("name", {"name" => {}}, @params)
197
+ end
198
+ end
199
+ end
200
+ context "add AND" do
201
+ context "with 'field' present" do
202
+ context "with 'field' present" do
203
+ before(:each) do
204
+ @params = {"and" => {"field" => "myfield", "commit" => "AND"}}
205
+ end
206
+ it "adds an or filter" do
207
+ @object.should_receive(:add_and_filter).with("name", {"name" => {}}, "myfield")
208
+ @object.apply_filter_actions("name", {"name" => {}}, @params)
209
+ end
210
+ end
211
+ context "without 'field' present" do
212
+ before(:each) do
213
+ @params = {"and" => {"field" => nil, "commit" => "OR"}}
214
+ end
215
+ it "does not add an or filter" do
216
+ @object.should_not_receive(:add_and_filter)
217
+ @object.apply_filter_actions("name", {"name" => {}}, @params)
218
+ end
219
+ end
220
+ end
221
+ end
222
+ context "remove" do
223
+ before(:each) do
224
+ @params = {"remove" => "myfield"}
225
+ end
226
+ it "adds an or filter" do
227
+ @object.should_receive(:remove_and_filter).with("name", {"name" => {}}, "myfield")
228
+ @object.apply_filter_actions("name", {"name" => {}}, @params)
229
+ end
230
+ end
231
+ end
232
+
233
+ end