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.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/Gemfile +1 -0
  4. data/README.md +18 -18
  5. data/Rakefile +1 -0
  6. data/lib/soapy_bing.rb +5 -1
  7. data/lib/soapy_bing/account.rb +1 -0
  8. data/lib/soapy_bing/accounts.rb +13 -17
  9. data/lib/soapy_bing/ads.rb +18 -41
  10. data/lib/soapy_bing/ads/campaign_performance_report.rb +49 -0
  11. data/lib/soapy_bing/ads/campaigns.rb +106 -0
  12. data/lib/soapy_bing/ads/parsers/bulk_csv_parser.rb +34 -0
  13. data/lib/soapy_bing/ads/parsers/report_csv_parser.rb +45 -0
  14. data/lib/soapy_bing/ads/report.rb +93 -0
  15. data/lib/soapy_bing/campaign_management.rb +21 -0
  16. data/lib/soapy_bing/country_codes.rb +17 -0
  17. data/lib/soapy_bing/country_codes.yml +727 -0
  18. data/lib/soapy_bing/customer.rb +1 -0
  19. data/lib/soapy_bing/helpers.rb +1 -1
  20. data/lib/soapy_bing/helpers/zip_downloader.rb +1 -0
  21. data/lib/soapy_bing/oauth_credentials.rb +1 -0
  22. data/lib/soapy_bing/param_guard.rb +1 -0
  23. data/lib/soapy_bing/service.rb +69 -0
  24. data/lib/soapy_bing/service_operation.rb +62 -0
  25. data/lib/soapy_bing/version.rb +2 -1
  26. data/lib/soapy_bing/wsdl/ad_insight.wsdl +1 -0
  27. data/lib/soapy_bing/wsdl/bulk.wsdl +1 -0
  28. data/lib/soapy_bing/wsdl/campaign_management.wsdl +1 -0
  29. data/lib/soapy_bing/wsdl/customer_billing.wsdl +1 -0
  30. data/lib/soapy_bing/wsdl/customer_management.wsdl +1 -0
  31. data/lib/soapy_bing/wsdl/reporting.wsdl +1 -0
  32. data/lib/tasks/console.rake +1 -0
  33. data/lib/tasks/coverage.rake +1 -0
  34. data/lib/tasks/spec.rake +1 -0
  35. data/lib/tasks/upate_wsdl_files.rake +23 -0
  36. data/lib/tasks/update_country_codes.rake +24 -0
  37. data/soapy_bing.gemspec +2 -1
  38. data/spec/fixtures/ads/campaign_performance_report.csv +37 -0
  39. data/spec/fixtures/ads/campaign_performance_report.json +170 -0
  40. data/spec/fixtures/ads/campaigns_by_account_id.csv +7 -0
  41. data/spec/fixtures/{bulk/campaigns.json → ads/campaigns_by_account_id.json} +496 -240
  42. data/spec/fixtures/ads/campaigns_by_campaign_ids.csv +5 -0
  43. data/spec/fixtures/ads/campaigns_by_campaign_ids.json +910 -0
  44. data/spec/fixtures/vcr_cassettes/SoapyBing_Accounts/_list/returns_a_list_of_SoapyBing_Account_objects.yml +27 -27
  45. data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_campaigns/by_account_id/returns_parsed_rows.yml +301 -0
  46. data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_campaigns/by_campaign_ids/returns_parsed_rows.yml +300 -0
  47. data/spec/fixtures/vcr_cassettes/SoapyBing_CampaignManagement/_get_geo_locations/returns_a_list_of_geo_locations_hashes.yml +154 -0
  48. data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_pending_status.yml +65 -94
  49. data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_successful_empty_response.yml +511 -0
  50. data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_successful_response.yml +384 -0
  51. data/spec/integration/soapy_bing/accounts_spec.rb +1 -0
  52. data/spec/integration/soapy_bing/ads_campaigns_spec.rb +85 -0
  53. data/spec/integration/soapy_bing/campaign_management_spec.rb +22 -0
  54. data/spec/integration/soapy_bing/oauth_credentials_spec.rb +1 -0
  55. data/spec/simplecov_setup.rb +1 -0
  56. data/spec/soapy_bing/account_spec.rb +6 -2
  57. data/spec/soapy_bing/accounts_spec.rb +47 -0
  58. data/spec/soapy_bing/ads/campaign_performance_report_spec.rb +79 -0
  59. data/spec/soapy_bing/ads/campaigns_spec.rb +99 -0
  60. data/spec/soapy_bing/ads/{bulk/parsers/csv_parser_spec.rb → parsers/bulk_csv_parser_spec.rb} +5 -4
  61. data/spec/soapy_bing/ads/{reports/parsers/csv_parser_spec.rb → parsers/report_csv_parser_spec.rb} +6 -4
  62. data/spec/soapy_bing/country_codes_spec.rb +39 -0
  63. data/spec/soapy_bing/helpers/zip_downloader_spec.rb +2 -0
  64. data/spec/soapy_bing/oauth_credentials_spec.rb +6 -2
  65. data/spec/soapy_bing/param_guard_spec.rb +2 -0
  66. data/spec/soapy_bing/service_spec.rb +56 -0
  67. data/spec/spec_helper.rb +1 -0
  68. data/spec/support/dotenv.rb +1 -0
  69. data/spec/support/vcr.rb +75 -6
  70. metadata +74 -118
  71. data/lib/soapy_bing/ads/bulk.rb +0 -3
  72. data/lib/soapy_bing/ads/bulk/campaigns.rb +0 -65
  73. data/lib/soapy_bing/ads/bulk/parsers.rb +0 -2
  74. data/lib/soapy_bing/ads/bulk/parsers/csv_parser.rb +0 -35
  75. data/lib/soapy_bing/ads/reports.rb +0 -4
  76. data/lib/soapy_bing/ads/reports/base.rb +0 -74
  77. data/lib/soapy_bing/ads/reports/campaign_performance_report.rb +0 -24
  78. data/lib/soapy_bing/ads/reports/parsers.rb +0 -2
  79. data/lib/soapy_bing/ads/reports/parsers/csv_parser.rb +0 -46
  80. data/lib/soapy_bing/helpers/class_name.rb +0 -10
  81. data/lib/soapy_bing/soap.rb +0 -4
  82. data/lib/soapy_bing/soap/request.rb +0 -10
  83. data/lib/soapy_bing/soap/request/base.rb +0 -38
  84. data/lib/soapy_bing/soap/request/download_campaigns_by_account_ids_request.rb +0 -17
  85. data/lib/soapy_bing/soap/request/get_accounts_info_request.rb +0 -17
  86. data/lib/soapy_bing/soap/request/get_ad_groups_by_campaign_id_request.rb +0 -17
  87. data/lib/soapy_bing/soap/request/get_ads_by_ad_group_id_request.rb +0 -17
  88. data/lib/soapy_bing/soap/request/get_bulk_download_status_request.rb +0 -17
  89. data/lib/soapy_bing/soap/request/get_targets_by_campaign_ids_request.rb +0 -17
  90. data/lib/soapy_bing/soap/request/poll_generate_report_request.rb +0 -34
  91. data/lib/soapy_bing/soap/request/submit_generate_report_request.rb +0 -17
  92. data/lib/soapy_bing/soap/response.rb +0 -14
  93. data/lib/soapy_bing/soap/response/base.rb +0 -17
  94. data/lib/soapy_bing/soap/response/download_campaigns_by_account_ids_response.rb +0 -12
  95. data/lib/soapy_bing/soap/response/get_accounts_info_response.rb +0 -12
  96. data/lib/soapy_bing/soap/response/get_ad_groups_by_campaign_id_response.rb +0 -12
  97. data/lib/soapy_bing/soap/response/get_ads_by_ad_group_id_response.rb +0 -12
  98. data/lib/soapy_bing/soap/response/get_bulk_download_status_response.rb +0 -17
  99. data/lib/soapy_bing/soap/response/get_targets_by_campaign_ids_response.rb +0 -12
  100. data/lib/soapy_bing/soap/response/payload.rb +0 -28
  101. data/lib/soapy_bing/soap/response/poll_generate_report_response.rb +0 -14
  102. data/lib/soapy_bing/soap/response/report_status.rb +0 -34
  103. data/lib/soapy_bing/soap/response/submit_generate_report_response.rb +0 -12
  104. data/lib/soapy_bing/soap/template_renderer.rb +0 -22
  105. data/lib/soapy_bing/soap/templates/download_campaigns_by_account_ids.xml.erb +0 -22
  106. data/lib/soapy_bing/soap/templates/get_accounts_info.xml.erb +0 -12
  107. data/lib/soapy_bing/soap/templates/get_ad_groups_by_campaign_id.xml.erb +0 -15
  108. data/lib/soapy_bing/soap/templates/get_ads_by_ad_group_id.xml.erb +0 -15
  109. data/lib/soapy_bing/soap/templates/get_bulk_download_status.xml.erb +0 -15
  110. data/lib/soapy_bing/soap/templates/get_targets_by_campaign_ids.xml.erb +0 -20
  111. data/lib/soapy_bing/soap/templates/poll_generate_report.xml.erb +0 -18
  112. data/lib/soapy_bing/soap/templates/submit_generate_report.xml.erb +0 -46
  113. data/spec/fixtures/bulk/campaigns.csv +0 -8
  114. data/spec/fixtures/get_ad_groups_by_campaign_id.json +0 -587
  115. data/spec/fixtures/get_ads_by_ad_group_id.json +0 -218
  116. data/spec/fixtures/get_targets_by_campaign_ids.json +0 -81
  117. data/spec/fixtures/reports/campaign_performance_report.csv +0 -37
  118. data/spec/fixtures/reports/campaign_performance_report.json +0 -146
  119. data/spec/fixtures/soap_templates/simple.xml.erb +0 -2
  120. data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_get_ad_groups_by_campaign_id/1_1_1.yml +0 -150
  121. data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_get_ads_by_ad_group_id/1_2_1.yml +0 -141
  122. data/spec/fixtures/vcr_cassettes/SoapyBing_Ads/_get_targets_by_campaign_ids/1_3_1.yml +0 -111
  123. data/spec/fixtures/vcr_cassettes/SoapyBing_Ads_Bulk_Campaigns/_result_file_url/returns_result_file_url.yml +0 -216
  124. data/spec/fixtures/vcr_cassettes/campaign_performance_report/with_successful_status.yml +0 -284
  125. data/spec/integration/soapy_bing/ads/bulk/campaigns_spec.rb +0 -35
  126. data/spec/integration/soapy_bing/ads/reports/campaign_performance_report_spec.rb +0 -40
  127. data/spec/integration/soapy_bing/ads_spec.rb +0 -32
  128. data/spec/soapy_bing/ads/reports/campaign_performance_report_spec.rb +0 -42
  129. data/spec/soapy_bing/ads_spec.rb +0 -33
  130. data/spec/soapy_bing/helpers/class_name_spec.rb +0 -15
  131. data/spec/soapy_bing/soap/request/base_spec.rb +0 -55
  132. data/spec/soapy_bing/soap/request/poll_generate_report_request_spec.rb +0 -60
  133. data/spec/soapy_bing/soap/response/base_spec.rb +0 -13
  134. data/spec/soapy_bing/soap/response/get_bulk_download_status_response_spec.rb +0 -60
  135. data/spec/soapy_bing/soap/response/payload_spec.rb +0 -48
  136. data/spec/soapy_bing/soap/response/poll_generate_report_response_spec.rb +0 -26
  137. data/spec/soapy_bing/soap/response/report_status_spec.rb +0 -92
  138. data/spec/soapy_bing/soap/response/submit_generate_report_response_spec.rb +0 -20
  139. 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
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  RSpec.describe SoapyBing::OauthCredentials do
3
4
  subject(:oauth_credentials) { described_class.new }
