rbitter 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +9 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +65 -0
  8. data/Rakefile +8 -0
  9. data/XMLRPC.md +19 -0
  10. data/bin/rbitter +6 -0
  11. data/config.json.example +30 -0
  12. data/lib/rbitter/arcserver.rb +97 -0
  13. data/lib/rbitter/console.rb +61 -0
  14. data/lib/rbitter/default/config_json.rb +37 -0
  15. data/lib/rbitter/dlthread.rb +66 -0
  16. data/lib/rbitter/env.rb +59 -0
  17. data/lib/rbitter/libtwitter_connection_override.rb +46 -0
  18. data/lib/rbitter/records.rb +109 -0
  19. data/lib/rbitter/records_migrate/.keep +0 -0
  20. data/lib/rbitter/records_migrate/20150327_add_index.rb +8 -0
  21. data/lib/rbitter/streaming.rb +76 -0
  22. data/lib/rbitter/version.rb +3 -0
  23. data/lib/rbitter/xmlrpc.rb +4 -0
  24. data/lib/rbitter/xmlrpcd/base.rb +25 -0
  25. data/lib/rbitter/xmlrpcd/rpchandles.rb +12 -0
  26. data/lib/rbitter/xmlrpcd/xmlrpc_auth_server.rb +84 -0
  27. data/lib/rbitter/xmlrpcd/xmlrpcd.rb +63 -0
  28. data/lib/rbitter.rb +92 -0
  29. data/rbitter.gemspec +42 -0
  30. data/spec/config/.keep +0 -0
  31. data/spec/config/default.json +33 -0
  32. data/spec/rbitter/arcserver_spec.rb +9 -0
  33. data/spec/rbitter/console_spec.rb +9 -0
  34. data/spec/rbitter/default/config_json_spec.rb +3 -0
  35. data/spec/rbitter/dlthread_spec.rb +9 -0
  36. data/spec/rbitter/env_spec.rb +56 -0
  37. data/spec/rbitter/libtwitter_connection_override_spec.rb +8 -0
  38. data/spec/rbitter/records_spec.rb +13 -0
  39. data/spec/rbitter/streaming_spec.rb +9 -0
  40. data/spec/rbitter/version_spec.rb +8 -0
  41. data/spec/rbitter/xmlrpc_spec.rb +8 -0
  42. data/spec/rbitter/xmlrpcd/base_spec.rb +29 -0
  43. data/spec/rbitter/xmlrpcd/rpchandles_spec.rb +10 -0
  44. data/spec/rbitter/xmlrpcd/xmlrpc_auth_server_spec.rb +8 -0
  45. data/spec/rbitter/xmlrpcd/xmlrpcd_spec.rb +9 -0
  46. data/spec/rbitter_spec.rb +46 -0
  47. data/spec/sample_data/.keep +0 -0
  48. data/spec/spec_helper.rb +36 -0
  49. metadata +238 -0
File without changes
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ class AddIndex < ActiveRecord::Migration
5
+ def self.change
6
+ add_index :records, :tweetid
7
+ end
8
+ end
@@ -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,3 @@
1
+ module Rbitter
2
+ VERSION = "0.0.8"
3
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ #
3
+
4
+ require "rbitter/xmlrpcd/xmlrpcd"
@@ -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,12 @@
1
+ # encoding: utf-8
2
+
3
+ module RPCHandles
4
+ # Override this function will activate authentication feature.
5
+ # You can write and add RPCHandle. See 'rpc' folder.
6
+
7
+ @@auth_pool = nil
8
+ module_function
9
+ def auth
10
+ @@auth_pool
11
+ end
12
+ 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,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/arcserver"
3
+
4
+ describe Rbitter::ArcServer do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::ArcServer).to be_a(Class)
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/console"
3
+
4
+ describe Rbitter::Console do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::Console).to be_a(Class)
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ # encoding: utf-8
2
+
3
+ require "rbitter/default/config_json"
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/dlthread"
3
+
4
+ describe Rbitter::DLThread do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::DLThread).to be_a(Class)
8
+ end
9
+ end
@@ -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,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/libtwitter_connection_override"
3
+
4
+ describe Rbitter do
5
+ it 'overrides twitter gem' do
6
+ expect(Twitter::Streaming::Connection::MODIFIED).to be(true)
7
+ end
8
+ 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,9 @@
1
+ # encoding: utf-8
2
+ require "rbitter/streaming"
3
+
4
+ describe Rbitter::StreamClient do
5
+ # TODO: Perform test...
6
+ it 'is presented' do
7
+ expect(Rbitter::StreamClient).to be_a(Class)
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/version"
3
+
4
+ describe Rbitter do
5
+ it 'has version string' do
6
+ expect(Rbitter::VERSION).to be_a(String)
7
+ end
8
+ end
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/xmlrpc"
3
+
4
+ describe Rbitter do
5
+ it 'Rbitter is a module' do
6
+ expect(Rbitter.class === Module).to be(true)
7
+ end
8
+ 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
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ require "rbitter/xmlrpcd/xmlrpc_auth_server"
3
+
4
+ describe Rbitter do
5
+ it 'Rbitter is a module' do
6
+ expect(Rbitter.class === Module).to be(true)
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ require "rbitter/xmlrpcd/xmlrpcd"
4
+
5
+ describe Rbitter do
6
+ it 'Rbitter is a module' do
7
+ expect(Rbitter.class === Module).to be(true)
8
+ end
9
+ end