rbitter 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.travis.yml +9 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +65 -0
- data/Rakefile +8 -0
- data/XMLRPC.md +19 -0
- data/bin/rbitter +6 -0
- data/config.json.example +30 -0
- data/lib/rbitter/arcserver.rb +97 -0
- data/lib/rbitter/console.rb +61 -0
- data/lib/rbitter/default/config_json.rb +37 -0
- data/lib/rbitter/dlthread.rb +66 -0
- data/lib/rbitter/env.rb +59 -0
- data/lib/rbitter/libtwitter_connection_override.rb +46 -0
- data/lib/rbitter/records.rb +109 -0
- data/lib/rbitter/records_migrate/.keep +0 -0
- data/lib/rbitter/records_migrate/20150327_add_index.rb +8 -0
- data/lib/rbitter/streaming.rb +76 -0
- data/lib/rbitter/version.rb +3 -0
- data/lib/rbitter/xmlrpc.rb +4 -0
- data/lib/rbitter/xmlrpcd/base.rb +25 -0
- data/lib/rbitter/xmlrpcd/rpchandles.rb +12 -0
- data/lib/rbitter/xmlrpcd/xmlrpc_auth_server.rb +84 -0
- data/lib/rbitter/xmlrpcd/xmlrpcd.rb +63 -0
- data/lib/rbitter.rb +92 -0
- data/rbitter.gemspec +42 -0
- data/spec/config/.keep +0 -0
- data/spec/config/default.json +33 -0
- data/spec/rbitter/arcserver_spec.rb +9 -0
- data/spec/rbitter/console_spec.rb +9 -0
- data/spec/rbitter/default/config_json_spec.rb +3 -0
- data/spec/rbitter/dlthread_spec.rb +9 -0
- data/spec/rbitter/env_spec.rb +56 -0
- data/spec/rbitter/libtwitter_connection_override_spec.rb +8 -0
- data/spec/rbitter/records_spec.rb +13 -0
- data/spec/rbitter/streaming_spec.rb +9 -0
- data/spec/rbitter/version_spec.rb +8 -0
- data/spec/rbitter/xmlrpc_spec.rb +8 -0
- data/spec/rbitter/xmlrpcd/base_spec.rb +29 -0
- data/spec/rbitter/xmlrpcd/rpchandles_spec.rb +10 -0
- data/spec/rbitter/xmlrpcd/xmlrpc_auth_server_spec.rb +8 -0
- data/spec/rbitter/xmlrpcd/xmlrpcd_spec.rb +9 -0
- data/spec/rbitter_spec.rb +46 -0
- data/spec/sample_data/.keep +0 -0
- data/spec/spec_helper.rb +36 -0
- metadata +238 -0
File without changes
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'twitter'
|
4
|
+
|
5
|
+
module Rbitter
|
6
|
+
class StreamClient
|
7
|
+
def initialize(tokens)
|
8
|
+
@t = Twitter::Streaming::Client.new do |object|
|
9
|
+
object.consumer_key = tokens['consumer_key']
|
10
|
+
object.consumer_secret = tokens['consumer_secret']
|
11
|
+
object.access_token = tokens['access_token']
|
12
|
+
object.access_token_secret = tokens['access_token_secret']
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(&operation_block)
|
17
|
+
begin
|
18
|
+
internal(&operation_block)
|
19
|
+
rescue EOFError => e
|
20
|
+
puts "Network unreachable. Retry in 3 seconds..."
|
21
|
+
sleep 3
|
22
|
+
retry
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def internal(&operation_block)
|
28
|
+
@t.user do |tweet|
|
29
|
+
if tweet.is_a?(Twitter::Tweet)
|
30
|
+
if tweet.retweet?
|
31
|
+
tweet = tweet.retweeted_tweet
|
32
|
+
end
|
33
|
+
|
34
|
+
text = tweet.full_text.gsub(/(\r\n|\n)/, '')
|
35
|
+
|
36
|
+
# unpack uris and media links
|
37
|
+
media_urls = Array.new
|
38
|
+
web_urls = Array.new
|
39
|
+
|
40
|
+
if tweet.entities?
|
41
|
+
if tweet.media?
|
42
|
+
tweet.media.each { |media|
|
43
|
+
media_urls.push("#{media.media_uri_https}")
|
44
|
+
text.gsub!("#{media.url}", "#{media.display_url}")
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
text += " "
|
49
|
+
text += media_urls.join(" ")
|
50
|
+
|
51
|
+
if tweet.uris?
|
52
|
+
tweet.uris.each { |uri|
|
53
|
+
web_urls.push("#{uri.expanded_url}")
|
54
|
+
text.gsub!("#{uri.url}", "#{uri.expanded_url}")
|
55
|
+
}
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
res = {
|
60
|
+
"tweetid" => tweet.id,
|
61
|
+
"userid" => tweet.user.id,
|
62
|
+
"tweet" => text,
|
63
|
+
"rt_count" => tweet.retweet_count,
|
64
|
+
"fav_count" => tweet.favorite_count,
|
65
|
+
"screen_name" => tweet.user.screen_name,
|
66
|
+
"date" => tweet.created_at,
|
67
|
+
"media_urls" => media_urls,
|
68
|
+
"web_urls" => web_urls
|
69
|
+
}
|
70
|
+
|
71
|
+
yield res
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module RPCHandles
|
4
|
+
RH_INFO = Struct.new("RPCHANDLE_INFO", :name, :version, :author, :description) {
|
5
|
+
def digest
|
6
|
+
"<rpchandle: #{name}-#{version} (written by #{author}, #{description})>"
|
7
|
+
end
|
8
|
+
}
|
9
|
+
|
10
|
+
module BaseHandle
|
11
|
+
# If a handler doesn't require an authorization, please inherit below class
|
12
|
+
class NoAuth < Object
|
13
|
+
def self.auth?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# If a handler does require an authorization, please inherit below class
|
19
|
+
class Auth < Object
|
20
|
+
def self.auth?
|
21
|
+
true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
|
4
|
+
require "rbitter/xmlrpcd/rpchandles"
|
5
|
+
require "rbitter/xmlrpcd/base"
|
6
|
+
require "xmlrpc/server"
|
7
|
+
require "webrick"
|
8
|
+
|
9
|
+
module XMLRPC
|
10
|
+
class HTTPAuthXMLRPCServer < XMLRPC::WEBrickServlet
|
11
|
+
def extract_method(methodname, *args)
|
12
|
+
for name, obj in @handler
|
13
|
+
if obj.kind_of? Proc
|
14
|
+
next unless methodname == name
|
15
|
+
else
|
16
|
+
next unless methodname =~ /^#{name}(.+)$/
|
17
|
+
next unless obj.respond_to? $1
|
18
|
+
return obj.method($1)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
|
24
|
+
def service(request, response)
|
25
|
+
# Taken from xmlrpc/server.rb
|
26
|
+
if @valid_ip
|
27
|
+
raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
|
28
|
+
end
|
29
|
+
|
30
|
+
if request.request_method != "POST"
|
31
|
+
raise WEBrick::HTTPStatus::MethodNotAllowed,
|
32
|
+
"unsupported method `#{request.request_method}'."
|
33
|
+
end
|
34
|
+
|
35
|
+
if parse_content_type(request['Content-type']).first != "text/xml"
|
36
|
+
raise WEBrick::HTTPStatus::BadRequest
|
37
|
+
end
|
38
|
+
|
39
|
+
length = (request['Content-length'] || 0).to_i
|
40
|
+
|
41
|
+
raise WEBrick::HTTPStatus::LengthRequired unless length > 0
|
42
|
+
|
43
|
+
data = request.body
|
44
|
+
|
45
|
+
if data.nil? or data.bytesize != length
|
46
|
+
raise WEBrick::HTTPStatus::BadRequest
|
47
|
+
end
|
48
|
+
|
49
|
+
# Originally, process(data) was here.
|
50
|
+
# We need to check whether a method requires authorization.
|
51
|
+
rpc_method_name, rpc_params = parser().parseMethodCall(data)
|
52
|
+
rpc_method = extract_method(rpc_method_name)
|
53
|
+
|
54
|
+
if RPCHandles.auth.nil?
|
55
|
+
resp = handle(rpc_method_name, *rpc_params)
|
56
|
+
else
|
57
|
+
if rpc_method.owner.ancestors.include?(RPCHandles::BaseHandle::Auth)
|
58
|
+
# Check cookie and check it's valid
|
59
|
+
if request.cookies.size == 1 \
|
60
|
+
and request.cookies[0].name == "auth_key" \
|
61
|
+
and RPCHandles.auth.include?(request.cookies[0].value)
|
62
|
+
resp = handle(rpc_method_name, *rpc_params)
|
63
|
+
else
|
64
|
+
# Permission required
|
65
|
+
raise WEBrick::HTTPStatus::Forbidden
|
66
|
+
end
|
67
|
+
elsif rpc_method.owner.ancestors.include?(RPCHandles::BaseHandle::NoAuth)
|
68
|
+
resp = handle(rpc_method_name, *rpc_params)
|
69
|
+
else
|
70
|
+
raise WEBrick::HTTPStatus::Forbidden
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
if resp.nil? or resp.bytesize <= 0
|
75
|
+
raise WEBrick::HTTPStatus::InternalServerError
|
76
|
+
end
|
77
|
+
|
78
|
+
response.status = 200
|
79
|
+
response['Content-Length'] = resp.bytesize
|
80
|
+
response['Content-Type'] = "text/xml; charset=utf-8"
|
81
|
+
response.body = resp
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "rbitter/xmlrpcd/rpchandles"
|
4
|
+
require "rbitter/xmlrpcd/xmlrpc_auth_server"
|
5
|
+
require "webrick"
|
6
|
+
|
7
|
+
module Rbitter
|
8
|
+
RPC_PREFIX="rbitter"
|
9
|
+
|
10
|
+
class RPCServer
|
11
|
+
def initialize bind_host, bind_port
|
12
|
+
@server = WEBrick::HTTPServer.new(:Port => bind_port.to_i, :BindAddress => bind_host.to_s, :MaxClients => 4, :Logger => WEBrick::Log.new($stdout))
|
13
|
+
@core = XMLRPC::HTTPAuthXMLRPCServer.new
|
14
|
+
load_all_handles
|
15
|
+
@core.set_default_handler { |name, *args|
|
16
|
+
"NO_COMMAND: #{name} with args #{args.inspect}"
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_all_handles
|
21
|
+
Rbitter.env["xmlrpc"]["handles"].each { |path|
|
22
|
+
puts "[xmlrpc] Scanning handles from (#{path})"
|
23
|
+
Dir.entries(path).each { |fname|
|
24
|
+
fname = File.join(path, fname)
|
25
|
+
if File.exist?(fname) and File.file?(fname)
|
26
|
+
if fname.match(/rh_\w+\.rb$/)
|
27
|
+
begin
|
28
|
+
load fname
|
29
|
+
rescue Exception => e
|
30
|
+
# stub
|
31
|
+
puts "Exception while loading #{fname}"
|
32
|
+
puts e.inspect
|
33
|
+
end
|
34
|
+
else
|
35
|
+
puts "Ignored: #{fname}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
puts "[xmlrpc] found #{RPCHandles.constants.length} constants."
|
42
|
+
RPCHandles.constants.each { |handler|
|
43
|
+
if RPCHandles.const_get(handler).is_a?(Class)
|
44
|
+
@core.add_handler(RPC_PREFIX, RPCHandles.const_get(handler).new)
|
45
|
+
end
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
def main_loop
|
50
|
+
puts "RPCServer starts"
|
51
|
+
@server.mount("/", @core)
|
52
|
+
@server.start
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
if __FILE__ == $0
|
59
|
+
puts "Local testing server starts..."
|
60
|
+
rpcd = Rbitter::RPCServer.new('127.0.0.1', 1300)
|
61
|
+
rpcd.main_loop
|
62
|
+
end
|
63
|
+
|
data/lib/rbitter.rb
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
|
4
|
+
require "rbitter/version"
|
5
|
+
require "rbitter/arcserver"
|
6
|
+
require "rbitter/env"
|
7
|
+
require "rbitter/console"
|
8
|
+
require "rbitter/xmlrpc"
|
9
|
+
|
10
|
+
module Rbitter
|
11
|
+
def self.rbitter_header
|
12
|
+
puts "Rbitter #{VERSION} on Ruby-#{RUBY_VERSION} (#{RUBY_PLATFORM})"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.rbitter_help_msg
|
16
|
+
puts "Rbitter is a Twitter streaming archiver, with XMLRPC access."
|
17
|
+
puts "-------"
|
18
|
+
puts "Usage: rbitter (application-mode)"
|
19
|
+
puts "application-mode's are:"
|
20
|
+
puts "|- serve : Launch Rbitter full system (Streaming + Database + XMLRPC)"
|
21
|
+
puts "|- console : Launch console application utilizing XMLRPC"
|
22
|
+
puts "|- configure: Write default configuration file 'config.json' in current folder"
|
23
|
+
puts "|- help : Show this message"
|
24
|
+
puts "`- logs : Show Rbitter internal logs"
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.prebootstrap
|
28
|
+
# Due to stalled socket problem, If unpatched twitter gem is installed.
|
29
|
+
# Twitter::Streaming::Connection will be monkey-patched.
|
30
|
+
patch_required = false
|
31
|
+
|
32
|
+
if Twitter::Version.const_defined?(:MAJOR)
|
33
|
+
b5_version = Twitter::Version::MAJOR * 10000
|
34
|
+
+ Twitter::Version::MINOR * 100 + Twitter::Version::PATCH
|
35
|
+
if b5_version <= 51400
|
36
|
+
warn "[rbitter] Monkey-patching Twitter::Streaming::Connection..."
|
37
|
+
warn "[rbitter] Gem installed on here seemed that it doesn't handle socket read timeout."
|
38
|
+
warn "[rbitter] Please upgrade twitter gem"
|
39
|
+
patch_required = true
|
40
|
+
end
|
41
|
+
else
|
42
|
+
b6_version = Twitter::Version.to_a
|
43
|
+
if b6_version[0] <= 6 and b6_version[1] <= 0 and b6_version[2] <= 0
|
44
|
+
patch_required = true
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
require "rbitter/libtwitter_connection_override" if patch_required
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.bootstrap args=[]
|
52
|
+
prebootstrap
|
53
|
+
|
54
|
+
if args.length == 0
|
55
|
+
rbitter_header
|
56
|
+
elsif args[0] == "serve"
|
57
|
+
Rbitter.config_initialize
|
58
|
+
|
59
|
+
main = Rbitter::ArcServer.new
|
60
|
+
if env['xmlrpc']['enable']
|
61
|
+
$rpc_service_thread = Thread.new {
|
62
|
+
rpc_server = Rbitter::RPCServer.new(env['xmlrpc']['bind_host'], env['xmlrpc']['bind_port'])
|
63
|
+
rpc_server.main_loop
|
64
|
+
}
|
65
|
+
$rpc_service_thread.run
|
66
|
+
end
|
67
|
+
main.main_loop
|
68
|
+
elsif args[0] == "configure"
|
69
|
+
require "rbitter/default/config_json"
|
70
|
+
|
71
|
+
puts "Writing config.json now"
|
72
|
+
open(File.join(Dir.pwd, "config.json"), "w") { |io|
|
73
|
+
io.write(DEFAULT_CONFIG_JSON)
|
74
|
+
}
|
75
|
+
puts "Writing finished"
|
76
|
+
puts "You can put config.json one of these locations:"
|
77
|
+
puts "[1] config.json (current folder)"
|
78
|
+
puts "[2] .rbitter/config.json (current folder)"
|
79
|
+
elsif args[0] == "console"
|
80
|
+
Rbitter.config_initialize
|
81
|
+
|
82
|
+
con = Rbitter::Console.new
|
83
|
+
con.start
|
84
|
+
elsif args[0] == "logs"
|
85
|
+
# show log in stdout
|
86
|
+
puts "This feature is in heavy development. Sorry."
|
87
|
+
else
|
88
|
+
rbitter_header
|
89
|
+
rbitter_help_msg
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
data/rbitter.gemspec
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
lib = File.expand_path('../lib', __FILE__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'rbitter/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "rbitter"
|
9
|
+
spec.version = Rbitter::VERSION
|
10
|
+
spec.authors = ["Nidev Plontra"]
|
11
|
+
spec.email = ["nidev.plontra@gmail.com"]
|
12
|
+
spec.summary = %q{Rbitter is a Twitter client specialized in archiving}
|
13
|
+
spec.description = %q{Rbitter archives all tweets appeared on user streaming using ActiveRecord. XMLRPC is used to serve archived tweets and useful features}
|
14
|
+
spec.homepage = "https://github.com/nidev/rbitter"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
|
23
|
+
spec.add_dependency 'twitter', '~> 5.14'
|
24
|
+
spec.add_dependency 'json', '~> 1.7'
|
25
|
+
spec.add_dependency 'ripl', '~> 0'
|
26
|
+
spec.add_dependency 'activerecord', '~> 4.0'
|
27
|
+
|
28
|
+
if RUBY_PLATFORM == 'java'
|
29
|
+
spec.add_dependency 'activerecord-jdbc-adapter', '~> 1.3'
|
30
|
+
spec.add_dependency 'jdbc-sqlite3', '~> 3.8'
|
31
|
+
spec.add_dependency 'jdbc-mysql', '~> 5.1'
|
32
|
+
spec.add_dependency 'activerecord-jdbcsqlite3-adapter', '~> 1.3'
|
33
|
+
spec.add_dependency 'activerecord-jdbcmysql-adapter', '~> 1.3'
|
34
|
+
else
|
35
|
+
spec.add_dependency 'sqlite3', '~> 1.3'
|
36
|
+
spec.add_dependency 'mysql2', '~> 0.3'
|
37
|
+
spec.add_dependency 'activerecord-mysql2-adapter', '~> 0.0.3'
|
38
|
+
end
|
39
|
+
|
40
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
41
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
42
|
+
end
|
data/spec/config/.keep
ADDED
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
{
|
2
|
+
"twitter": {
|
3
|
+
"consumer_key": "",
|
4
|
+
"consumer_secret": "",
|
5
|
+
"access_token": "",
|
6
|
+
"access_token_secret": ""
|
7
|
+
},
|
8
|
+
"activerecord": "sqlite3",
|
9
|
+
"sqlite3": {
|
10
|
+
"dbfile": "rbitter.sqlite"
|
11
|
+
},
|
12
|
+
"mysql2": {
|
13
|
+
"host": "localhost",
|
14
|
+
"port": 3306,
|
15
|
+
"dbname": "archive",
|
16
|
+
"username": "",
|
17
|
+
"password": ""
|
18
|
+
},
|
19
|
+
"media_downloader": {
|
20
|
+
"cacert_path": "/cacerts/cacert.pem",
|
21
|
+
"download_dir": "imgs/"
|
22
|
+
},
|
23
|
+
"xmlrpc": {
|
24
|
+
"enable": true,
|
25
|
+
"bind_host": "0.0.0.0",
|
26
|
+
"bind_port": 1400,
|
27
|
+
"auth": {
|
28
|
+
"username": "username",
|
29
|
+
"password": "password"
|
30
|
+
},
|
31
|
+
"handles": ["/path/to/handles"]
|
32
|
+
}
|
33
|
+
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "rbitter"
|
4
|
+
|
5
|
+
describe Rbitter do
|
6
|
+
it 'has env_reset function and clears Rbitter.env,' do
|
7
|
+
Rbitter.env_reset
|
8
|
+
expect(Rbitter.env).to be_a(Hash)
|
9
|
+
expect(Rbitter.env.length).to be(0)
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when config.json is not installed,' do
|
13
|
+
it 'fails on loading' do
|
14
|
+
expect{Rbitter.config_initialize}.to raise_error(Rbitter::ConfigurationFileError)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context 'when path to config.json is invalid,' do
|
19
|
+
it 'fals on loading' do
|
20
|
+
expect{Rbitter.config_initialize("/silly/dummy/.")}.to raise_error(Rbitter::ConfigurationFileError)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
25
|
+
context 'when default config.json is installed,' do
|
26
|
+
before(:all) do
|
27
|
+
Rbitter.bootstrap(['configure'])
|
28
|
+
expect(File.file?('config.json')).to be(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'loads configuration successfully with autodetection' do
|
32
|
+
expect{Rbitter.config_initialize}.to_not raise_error
|
33
|
+
expect(Rbitter.env.length > 0).to be(true)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'loads configuration successfully with given config.json path' do
|
37
|
+
expect{Rbitter.config_initialize('config.json')}.to_not raise_error
|
38
|
+
expect(Rbitter.env.length > 0).to be(true)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'checks that Rbitter.env returns Hash' do
|
42
|
+
expect(Rbitter.env).to be_a(Hash)
|
43
|
+
end
|
44
|
+
|
45
|
+
after(:all) do
|
46
|
+
File.delete('config.json')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when config.json is corrupted' do
|
51
|
+
# TODO: Perform test with spec/config/default.json
|
52
|
+
# TODO: Adding configuration validator on env.rb
|
53
|
+
end
|
54
|
+
|
55
|
+
# TODO: Perform test with spec/config/default.json
|
56
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rbitter/records"
|
3
|
+
|
4
|
+
describe Rbitter::Record do
|
5
|
+
# TODO: Perform test...
|
6
|
+
it 'has ActiveRecord class named Record' do
|
7
|
+
expect(Rbitter::Record).to be_a(Class)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'has supportive module of ActiveRecord' do
|
11
|
+
expect(ARSupport).to be_a(Module)
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "rbitter/xmlrpcd/base"
|
4
|
+
|
5
|
+
describe RPCHandles do
|
6
|
+
context 'when RH_INFO Struct is served as RPCHandle information,' do
|
7
|
+
it 'structs corrct Struct::RPCHANDLE_INFO' do
|
8
|
+
# String comparison: use eq(==), not be(===)
|
9
|
+
expect(RPCHandles::RH_INFO.to_s).to eq("Struct::RPCHANDLE_INFO")
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'provides correct information when #digest is called' do
|
13
|
+
digest_string = RPCHandles::RH_INFO.new('test', 0.1, 'test', 'test').digest
|
14
|
+
expect(digest_string).to eq("<rpchandle: test-0.1 (written by test, test)>")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe RPCHandles::BaseHandle do
|
20
|
+
context 'when an RPCHandle inherits one of classes Auth and NoAuth' do
|
21
|
+
it 'returns false on #auth? when an RPCHandle class inherits NoAuth' do
|
22
|
+
expect(RPCHandles::BaseHandle::NoAuth.auth?).to be(false)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns true on #auth? when an RPCHandle class inherits Auth' do
|
26
|
+
expect(RPCHandles::BaseHandle::Auth.auth?).to be(true)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "rbitter/xmlrpcd/rpchandles"
|
3
|
+
|
4
|
+
describe RPCHandles do
|
5
|
+
context 'When features related to authentication needs ::auth method,'
|
6
|
+
it 'responds to ::auth' do
|
7
|
+
expect(RPCHandles.respond_to?(:auth)).to be(true)
|
8
|
+
expect(RPCHandles.auth).to be_a(NilClass)
|
9
|
+
end
|
10
|
+
end
|