direct-api-v5 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +19 -0
  5. data/.travis.yml +17 -0
  6. data/Gemfile +2 -0
  7. data/README.md +127 -3
  8. data/direct-api-v5.gemspec +11 -5
  9. data/lib/direct/api/v5.rb +48 -3
  10. data/lib/direct/api/v5/client.rb +18 -0
  11. data/lib/direct/api/v5/default_settings.rb +42 -0
  12. data/lib/direct/api/v5/errors.rb +10 -0
  13. data/lib/direct/api/v5/params_builder.rb +46 -0
  14. data/lib/direct/api/v5/refinements/camelize.rb +22 -0
  15. data/lib/direct/api/v5/request.rb +66 -0
  16. data/lib/direct/api/v5/response.rb +32 -0
  17. data/lib/direct/api/v5/response/error.rb +21 -0
  18. data/lib/direct/api/v5/response/units.rb +34 -0
  19. data/lib/direct/api/v5/service.rb +32 -0
  20. data/lib/direct/api/v5/settings.rb +19 -0
  21. data/lib/direct/api/v5/version.rb +1 -1
  22. data/spec/acceptance/error_spec.rb +32 -0
  23. data/spec/acceptance/get_campaigns_spec.rb +72 -0
  24. data/spec/direct/api/v5/client_spec.rb +28 -0
  25. data/spec/direct/api/v5/default_settings_spec.rb +42 -0
  26. data/spec/direct/api/v5/params_builder_spec.rb +39 -0
  27. data/spec/direct/api/v5/refinements/camelize_spec.rb +21 -0
  28. data/spec/direct/api/v5/request_spec.rb +60 -0
  29. data/spec/direct/api/v5/response/error_spec.rb +30 -0
  30. data/spec/direct/api/v5/response/units_spec.rb +31 -0
  31. data/spec/direct/api/v5/response_spec.rb +66 -0
  32. data/spec/direct/api/v5/settings_spec.rb +42 -0
  33. data/spec/direct/api/v5_spec.rb +37 -0
  34. data/spec/fixtures/settings.yml +5 -0
  35. data/spec/shared/direct_api_helper.rb +66 -0
  36. data/spec/spec_helper.rb +25 -0
  37. data/spec/support/webmock.rb +3 -0
  38. metadata +127 -11
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Direct::API::V5::Request do
4
+ let(:client) { make_direct_api_client }
5
+
6
+ describe '#send' do
7
+ let(:service) { :Campaigns }
8
+ let(:method) { :get }
9
+ let(:params) do
10
+ {
11
+ field_names: [:id, :name],
12
+ selection_criteria: { types: %w(TEXT_CAMPAIGN) }
13
+ }
14
+ end
15
+ let(:result) do
16
+ [
17
+ { Id: 1, Name: 'Campaign 1' },
18
+ { Id: 2, Name: 'Campaign 2' }
19
+ ]
20
+ end
21
+
22
+ let(:request_params) do
23
+ Direct::API::V5::ParamsBuilder.new(params).build
24
+ end
25
+ let(:request_body) do
26
+ { method: method, params: request_params }
27
+ end
28
+ let(:response_body) do
29
+ { result: { Campaigns: result } }
30
+ end
31
+
32
+ let(:request) do
33
+ described_class.new(
34
+ settings: client.settings,
35
+ service_name: service,
36
+ api_method: method,
37
+ params: params
38
+ )
39
+ end
40
+
41
+ context 'with valid response' do
42
+ before { stub_direct_api_request(service, request_body, response_body) }
43
+
44
+ it 'return body and headers' do
45
+ body, headers = request.send
46
+ expect(body).to eq(response_body)
47
+ expect(headers[:RequestId]).to eq(direct_api_request_id)
48
+ expect(headers[:Units]).to eq(direct_api_units)
49
+ end
50
+ end
51
+
52
+ context 'with invalid response' do
53
+ before { stub_direct_api_request(service, request_body, 'invalid') }
54
+
55
+ it 'raise error' do
56
+ expect { request.send }.to raise_error(Direct::API::V5::InvalidResponseError)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,30 @@
1
+ require 'spec_helper'
2
+
3
+ describe Direct::API::V5::Response::Error do
4
+ let(:data) do
5
+ {
6
+ error_code: 54,
7
+ error_string: 'No rights',
8
+ error_detail: 'No rights to indicated client'
9
+ }
10
+ end
11
+
12
+ subject { described_class.new(data) }
13
+
14
+ describe '#code' do
15
+ it { expect(subject.code).to eq(54) }
16
+ end
17
+
18
+ describe '#message' do
19
+ it { expect(subject.message).to eq('No rights') }
20
+ end
21
+
22
+ describe '#details' do
23
+ it { expect(subject.details).to eq('No rights to indicated client') }
24
+ end
25
+
26
+ describe '#to_h' do
27
+ error_hash = { code: 54, message: 'No rights', details: 'No rights to indicated client' }
28
+ it { expect(subject.to_h).to eq(error_hash) }
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Direct::API::V5::Response::Units do
4
+ let(:raw_units) { '10/20828/64000' }
5
+
6
+ let(:units) { described_class.new(raw_units) }
7
+
8
+ describe '#raw' do
9
+ it { expect(units.raw).to eq(raw_units) }
10
+ end
11
+
12
+ describe '#spent' do
13
+ it { expect(units.spent).to eq(10) }
14
+ end
15
+
16
+ describe '#available' do
17
+ it { expect(units.available).to eq(20_828) }
18
+ end
19
+
20
+ describe '#daily_limit' do
21
+ it { expect(units.daily_limit).to eq(64_000) }
22
+ end
23
+
24
+ context 'with invalid data' do
25
+ let(:units) { described_class.new('invalid/data') }
26
+
27
+ it { expect(units.spent).to be_nil }
28
+ it { expect(units.available).to be_nil }
29
+ it { expect(units.daily_limit).to be_nil }
30
+ end
31
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ describe Direct::API::V5::Response do
4
+ let(:headers) do
5
+ {
6
+ RequestId: '123',
7
+ Units: '10/100/200'
8
+ }
9
+ end
10
+ let(:body) do
11
+ {
12
+ result: {
13
+ Campaigns: []
14
+ }
15
+ }
16
+ end
17
+ let(:error_body) do
18
+ {
19
+ error: {
20
+ error_code: 54,
21
+ error_string: 'No rights',
22
+ error_detail: 'No rights to indicated client'
23
+ }
24
+ }
25
+ end
26
+
27
+ let(:response) { described_class.new(body, headers) }
28
+ let(:error_response) { described_class.new(error_body, headers) }
29
+
30
+ describe '#result' do
31
+ it 'return data from result key' do
32
+ expect(response.result).to eq(Campaigns: [])
33
+ expect(error_response.result).to be_nil
34
+ end
35
+ end
36
+
37
+ describe '#request_id' do
38
+ it 'return data from headers' do
39
+ expect(response.request_id).to eq('123')
40
+ expect(error_response.request_id).to eq('123')
41
+ end
42
+ end
43
+
44
+ describe '#units' do
45
+ it 'return Units object' do
46
+ expect(response.units).to be_a(Direct::API::V5::Response::Units)
47
+ expect(response.units.raw).to eq('10/100/200')
48
+ end
49
+ end
50
+
51
+ describe '#error?' do
52
+ it 'check error key' do
53
+ expect(response.error?).to eq(false)
54
+ expect(error_response.error?).to eq(true)
55
+ end
56
+ end
57
+
58
+ describe '#error' do
59
+ it 'return Error object' do
60
+ expect(response.error).to be_nil
61
+
62
+ expect(error_response.error).to be_a(Direct::API::V5::Response::Error)
63
+ expect(error_response.error.code).to eq(54)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Direct::API::V5::Settings do
4
+ describe '::new' do
5
+ let(:default_host) { 'default_host.com' }
6
+ let(:default_language) { 'en' }
7
+ let(:default_auth_token) { 'default_token' }
8
+ let(:default_client_login) { 'default_login' }
9
+
10
+ let(:host) { 'host.com' }
11
+ let(:language) { 'ru' }
12
+ let(:auth_token) { 'token' }
13
+ let(:client_login) { 'login' }
14
+
15
+ before do
16
+ allow(Direct::API::V5::DefaultSettings).to receive(:host).and_return(default_host)
17
+ allow(Direct::API::V5::DefaultSettings).to receive(:language).and_return(default_language)
18
+ allow(Direct::API::V5::DefaultSettings).to receive(:auth_token).and_return(default_auth_token)
19
+ allow(Direct::API::V5::DefaultSettings).to receive(:client_login).and_return(default_client_login)
20
+ end
21
+
22
+ context 'with params' do
23
+ subject do
24
+ described_class.new(host: host, language: language, auth_token: auth_token, client_login: client_login)
25
+ end
26
+
27
+ it { expect(subject.host).to eq(host) }
28
+ it { expect(subject.language).to eq(language) }
29
+ it { expect(subject.auth_token).to eq(auth_token) }
30
+ it { expect(subject.client_login).to eq(client_login) }
31
+ end
32
+
33
+ context 'without params' do
34
+ subject { described_class.new }
35
+
36
+ it { expect(subject.host).to eq(default_host) }
37
+ it { expect(subject.language).to eq(default_language) }
38
+ it { expect(subject.auth_token).to eq(default_auth_token) }
39
+ it { expect(subject.client_login).to eq(default_client_login) }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Direct::API::V5 do
4
+ describe '::client' do
5
+ let(:settings) { { param1: 'value1', param2: 'value2' } }
6
+ let(:client) { double('client') }
7
+
8
+ before { allow(described_class::Client).to receive(:new).with(settings).and_return(client) }
9
+
10
+ subject { described_class.client(settings) }
11
+
12
+ it 'create new client' do
13
+ is_expected.to eq(client)
14
+ end
15
+ end
16
+
17
+ describe '::load_settings' do
18
+ let(:yml_path) { 'file_path' }
19
+
20
+ it 'call DefaultSettings::load_from_yml' do
21
+ expect(described_class::DefaultSettings).to receive(:load_from_yml).with(yml_path)
22
+ described_class.load_settings(yml_path)
23
+ end
24
+ end
25
+
26
+ describe '::configure' do
27
+ # rubocop:disable Style/Proc
28
+ let(:proc) { Proc.new {} }
29
+
30
+ it 'call DefaultSettings::configure' do
31
+ expect(described_class::DefaultSettings).to receive(:configure) do |&block|
32
+ expect(proc).to be(block)
33
+ end
34
+ described_class.configure(&proc)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,5 @@
1
+ test:
2
+ host: api-sandbox.direct.yandex.com
3
+ language: ru
4
+ auth_token: token_string
5
+ client_login: login_string
@@ -0,0 +1,66 @@
1
+ require 'direct/api/v5'
2
+
3
+ module DirectApiHelper
4
+ def make_direct_api_client
5
+ Direct::API::V5.client(
6
+ host: direct_api_host,
7
+ language: direct_api_language,
8
+ auth_token: direct_api_auth_token,
9
+ client_login: direct_api_client_login
10
+ )
11
+ end
12
+
13
+ def stub_direct_api_request(direct_service, request_body, response_body)
14
+ url = "https://#{direct_api_host}/json/v5/#{direct_service}/"
15
+ request_body = request_body.to_json if request_body.is_a?(Hash)
16
+ response_body = response_body.to_json if response_body.is_a?(Hash)
17
+ stub_request(:post, url)
18
+ .with(body: request_body, headers: direct_api_request_headers)
19
+ .to_return(body: response_body, headers: direct_api_response_headers)
20
+ end
21
+
22
+ def direct_api_request_headers
23
+ {
24
+ 'Content-Type' => 'application/json; charset=utf-8',
25
+ 'Accept-Language' => direct_api_language,
26
+ 'Authorization' => "Bearer #{direct_api_auth_token}",
27
+ 'Client-Login' => direct_api_client_login
28
+ }
29
+ end
30
+
31
+ def direct_api_response_headers
32
+ {
33
+ 'Content-Type' => 'application/json',
34
+ 'RequestId' => direct_api_request_id,
35
+ 'Units' => direct_api_units
36
+ }
37
+ end
38
+
39
+ def direct_api_host
40
+ 'api.direct.yandex.com'
41
+ end
42
+
43
+ def direct_api_language
44
+ 'en'
45
+ end
46
+
47
+ def direct_api_auth_token
48
+ 'token'
49
+ end
50
+
51
+ def direct_api_client_login
52
+ 'client_id'
53
+ end
54
+
55
+ def direct_api_request_id
56
+ '8695244274068608439'
57
+ end
58
+
59
+ def direct_api_units
60
+ '10/20828/64000'
61
+ end
62
+ end
63
+
64
+ RSpec.configure do |config|
65
+ config.include DirectApiHelper
66
+ end
@@ -0,0 +1,25 @@
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+
4
+ ENV['RAILS_ENV'] ||= 'test'
5
+
6
+ %w(support shared).each do |dir|
7
+ Dir[File.expand_path(File.join(File.dirname(__FILE__), dir, '**', '*.rb'))].each { |f| require f }
8
+ end
9
+
10
+ RSpec.configure do |config|
11
+ config.expect_with :rspec do |expectations|
12
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
13
+ end
14
+
15
+ config.mock_with :rspec do |mocks|
16
+ mocks.verify_partial_doubles = true
17
+ end
18
+
19
+ config.filter_run :focus
20
+ config.run_all_when_everything_filtered = true
21
+
22
+ config.define_derived_metadata do |meta|
23
+ meta[:aggregate_failures] = true
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ require 'webmock/rspec'
2
+
3
+ WebMock.disable_net_connect!(allow: 'codeclimate.com')
metadata CHANGED
@@ -1,50 +1,123 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: direct-api-v5
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Khrebtov Roman
7
+ - Roman Khrebtov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-03 00:00:00.000000000 Z
11
+ date: 2016-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: multi_json
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.12'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.12'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: bundler
15
43
  requirement: !ruby/object:Gem::Requirement
