cachai 0.0.5 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/cachai.gemspec +3 -1
- data/db/schema.rb +1 -1
- data/lib/cachai.rb +55 -30
- data/lib/models.rb +32 -1
- data/spec/get_comments_test.rb +206 -0
- data/spec/post_comments_test.rb +135 -0
- data/spec/spec_helper.rb +30 -0
- metadata +38 -4
- data/Gemfile.lock +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f79e9baf1b4289c37e88e4208c5fa4ac903b5cf9
|
4
|
+
data.tar.gz: b91b0e7f759f7d6c2c95ec5b7ef70a77fecc0a00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8a52ba8af374c0c7f0b3811214963b1ae46e43f6885da2070a15059e184b117110c939ce236b7be92cd65a6b870f87f3bf185d080868f0db408c82299bc4e5f
|
7
|
+
data.tar.gz: 9b3576d707f7d9f1120886fecc20b963b918e8d4b64abc822157a039a43a3ffc349f17ea1434a14fc981f0f5d59e8601b1bf374e0ead3dd153fb24f37e7ab7dc
|
data/.gitignore
CHANGED
data/cachai.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "cachai"
|
7
|
-
spec.version = '0.0.
|
7
|
+
spec.version = '0.0.7'
|
8
8
|
spec.authors = ["Tomás Pollak"]
|
9
9
|
spec.email = ["tomas@forkhq.com"]
|
10
10
|
spec.description = %q{Middleware for embedabble comments.}
|
@@ -19,10 +19,12 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
21
21
|
spec.add_development_dependency "rspec", "~> 2.6"
|
22
|
+
spec.add_development_dependency "rack-test"
|
22
23
|
|
23
24
|
spec.add_dependency "redis"
|
24
25
|
spec.add_dependency "sinatra"
|
25
26
|
spec.add_dependency "sinatra-activerecord"
|
26
27
|
spec.add_dependency "sqlite3"
|
27
28
|
spec.add_dependency "rake"
|
29
|
+
spec.add_dependency "sendgrid-ruby"
|
28
30
|
end
|
data/db/schema.rb
CHANGED
@@ -26,7 +26,7 @@ ActiveRecord::Schema.define(version: 20130901232253) do
|
|
26
26
|
t.string "author_url"
|
27
27
|
t.string "author_ip", :length => 15
|
28
28
|
t.text "content", :null => false
|
29
|
-
t.integer "parent_id"
|
29
|
+
t.integer "parent_id", :default => 0
|
30
30
|
t.integer "approved", :default => 1, :length => 1, :null => false
|
31
31
|
t.datetime "created_at"
|
32
32
|
t.datetime "updated_at"
|
data/lib/cachai.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'sinatra/base'
|
2
|
+
require 'sendgrid-ruby'
|
2
3
|
require 'redis'
|
3
4
|
require 'json'
|
4
|
-
require 'rake'
|
5
5
|
|
6
6
|
require_relative 'models'
|
7
7
|
require_relative 'akismet'
|
@@ -19,21 +19,28 @@ module Cachai
|
|
19
19
|
# use Rack::Static, :urls => %w(/css /img /js /favicon.ico), :root => 'public'
|
20
20
|
use ActiveRecord::ConnectionAdapters::ConnectionManagement
|
21
21
|
|
22
|
+
CACHE_MINUTES = 10 * 60 # 10 minutes
|
23
|
+
|
22
24
|
def initialize(app, opts = nil)
|
23
25
|
opts = opts || {}
|
24
|
-
|
26
|
+
domain = opts.delete(:domain) or raise 'Domain required.'
|
27
|
+
redis_host = opts.delete(:redis_host) || 'localhost'
|
25
28
|
|
29
|
+
Cachai.domain = domain
|
30
|
+
Cachai.cache = Redis.new(:host => redis_host)
|
26
31
|
Cachai.load_db!
|
27
32
|
|
28
|
-
redis_host = opts.delete(:redis_host) || 'localhost'
|
29
|
-
@redis = Redis.new(:host => redis_host)
|
30
|
-
|
31
33
|
if key = opts.delete(:akismet_key)
|
32
|
-
@akismet = Akismet.new(:api_key => key, :blog => "http://#{
|
34
|
+
@akismet = Akismet.new(:api_key => key, :blog => "http://#{domain}")
|
33
35
|
else
|
34
36
|
puts "No Akismet key found! Will not check comments for spam."
|
35
37
|
end
|
36
38
|
|
39
|
+
if sendgrid_opts = opts.delete(:sendgrid)
|
40
|
+
@sendgrid = SendGrid::Client.new(sendgrid_opts)
|
41
|
+
@recipient = opts.delete(:recipient) or raise "No recipient set!"
|
42
|
+
end
|
43
|
+
|
37
44
|
super(app)
|
38
45
|
end
|
39
46
|
|
@@ -48,16 +55,14 @@ module Cachai
|
|
48
55
|
get '/comments.?:format?' do
|
49
56
|
check_domain!(params[:domain])
|
50
57
|
|
51
|
-
@redis.del(redis_key(params[:path])) if params[:nocache]
|
52
|
-
|
53
58
|
# puts "Comments for: #{params[:domain]}#{params[:path]}"
|
54
|
-
json_list = get_comments(params[:path])
|
59
|
+
json_list = get_comments(params[:path], params[:nocache])
|
55
60
|
|
56
61
|
if params[:callback]
|
57
62
|
content_type 'application/javascript'
|
58
63
|
"#{params[:callback]}(#{json_list});"
|
59
64
|
else
|
60
|
-
json(
|
65
|
+
json(json_list)
|
61
66
|
end
|
62
67
|
end
|
63
68
|
|
@@ -66,8 +71,9 @@ module Cachai
|
|
66
71
|
data = JSON.parse(request.body.read)
|
67
72
|
check_domain!(data['domain'])
|
68
73
|
|
69
|
-
|
74
|
+
halt(400, "Missing params") if data['protocol'].blank? or data['path'].blank?
|
70
75
|
|
76
|
+
headers['Access-Control-Allow-Origin'] = data['protocol'] + '//' + data['domain']
|
71
77
|
permalink = 'http://' + data['domain'] + data['path']
|
72
78
|
halt(400, "No spam allowed") if is_spam?(data, permalink, request)
|
73
79
|
|
@@ -76,25 +82,31 @@ module Cachai
|
|
76
82
|
:author_name => data['author_name'],
|
77
83
|
:author_email => data['author_email'],
|
78
84
|
:author_url => data['author_url'],
|
79
|
-
:parent_id => data['parent_id'],
|
85
|
+
:parent_id => data['parent_id'].to_i,
|
80
86
|
:author_ip => request.ip
|
81
87
|
}
|
82
88
|
|
83
89
|
post = Post.find_or_create_by_path(data['path'])
|
84
90
|
response = Response.create!(attrs.merge(:post_id => post.id))
|
91
|
+
Cachai.clear_cache(data['path'])
|
92
|
+
notify_new_response(response, data['path'])
|
85
93
|
|
86
|
-
@redis.del(redis_key(data['path']))
|
87
94
|
json({ :status => 'ok', :comment => response })
|
88
95
|
|
89
96
|
rescue JSON::ParserError
|
90
97
|
status 400 and json({ :error => 'Invalid JSON.' })
|
91
98
|
rescue ActiveRecord::RecordInvalid => e
|
92
99
|
status 422 and json({ :error => e.message })
|
100
|
+
rescue => e
|
101
|
+
puts e.message
|
102
|
+
puts e.backtrace.join("\n")
|
103
|
+
status 500 and "Something went wrong."
|
93
104
|
end
|
94
105
|
end
|
95
106
|
|
96
107
|
private
|
97
108
|
|
109
|
+
=begin
|
98
110
|
def set_cache(timestamp)
|
99
111
|
return if timestamp.nil?
|
100
112
|
last_modified timestamp
|
@@ -105,9 +117,10 @@ module Cachai
|
|
105
117
|
cache_control :public, :no_cache, :no_store, :must_revalidate, :max_age => 0
|
106
118
|
# expires 1.year.ago
|
107
119
|
end
|
120
|
+
=end
|
108
121
|
|
109
122
|
def check_domain!(domain)
|
110
|
-
halt(400, 'Invalid domain.') unless domain ==
|
123
|
+
halt(400, 'Invalid domain.') unless domain == Cachai.domain
|
111
124
|
end
|
112
125
|
|
113
126
|
def not_found(message = nil)
|
@@ -119,9 +132,10 @@ module Cachai
|
|
119
132
|
return obj.is_a?(String) ? obj : obj.to_json
|
120
133
|
end
|
121
134
|
|
122
|
-
def get_comments(path)
|
123
|
-
key =
|
124
|
-
|
135
|
+
def get_comments(path, nocache = false)
|
136
|
+
key = Cachai.key_for(path)
|
137
|
+
|
138
|
+
unless !nocache && json_list = Cachai.cache.get(key)
|
125
139
|
puts "Not cached. Getting from DB: #{path}"
|
126
140
|
|
127
141
|
if post = Post.find_by_path(path)
|
@@ -130,9 +144,10 @@ module Cachai
|
|
130
144
|
json_list = '[]'
|
131
145
|
end
|
132
146
|
|
133
|
-
|
134
|
-
|
147
|
+
Cachai.cache.set(key, json_list)
|
148
|
+
Cachai.cache.expire(key, CACHE_MINUTES)
|
135
149
|
end
|
150
|
+
|
136
151
|
json_list
|
137
152
|
end
|
138
153
|
|
@@ -153,22 +168,18 @@ module Cachai
|
|
153
168
|
result
|
154
169
|
end
|
155
170
|
|
156
|
-
def redis_key(path)
|
157
|
-
"comments:#{@domain}:#{path}"
|
158
|
-
end
|
159
|
-
|
160
171
|
def is_spam?(data, link, request)
|
161
172
|
return false unless @akismet
|
162
173
|
# return true if blacklisted?(name, email, content)
|
163
174
|
|
164
175
|
comment = {
|
165
|
-
:user_ip
|
166
|
-
:referrer
|
167
|
-
:user_agent
|
168
|
-
:permalink
|
169
|
-
:comment_type
|
170
|
-
:comment_content
|
171
|
-
:comment_author
|
176
|
+
:user_ip => request.ip,
|
177
|
+
:referrer => request.referrer,
|
178
|
+
:user_agent => request.user_agent,
|
179
|
+
:permalink => link,
|
180
|
+
:comment_type => 'comment',
|
181
|
+
:comment_content => data['content'],
|
182
|
+
:comment_author => data['author_name'],
|
172
183
|
:comment_author_url => data['author_url'],
|
173
184
|
:comment_author_email => data['author_email']
|
174
185
|
}
|
@@ -181,6 +192,20 @@ module Cachai
|
|
181
192
|
false
|
182
193
|
end
|
183
194
|
|
195
|
+
def notify_new_response(response, path)
|
196
|
+
mail = SendGrid::Mail.new do |m|
|
197
|
+
m.to = @recipient
|
198
|
+
m.from = 'comments@' + Cachai.domain
|
199
|
+
m.reply_to = response.author_email
|
200
|
+
m.subject = "New comment from #{response.author_name} at #{path}"
|
201
|
+
m.text = "#{response.content}\n\n--\nhttp://#{Cachai.domain}/#{path}"
|
202
|
+
end
|
203
|
+
|
204
|
+
puts @sendgrid.send(mail)
|
205
|
+
rescue SendGrid::Exception => e
|
206
|
+
puts e.inspect
|
207
|
+
end
|
208
|
+
|
184
209
|
end
|
185
210
|
|
186
211
|
end
|
data/lib/models.rb
CHANGED
@@ -22,6 +22,34 @@ module Cachai
|
|
22
22
|
# SQLite3::SQLException => e
|
23
23
|
# return !e.message['no such table']
|
24
24
|
false
|
25
|
+
rescue ActiveRecord::ConnectionNotEstablished
|
26
|
+
puts "Connection not established."
|
27
|
+
false
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.domain=(value)
|
31
|
+
@domain = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.domain
|
35
|
+
@domain
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.cache=(obj)
|
39
|
+
@cache = obj
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.cache
|
43
|
+
@cache
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.clear_cache(path)
|
47
|
+
cache.del(key_for(path))
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.key_for(path)
|
51
|
+
raise "Domain not set!" unless @domain
|
52
|
+
"comments:#{@domain}:#{path}"
|
25
53
|
end
|
26
54
|
|
27
55
|
class Post < ActiveRecord::Base
|
@@ -34,11 +62,14 @@ module Cachai
|
|
34
62
|
find_by_path(path) || create({:path => path})
|
35
63
|
end
|
36
64
|
|
65
|
+
def clear_cache
|
66
|
+
Cachai.clear_cache(path)
|
67
|
+
end
|
37
68
|
end
|
38
69
|
|
39
70
|
class Response < ActiveRecord::Base
|
40
71
|
belongs_to :post
|
41
|
-
validates_presence_of :author_name, :
|
72
|
+
validates_presence_of :author_name, :author_email, :content
|
42
73
|
|
43
74
|
scope :approved, lambda { where(:approved => 1) }
|
44
75
|
scope :comment, lambda { where(:response_type => 'comment') }
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'get comments' do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
TestApp
|
8
|
+
end
|
9
|
+
|
10
|
+
describe 'no domain' do
|
11
|
+
|
12
|
+
it 'returns 400' do
|
13
|
+
get '/comments.json', :path => '/foobar'
|
14
|
+
puts last_response.body
|
15
|
+
last_response.status.should == 400
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'no path' do
|
21
|
+
|
22
|
+
it 'returns 400' do
|
23
|
+
get '/comments.json', :domain => 'invalid.com'
|
24
|
+
last_response.status.should == 400
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'existing domain and path' do
|
30
|
+
|
31
|
+
describe 'invalid domain' do
|
32
|
+
|
33
|
+
it 'returns 400' do
|
34
|
+
get '/comments.json', :domain => 'invalid.com'
|
35
|
+
last_response.status.should == 400
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'valid domain' do
|
41
|
+
|
42
|
+
let(:cache_key) { Cachai.key_for('/blog/post.html') }
|
43
|
+
|
44
|
+
before do
|
45
|
+
Cachai.cache.del(cache_key)
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'unexisting post' do
|
49
|
+
|
50
|
+
it 'returns 200' do
|
51
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
52
|
+
last_response.status.should == 200
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns an empty JSON array' do
|
56
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
57
|
+
last_response.body.should == '[]'
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'does not create a new entry for that post' do
|
61
|
+
expect do
|
62
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
63
|
+
end.not_to change(Cachai::Post, :count)
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'existing post, no comments' do
|
69
|
+
|
70
|
+
before do
|
71
|
+
Cachai::Post.create(:path => '/blog/post.html')
|
72
|
+
Cachai::Post.count.should == 1
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'returns 200' do
|
76
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
77
|
+
last_response.status.should == 200
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'queries the database' do
|
81
|
+
# ActiveRecord::Base.should_receive(:query)
|
82
|
+
Cachai::Post.should_receive(:find_by_path)
|
83
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'returns an empty JSON array' do
|
87
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
88
|
+
last_response.body.should == '[]'
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
describe 'existing post, with comments' do
|
94
|
+
|
95
|
+
before do
|
96
|
+
Cachai::Post.delete_all
|
97
|
+
|
98
|
+
post = Cachai::Post.create(:path => '/blog/post.html')
|
99
|
+
Cachai::Post.count.should == 1
|
100
|
+
|
101
|
+
post.responses.create({
|
102
|
+
:content => 'Foobar',
|
103
|
+
:author_name => 'Someone',
|
104
|
+
:author_email => 'test@email.com'
|
105
|
+
})
|
106
|
+
|
107
|
+
post.responses.count.should == 1
|
108
|
+
end
|
109
|
+
|
110
|
+
describe 'not in cache' do
|
111
|
+
|
112
|
+
before do
|
113
|
+
Cachai.cache.get(cache_key).should be_nil
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'returns 200' do
|
117
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
118
|
+
last_response.status.should == 200
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'queries the database' do
|
122
|
+
# ActiveRecord::Base.connection.should_receive(:execute)
|
123
|
+
Cachai::Post.should_receive(:find_by_path)
|
124
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'returns an JSON array with comment' do
|
128
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
129
|
+
data = JSON.parse(last_response.body)
|
130
|
+
data.count.should == 1
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'stores data in cache' do
|
134
|
+
Cachai.cache.should_receive(:set)
|
135
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
describe 'in cache' do
|
141
|
+
|
142
|
+
before do
|
143
|
+
Cachai.cache.set(cache_key, 'something')
|
144
|
+
Cachai.cache.get(cache_key).should == 'something'
|
145
|
+
end
|
146
|
+
|
147
|
+
describe 'without nocache param' do
|
148
|
+
|
149
|
+
it 'returns 200' do
|
150
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
151
|
+
last_response.status.should == 200
|
152
|
+
end
|
153
|
+
|
154
|
+
it 'does not query the database' do
|
155
|
+
# ActiveRecord::Base.should_not_receive(:query)
|
156
|
+
Cachai::Post.should_not_receive(:find_by_path)
|
157
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'returns an JSON array with comment' do
|
161
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
162
|
+
last_response.body.should == 'something'
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'does not store data in cache' do
|
166
|
+
Cachai.cache.should_not_receive(:set)
|
167
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html'
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'with nocache=1' do
|
173
|
+
|
174
|
+
it 'returns 200' do
|
175
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
|
176
|
+
last_response.status.should == 200
|
177
|
+
end
|
178
|
+
|
179
|
+
it 'queries the database' do
|
180
|
+
# ActiveRecord::Base.should_receive(:query)
|
181
|
+
Cachai::Post.should_receive(:find_by_path)
|
182
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'returns an JSON array with comment' do
|
186
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
|
187
|
+
data = JSON.parse(last_response.body)
|
188
|
+
data.count.should == 1
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'stores data in cache' do
|
192
|
+
Cachai.cache.should_receive(:set)
|
193
|
+
get '/comments.json', :domain => 'domain.com', :path => '/blog/post.html', :nocache => 1
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe 'post comment' do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
TestApp
|
8
|
+
end
|
9
|
+
|
10
|
+
def post_comment(opts = {})
|
11
|
+
data = {
|
12
|
+
:domain => 'domain.com',
|
13
|
+
:protocol => 'http',
|
14
|
+
:path => '/another/blog/post.html',
|
15
|
+
:content => 'New comment',
|
16
|
+
:author_name => 'Some author',
|
17
|
+
:author_email => 'test@email.com',
|
18
|
+
:author_url => 'http://url.com'
|
19
|
+
}.merge(opts)
|
20
|
+
post '/comments.json', data.to_json, { 'CONTENT_TYPE' => 'application/json' }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'no domain' do
|
24
|
+
|
25
|
+
it 'returns 400' do
|
26
|
+
post_comment :domain => nil
|
27
|
+
puts last_response.body
|
28
|
+
last_response.status.should == 400
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe 'no protocol' do
|
34
|
+
|
35
|
+
it 'returns 400' do
|
36
|
+
post_comment :protocol => nil
|
37
|
+
last_response.status.should == 400
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
describe 'no path' do
|
43
|
+
|
44
|
+
it 'returns 400' do
|
45
|
+
post_comment :path => nil
|
46
|
+
last_response.status.should == 400
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe 'existing domain and path' do
|
52
|
+
|
53
|
+
describe 'invalid domain' do
|
54
|
+
|
55
|
+
it 'returns 400' do
|
56
|
+
post_comment :domain => 'invalid.com'
|
57
|
+
last_response.status.should == 400
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'valid domain' do
|
63
|
+
|
64
|
+
describe 'no author name' do
|
65
|
+
|
66
|
+
it 'returns 422' do
|
67
|
+
post_comment :author_name => nil
|
68
|
+
last_response.status.should == 422
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'no email' do
|
74
|
+
|
75
|
+
it 'returns 422' do
|
76
|
+
post_comment :author_email => nil
|
77
|
+
last_response.status.should == 422
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'no content' do
|
83
|
+
|
84
|
+
it 'returns 422' do
|
85
|
+
post_comment :content => nil
|
86
|
+
last_response.status.should == 422
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
describe 'valid data' do
|
92
|
+
|
93
|
+
describe 'unexisting post' do
|
94
|
+
|
95
|
+
before do
|
96
|
+
Cachai::Post.delete_all
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'creates a new entry for that post' do
|
100
|
+
expect do
|
101
|
+
post_comment
|
102
|
+
end.to change(Cachai::Post, :count).by(1)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'creates a new response for that post' do
|
106
|
+
expect do
|
107
|
+
post_comment
|
108
|
+
end.to change(Cachai::Response, :count).by(1)
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
describe 'existing post' do
|
114
|
+
|
115
|
+
it 'does not create a new post entry' do
|
116
|
+
expect do
|
117
|
+
post_comment
|
118
|
+
end.not_to change(Cachai::Post, :count).by(1)
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'creates a new response for that post' do
|
122
|
+
expect do
|
123
|
+
post_comment
|
124
|
+
end.to change(Cachai::Response, :count).by(1)
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'active_record'
|
5
|
+
require 'cachai'
|
6
|
+
require 'rack/test'
|
7
|
+
|
8
|
+
ActiveRecord::Base.establish_connection(
|
9
|
+
"adapter" => "sqlite3",
|
10
|
+
"database" => ':memory:'
|
11
|
+
)
|
12
|
+
|
13
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
14
|
+
|
15
|
+
# this is done automatically by cachai
|
16
|
+
# load File.join(File.dirname(__FILE__), '/../db/schema.rb')
|
17
|
+
|
18
|
+
class TestApp < Sinatra::Base
|
19
|
+
use Cachai::Middleware, {
|
20
|
+
:domain => 'domain.com',
|
21
|
+
:recipient => 'test@example.com',
|
22
|
+
:sendgrid => {
|
23
|
+
:api_key => 'test',
|
24
|
+
:api_user => 'test'
|
25
|
+
}
|
26
|
+
}
|
27
|
+
get '/' do
|
28
|
+
'Hello world'
|
29
|
+
end
|
30
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cachai
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tomás Pollak
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rack-test
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: redis
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -108,6 +122,20 @@ dependencies:
|
|
108
122
|
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: sendgrid-ruby
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :runtime
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
111
139
|
description: Middleware for embedabble comments.
|
112
140
|
email:
|
113
141
|
- tomas@forkhq.com
|
@@ -117,7 +145,6 @@ extra_rdoc_files: []
|
|
117
145
|
files:
|
118
146
|
- ".gitignore"
|
119
147
|
- Gemfile
|
120
|
-
- Gemfile.lock
|
121
148
|
- Procfile
|
122
149
|
- README.md
|
123
150
|
- Rakefile
|
@@ -127,6 +154,9 @@ files:
|
|
127
154
|
- lib/cachai.rb
|
128
155
|
- lib/models.rb
|
129
156
|
- lib/time_ago.rb
|
157
|
+
- spec/get_comments_test.rb
|
158
|
+
- spec/post_comments_test.rb
|
159
|
+
- spec/spec_helper.rb
|
130
160
|
- test/app_test.rb
|
131
161
|
homepage: ''
|
132
162
|
licenses:
|
@@ -148,9 +178,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
178
|
version: '0'
|
149
179
|
requirements: []
|
150
180
|
rubyforge_project:
|
151
|
-
rubygems_version: 2.
|
181
|
+
rubygems_version: 2.2.0
|
152
182
|
signing_key:
|
153
183
|
specification_version: 4
|
154
184
|
summary: Middleware for embedabble comments.
|
155
185
|
test_files:
|
186
|
+
- spec/get_comments_test.rb
|
187
|
+
- spec/post_comments_test.rb
|
188
|
+
- spec/spec_helper.rb
|
156
189
|
- test/app_test.rb
|
190
|
+
has_rdoc:
|
data/Gemfile.lock
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
cachai (0.0.1)
|
5
|
-
rake
|
6
|
-
sinatra
|
7
|
-
sinatra-activerecord
|
8
|
-
sqlite3
|
9
|
-
|
10
|
-
GEM
|
11
|
-
remote: http://rubygems.org/
|
12
|
-
specs:
|
13
|
-
activemodel (4.2.1)
|
14
|
-
activesupport (= 4.2.1)
|
15
|
-
builder (~> 3.1)
|
16
|
-
activerecord (4.2.1)
|
17
|
-
activemodel (= 4.2.1)
|
18
|
-
activesupport (= 4.2.1)
|
19
|
-
arel (~> 6.0)
|
20
|
-
activesupport (4.2.1)
|
21
|
-
i18n (~> 0.7)
|
22
|
-
json (~> 1.7, >= 1.7.7)
|
23
|
-
minitest (~> 5.1)
|
24
|
-
thread_safe (~> 0.3, >= 0.3.4)
|
25
|
-
tzinfo (~> 1.1)
|
26
|
-
arel (6.0.0)
|
27
|
-
builder (3.2.2)
|
28
|
-
diff-lcs (1.2.5)
|
29
|
-
i18n (0.7.0)
|
30
|
-
json (1.8.3)
|
31
|
-
minitest (5.7.0)
|
32
|
-
rack (1.6.1)
|
33
|
-
rack-protection (1.5.3)
|
34
|
-
rack
|
35
|
-
rake (10.4.2)
|
36
|
-
rspec (2.99.0)
|
37
|
-
rspec-core (~> 2.99.0)
|
38
|
-
rspec-expectations (~> 2.99.0)
|
39
|
-
rspec-mocks (~> 2.99.0)
|
40
|
-
rspec-core (2.99.2)
|
41
|
-
rspec-expectations (2.99.2)
|
42
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
43
|
-
rspec-mocks (2.99.3)
|
44
|
-
sinatra (1.4.6)
|
45
|
-
rack (~> 1.4)
|
46
|
-
rack-protection (~> 1.4)
|
47
|
-
tilt (>= 1.3, < 3)
|
48
|
-
sinatra-activerecord (2.0.6)
|
49
|
-
activerecord (>= 3.2)
|
50
|
-
sinatra (~> 1.0)
|
51
|
-
sqlite3 (1.3.10)
|
52
|
-
thread_safe (0.3.5)
|
53
|
-
tilt (2.0.1)
|
54
|
-
tzinfo (1.2.2)
|
55
|
-
thread_safe (~> 0.1)
|
56
|
-
|
57
|
-
PLATFORMS
|
58
|
-
ruby
|
59
|
-
|
60
|
-
DEPENDENCIES
|
61
|
-
bundler (~> 1.3)
|
62
|
-
cachai!
|
63
|
-
rspec (~> 2.6)
|