4
5
 
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  if ENV['CI'] || ENV['COVERAGE']
3
4
  require 'simplecov'
4
5
 
@@ -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( BING_ADS_DEVELOPER_TOKEN
59
+ %w[ BING_ADS_DEVELOPER_TOKEN
56
60
  BING_ADS_ACCOUNT_ID
57
- BING_ADS_CUSTOMER_ID ).each do |var|
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
@@ -1,19 +1,20 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require 'json'
3
4
 
4
- RSpec.describe SoapyBing::Ads::Bulk::Parsers::CSVParser do
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', 'bulk', 'campaigns.csv')
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', 'bulk', 'campaigns.json')
15
+ File.join('spec', 'fixtures', 'ads', 'campaigns_by_account_id.json')
15
16
  end
16
- let(:json_data) { JSON.load(File.read(json_fixture_path)) }
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
@@ -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::Reports::Parsers::CSVParser do
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', 'reports', 'campaign_performance_report.csv')
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', 'reports', 'campaign_performance_report.json')
17
+ File.join('spec', 'fixtures', 'ads', 'campaign_performance_report.json')
16
18
  end
17
- let(:json_data) { JSON.load(File.read(json_fixture_path)) }
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( BING_ADS_OAUTH_CLIENT_ID
57
+ %w[ BING_ADS_OAUTH_CLIENT_ID
54
58
  BING_ADS_OAUTH_CLIENT_SECRET
55
- BING_ADS_OAUTH_REFRESH_TOKEN ).each do |var|
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