16
44
  requirements:
17
45
  - - "~>"
18
46
  - !ruby/object:Gem::Version
19
- version: '1.6'
47
+ version: '1.12'
20
48
  type: :development
21
49
  prerelease: false
22
50
  version_requirements: !ruby/object:Gem::Requirement
23
51
  requirements:
24
52
  - - "~>"
25
53
  - !ruby/object:Gem::Version
26
- version: '1.6'
54
+ version: '1.12'
27
55
  - !ruby/object:Gem::Dependency
28
56
  name: rake
29
57
  requirement: !ruby/object:Gem::Requirement
30
58
  requirements:
31
59
  - - "~>"
32
60
  - !ruby/object:Gem::Version
33
- version: '10.1'
61
+ version: '10.5'
34
62
  type: :development
35
63
  prerelease: false
36
64
  version_requirements: !ruby/object:Gem::Requirement
37
65
  requirements:
38
66
  - - "~>"
39
67
  - !ruby/object:Gem::Version
40
- version: '10.1'
41
- description: Ruby client for Yandex Direct API V5
68
+ version: '10.5'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: webmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '2.1'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '2.1'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Ruby wrapper for Yandex Direct API V5
42
112
  email: roman@alltmb.ru
43
113
  executables: []
44
114
  extensions: []
