wialon_api 0.0.1

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.
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