wialon_api 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +4 -0
  5. data/.yardopts +3 -0
  6. data/CHANGELOG.md +0 -0
  7. data/Gemfile +4 -0
  8. data/Guardfile +22 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +170 -0
  11. data/Rakefile +13 -0
  12. data/bin/rspec +16 -0
  13. data/lib/generators/wialon_api/install/USAGE +0 -0
  14. data/lib/generators/wialon_api/install/install_generator.rb +10 -0
  15. data/lib/generators/wialon_api/install/templates/initializer.rb +30 -0
  16. data/lib/wialon_api/api.rb +24 -0
  17. data/lib/wialon_api/authorization.rb +9 -0
  18. data/lib/wialon_api/client.rb +29 -0
  19. data/lib/wialon_api/configuration.rb +54 -0
  20. data/lib/wialon_api/error.rb +36 -0
  21. data/lib/wialon_api/logger.rb +36 -0
  22. data/lib/wialon_api/method.rb +23 -0
  23. data/lib/wialon_api/namespace.rb +36 -0
  24. data/lib/wialon_api/namespaces.yml +14 -0
  25. data/lib/wialon_api/resolvable.rb +20 -0
  26. data/lib/wialon_api/resolver.rb +34 -0
  27. data/lib/wialon_api/result.rb +20 -0
  28. data/lib/wialon_api/version.rb +3 -0
  29. data/lib/wialon_api.rb +23 -0
  30. data/spec/spec_helper.rb +24 -0
  31. data/spec/wialon_api/api_spec.rb +41 -0
  32. data/spec/wialon_api/authorization_spec.rb +20 -0
  33. data/spec/wialon_api/client_spec.rb +23 -0
  34. data/spec/wialon_api/configuration_spec.rb +35 -0
  35. data/spec/wialon_api/error_spec.rb +12 -0
  36. data/spec/wialon_api/logger_spec.rb +103 -0
  37. data/spec/wialon_api/method_spec.rb +44 -0
  38. data/spec/wialon_api/namespace_spec.rb +51 -0
  39. data/spec/wialon_api/resolvable_spec.rb +19 -0
  40. data/spec/wialon_api/resolver_spec.rb +50 -0
  41. data/spec/wialon_api/result_spec.rb +92 -0
  42. data/spec/wialon_api_spec.rb +7 -0
  43. data/wialon_api.gemspec +35 -0
  44. metadata +269 -0
