cachai 0.0.5 → 0.0.7
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.
- 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)
|