ballot_box 0.1.8 → 0.1.9

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 (49) hide show
  1. data/README.rdoc +7 -3
  2. data/Rakefile +26 -16
  3. data/db/migrate/20122108134415_create_votes.rb +34 -0
  4. data/lib/ballot_box/version.rb +1 -1
  5. data/spec/ballot_box_spec.rb +7 -0
  6. data/spec/dummy/Rakefile +7 -0
  7. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  8. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  9. data/spec/dummy/app/models/work.rb +7 -0
  10. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  11. data/spec/dummy/config.ru +4 -0
  12. data/spec/dummy/config/application.rb +50 -0
  13. data/spec/dummy/config/boot.rb +10 -0
  14. data/spec/dummy/config/database.yml +25 -0
  15. data/spec/dummy/config/environment.rb +5 -0
  16. data/spec/dummy/config/environments/development.rb +26 -0
  17. data/spec/dummy/config/environments/production.rb +49 -0
  18. data/spec/dummy/config/environments/test.rb +35 -0
  19. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  20. data/spec/dummy/config/initializers/ballot_box.rb +1 -0
  21. data/spec/dummy/config/initializers/inflections.rb +10 -0
  22. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  23. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  24. data/spec/dummy/config/initializers/session_store.rb +8 -0
  25. data/spec/dummy/config/locales/en.yml +5 -0
  26. data/spec/dummy/config/routes.rb +58 -0
  27. data/spec/dummy/db/migrate/20111017114701_create_works.rb +15 -0
  28. data/spec/dummy/db/migrate/20111017115056_ballot_box_create_votes.rb +34 -0
  29. data/spec/dummy/db/test.sqlite3 +0 -0
  30. data/spec/dummy/lib/sms_strategy.rb +9 -0
  31. data/spec/dummy/log/development.log +7 -0
  32. data/spec/dummy/log/production.log +0 -0
  33. data/spec/dummy/log/server.log +0 -0
  34. data/spec/dummy/log/test.log +382 -0
  35. data/spec/dummy/public/404.html +26 -0
  36. data/spec/dummy/public/422.html +26 -0
  37. data/spec/dummy/public/500.html +26 -0
  38. data/spec/dummy/public/favicon.ico +0 -0
  39. data/spec/dummy/public/javascripts/application.js +2 -0
  40. data/spec/dummy/public/javascripts/controls.js +965 -0
  41. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  42. data/spec/dummy/public/javascripts/effects.js +1123 -0
  43. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  44. data/spec/dummy/public/javascripts/rails.js +191 -0
  45. data/spec/dummy/script/rails +6 -0
  46. data/spec/models/work_spec.rb +76 -0
  47. data/spec/requests/works_spec.rb +27 -0
  48. data/spec/spec_helper.rb +38 -0
  49. metadata +91 -2