@@ -0,0 +1,20 @@
1
+ module WialonApi
2
+ class Result
3
+ def self.process(response, block = nil)
4
+ result = extract_result(response)
5
+ if result.respond_to?(:each)
6
+ block.nil? ? result : result.map(&block)
7
+ else
8
+ block.nil? ? result : block.call(result)
9
+ end
10
+ end
11
+
12
+ def self.extract_result(response)
13
+ if response.error
14
+ fail WialonApi::Error.new(response)
15
+ else
16
+ response
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module WialonApi
2
+ VERSION = "0.0.1"
3
+ end
data/lib/wialon_api.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+ require 'faraday_middleware/parse_oj'
4
+ require 'yaml'
5
+ require 'hashie'
6
+
7
+ require 'wialon_api/version'
8
+ require 'wialon_api/error'
9
+ require 'wialon_api/configuration'
10
+ require 'wialon_api/authorization'
11
+ require 'wialon_api/api'
12
+ require 'wialon_api/resolver'
13
+ require 'wialon_api/resolvable'
14
+ require 'wialon_api/client'
15
+ require 'wialon_api/namespace'
16
+ require 'wialon_api/method'
17
+ require 'wialon_api/result'
18
+ require 'wialon_api/logger'
19
+
20
+ module WialonApi
21
+ extend WialonApi::Authorization
22
+ extend WialonApi::Configuration
23
+ end
@@ -0,0 +1,24 @@
1
+ require 'wialon_api'
2
+ require 'pry'
3
+
4
+ RSpec.configure do |config|
5
+ config.raise_errors_for_deprecations!
6
+ end
7
+
8
+ RSpec::Matchers.define :log_requests do
9
+ match do |logger|
10
+ logger.log_requests?
11
+ end
12
+ end
13
+
14
+ RSpec::Matchers.define :log_errors do
15
+ match do |logger|
16
+ logger.log_errors?
17
+ end
18
+ end
19
+
20
+ RSpec::Matchers.define :log_responses do
21
+ match do |logger|
22
+ logger.log_responses?
23
+ end
24
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Api do
4
+ def create_connection
5
+ @result = { 'response' => { 'key' => 'value' } }
6
+
7
+ @connection = Faraday.new do |builder|
8
+ builder.response :mashify
9
+ builder.response :oj, preserve_raw: true
10
+ builder.adapter :test do |stub|
11
+ stub.post('/wialon/ajax.html') do
12
+ [200, {}, Oj.dump(@result)]
13
+ end
14
+ end
15
+ end
16
+ allow(subject).to receive(:connection).and_return(@connection)
17
+ end
18
+
19
+ describe '.call' do
20
+ before(:each) do
21
+ WialonApi.reset
22
+ create_connection
23
+ end
24
+
25
+ it 'sends a sid if it was passed with parameter' do
26
+ expect(subject).to receive(:connection).with(url: WialonApi.wialon_host, sid: 'sid')
27
+ subject.call('core/search_items', { params: :value }, 'sid')
28
+ end
29
+ end
30
+
31
+ describe '.connection' do
32
+ it 'uses the :url parameter and WialonApi.faraday_options' do
33
+ faraday_options = double('Faraday options')
34
+ allow(WialonApi).to receive(:faraday_options).and_return(faraday_options)
35
+ url = double('URL')
36
+
37
+ expect(Faraday).to receive(:new).with(url, faraday_options)
38
+ subject.connection(url: url)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Authorization do
4
+ describe '.authorize' do
5
+ let(:success) { Hashie::Mash.new(eid: 'sid') }
6
+ let(:error) { Hashie::Mash.new(error: '8') }
7
+ let(:credentials) { ['user', 'password'] }
8
+
9
+ it 'bulds a WialonApi client if the credentials are correct' do
10
+ allow(WialonApi::Api).to receive(:call).and_return(success)
11
+ expect(WialonApi::Client).to receive(:new).with('sid')
12
+ WialonApi.authorize(*credentials)
13
+ end
14
+
15
+ it 'raises an error if password or login do not match' do
16
+ allow(WialonApi::Api).to receive(:call).and_return(error)
17
+ expect { WialonApi.authorize(*credentials) }.to raise_error(WialonApi::Error)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Client do
4
+ let(:sid) { 'sid' }
5
+
6
+ describe '#authorized?' do
7
+ context 'with an unauthorized client' do
8
+ let(:client) { WialonApi::Client.new }
9
+
10
+ it 'returns false' do
11
+ expect(client).not_to be_authorized
12
+ end
13
+ end
14
+
15
+ context 'with an authorized client' do
16
+ let(:client) { WialonApi::Client.new(sid) }
17
+
18
+ it 'returns true' do
19
+ expect(client).to be_authorized
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ require 'spec_helper'
2
+
3
+ # Dummy class
4
+ class TestConfiguration
5
+ extend WialonApi::Configuration
6
+ end
7
+
8
+ describe WialonApi::Configuration do
9
+ describe '#configure' do
10
+ it 'yields self' do
11
+ expect(TestConfiguration).to receive(:wialon_host)
12
+ TestConfiguration.configure(&:wialon_host)
13
+ end
14
+
15
+ it 'returns self' do
16
+ expect(TestConfiguration.configure).to eq(TestConfiguration)
17
+ end
18
+ end
19
+
20
+ describe '#reset' do
21
+ it 'resets all the values to their default values' do
22
+ TestConfiguration.reset
23
+ expect(TestConfiguration.wialon_host).to eq('https://hst-api.wialon.com/wialon/ajax.html')
24
+ expect(TestConfiguration.http_verb).to eq(:post)
25
+ expect(TestConfiguration.max_retries).to eq(1)
26
+ expect(TestConfiguration.faraday_options).to eq({})
27
+ expect(TestConfiguration.faraday_options).to eq({})
28
+ expect(TestConfiguration.adapter).to eq(Faraday.default_adapter)
29
+ expect(TestConfiguration.logger).to be_a(Logger)
30
+ expect(TestConfiguration.log_requests?).to eq(true)
31
+ expect(TestConfiguration.log_errors).to eq(true)
32
+ expect(TestConfiguration.log_responses).not_to eq(true)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,12 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe WialonApi::Error do
5
+ let(:error_data) { Hashie::Mash.new('error' => 4) }
6
+ let(:error) { WialonApi::Error.new(error_data) }
7
+
8
+ it '#message returns error message by it\'s code' do
9
+ message = "Wialon server #{WialonApi.wialon_host} returned error 4: Invalid input"
10
+ expect { fail error }.to raise_error(error.class, message)
11
+ end
12
+ end
@@ -0,0 +1,103 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Logger do
4
+ before(:each) do
5
+ WialonApi.logger = double('Logger').as_null_object
6
+
7
+ WialonApi.log_requests = false
8
+ WialonApi.log_responses = false
9
+ WialonApi.log_errors = false
10
+ end
11
+
12
+ let(:success_response) { Oj.dump('a' => 1, 'b' => 2) }
13
+ let(:fail_response) { Oj.dump('error' => 404) }
14
+
15
+ let(:connection) do
16
+ Faraday.new(url: 'http://example.com') do |builder|
17
+ builder.request :url_encoded
18
+ builder.response :wialon_logger
19
+ builder.response :mashify
20
+ builder.response :oj, preserve_raw: true
21
+
22
+ builder.adapter :test do |stub|
23
+ stub.get('/success') do
24
+ [200, {}, success_response]
25
+ end
26
+
27
+ stub.post('/success') do
28
+ [200, {}, success_response]
29
+ end
30
+
31
+ stub.get('/fail') do
32
+ [200, {}, fail_response]
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'with WialonApi.log_requests?' do
39
+ before(:each) do
40
+ WialonApi.log_requests = true
41
+ end
42
+
43
+ it 'logs the request URL' do
44
+ expect(WialonApi.logger).to receive(:debug).with('GET http://example.com/success')
45
+ connection.get('/success')
46
+ end
47
+
48
+ context 'with a POST request' do
49
+ it 'logs the request URL and the request body' do
50
+ expect(WialonApi.logger).to receive(:debug).with('POST http://example.com/success')
51
+ expect(WialonApi.logger).to receive(:debug).with('body: "param=1"')
52
+ connection.post('/success', param: 1)
53
+ end
54
+ end
55
+ end
56
+
57
+ context 'without WialonApi.log_requests?' do
58
+ it 'does not log the request' do
59
+ expect(WialonApi.logger).not_to receive(:debug)
60
+ connection.get('/success')
61
+ end
62
+ end
63
+
64
+ context 'with a successful response' do
65
+ context 'with WialonApi.log_responses?' do
66
+ before(:each) do
67
+ WialonApi.log_responses = true
68
+ end
69
+
70
+ it 'logs the response body' do
71
+ expect(WialonApi.logger).to receive(:debug).with(success_response)
72
+ connection.get('/success')
73
+ end
74
+ end
75
+
76
+ context 'without WialonApi.log_responses?' do
77
+ it 'does not log the response body' do
78
+ expect(WialonApi.logger).not_to receive(:debug)
79
+ connection.get('/success')
80
+ end
81
+ end
82
+ end
83
+
84
+ context 'with an error response' do
85
+ context 'with WialonApi.log_errors?' do
86
+ before(:each) do
87
+ WialonApi.log_errors = true
88
+ end
89
+
90
+ it 'logs the response body' do
91
+ expect(WialonApi.logger).to receive(:warn).with(fail_response)
92
+ connection.get('/fail')
93
+ end
94
+ end
95
+
96
+ context 'without WialonApi.log_errors?' do
97
+ it 'does not log the response body' do
98
+ expect(WialonApi.logger).not_to receive(:warn)
99
+ connection.get('/fail')
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Method do
4
+ describe '#call' do
5
+ let(:full_name) { double('Full method name') }
6
+ let(:args) { double('Method arguments') }
7
+ let(:sid) { double('Session\'s id') }
8
+
9
+ let(:method) do
10
+ WialonApi::Method.new('some_name').tap do |method|
11
+ allow(method).to receive(:full_name).and_return(full_name)
12
+ allow(method).to receive(:sid).and_return(sid)
13
+ end
14
+ end
15
+
16
+ before(:each) do
17
+ allow(WialonApi::Result).to receive(:process)
18
+ end
19
+
20
+ it 'calls API.call with full name, args and sid' do
21
+ expect(WialonApi::Api).to receive(:call).with(full_name, args, sid)
22
+ method.call(args)
23
+ end
24
+
25
+ it 'sends the response to Result.process' do
26
+ response = double('WialonApi response')
27
+ allow(WialonApi::Api).to receive(:call).and_return(response)
28
+
29
+ expect(WialonApi::Result).to receive(:process).with(response, nil)
30
+ method.call(args)
31
+ end
32
+ end
33
+
34
+ describe '#full_name' do
35
+ let(:method) do
36
+ resolver = Hashie::Mash.new(name: 'name_space')
37
+ WialonApi::Method.new('name', resolver: resolver)
38
+ end
39
+
40
+ it 'sends each part to #camelize' do
41
+ expect(method.send(:full_name)).to eq('name_space/name')
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Namespace do
4
+ describe '.names' do
5
+ before(:each) do
6
+ WialonApi::Namespace.instance_variable_set(:@names, nil)
7
+ end
8
+
9
+ context 'on first call' do
10
+ it 'loads namespaces from a file' do
11
+ filename = double('Filename')
12
+ expect(File).to receive(:expand_path).and_return(filename)
13
+ namespaces = double('Namespaces list')
14
+ expect(YAML).to receive(:load_file).with(filename).and_return(namespaces)
15
+
16
+ WialonApi::Namespace.names
17
+ end
18
+ end
19
+
20
+ context 'on subsequent calls' do
21
+ before(:each) do
22
+ WialonApi::Namespace.names
23
+ end
24
+
25
+ it 'returns the cached list' do
26
+ expect(YAML).not_to receive(:load_file)
27
+ WialonApi::Namespace.names
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '.exists?' do
33
+ context 'with an existing namespace' do
34
+ it 'returns true' do
35
+ expect(WialonApi::Namespace).to exist('core')
36
+ end
37
+ end
38
+
39
+ context 'with a non-existent namespace' do
40
+ it 'returns false' do
41
+ expect(WialonApi::Namespace).not_to exist('wrong')
42
+ end
43
+ end
44
+
45
+ context 'with an existing symbol namespace' do
46
+ it 'returns true' do
47
+ expect(WialonApi::Namespace).to exist(:user)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Resolvable do
4
+ before(:each) do
5
+ @class = Class.new do
6
+ include WialonApi::Resolvable
7
+ end
8
+ end
9
+
10
+ describe '#initialize' do
11
+ it 'saves the name and the resolver' do
12
+ resolver = Hashie::Mash.new(sid: 'sid')
13
+ resolvable = @class.new(:name, resolver: resolver)
14
+
15
+ expect(resolvable.name).to eq('name')
16
+ expect(resolvable.sid).to eq('sid')
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Resolver do
4
+ before(:each) do
5
+ @class = Class.new do
6
+ include WialonApi::Resolver
7
+
8
+ attr_accessor :sid
9
+
10
+ def initialize(name)
11
+ @name = name
12
+ end
13
+ end
14
+ end
15
+
16
+ describe '#send' do
17
+ before(:each) do
18
+ @resolver = @class.new('trololo')
19
+ @sid = double('sid')
20
+ allow(@resolver).to receive(:sid).and_return(@sid)
21
+ end
22
+
23
+ it 'gets into #method_missing' do
24
+ expect(@resolver).to receive(:method_missing).with(:send, message: 'hello')
25
+ @resolver.send(message: 'hello')
26
+ end
27
+ end
28
+
29
+ describe '#resolver' do
30
+ before(:each) do
31
+ @name = double('Name')
32
+ @resolver = @class.new(@name)
33
+ @sid = double('sid')
34
+ allow(@resolver).to receive(:sid).and_return(@sid)
35
+ end
36
+
37
+ let(:resolver) { @resolver.resolver }
38
+
39
+ it 'returns a Hashie::Mash with a name and a sid' do
40
+ expect(resolver.name).to eq(@name)
41
+ expect(resolver.sid).to eq(@sid)
42
+ end
43
+
44
+ it 'caches the result' do
45
+ @mash = double('Mash', name: @name, sid: @sid)
46
+ expect(Hashie::Mash).to receive(:new).once.and_return(@mash)
47
+ 5.times { @resolver.resolver }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,92 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi::Result do
4
+ describe '.process' do
5
+ let(:response) { double('Response') }
6
+ let(:result) { double('Result') }
7
+
8
+ before(:each) do
9
+ allow(WialonApi::Result).to receive(:extract_result).and_return(result)
10
+ end
11
+
12
+ it 'calls .extract_result passing it the response' do
13
+ expect(WialonApi::Result).to receive(:extract_result).with(response)
14
+ WialonApi::Result.process(response, nil)
15
+ end
16
+
17
+ context 'with a non-enumerable result' do
18
+ let(:type) { double('Type') }
19
+ let(:value) { double('value') }
20
+
21
+ context 'when block_given?' do
22
+ it 'yields the #typecast-ed value and returns the result of the block' do
23
+ block_result = double('Block result')
24
+ expect(result).to receive(:result_method).and_return(block_result)
25
+ block = proc(&:result_method)
26
+
27
+ expect(WialonApi::Result.process(response, block)).to eq(block_result)
28
+ end
29
+ end
30
+ end
31
+
32
+ context 'with an enumerable result' do
33
+ let(:element1) { double('First element') }
34
+ let(:element2) { double('Second element') }
35
+ let(:enumerable_result) { [element1, element2] }
36
+
37
+ before(:each) do
38
+ allow(WialonApi::Result).to receive(:extract_result).and_return(enumerable_result)
39
+ end
40
+
41
+ it 'returns the untouched value' do
42
+ expect(WialonApi::Result.process(enumerable_result, nil)).to eq(enumerable_result)
43
+ end
44
+
45
+ context 'when block_given?' do
46
+ it 'yields each element untouched to the block' do
47
+ result1 = double('First element after result_method')
48
+ result2 = double('Second element after result_method')
49
+ expect(element1).to receive(:result_method).and_return(result1)
50
+ expect(element2).to receive(:result_method).and_return(result2)
51
+ block = proc(&:result_method)
52
+
53
+ expect(WialonApi::Result.process(enumerable_result, block)).to eq([result1, result2])
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ describe '.extract_result' do
60
+ let(:result_response) do
61
+ { 'key' => 'value' }
62
+ end
63
+
64
+ let(:result_error) do
65
+ {
66
+ 'request_params' => [
67
+ {
68
+ 'key' => 'error',
69
+ 'value' => 'description'
70
+ }
71
+ ]
72
+ }
73
+ end
74
+
75
+ context 'with a success response' do
76
+ let(:result) { Hashie::Mash.new(result_response) }
77
+ it 'returns plain result' do
78
+ expect(WialonApi::Result.send(:extract_result, result)).to eq(result)
79
+ end
80
+ end
81
+
82
+ context 'with an error response' do
83
+ let(:result) { Hashie::Mash.new(error: result_error) }
84
+
85
+ it 'raises a WialonApi::Error' do
86
+ expect do
87
+ WialonApi::Result.send(:extract_result, result)
88
+ end.to raise_error(WialonApi::Error)
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe WialonApi do
4
+ it 'should return current version' do
5
+ expect(WialonApi::VERSION).to eq('0.0.1')
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wialon_api/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wialon_api"
8
+ spec.version = WialonApi::VERSION
9
+ spec.authors = ["Arsen Shamkhalov"]
10
+ spec.email = ["thornu731@gmail.com"]
11
+ spec.summary = %q{Simple to use WialonPro API client. http://sdk.wialon.com/wiki/ru/pro/pro}
12
+ spec.description = %q{}
13
+ spec.homepage = "https://github.com/thorn/wialon_api"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec", "~> 3.2"
23
+ spec.add_development_dependency 'pry'
24
+ spec.add_development_dependency 'guard-rspec'
25
+
26
+ spec.add_development_dependency 'curb'
27
+ spec.add_development_dependency 'hashie'
28
+ spec.add_development_dependency 'faraday'
29
+ spec.add_development_dependency 'faraday_middleware'
30
+ spec.add_development_dependency 'faraday_middleware-parse_oj'
31
+
32
+ spec.add_development_dependency 'yard'
33
+ spec.add_development_dependency 'redcarpet'
34
+ spec.add_development_dependency 'guard-yard'
35
+ end