45
115
  extra_rdoc_files: []
46
116
  files:
47
117
  - ".gitignore"
118
+ - ".rspec"
119
+ - ".rubocop.yml"
120
+ - ".travis.yml"
48
121
  - Gemfile
49
122
  - LICENSE
50
123
  - LICENSE.txt
@@ -52,7 +125,34 @@ files:
52
125
  - Rakefile
53
126
  - direct-api-v5.gemspec
54
127
  - lib/direct/api/v5.rb
128
+ - lib/direct/api/v5/client.rb
129
+ - lib/direct/api/v5/default_settings.rb
130
+ - lib/direct/api/v5/errors.rb
131
+ - lib/direct/api/v5/params_builder.rb
132
+ - lib/direct/api/v5/refinements/camelize.rb
133
+ - lib/direct/api/v5/request.rb
134
+ - lib/direct/api/v5/response.rb
135
+ - lib/direct/api/v5/response/error.rb
136
+ - lib/direct/api/v5/response/units.rb
137
+ - lib/direct/api/v5/service.rb
138
+ - lib/direct/api/v5/settings.rb
55
139
  - lib/direct/api/v5/version.rb
140
+ - spec/acceptance/error_spec.rb
141
+ - spec/acceptance/get_campaigns_spec.rb
142
+ - spec/direct/api/v5/client_spec.rb
143
+ - spec/direct/api/v5/default_settings_spec.rb
144
+ - spec/direct/api/v5/params_builder_spec.rb
145
+ - spec/direct/api/v5/refinements/camelize_spec.rb
146
+ - spec/direct/api/v5/request_spec.rb
147
+ - spec/direct/api/v5/response/error_spec.rb
148
+ - spec/direct/api/v5/response/units_spec.rb
149
+ - spec/direct/api/v5/response_spec.rb
150
+ - spec/direct/api/v5/settings_spec.rb
151
+ - spec/direct/api/v5_spec.rb
152
+ - spec/fixtures/settings.yml
153
+ - spec/shared/direct_api_helper.rb
154
+ - spec/spec_helper.rb
155
+ - spec/support/webmock.rb
56
156
  homepage: https://github.com/Hrom512/direct-api-v5