@@ -0,0 +1,191 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+
176
+ Ajax.Responders.register({
177
+ onCreate: function(request) {
178
+ var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
179
+
180
+ if (csrf_meta_tag) {
181
+ var header = 'X-CSRF-Token',
182
+ token = csrf_meta_tag.readAttribute('content');
183
+
184
+ if (!request.options.requestHeaders) {
185
+ request.options.requestHeaders = {};
186
+ }
187
+ request.options.requestHeaders[header] = token;
188
+ }
189
+ }
190
+ });
191
+ })();
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe Work do
4
+ context "class methods" do
5
+ it "should return cached column" do
6
+ Work.ballot_box_cached_column.to_s.should == "rating"
7
+ end
8
+
9
+ it "should return place column" do
10
+ Work.ballot_box_place_column.to_s.should == "position"
11
+ end
12
+
13
+ it "should return ballot_box options" do
14
+ Work.ballot_box_options.should be_a(Hash)
15
+
16
+ Work.ballot_box_options[:counter_cache].should == :rating
17
+ Work.ballot_box_options[:strategies].should == ['SmsStrategy']
18
+ Work.ballot_box_options[:place].should == :position
19
+ Work.ballot_box_options[:refresh].should == false
20
+ Work.ballot_box_options[:scope].should == :group_id
21
+ end
22
+ end
23
+
24
+ context "counters" do
25
+ before(:all) do
26
+ vote_attributes = {
27
+ :ip => '195.34.91.163',
28
+ :user_agent => 'Mozilla/5.0 (X11; Linux i686; rv:7.0.1) Gecko/20100101 Firefox/7.0.1',
29
+ :value => 1
30
+ }
31
+
32
+ @works1 = []
33
+ @works2 = []
34
+
35
+ (1..5).to_a.each { |n| @works1 << Work.create(:title => "Work #{n}", :group_id => 1) }
36
+ (1..6).to_a.each { |n| @works2 << Work.create(:title => "Work #{n}", :group_id => 2) }
37
+
38
+ @works = [@works1, @works2].flatten
39
+
40
+ @works.each_with_index do |work, index|
41
+ (index + 1).times do
42
+ work.votes.create do |v|
43
+ v.ip = vote_attributes[:ip]
44
+ v.user_agent = vote_attributes[:user_agent]
45
+ v.value = vote_attributes[:value]
46
+ end
47
+ end
48
+ end
49
+
50
+ Work.ballot_box_update_votes!
51
+ Work.ballot_box_update_place!
52
+
53
+ @works.map(&:reload)
54
+ end
55
+
56
+ it "should calculate all work votes" do
57
+ @works1.each_with_index do |work, index|
58
+ work.rating.should == (index + 1)
59
+ end
60
+
61
+ @works2.each_with_index do |work, index|
62
+ work.rating.should == (index + 1 + @works1.size)
63
+ end
64
+ end
65
+
66
+ it "should calculate all works position" do
67
+ @works1.reverse.each_with_index do |work, index|
68
+ work.position.should == (index + 1)
69
+ end
70
+
71
+ @works2.reverse.each_with_index do |work, index|
72
+ work.position.should == (index + 1)
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,27 @@
1
+ require 'spec_helper'
2
+
3
+ describe BallotBox::Manager do
4
+ include Rack::Test::Methods
5
+
6
+ before(:each) do
7
+ @work = Work.create(:title => "Work one", :group_id => 1)
8
+ end
9
+
10
+ it "should create new vote" do
11
+ lambda {
12
+ post "/works/votes", { :id => @work.id }, { 'HTTP_USER_AGENT' => 'Mozilla' }
13
+ }.should change { @work.votes.count }.by(1)
14
+
15
+ last_response.status.should == 200
16
+ last_response.body.should_not be_blank
17
+ end
18
+
19
+ it "should not create new vote without user agent" do
20
+ lambda {
21
+ post "/works/votes", { :id => @work.id }
22
+ }.should_not change { @work.votes.count }
23
+
24
+ last_response.status.should == 422
25
+ last_response.body.should_not be_blank
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ # Configure Rails Envinronment
2
+ ENV["RAILS_ENV"] = "test"
3
+
4
+ require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
+ require "rails/test_help"
6
+ require "rspec/rails"
7
+
8
+ ActionMailer::Base.delivery_method = :test
9
+ ActionMailer::Base.perform_deliveries = true
10
+ ActionMailer::Base.default_url_options[:host] = "test.com"
11
+
12
+ Rails.backtrace_cleaner.remove_silencers!
13
+
14
+ # Run any available migration
15
+ ActiveRecord::Migrator.migrate File.expand_path("../dummy/db/migrate/", __FILE__)
16
+
17
+ # Load support files
18
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
19
+
20
+ RSpec.configure do |config|
21
+ # Remove this line if you don't want RSpec's should and should_not
22
+ # methods or matchers
23
+ require 'rspec/expectations'
24
+ config.include RSpec::Matchers
25
+
26
+ # == Mock Framework
27
+ config.mock_with :rspec
28
+
29
+ require 'database_cleaner'
30
+ config.before(:suite) do
31
+ DatabaseCleaner.strategy = :truncation
32
+ DatabaseCleaner.clean
33
+ end
34
+
35
+ config.after(:all) do
36
+ DatabaseCleaner.clean
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ballot_box
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.1.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -51,6 +51,7 @@ extra_rdoc_files:
51
51
  - README.rdoc
52
52
  files:
53
53
  - app/models/ballot_box/vote.rb
54
+ - db/migrate/20122108134415_create_votes.rb
54
55
  - lib/ballot_box/base.rb
55
56
  - lib/ballot_box/callbacks.rb
56
57
  - lib/ballot_box/strategies/base.rb
@@ -68,6 +69,50 @@ files:
68
69
  - Rakefile
69
70
  - Gemfile
70
71
  - README.rdoc
