soapy_bing 0.3.1 → 0.4.0
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.
- checksums.yaml +4 -4
- data/.ruby-version +1 -1
- data/Gemfile +1 -0
- data/README.md +18 -18
- data/Rakefile +1 -0
- data/lib/soapy_bing.rb +5 -1
- data/lib/soapy_bing/account.rb +1 -0
- data/lib/soapy_bing/accounts.rb +13 -17
- data/lib/soapy_bing/ads.rb +18 -41
- data/lib/soapy_bing/ads/campaign_performance_report.rb +49 -0
- data/lib/soapy_bing/ads/campaigns.rb +106 -0
- data/lib/soapy_bing/ads/parsers/bulk_csv_parser.rb +34 -0
- data/lib/soapy_bing/ads/parsers/report_csv_parser.rb +45 -0
- data/lib/soapy_bing/ads/report.rb +93 -0
- data/lib/soapy_bing/campaign_management.rb +21 -0
- data/lib/soapy_bing/country_codes.rb +17 -0
- data/lib/soapy_bing/country_codes.yml +727 -0
- data/lib/soapy_bing/customer.rb +1 -0
- data/lib/soapy_bing/helpers.rb +1 -1
- data/lib/soapy_bing/helpers/zip_downloader.rb +1 -0
- data/lib/soapy_bing/oauth_credentials.rb +1 -0
- data/lib/soapy_bing/param_guard.rb +1 -0
- data/lib/soapy_bing/service.rb +69 -0
- data/lib/soapy_bing/service_operation.rb +62 -0
- data/lib/soapy_bing/version.rb +2 -1
- data/lib/soapy_bing/wsdl/ad_insight.wsdl +1 -0
- data/lib/soapy_bing/wsdl/bulk.wsdl +1 -0
- data/lib/soapy_bing/wsdl/campaign_management.wsdl +1 -0
- data/lib/soapy_bing/wsdl/customer_billing.wsdl +1 -0
- data/lib/soapy_bing/wsdl/customer_management.wsdl +1 -0
- data/lib/soapy_bing/wsdl/reporting.wsdl +1 -0
- data/lib/tasks/console.rake +1 -0
- data/lib/tasks/coverage.rake +1 -0
- data/lib/tasks/spec.rake +1 -0
- data/lib/tasks/upate_wsdl_files.rake +23 -0
- data/lib/tasks/update_country_codes.rake +24 -0
- data/soapy_bing.gemspec +2 -1
- data/spec/fixtures/ads/campaign_performance_report.csv +37 -0
- data/spec/fixtures/ads/campaign_performance_report.json +170 -0
- data/spec/fixtures/ads/campaigns_by_account_id.csv +7 -0
- data/spec/fixtures/{bulk/campaigns.json → ads/campaigns_by_account_id.json} +496 -240
- data/spec/fixtures/ads/campaigns_by_campaign_ids.csv +5 -0
- data/spec/fixtures/ads/campaigns_by_campaign_ids.json +910 -0
- data/spec/fixtures/vcr_cassettes/SoapyBing_Accounts/_list/returns_a_list_of_SoapyBing_Account_objects.yml +27 -27
- data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_campaigns/by_account_id/returns_parsed_rows.yml +301 -0
- data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_campaigns/by_campaign_ids/returns_parsed_rows.yml +300 -0
- data/spec/fixtures/vcr_cassettes/SoapyBing_CampaignManagement/_get_geo_locations/returns_a_list_of_geo_locations_hashes.yml +154 -0
- data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_pending_status.yml +65 -94
- data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_successful_empty_response.yml +511 -0
- data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_successful_response.yml +384 -0
- data/spec/integration/soapy_bing/accounts_spec.rb +1 -0
- data/spec/integration/soapy_bing/ads_campaigns_spec.rb +85 -0
- data/spec/integration/soapy_bing/campaign_management_spec.rb +22 -0
- data/spec/integration/soapy_bing/oauth_credentials_spec.rb +1 -0
- data/spec/simplecov_setup.rb +1 -0
- data/spec/soapy_bing/account_spec.rb +6 -2
- data/spec/soapy_bing/accounts_spec.rb +47 -0
- data/spec/soapy_bing/ads/campaign_performance_report_spec.rb +79 -0
- data/spec/soapy_bing/ads/campaigns_spec.rb +99 -0
- data/spec/soapy_bing/ads/{bulk/parsers/csv_parser_spec.rb → parsers/bulk_csv_parser_spec.rb} +5 -4
- data/spec/soapy_bing/ads/{reports/parsers/csv_parser_spec.rb → parsers/report_csv_parser_spec.rb} +6 -4
- data/spec/soapy_bing/country_codes_spec.rb +39 -0
- data/spec/soapy_bing/helpers/zip_downloader_spec.rb +2 -0
- data/spec/soapy_bing/oauth_credentials_spec.rb +6 -2
- data/spec/soapy_bing/param_guard_spec.rb +2 -0
- data/spec/soapy_bing/service_spec.rb +56 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/support/dotenv.rb +1 -0
- data/spec/support/vcr.rb +75 -6
- metadata +74 -118
- data/lib/soapy_bing/ads/bulk.rb +0 -3
- data/lib/soapy_bing/ads/bulk/campaigns.rb +0 -65
- data/lib/soapy_bing/ads/bulk/parsers.rb +0 -2
- data/lib/soapy_bing/ads/bulk/parsers/csv_parser.rb +0 -35
- data/lib/soapy_bing/ads/reports.rb +0 -4
- data/lib/soapy_bing/ads/reports/base.rb +0 -74
- data/lib/soapy_bing/ads/reports/campaign_performance_report.rb +0 -24
- data/lib/soapy_bing/ads/reports/parsers.rb +0 -2
- data/lib/soapy_bing/ads/reports/parsers/csv_parser.rb +0 -46
- data/lib/soapy_bing/helpers/class_name.rb +0 -10
- data/lib/soapy_bing/soap.rb +0 -4
- data/lib/soapy_bing/soap/request.rb +0 -10
- data/lib/soapy_bing/soap/request/base.rb +0 -38
- data/lib/soapy_bing/soap/request/download_campaigns_by_account_ids_request.rb +0 -17
- data/lib/soapy_bing/soap/request/get_accounts_info_request.rb +0 -17
- data/lib/soapy_bing/soap/request/get_ad_groups_by_campaign_id_request.rb +0 -17
- data/lib/soapy_bing/soap/request/get_ads_by_ad_group_id_request.rb +0 -17
- data/lib/soapy_bing/soap/request/get_bulk_download_status_request.rb +0 -17
- data/lib/soapy_bing/soap/request/get_targets_by_campaign_ids_request.rb +0 -17
- data/lib/soapy_bing/soap/request/poll_generate_report_request.rb +0 -34
- data/lib/soapy_bing/soap/request/submit_generate_report_request.rb +0 -17
- data/lib/soapy_bing/soap/response.rb +0 -14
- data/lib/soapy_bing/soap/response/base.rb +0 -17
- data/lib/soapy_bing/soap/response/download_campaigns_by_account_ids_response.rb +0 -12
- data/lib/soapy_bing/soap/response/get_accounts_info_response.rb +0 -12
- data/lib/soapy_bing/soap/response/get_ad_groups_by_campaign_id_response.rb +0 -12
- data/lib/soapy_bing/soap/response/get_ads_by_ad_group_id_response.rb +0 -12
- data/lib/soapy_bing/soap/response/get_bulk_download_status_response.rb +0 -17
- data/lib/soapy_bing/soap/response/get_targets_by_campaign_ids_response.rb +0 -12
- data/lib/soapy_bing/soap/response/payload.rb +0 -28
- data/lib/soapy_bing/soap/response/poll_generate_report_response.rb +0 -14
- data/lib/soapy_bing/soap/response/report_status.rb +0 -34
- data/lib/soapy_bing/soap/response/submit_generate_report_response.rb +0 -12
- data/lib/soapy_bing/soap/template_renderer.rb +0 -22
- data/lib/soapy_bing/soap/templates/download_campaigns_by_account_ids.xml.erb +0 -22
- data/lib/soapy_bing/soap/templates/get_accounts_info.xml.erb +0 -12
- data/lib/soapy_bing/soap/templates/get_ad_groups_by_campaign_id.xml.erb +0 -15
- data/lib/soapy_bing/soap/templates/get_ads_by_ad_group_id.xml.erb +0 -15
- data/lib/soapy_bing/soap/templates/get_bulk_download_status.xml.erb +0 -15
- data/lib/soapy_bing/soap/templates/get_targets_by_campaign_ids.xml.erb +0 -20
- data/lib/soapy_bing/soap/templates/poll_generate_report.xml.erb +0 -18
- data/lib/soapy_bing/soap/templates/submit_generate_report.xml.erb +0 -46
- data/spec/fixtures/bulk/campaigns.csv +0 -8
- data/spec/fixtures/get_ad_groups_by_campaign_id.json +0 -587
- data/spec/fixtures/get_ads_by_ad_group_id.json +0 -218
- data/spec/fixtures/get_targets_by_campaign_ids.json +0 -81
- data/spec/fixtures/reports/campaign_performance_report.csv +0 -37
- data/spec/fixtures/reports/campaign_performance_report.json +0 -146
- data/spec/fixtures/soap_templates/simple.xml.erb +0 -2
- data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_get_ad_groups_by_campaign_id/1_1_1.yml +0 -150
- data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_get_ads_by_ad_group_id/1_2_1.yml +0 -141
- data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_get_targets_by_campaign_ids/1_3_1.yml +0 -111
- data/spec/fixtures/vcr_cassettes/SoapyBing_Ads_Bulk_Campaigns/_result_file_url/returns_result_file_url.yml +0 -216
- data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_successful_status.yml +0 -284
- data/spec/integration/soapy_bing/ads/bulk/campaigns_spec.rb +0 -35
- data/spec/integration/soapy_bing/ads/reports/campaign_performance_report_spec.rb +0 -40
- data/spec/integration/soapy_bing/ads_spec.rb +0 -32
- data/spec/soapy_bing/ads/reports/campaign_performance_report_spec.rb +0 -42
- data/spec/soapy_bing/ads_spec.rb +0 -33
- data/spec/soapy_bing/helpers/class_name_spec.rb +0 -15
- data/spec/soapy_bing/soap/request/base_spec.rb +0 -55
- data/spec/soapy_bing/soap/request/poll_generate_report_request_spec.rb +0 -60
- data/spec/soapy_bing/soap/response/base_spec.rb +0 -13
- data/spec/soapy_bing/soap/response/get_bulk_download_status_response_spec.rb +0 -60
- data/spec/soapy_bing/soap/response/payload_spec.rb +0 -48
- data/spec/soapy_bing/soap/response/poll_generate_report_response_spec.rb +0 -26
- data/spec/soapy_bing/soap/response/report_status_spec.rb +0 -92
- data/spec/soapy_bing/soap/response/submit_generate_report_response_spec.rb +0 -20
- data/spec/soapy_bing/soap/template_renderer_spec.rb +0 -25
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe SoapyBing::CampaignManagement do
|
|
4
|
+
subject(:campaign_management) { described_class.new }
|
|
5
|
+
|
|
6
|
+
describe '#get_geo_locations', :vcr do
|
|
7
|
+
it 'returns a list of geo_locations hashes' do
|
|
8
|
+
rows = campaign_management.get_geo_locations
|
|
9
|
+
expect(rows.size).to eq(5)
|
|
10
|
+
expect(rows.first).to eq(
|
|
11
|
+
'ID' => '1',
|
|
12
|
+
'Code' => 'AL',
|
|
13
|
+
'Display Name' => 'Albania',
|
|
14
|
+
'Descriptor' => 'country/region',
|
|
15
|
+
'Target Type' => 'Country',
|
|
16
|
+
'Replaces' => nil,
|
|
17
|
+
'Status' => 'Active',
|
|
18
|
+
'AdWords Location ID' => '2008'
|
|
19
|
+
)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/spec/simplecov_setup.rb
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
RSpec.describe SoapyBing::Account do
|
|
3
4
|
describe '#initialize' do
|
|
4
5
|
subject(:account_obj) { described_class.new(account) }
|
|
@@ -7,6 +8,7 @@ RSpec.describe SoapyBing::Account do
|
|
|
7
8
|
let(:account) do
|
|
8
9
|
{ developer_token: 'foo', account_id: 'baz', customer_id: 'qux' }
|
|
9
10
|
end
|
|
11
|
+
|
|
10
12
|
before do
|
|
11
13
|
allow(ENV).to receive(:[]).with('BING_ADS_DEVELOPER_TOKEN').and_return('foo_env')
|
|
12
14
|
allow(ENV).to receive(:[]).with('BING_ADS_ACCOUNT_ID').and_return('baz_env')
|
|
@@ -28,6 +30,7 @@ RSpec.describe SoapyBing::Account do
|
|
|
28
30
|
|
|
29
31
|
context 'when account credentials passed via Enviromenment variables' do
|
|
30
32
|
let(:account) { {} }
|
|
33
|
+
|
|
31
34
|
before do
|
|
32
35
|
allow(ENV).to receive(:[]).with('BING_ADS_DEVELOPER_TOKEN').and_return('foo_env')
|
|
33
36
|
allow(ENV).to receive(:[]).with('BING_ADS_ACCOUNT_ID').and_return('baz_env')
|
|
@@ -51,10 +54,11 @@ RSpec.describe SoapyBing::Account do
|
|
|
51
54
|
let(:account) do
|
|
52
55
|
{ developer_token: 'foo', account_id: 'baz', customer_id: 'qux' }
|
|
53
56
|
end
|
|
57
|
+
|
|
54
58
|
before do
|
|
55
|
-
%w
|
|
59
|
+
%w[ BING_ADS_DEVELOPER_TOKEN
|
|
56
60
|
BING_ADS_ACCOUNT_ID
|
|
57
|
-
BING_ADS_CUSTOMER_ID
|
|
61
|
+
BING_ADS_CUSTOMER_ID ].each do |var|
|
|
58
62
|
allow(ENV).to receive(:[]).with(var).and_return(nil)
|
|
59
63
|
end
|
|
60
64
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe SoapyBing::Accounts do
|
|
4
|
+
describe '#customer_management' do
|
|
5
|
+
subject(:accounts) { described_class.new }
|
|
6
|
+
|
|
7
|
+
let(:accounts_list_response) do
|
|
8
|
+
{
|
|
9
|
+
accounts_info: {
|
|
10
|
+
account_info: [
|
|
11
|
+
{ id: '123' },
|
|
12
|
+
{ id: '456' }
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
before do
|
|
19
|
+
allow(accounts.service).to receive(:get_accounts_info).and_return(accounts_list_response)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'returns accounts list' do
|
|
23
|
+
result = accounts.list
|
|
24
|
+
|
|
25
|
+
expect(result.size).to eq(2)
|
|
26
|
+
expect(result.first.account_id).to eq('123')
|
|
27
|
+
expect(result.last.account_id).to eq('456')
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
context 'without BING_ADS_ACCOUNT_ID' do
|
|
31
|
+
around do |example|
|
|
32
|
+
original_bing_ads_account_id = ENV['BING_ADS_ACCOUNT_ID']
|
|
33
|
+
ENV.delete('BING_ADS_ACCOUNT_ID')
|
|
34
|
+
example.run
|
|
35
|
+
ENV['BING_ADS_ACCOUNT_ID'] = original_bing_ads_account_id
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'returns accounts list' do
|
|
39
|
+
result = accounts.list
|
|
40
|
+
|
|
41
|
+
expect(result.size).to eq(2)
|
|
42
|
+
expect(result.first.account_id).to eq('123')
|
|
43
|
+
expect(result.last.account_id).to eq('456')
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'date'
|
|
4
|
+
|
|
5
|
+
RSpec.describe SoapyBing::Ads::CampaignPerformanceReport do
|
|
6
|
+
subject(:report) { described_class.new(report_options) }
|
|
7
|
+
|
|
8
|
+
let(:report_options) do
|
|
9
|
+
{
|
|
10
|
+
service_options: {},
|
|
11
|
+
date_start: date_start,
|
|
12
|
+
date_end: date_end,
|
|
13
|
+
polling_settings: polling_settings
|
|
14
|
+
}
|
|
15
|
+
end
|
|
16
|
+
let(:polling_settings) { {} }
|
|
17
|
+
let(:service_double) { double }
|
|
18
|
+
|
|
19
|
+
describe '#initialize' do
|
|
20
|
+
context 'when there is a wrong date format' do
|
|
21
|
+
let(:date_start) { 'wrong_date' }
|
|
22
|
+
let(:date_end) { 'today' }
|
|
23
|
+
|
|
24
|
+
it 'throws exception' do
|
|
25
|
+
expect { report }.to raise_error(ArgumentError, 'invalid date')
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context 'with valid dates' do
|
|
30
|
+
let(:date_start) { '2017-06-20' }
|
|
31
|
+
let(:date_end) { '2017-06-21' }
|
|
32
|
+
|
|
33
|
+
it 'sets default pooling settings' do
|
|
34
|
+
polling_settings = report.polling_settings
|
|
35
|
+
expect(polling_settings[:tries]).to eq(20)
|
|
36
|
+
expect(polling_settings[:sleep].call(6)).to eq(64)
|
|
37
|
+
expect(polling_settings[:sleep].call(7)).to eq(120)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe '#rows' do
|
|
43
|
+
let(:date_start) { '2016-09-15' }
|
|
44
|
+
let(:date_end) { '2016-09-15' }
|
|
45
|
+
|
|
46
|
+
before do
|
|
47
|
+
allow(SoapyBing::Service).to receive(:reporting).and_return(service_double)
|
|
48
|
+
allow(service_double).to receive(:submit_generate_report) do
|
|
49
|
+
{ report_request_id: '123' }
|
|
50
|
+
end
|
|
51
|
+
allow(service_double).to receive(:poll_generate_report) do
|
|
52
|
+
{
|
|
53
|
+
report_request_status: { status: status }
|
|
54
|
+
}
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'with pending response' do
|
|
59
|
+
let(:polling_settings) { { tries: 3, sleep: 0 } }
|
|
60
|
+
let(:status) { 'Pending' }
|
|
61
|
+
|
|
62
|
+
it 'raises NotCompleted' do
|
|
63
|
+
expect { report.rows }.to raise_error SoapyBing::Ads::NotCompleted
|
|
64
|
+
expect(service_double).to have_received(:submit_generate_report).once
|
|
65
|
+
expect(service_double).to have_received(:poll_generate_report).exactly(3).times
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context 'with failed response' do
|
|
70
|
+
let(:status) { 'Error' }
|
|
71
|
+
|
|
72
|
+
it 'raises StatusFailed' do
|
|
73
|
+
expect { report.rows }.to raise_error SoapyBing::Ads::StatusFailed
|
|
74
|
+
expect(service_double).to have_received(:submit_generate_report).once
|
|
75
|
+
expect(service_double).to have_received(:poll_generate_report).once
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe SoapyBing::Ads::Campaigns do
|
|
4
|
+
subject(:campaigns) do
|
|
5
|
+
described_class.new(
|
|
6
|
+
service_options: {},
|
|
7
|
+
polling_settings: polling_settings
|
|
8
|
+
)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
let(:service_double) { double }
|
|
12
|
+
let(:account_double) { instance_double(SoapyBing::Account) }
|
|
13
|
+
let(:zip_downloader_double) { instance_double(SoapyBing::Helpers::ZipDownloader) }
|
|
14
|
+
let(:polling_settings) { {} }
|
|
15
|
+
|
|
16
|
+
describe '#rows' do
|
|
17
|
+
let(:completed_response) do
|
|
18
|
+
{
|
|
19
|
+
request_status: 'Completed',
|
|
20
|
+
result_file_url: 'http://example.com/result_file'
|
|
21
|
+
}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
let(:pending_response) do
|
|
25
|
+
{
|
|
26
|
+
request_status: 'Pending'
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
allow(SoapyBing::Service).to receive(:bulk).and_return(service_double)
|
|
32
|
+
|
|
33
|
+
allow(SoapyBing::Helpers::ZipDownloader).to receive(:new)
|
|
34
|
+
.with('http://example.com/result_file')
|
|
35
|
+
.and_return(zip_downloader_double)
|
|
36
|
+
|
|
37
|
+
allow(zip_downloader_double).to receive(:read)
|
|
38
|
+
.and_return("a,b\nc,d\ne,f")
|
|
39
|
+
|
|
40
|
+
allow(service_double).to receive(:download_campaigns_by_account_ids)
|
|
41
|
+
.and_return(download_request_id: '123')
|
|
42
|
+
|
|
43
|
+
allow(service_double).to receive(:account)
|
|
44
|
+
.and_return(account_double)
|
|
45
|
+
|
|
46
|
+
allow(account_double).to receive(:account_id).and_return(1)
|
|
47
|
+
|
|
48
|
+
call_count = 0
|
|
49
|
+
allow(service_double).to receive(:get_bulk_download_status) do
|
|
50
|
+
call_count += 1
|
|
51
|
+
call_count == 3 ? completed_response : pending_response
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it 'polls until successful response' do
|
|
56
|
+
expect(campaigns.rows).to eq(
|
|
57
|
+
[
|
|
58
|
+
{ 'a' => 'c', 'b' => 'd' },
|
|
59
|
+
{ 'a' => 'e', 'b' => 'f' }
|
|
60
|
+
]
|
|
61
|
+
)
|
|
62
|
+
expect(service_double).to have_received(:download_campaigns_by_account_ids).once
|
|
63
|
+
expect(service_double).to have_received(:get_bulk_download_status).exactly(3).times
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context 'with polling_tries = 1' do
|
|
67
|
+
let(:polling_settings) { { tries: 1 } }
|
|
68
|
+
|
|
69
|
+
it 'raises NotCompleted error after exceeded polling tries' do
|
|
70
|
+
expect { campaigns.rows }.to raise_error described_class::NotCompleted
|
|
71
|
+
expect(service_double).to have_received(:get_bulk_download_status).once
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context 'with failed response' do
|
|
76
|
+
before do
|
|
77
|
+
allow(service_double).to receive(:get_bulk_download_status) do
|
|
78
|
+
{
|
|
79
|
+
request_status: 'Failed',
|
|
80
|
+
errors: {
|
|
81
|
+
operation_error: {
|
|
82
|
+
code: '0',
|
|
83
|
+
error_code: 'InternalError',
|
|
84
|
+
message: 'An internal error has occurred'
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'raises StatusFailed with error message' do
|
|
92
|
+
expect { campaigns.rows }.to raise_error described_class::StatusFailed do |error|
|
|
93
|
+
expect(error.message).to match(/An internal error has occurred/)
|
|
94
|
+
end
|
|
95
|
+
expect(service_double).to have_received(:get_bulk_download_status).once
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
data/spec/soapy_bing/ads/{bulk/parsers/csv_parser_spec.rb → parsers/bulk_csv_parser_spec.rb}
RENAMED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'json'
|
|
3
4
|
|
|
4
|
-
RSpec.describe SoapyBing::Ads::
|
|
5
|
+
RSpec.describe SoapyBing::Ads::Parsers::BulkCsvParser do
|
|
5
6
|
describe '#rows' do
|
|
6
7
|
subject(:rows) { described_class.new(csv_data).rows }
|
|
7
8
|
|
|
8
9
|
let(:csv_fixture_path) do
|
|
9
|
-
File.join('spec', 'fixtures', '
|
|
10
|
+
File.join('spec', 'fixtures', 'ads', 'campaigns_by_account_id.csv')
|
|
10
11
|
end
|
|
11
12
|
let(:csv_data) { File.read(csv_fixture_path) }
|
|
12
13
|
|
|
13
14
|
let(:json_fixture_path) do
|
|
14
|
-
File.join('spec', 'fixtures', '
|
|
15
|
+
File.join('spec', 'fixtures', 'ads', 'campaigns_by_account_id.json')
|
|
15
16
|
end
|
|
16
|
-
let(:json_data) { JSON.
|
|
17
|
+
let(:json_data) { JSON.parse(File.read(json_fixture_path)) }
|
|
17
18
|
|
|
18
19
|
it 'responds with array of Hashes' do
|
|
19
20
|
expect(rows).to eq json_data
|
data/spec/soapy_bing/ads/{reports/parsers/csv_parser_spec.rb → parsers/report_csv_parser_spec.rb}
RENAMED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'json'
|
|
3
4
|
require 'csv'
|
|
4
5
|
|
|
5
|
-
RSpec.describe SoapyBing::Ads::
|
|
6
|
+
RSpec.describe SoapyBing::Ads::Parsers::ReportCsvParser do
|
|
6
7
|
describe '#rows' do
|
|
7
8
|
subject(:rows) { described_class.new(csv_data).rows }
|
|
9
|
+
|
|
8
10
|
context 'on valid CSV data' do
|
|
9
11
|
let(:csv_fixture_path) do
|
|
10
|
-
File.join('spec', 'fixtures', '
|
|
12
|
+
File.join('spec', 'fixtures', 'ads', 'campaign_performance_report.csv')
|
|
11
13
|
end
|
|
12
14
|
let(:csv_data) { File.read(csv_fixture_path) }
|
|
13
15
|
|
|
14
16
|
let(:json_fixture_path) do
|
|
15
|
-
File.join('spec', 'fixtures', '
|
|
17
|
+
File.join('spec', 'fixtures', 'ads', 'campaign_performance_report.json')
|
|
16
18
|
end
|
|
17
|
-
let(:json_data) { JSON.
|
|
19
|
+
let(:json_data) { JSON.parse(File.read(json_fixture_path)) }
|
|
18
20
|
|
|
19
21
|
it 'responds with array of Hashes' do
|
|
20
22
|
expect(rows).to eq json_data
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
RSpec.describe SoapyBing::CountryCodes do
|
|
4
|
+
subject(:country_codes) { described_class.new }
|
|
5
|
+
|
|
6
|
+
describe '#code' do
|
|
7
|
+
context 'valid country id' do
|
|
8
|
+
let(:id) { 20 }
|
|
9
|
+
|
|
10
|
+
it 'returns contry code' do
|
|
11
|
+
expect(country_codes.code(id)).to eq('BR')
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
context 'valid country id as string' do
|
|
16
|
+
let(:id) { '20' }
|
|
17
|
+
|
|
18
|
+
it 'returns contry code' do
|
|
19
|
+
expect(country_codes.code(id)).to eq('BR')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context 'valid state id' do
|
|
24
|
+
let(:id) { 685 }
|
|
25
|
+
|
|
26
|
+
it 'returns contry code' do
|
|
27
|
+
expect(country_codes.code(id)).to eq('BR-RS')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'invalid id' do
|
|
32
|
+
let(:id) { 0 }
|
|
33
|
+
|
|
34
|
+
it 'raises error' do
|
|
35
|
+
expect { country_codes.code(id) }.to raise_error(KeyError)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
RSpec.describe SoapyBing::Helpers::ZipDownloader do
|
|
3
4
|
describe '#read' do
|
|
4
5
|
let(:hello_zip_file_path) { File.join('spec', 'fixtures', 'helpers', 'hello.zip') }
|
|
@@ -6,6 +7,7 @@ RSpec.describe SoapyBing::Helpers::ZipDownloader do
|
|
|
6
7
|
instance_double(HTTParty::Response, body: File.read(hello_zip_file_path))
|
|
7
8
|
end
|
|
8
9
|
let(:download_url) { 'https://example.com/file.zip' }
|
|
10
|
+
|
|
9
11
|
subject(:instance) { described_class.new(download_url) }
|
|
10
12
|
|
|
11
13
|
it 'unzips and reads file content' do
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
RSpec.describe SoapyBing::OauthCredentials do
|
|
3
4
|
subject(:oauth_credentials) { described_class.new(credentials) }
|
|
4
5
|
|
|
5
6
|
describe '#initialize' do
|
|
6
7
|
context 'when oauth credentials passed explicitly' do
|
|
7
8
|
let(:credentials) { { client_id: 'foo', client_secret: 'bar', refresh_token: 'baz' } }
|
|
9
|
+
|
|
8
10
|
before do
|
|
9
11
|
allow(ENV).to receive(:[]).with('BING_ADS_OAUTH_CLIENT_ID').and_return('foo_env')
|
|
10
12
|
allow(ENV).to receive(:[]).with('BING_ADS_OAUTH_CLIENT_SECRET').and_return('bar_env')
|
|
@@ -27,6 +29,7 @@ RSpec.describe SoapyBing::OauthCredentials do
|
|
|
27
29
|
|
|
28
30
|
context 'when oauth credentials passed via Enviromenment variables' do
|
|
29
31
|
let(:credentials) { {} }
|
|
32
|
+
|
|
30
33
|
before do
|
|
31
34
|
allow(ENV).to receive(:[]).with('BING_ADS_OAUTH_CLIENT_ID').and_return('foo_env')
|
|
32
35
|
allow(ENV).to receive(:[]).with('BING_ADS_OAUTH_CLIENT_SECRET').and_return('bar_env')
|
|
@@ -49,10 +52,11 @@ RSpec.describe SoapyBing::OauthCredentials do
|
|
|
49
52
|
|
|
50
53
|
context 'when no oauth credentials passed' do
|
|
51
54
|
let(:credentials) { { client_id: 'foo', client_secret: 'bar', refresh_token: 'baz' } }
|
|
55
|
+
|
|
52
56
|
before do
|
|
53
|
-
%w
|
|
57
|
+
%w[ BING_ADS_OAUTH_CLIENT_ID
|
|
54
58
|
BING_ADS_OAUTH_CLIENT_SECRET
|
|
55
|
-
BING_ADS_OAUTH_REFRESH_TOKEN
|
|
59
|
+
BING_ADS_OAUTH_REFRESH_TOKEN ].each do |var|
|
|
56
60
|
allow(ENV).to receive(:[]).with(var).and_return(nil)
|
|
57
61
|
end
|
|
58
62
|
end
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
RSpec.describe SoapyBing::ParamGuard do
|
|
3
4
|
describe '#require!' do
|
|
4
5
|
let(:param_guard) { described_class.new(options, env_namespace: 'MY') }
|
|
6
|
+
|
|
5
7
|
subject(:require_foo) { param_guard.require!(:foo) }
|
|
6
8
|
|
|
7
9
|
context 'when option is empty' do
|