57
157
  licenses:
58
158
  - MIT
@@ -65,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
165
  requirements:
66
166
  - - ">="
67
167
  - !ruby/object:Gem::Version
68
- version: '2.0'
168
+ version: '2.1'
69
169
  required_rubygems_version: !ruby/object:Gem::Requirement
70
170
  requirements:
71
171
  - - ">="
@@ -73,8 +173,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
173
  version: '0'
74
174
  requirements: []
75
175
  rubyforge_project:
76
- rubygems_version: 2.2.2
176
+ rubygems_version: 2.4.8
77
177
  signing_key:
78
178
  specification_version: 4
79
179
  summary: Yandex Direct API V5
80
- test_files: []
180
+ test_files:
181
+ - spec/acceptance/error_spec.rb
182
+ - spec/acceptance/get_campaigns_spec.rb
183
+ - spec/direct/api/v5/client_spec.rb
184
+ - spec/direct/api/v5/default_settings_spec.rb
185
+ - spec/direct/api/v5/params_builder_spec.rb
186
+ - spec/direct/api/v5/refinements/camelize_spec.rb
187
+ - spec/direct/api/v5/request_spec.rb
188
+ - spec/direct/api/v5/response/error_spec.rb
189
+ - spec/direct/api/v5/response/units_spec.rb
190
+ - spec/direct/api/v5/response_spec.rb
191
+ - spec/direct/api/v5/settings_spec.rb
192
+ - spec/direct/api/v5_spec.rb
193
+ - spec/fixtures/settings.yml
194
+ - spec/shared/direct_api_helper.rb
195
+ - spec/spec_helper.rb
196
+ - spec/support/webmock.rb