72
+ - spec/dummy/config.ru
73
+ - spec/dummy/lib/sms_strategy.rb
74
+ - spec/dummy/Rakefile
75
+ - spec/dummy/public/500.html
76
+ - spec/dummy/public/favicon.ico
77
+ - spec/dummy/public/404.html
78
+ - spec/dummy/public/422.html
79
+ - spec/dummy/public/javascripts/prototype.js
80
+ - spec/dummy/public/javascripts/application.js
81
+ - spec/dummy/public/javascripts/effects.js
82
+ - spec/dummy/public/javascripts/rails.js
83
+ - spec/dummy/public/javascripts/controls.js
84
+ - spec/dummy/public/javascripts/dragdrop.js
85
+ - spec/dummy/app/views/layouts/application.html.erb
86
+ - spec/dummy/app/models/work.rb
87
+ - spec/dummy/app/helpers/application_helper.rb
88
+ - spec/dummy/app/controllers/application_controller.rb
89
+ - spec/dummy/log/server.log
90
+ - spec/dummy/log/development.log
91
+ - spec/dummy/log/test.log
92
+ - spec/dummy/log/production.log
93
+ - spec/dummy/config/database.yml
94
+ - spec/dummy/config/routes.rb
95
+ - spec/dummy/config/application.rb
96
+ - spec/dummy/config/locales/en.yml
97
+ - spec/dummy/config/environment.rb
98
+ - spec/dummy/config/boot.rb
99
+ - spec/dummy/config/environments/production.rb
100
+ - spec/dummy/config/environments/test.rb
101
+ - spec/dummy/config/environments/development.rb
102
+ - spec/dummy/config/initializers/secret_token.rb
103
+ - spec/dummy/config/initializers/inflections.rb
104
+ - spec/dummy/config/initializers/backtrace_silencers.rb
105
+ - spec/dummy/config/initializers/session_store.rb
106
+ - spec/dummy/config/initializers/mime_types.rb
107
+ - spec/dummy/config/initializers/ballot_box.rb
108
+ - spec/dummy/db/test.sqlite3
109
+ - spec/dummy/db/migrate/20111017114701_create_works.rb
110
+ - spec/dummy/db/migrate/20111017115056_ballot_box_create_votes.rb
111
+ - spec/dummy/script/rails
112
+ - spec/spec_helper.rb
113
+ - spec/models/work_spec.rb
114
+ - spec/requests/works_spec.rb
115
+ - spec/ballot_box_spec.rb
71
116
  homepage: https://github.com/galetahub/ballot_box
72
117
  licenses: []
73
118
  post_install_message:
@@ -92,4 +137,48 @@ rubygems_version: 1.8.24
92
137
  signing_key:
93
138
  specification_version: 3
94
139
  summary: The BallotBox gem enables visitors to vote for and against voteable objects
95
- test_files: []
140
+ test_files:
141
+ - spec/dummy/config.ru
142
+ - spec/dummy/lib/sms_strategy.rb
143
+ - spec/dummy/Rakefile
144
+ - spec/dummy/public/500.html
145
+ - spec/dummy/public/favicon.ico
146
+ - spec/dummy/public/404.html
147
+ - spec/dummy/public/422.html
148
+ - spec/dummy/public/javascripts/prototype.js
149
+ - spec/dummy/public/javascripts/application.js
150
+ - spec/dummy/public/javascripts/effects.js
151
+ - spec/dummy/public/javascripts/rails.js
152
+ - spec/dummy/public/javascripts/controls.js
153
+ - spec/dummy/public/javascripts/dragdrop.js
154
+ - spec/dummy/app/views/layouts/application.html.erb
155
+ - spec/dummy/app/models/work.rb
156
+ - spec/dummy/app/helpers/application_helper.rb
157
+ - spec/dummy/app/controllers/application_controller.rb
158
+ - spec/dummy/log/server.log
159
+ - spec/dummy/log/development.log
160
+ - spec/dummy/log/test.log
161
+ - spec/dummy/log/production.log
162
+ - spec/dummy/config/database.yml
163
+ - spec/dummy/config/routes.rb
164
+ - spec/dummy/config/application.rb
165
+ - spec/dummy/config/locales/en.yml
166
+ - spec/dummy/config/environment.rb
167
+ - spec/dummy/config/boot.rb
168
+ - spec/dummy/config/environments/production.rb
169
+ - spec/dummy/config/environments/test.rb
170
+ - spec/dummy/config/environments/development.rb
171
+ - spec/dummy/config/initializers/secret_token.rb
172
+ - spec/dummy/config/initializers/inflections.rb
173
+ - spec/dummy/config/initializers/backtrace_silencers.rb
174
+ - spec/dummy/config/initializers/session_store.rb
175
+ - spec/dummy/config/initializers/mime_types.rb
176
+ - spec/dummy/config/initializers/ballot_box.rb
177
+ - spec/dummy/db/test.sqlite3
178
+ - spec/dummy/db/migrate/20111017114701_create_works.rb
179
+ - spec/dummy/db/migrate/20111017115056_ballot_box_create_votes.rb
180
+ - spec/dummy/script/rails
181
+ - spec/spec_helper.rb
182
+ - spec/models/work_spec.rb
183
+ - spec/requests/works_spec.rb
184
+ - spec/ballot_box_spec.rb