sem4r 0.1.2 → 0.1.3

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 (175) hide show
  1. data/Gemfile +13 -2
  2. data/Gemfile.lock +13 -7
  3. data/README.rdoc +44 -7
  4. data/Rakefile +2 -122
  5. data/VERSION.yml +1 -1
  6. data/bin/sem +1 -0
  7. data/examples_sem4r/01_get_account.rb +1 -0
  8. data/examples_sem4r/02_get_info.rb +1 -0
  9. data/examples_sem4r/03_list_ad.rb +1 -0
  10. data/examples_sem4r/04_list_keywords.rb +1 -0
  11. data/examples_sem4r/05_request_report.rb +25 -14
  12. data/examples_sem4r/{05_request_report_2010.rb → 06_request_report_definition.rb} +2 -4
  13. data/examples_sem4r/{06_create_campaigns.rb → 07_create_campaigns.rb} +1 -0
  14. data/examples_sem4r/{07_create_campaigns_block.rb → 08_create_campaigns_block.rb} +1 -0
  15. data/examples_sem4r/{07_create_campaigns_simple.rb → 09_create_campaigns_simple.rb} +1 -0
  16. data/examples_sem4r/{08_ad_params.rb → 10_ad_params.rb} +1 -0
  17. data/examples_sem4r/{09_targeting_idea.rb → 11_targeting_idea.rb} +1 -0
  18. data/examples_sem4r/{10_get_location.rb → 12_get_location.rb} +1 -0
  19. data/examples_sem4r/{11_submit_bulk_job.rb → 13_submit_bulk_job.rb} +1 -1
  20. data/examples_sem4r/{12_list_bulk_job.rb → 14_list_bulk_job.rb} +3 -0
  21. data/examples_sem4r/30_prune_empty_adgroup.rb +1 -0
  22. data/examples_sem4r/31_empty_accounts.rb +1 -0
  23. data/examples_sem4r/example_helper.rb +2 -1
  24. data/lib/sem4r/ad_group/ad_group.rb +22 -7
  25. data/lib/sem4r/ad_group/ad_group_bids.rb +1 -1
  26. data/lib/sem4r/ad_group/ad_group_service.rb +12 -5
  27. data/lib/sem4r/ad_group_ad/ad_group_ad.rb +1 -0
  28. data/lib/sem4r/ad_group_ad/ad_group_ad_operations.rb +1 -0
  29. data/lib/sem4r/ad_group_ad/ad_group_ad_service.rb +14 -9
  30. data/lib/sem4r/ad_group_ad/ad_group_mobile_ad.rb +16 -25
  31. data/lib/sem4r/ad_group_ad/ad_group_text_ad.rb +18 -14
  32. data/lib/sem4r/ad_group_criterion/ad_group_criterion.rb +27 -19
  33. data/lib/sem4r/ad_group_criterion/ad_group_criterion_bids.rb +2 -1
  34. data/lib/sem4r/ad_group_criterion/ad_group_criterion_operations.rb +1 -0
  35. data/lib/sem4r/ad_group_criterion/ad_group_criterion_service.rb +9 -4
  36. data/lib/sem4r/ad_group_criterion/criterion.rb +1 -0
  37. data/lib/sem4r/ad_group_criterion/criterion_keyword.rb +1 -0
  38. data/lib/sem4r/ad_group_criterion/criterion_placement.rb +1 -0
  39. data/lib/sem4r/ad_param/ad_param.rb +24 -8
  40. data/lib/sem4r/ad_param/ad_param_service.rb +8 -5
  41. data/lib/sem4r/adwords.rb +232 -76
  42. data/lib/sem4r/base.rb +1 -1
  43. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job.rb +41 -35
  44. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_account_extension.rb +49 -15
  45. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_selector.rb +29 -20
  46. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_service.rb +13 -14
  47. data/lib/sem4r/bulk_mutate_job/job_operations.rb +1 -1
  48. data/lib/sem4r/campaign/campaign.rb +1 -0
  49. data/lib/sem4r/campaign/campaign_account_extension.rb +2 -1
  50. data/lib/sem4r/campaign/campaign_service.rb +9 -5
  51. data/lib/sem4r/credentials.rb +11 -5
  52. data/lib/sem4r/geo_location/address.rb +56 -0
  53. data/lib/sem4r/geo_location/geo_location_account_extension.rb +27 -6
  54. data/lib/sem4r/geo_location/geo_location_selector.rb +57 -0
  55. data/lib/sem4r/geo_location/geo_location_service.rb +9 -16
  56. data/lib/sem4r/info/info_account_extension.rb +3 -2
  57. data/lib/sem4r/info/info_selector.rb +2 -1
  58. data/lib/sem4r/info/info_service.rb +10 -3
  59. data/lib/sem4r/operation.rb +39 -20
  60. data/lib/sem4r/report_definition/report_definition.rb +37 -19
  61. data/lib/sem4r/report_definition/report_definition_account_extension.rb +66 -16
  62. data/lib/sem4r/report_definition/report_definition_operation.rb +2 -2
  63. data/lib/sem4r/report_definition/report_definition_selector.rb +1 -1
  64. data/lib/sem4r/report_definition/report_definition_service.rb +11 -7
  65. data/lib/sem4r/report_definition/report_field.rb +3 -2
  66. data/lib/sem4r/sem4r_templates.rb +77 -0
  67. data/lib/sem4r/{services/service.rb → service.rb} +23 -23
  68. data/lib/sem4r/targeting_idea/targeting_idea.rb +4 -4
  69. data/lib/sem4r/targeting_idea/targeting_idea_account_extension.rb +1 -1
  70. data/lib/sem4r/targeting_idea/targeting_idea_selector.rb +6 -6
  71. data/lib/sem4r/targeting_idea/targeting_idea_service.rb +7 -5
  72. data/lib/sem4r/v13_account/account_account_extension.rb +7 -10
  73. data/lib/sem4r/v13_account/account_service.rb +10 -4
  74. data/lib/sem4r/v13_account/billing_address.rb +2 -2
  75. data/lib/sem4r/v13_report/report_service.rb +11 -9
  76. data/lib/sem4r.rb +46 -31
  77. data/lib/{sem4r/cli → sem4r_cli}/cli_helpers.rb +3 -2
  78. data/lib/{sem4r/cli/cli_command.rb → sem4r_cli/cli_mini_framework.rb} +77 -32
  79. data/lib/{sem4r/cli/cli_common_args.rb → sem4r_cli/cli_sem.rb} +177 -157
  80. data/lib/{sem4r/cli/commands/cli_list_ads.rb → sem4r_cli/commands/cli_ads.rb} +7 -9
  81. data/lib/sem4r_cli/commands/cli_campaign.rb +69 -0
  82. data/lib/{sem4r/cli/commands/cli_list_client.rb → sem4r_cli/commands/cli_clients.rb} +2 -2
  83. data/lib/{sem4r/cli → sem4r_cli}/commands/cli_ideas.rb +35 -27
  84. data/lib/{sem4r/cli → sem4r_cli}/commands/cli_info.rb +3 -4
  85. data/lib/{sem4r/cli/commands/cli_repdef.rb → sem4r_cli/commands/cli_job.rb} +57 -55
  86. data/lib/{sem4r/cli/commands/cli_list_keywords.rb → sem4r_cli/commands/cli_keywords.rb} +14 -13
  87. data/lib/sem4r_cli/commands/cli_profile.rb +138 -0
  88. data/lib/{sem4r/cli/commands/cli_report.rb → sem4r_cli/commands/cli_repdef.rb} +67 -20
  89. data/lib/{sem4r/cli/commands/cli_request_report.rb → sem4r_cli/commands/cli_report.rb} +82 -19
  90. data/lib/sem4r_cli.rb +5 -7
  91. data/lib/sem4r_soap/http_connector.rb +206 -0
  92. data/lib/{soap_helpers → sem4r_soap}/soap_attributes.rb +8 -3
  93. data/lib/{sem4r/services → sem4r_soap}/soap_dumper.rb +36 -20
  94. data/lib/{sem4r/services → sem4r_soap}/soap_error.rb +5 -2
  95. data/lib/sem4r_soap/soap_response.rb +75 -0
  96. data/lib/sem4r_soap/soap_service.rb +137 -0
  97. data/lib/{sem4r/cli/cli_sem.rb → sem4r_soap/soap_service_v13.rb} +27 -28
  98. data/lib/sem4r_soap/soap_service_v2010.rb +80 -0
  99. data/lib/sem4r_soap.rb +17 -0
  100. data/sem4r.gemspec +93 -58
  101. data/spec/build_fixtures.rb +49 -42
  102. data/spec/fixtures/password.example.yml +3 -0
  103. data/spec/fixtures/sem4r.example.yml +6 -0
  104. data/spec/fixtures/{services/error.xml → soap_error.xml} +0 -0
  105. data/spec/fixtures/soap_error2.xml +29 -0
  106. data/spec/helpers/dump_interceptor.rb +90 -0
  107. data/spec/helpers/fixtures_bulk_mutate_job.rb +48 -0
  108. data/spec/helpers/fixtures_geo_location.rb +45 -0
  109. data/{lib/sem4r/campaign_criterion/campaign_criterion_service.rb → spec/helpers/fixtures_info.rb} +10 -6
  110. data/spec/helpers/fixtures_report_definition.rb +65 -0
  111. data/spec/{rspec_hash.rb → helpers/rspec_hash.rb} +1 -0
  112. data/spec/{rspec_matchers.rb → helpers/rspec_matchers.rb} +46 -19
  113. data/spec/{rspec_sem4r_helper.rb → helpers/rspec_sem4r_helper.rb} +19 -16
  114. data/spec/{sem4r_stubs.rb → helpers/sem4r_stubs.rb} +5 -4
  115. data/spec/rspec_helper.rb +4 -4
  116. data/spec/sem4r/account_spec.rb +2 -3
  117. data/spec/sem4r/ad_group/ad_group_service_spec.rb +1 -1
  118. data/spec/sem4r/ad_group/ad_group_spec.rb +1 -1
  119. data/spec/sem4r/ad_group_ad/ad_group_ad_operation_spec.rb +3 -3
  120. data/spec/sem4r/adwords_spec.rb +62 -39
  121. data/{lib/sem4r/cli/commands/cli_list_campaign.rb → spec/sem4r/bulk_mutate_job/bulk_mutate_job_selector_spec.rb} +14 -11
  122. data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_service_spec.rb +2 -3
  123. data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_spec.rb +23 -17
  124. data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-req.xml +35 -0
  125. data/spec/sem4r/bulk_mutate_job/fixtures/get-list_job-res.xml +417 -0
  126. data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-req.xml +106 -0
  127. data/spec/sem4r/bulk_mutate_job/fixtures/mutate-add_job-res.xml +48 -0
  128. data/spec/sem4r/bulk_mutate_job/job_operation_spec.rb +5 -7
  129. data/spec/sem4r/campaign/campaign_service_spec.rb +2 -2
  130. data/spec/sem4r/credentials_spec.rb +10 -8
  131. data/spec/sem4r/geo_location/address_spec.rb +62 -0
  132. data/spec/sem4r/geo_location/fixtures/get-req.xml +42 -0
  133. data/spec/sem4r/geo_location/fixtures/get-res.xml +60 -0
  134. data/spec/sem4r/info/fixtures/get-req.xml +34 -0
  135. data/spec/sem4r/info/fixtures/get-res.xml +27 -0
  136. data/spec/sem4r/nokogiri_parsing_spec.rb +1 -0
  137. data/spec/sem4r/operation_spec.rb +72 -0
  138. data/spec/sem4r/report_definition/fixtures/get-list-repdef-req.xml +22 -0
  139. data/spec/sem4r/report_definition/fixtures/get-list-repdef-res.xml +73 -0
  140. data/spec/sem4r/report_definition/fixtures/getReportFields-req.xml +24 -0
  141. data/spec/sem4r/report_definition/fixtures/getReportFields-res.xml +1199 -0
  142. data/spec/sem4r/report_definition/fixtures/mutate-add-report-req.xml +63 -0
  143. data/spec/sem4r/report_definition/fixtures/mutate-add-report-res.xml +68 -0
  144. data/spec/sem4r/report_definition/report_definition_service_spec.rb +5 -5
  145. data/spec/sem4r/report_definition/report_definition_spec.rb +28 -43
  146. data/{lib/sem4r/cli/commands/cli_list_report.rb → spec/sem4r/report_definition/report_field_spec.rb} +12 -10
  147. data/spec/sem4r/rexml_parsing_spec.rb +1 -0
  148. data/spec/sem4r/{services/service_spec.rb → service_spec.rb} +1 -1
  149. data/spec/sem4r/targeting_idea/targeting_idea_selector_spec.rb +1 -1
  150. data/spec/sem4r/targeting_idea/targeting_idea_service_spec.rb +1 -1
  151. data/spec/sem4r/targeting_idea/targeting_idea_spec.rb +1 -1
  152. data/spec/sem4r/v13_account/account_service_spec.rb +2 -2
  153. data/spec/sem4r/v13_report/report_service_spec.rb +2 -2
  154. data/spec/{sem4r/cli → sem4r_cli}/cli_spec.rb +22 -27
  155. data/spec/{soap_helpers → sem4r_soap}/soap_attributes_spec.rb +3 -3
  156. data/spec/{sem4r/services/soap_message_v13_spec.rb → sem4r_soap/soap_response_spec.rb} +10 -15
  157. data/spec/{sem4r/services/soap_call_spec.rb → sem4r_soap/soap_service_spec.rb} +35 -54
  158. data/tasks/jeweler.rake +66 -0
  159. data/tasks/rspec.rake +21 -0
  160. data/tasks/sem4r.rake +25 -0
  161. data/tasks/yard.rake +31 -0
  162. metadata +173 -76
  163. data/lib/sem4r/ad_extension_override/ad_extension_override_service.rb +0 -30
  164. data/lib/sem4r/api_counters.rb +0 -8
  165. data/lib/sem4r/campaign_target/campaign_target_service.rb +0 -30
  166. data/lib/sem4r/cli/commands/cli_download_report.rb +0 -82
  167. data/lib/sem4r/services/http_connector.rb +0 -93
  168. data/lib/sem4r/services/soap_call.rb +0 -122
  169. data/lib/sem4r/services/soap_connector.rb +0 -139
  170. data/lib/sem4r/services/soap_message_v13.rb +0 -135
  171. data/lib/sem4r/services/soap_message_v2010.rb +0 -184
  172. data/lib/sem4r/v13_traffic_estimator/traffic_estimator_service.rb +0 -30
  173. data/spec/aggregates_rspec_helper.rb +0 -59
  174. data/spec/sem4r/report_definition/fixtures/mutate_add-req.xml +0 -24
  175. data/spec/sem4r/report_definition/fixtures/mutate_add-req_orig.xml +0 -45
@@ -0,0 +1,106 @@
1
+ <!-- Post to 'https://adwords-sandbox.google.com/api/adwords/job/v201008/BulkMutateJobService' -->
2
+
3
+ <env:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' xmlns='https://adwords.google.com/api/adwords/cm/v201008' xmlns:s='https://adwords.google.com/api/adwords/cm/v201008'>
4
+ <env:Header>
5
+ <s:RequestHeader env:mustUnderstand='0'>
6
+ <authToken>
7
+ ***censured***
8
+ </authToken>
9
+ <userAgent>
10
+ Sem4r Adwords Ruby Client Library (http://github.com/sem4r/sem4r)
11
+ </userAgent>
12
+ <developerToken>
13
+ ***censured***
14
+ </developerToken>
15
+ </s:RequestHeader>
16
+ </env:Header>
17
+ <env:Body>
18
+ <mutate xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
19
+ <operation xsi:type='JobOperation'>
20
+ <operator>
21
+ ADD
22
+ </operator>
23
+ <operand xsi:type='BulkMutateJob'>
24
+ <request>
25
+ <partIndex>
26
+ 0
27
+ </partIndex>
28
+ <operationStreams>
29
+ <scopingEntityId>
30
+ <type>
31
+ CAMPAIGN_ID
32
+ </type>
33
+ <value>
34
+ 49247
35
+ </value>
36
+ </scopingEntityId>
37
+ <operations xsi:type='AdGroupAdOperation'>
38
+ <operator>
39
+ ADD
40
+ </operator>
41
+ <operand xsi:type='AdGroupAd'>
42
+ <adGroupId>
43
+ 3000128685
44
+ </adGroupId>
45
+ <ad xsi:type='TextAd'>
46
+ <url>
47
+ http://www.example.com
48
+ </url>
49
+ <displayUrl>
50
+ www.example.com
51
+ </displayUrl>
52
+ <headline>
53
+ Cruise to Mars Sector 1
54
+ </headline>
55
+ <description1>
56
+ Visit the Red Planet in style.
57
+ </description1>
58
+ <description2>
59
+ Low-gravity fun for everyone!
60
+ </description2>
61
+ </ad>
62
+ <status>
63
+ ENABLED
64
+ </status>
65
+ </operand>
66
+ </operations>
67
+ <operations xsi:type='AdGroupAdOperation'>
68
+ <operator>
69
+ ADD
70
+ </operator>
71
+ <operand xsi:type='AdGroupAd'>
72
+ <adGroupId>
73
+ 3000128685
74
+ </adGroupId>
75
+ <ad xsi:type='TextAd'>
76
+ <url>
77
+ http://www.example.com
78
+ </url>
79
+ <displayUrl>
80
+ www.example.com
81
+ </displayUrl>
82
+ <headline>
83
+ Cruise to Mars Sector 2
84
+ </headline>
85
+ <description1>
86
+ Visit the Red Planet in style.
87
+ </description1>
88
+ <description2>
89
+ Low-gravity fun for everyone!
90
+ </description2>
91
+ </ad>
92
+ <status>
93
+ ENABLED
94
+ </status>
95
+ </operand>
96
+ </operations>
97
+ </operationStreams>
98
+ </request>
99
+ <numRequestParts>
100
+ 2
101
+ </numRequestParts>
102
+ </operand>
103
+ </operation>
104
+ </mutate>
105
+ </env:Body>
106
+ </env:Envelope>
@@ -0,0 +1,48 @@
1
+ <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
2
+ <soap:Header>
3
+ <ResponseHeader xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
4
+ <requestId>
5
+ ecb7c017cc5a5b383577e2f05779ba29
6
+ </requestId>
7
+ <operations>
8
+ 1
9
+ </operations>
10
+ <responseTime>
11
+ 1109
12
+ </responseTime>
13
+ <units>
14
+ 1
15
+ </units>
16
+ </ResponseHeader>
17
+ </soap:Header>
18
+ <soap:Body>
19
+ <mutateResponse xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
20
+ <rval>
21
+ <context>
22
+ <authenticatedUserEmail>
23
+ sem4ruby@gmail.com
24
+ </authenticatedUserEmail>
25
+ <effectiveCustomerId>
26
+ 0
27
+ </effectiveCustomerId>
28
+ </context>
29
+ <Job.Type>
30
+ BulkMutateJob
31
+ </Job.Type>
32
+ <id>
33
+ 39169
34
+ </id>
35
+ <policy/>
36
+ <status>
37
+ PENDING
38
+ </status>
39
+ <numRequestParts>
40
+ 2
41
+ </numRequestParts>
42
+ <numRequestPartsReceived>
43
+ 1
44
+ </numRequestPartsReceived>
45
+ </rval>
46
+ </mutateResponse>
47
+ </soap:Body>
48
+ </soap:Envelope>
@@ -26,21 +26,19 @@
26
26
  require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
27
27
 
28
28
  describe JobOperation do
29
- include Sem4rSpecHelper, AggregatesSpecHelper
30
-
29
+ include Sem4rSpecHelper
31
30
 
32
31
  it "should produce xml" do
33
32
  @campaign = mock("campaign").as_null_object
34
33
  @campaign.stub(:id).and_return(100)
35
34
 
36
- @adgroup = mock("adgroup").as_null_object
37
- @adgroup.stub(:id).and_return(3060284754)
35
+ @ad_group = mock("adgroup").as_null_object
36
+ @ad_group.stub(:id).and_return(3060284754)
38
37
 
39
- bulk_mutate_job = create_bulk_mutate_job(@campaign, @adgroup)
38
+ bulk_mutate_job = template_bulk_mutate_job(@campaign, @ad_group)
40
39
  bulk_mutate_job.should_not be_empty
41
40
 
42
- job_operation = JobOperation.new
43
- job_operation.add(bulk_mutate_job)
41
+ job_operation = JobOperation.add(bulk_mutate_job)
44
42
 
45
43
  expected_xml = read_model("//operation", "bulk_mutate_job", "mutate-req.xml")
46
44
  job_operation.to_xml('operation').should xml_equivalent(expected_xml)
@@ -37,7 +37,7 @@ describe CampaignService do
37
37
  connector = mock("connector")
38
38
  connector.should_receive(:send).and_return(response_xml)
39
39
  service = CampaignService.new(connector)
40
- soap_message = service.all( @credentials )
40
+ soap_message = service.all(@credentials)
41
41
  els = soap_message.response.xpath("//getResponse")
42
42
  els.should_not be_empty
43
43
  end
@@ -59,7 +59,7 @@ describe CampaignService do
59
59
  connector = mock("connector")
60
60
  connector.should_receive(:send).and_return(response_xml)
61
61
  service = CampaignService.new(connector)
62
- soap_message = service.delete( @credentials, "xml" )
62
+ soap_message = service.delete(@credentials, "xml" )
63
63
  els = soap_message.response.xpath("//mutateResponse")
64
64
  els.should_not be_empty
65
65
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -27,7 +28,7 @@ require File.dirname(__FILE__) + '/../rspec_helper'
27
28
  describe Credentials do
28
29
 
29
30
  before do
30
- @opts = {
31
+ @credentials_options = {
31
32
  :environment => "sandbox",
32
33
  :email => "email",
33
34
  :password => "password",
@@ -35,7 +36,7 @@ describe Credentials do
35
36
  end
36
37
 
37
38
  it "should have getter" do
38
- credentials = Credentials.new(@opts)
39
+ credentials = Credentials.new(@credentials_options)
39
40
 
40
41
  credentials.email.should == "email"
41
42
  credentials.password.should == "password"
@@ -44,20 +45,21 @@ describe Credentials do
44
45
  end
45
46
 
46
47
  it "should be mutable" do
47
- @opts[:mutable] = true
48
- credentials = Credentials.new(@opts)
48
+ @credentials_options[:mutable] = true
49
+ credentials = Credentials.new(@credentials_options)
49
50
  credentials.should be_mutable
50
51
  end
51
52
 
52
53
  it "requests authentication token should raise an exception without connector" do
53
- credentials = Credentials.new(@opts)
54
+ credentials = Credentials.new(@credentials_options)
54
55
  lambda { credentials.authentication_token }.should raise_error
55
56
  end
56
57
 
57
58
  it "should call connector when request for an authentication token" do
58
- credentials = Credentials.new(@opts)
59
- connector = SoapConnector.new
60
- connector.should_receive(:authentication_token).and_return("auth_token")
59
+ connector = Sem4rSoap::HttpConnector.get
60
+ connector.should_receive(:post).and_return(double( :code => "200", :status => 200, :body => "Auth=auth_token") )
61
+
62
+ credentials = Credentials.new(@credentials_options)
61
63
  credentials.connector= connector
62
64
  credentials.authentication_token.should == "auth_token"
63
65
  end
@@ -0,0 +1,62 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -------------------------------------------------------------------------
3
+ # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #
24
+ # -------------------------------------------------------------------------
25
+
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
27
+
28
+ describe Address do
29
+ include Sem4rSpecHelper
30
+
31
+ it "should accept multiple address" do
32
+ selector = GeoLocationSelector.new
33
+ selector.address do
34
+ city "Pisa"
35
+ country "IT"
36
+ end
37
+ selector.address do
38
+ address "Via Nazionale, 10"
39
+ city "Rome"
40
+ country "IT"
41
+ end
42
+ selector.should have(2).addresses
43
+ end
44
+
45
+ it "should build xml (input for google)" do
46
+ address = Address.new do
47
+ address "Via Nazionale, 10"
48
+ city "Rome"
49
+ country "IT"
50
+ end
51
+ xml_expected = read_model("//addresses", "geo_location", "get-req.xml")
52
+ address.should xml_equivalent(xml_expected)
53
+ end
54
+
55
+ it "should parse xml (produced by google)" do
56
+ model = read_model("//address", "geo_location", "get-res.xml")
57
+ address = Address.from_element(model)
58
+ address.city.should == "Roma"
59
+ address.postal_code == "00184"
60
+ end
61
+
62
+ end
@@ -0,0 +1,42 @@
1
+ <!-- Post to 'https://adwords-sandbox.google.com/api/adwords/cm/v201008/GeoLocationService' -->
2
+
3
+ <env:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' xmlns='https://adwords.google.com/api/adwords/cm/v201008' xmlns:s='https://adwords.google.com/api/adwords/cm/v201008'>
4
+ <env:Header>
5
+ <s:RequestHeader env:mustUnderstand='0'>
6
+ <authToken>
7
+ ***censured***
8
+ </authToken>
9
+ <userAgent>
10
+ Sem4r Adwords Ruby Client Library (http://github.com/sem4r/sem4r)
11
+ </userAgent>
12
+ <developerToken>
13
+ ***censured***
14
+ </developerToken>
15
+ </s:RequestHeader>
16
+ </env:Header>
17
+ <env:Body>
18
+ <s:get>
19
+ <s:selector>
20
+ <addresses>
21
+ <streetAddress>
22
+ Via Nazionale, 10
23
+ </streetAddress>
24
+ <cityName>
25
+ Rome
26
+ </cityName>
27
+ <countryCode>
28
+ IT
29
+ </countryCode>
30
+ </addresses>
31
+ <addresses>
32
+ <cityName>
33
+ Pisa
34
+ </cityName>
35
+ <countryCode>
36
+ IT
37
+ </countryCode>
38
+ </addresses>
39
+ </s:selector>
40
+ </s:get>
41
+ </env:Body>
42
+ </env:Envelope>
@@ -0,0 +1,60 @@
1
+ <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
2
+ <soap:Header>
3
+ <ResponseHeader xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
4
+ <requestId>
5
+ 2f46eb41f5046946b248683b45a159fb
6
+ </requestId>
7
+ <operations>
8
+ 2
9
+ </operations>
10
+ <responseTime>
11
+ 162
12
+ </responseTime>
13
+ <units>
14
+ 2
15
+ </units>
16
+ </ResponseHeader>
17
+ </soap:Header>
18
+ <soap:Body>
19
+ <getResponse xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
20
+ <rval>
21
+ <geoPoint>
22
+ <latitudeInMicroDegrees>
23
+ 41901464
24
+ </latitudeInMicroDegrees>
25
+ <longitudeInMicroDegrees>
26
+ 12494510
27
+ </longitudeInMicroDegrees>
28
+ </geoPoint>
29
+ <address>
30
+ <streetAddress>
31
+ Via Nazionale, 10
32
+ </streetAddress>
33
+ <cityName>
34
+ Roma
35
+ </cityName>
36
+ <provinceCode>
37
+ Lazio
38
+ </provinceCode>
39
+ <postalCode>
40
+ 00184
41
+ </postalCode>
42
+ <countryCode>
43
+ IT
44
+ </countryCode>
45
+ </address>
46
+ <encodedLocation>
47
+ qrvM3QDB3iJsoW5CCm5ELDnrheCfJDpb74yQwvnJlSeV2uWWM7SqEqhwvlaHnOM383ATHFNQRP9+vLgh5ZhGfUhZ7NSmi+eP68KgvuxciuTnoDePQNB14CXChk7/x2h+p01JSnpiHBosblWjonSiBZqdRAeFcqd7jmst7t3qnwCs7PYyXBOKw47hxdiiVPHxagzknR8mvhhR1XjYzfeDS7nZDDAyRFs3x1l7Eq7VG2uNXz0T25VpFEhJfbjXee0c2YbkwcTZJnZLSRKBvyvuudu7oyw2OwSARrTNDnT1gubbhFvThThB1sXIvaHPRlirQDuKHOw9Jdn31LS/wNuxl7OZgV5w631hTdHS/dZUiPTpd2AbGDOMEoPRfdUpkrVQ1fDFXswqXlwgWPVTlrK/B3TVoFR/emc7TztipecXqA9YSc6tMQzJ5IAONn8ZpzLV2tLnpb/s2Zx0y+uEofWTfCvfS5LJ9MFtCobL+x/j99jBpG48wf/4UPGAFuN3Hsa5ZIsgP5J5n85xJmCKtmFhJM+tdnBfXFEhW9egjchy/Optt+2cJzdmAXiPfnsBY5YWGixI12WETHstsvkkZw==
48
+ </encodedLocation>
49
+ <GeoLocation.Type>
50
+ GeoLocation
51
+ </GeoLocation.Type>
52
+ </rval>
53
+ <rval xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:type='InvalidGeoLocation'>
54
+ <GeoLocation.Type>
55
+ InvalidGeoLocation
56
+ </GeoLocation.Type>
57
+ </rval>
58
+ </getResponse>
59
+ </soap:Body>
60
+ </soap:Envelope>
@@ -0,0 +1,34 @@
1
+ <!-- Post to 'https://adwords-sandbox.google.com/api/adwords/info/v201008/InfoService' -->
2
+
3
+ <env:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' xmlns='https://adwords.google.com/api/adwords/cm/v201008' xmlns:s='https://adwords.google.com/api/adwords/info/v201008'>
4
+ <env:Header>
5
+ <s:RequestHeader env:mustUnderstand='0'>
6
+ <authToken>
7
+ ***censured***
8
+ </authToken>
9
+ <userAgent>
10
+ Sem4r Adwords Ruby Client Library (http://github.com/sem4r/sem4r)
11
+ </userAgent>
12
+ <developerToken>
13
+ ***censured***
14
+ </developerToken>
15
+ </s:RequestHeader>
16
+ </env:Header>
17
+ <env:Body>
18
+ <s:get>
19
+ <s:selector>
20
+ <s:dateRange>
21
+ <min>
22
+ 20100101
23
+ </min>
24
+ <max>
25
+ 20101209
26
+ </max>
27
+ </s:dateRange>
28
+ <s:apiUsageType>
29
+ UNIT_COUNT
30
+ </s:apiUsageType>
31
+ </s:selector>
32
+ </s:get>
33
+ </env:Body>
34
+ </env:Envelope>
@@ -0,0 +1,27 @@
1
+ <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
2
+ <soap:Header>
3
+ <ResponseHeader xmlns:ns2='https://adwords.google.com/api/adwords/cm/v201008' xmlns='https://adwords.google.com/api/adwords/info/v201008'>
4
+ <ns2:requestId>
5
+ ac3eeab49b24416052180a26eab9e1ba
6
+ </ns2:requestId>
7
+ <ns2:operations>
8
+ 1
9
+ </ns2:operations>
10
+ <ns2:responseTime>
11
+ 171
12
+ </ns2:responseTime>
13
+ <ns2:units>
14
+ 1
15
+ </ns2:units>
16
+ </ResponseHeader>
17
+ </soap:Header>
18
+ <soap:Body>
19
+ <getResponse xmlns='https://adwords.google.com/api/adwords/info/v201008' xmlns:ns2='https://adwords.google.com/api/adwords/cm/v201008'>
20
+ <rval>
21
+ <cost>
22
+ 0
23
+ </cost>
24
+ </rval>
25
+ </getResponse>
26
+ </soap:Body>
27
+ </soap:Envelope>
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -0,0 +1,72 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -------------------------------------------------------------------------
3
+ # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ # -------------------------------------------------------------------------
24
+
25
+ require File.expand_path(File.dirname(__FILE__) + '/../rspec_helper')
26
+
27
+ describe Operation do
28
+ include Sem4rSpecHelper
29
+
30
+ class MyOperand
31
+
32
+ def _xml(t)
33
+ t.hello
34
+ end
35
+
36
+ def xml(t, tag = nil)
37
+ if tag
38
+ t.__send__(tag, {"xsi:type"=>'MyOperand'}) { |t| _xml(t) }
39
+ else
40
+ _xml(t)
41
+ end
42
+ end
43
+
44
+ def to_xml(tag)
45
+ xml(Builder::XmlMarkup.new, tag)
46
+ end
47
+ end
48
+
49
+ it "should marshal in xml (operation.to_xml)" do
50
+ op = Operation.add(MyOperand.new)
51
+ op.to_xml.should == "<operations><operator>ADD</operator><operand xsi:type=\"MyOperand\"><hello/></operand></operations>"
52
+ end
53
+
54
+ it "should marshal in xml by builder (operation.xml)" do
55
+ op = Operation.add(MyOperand.new)
56
+ builder = Builder::XmlMarkup.new
57
+ xml = builder.tag!("top") { |t| op.xml(t) }
58
+ xml.should == "<top><operator>ADD</operator><operand xsi:type=\"MyOperand\"><hello/></operand></top>"
59
+ end
60
+
61
+ it "should add attributes to the top tag" do
62
+ op = Operation.add(MyOperand.new)
63
+ op.instance_eval { @attrs = {"a" => "b"} }
64
+ op.to_xml.should == "<operations a=\"b\"><operator>ADD</operator><operand xsi:type=\"MyOperand\"><hello/></operand></operations>"
65
+ end
66
+
67
+ it "should add attribute type to the top tag" do
68
+ op = Operation.add(MyOperand.new)
69
+ op.instance_eval { @operation_type = "foo" }
70
+ op.to_xml.should == "<operations xsi:type=\"foo\"><operator>ADD</operator><operand xsi:type=\"MyOperand\"><hello/></operand></operations>"
71
+ end
72
+ end
@@ -0,0 +1,22 @@
1
+ <!-- Post to 'https://adwords-sandbox.google.com/api/adwords/cm/v201008/ReportDefinitionService' -->
2
+
3
+ <env:Envelope xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:env='http://schemas.xmlsoap.org/soap/envelope/' xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
4
+ <env:Header>
5
+ <RequestHeader env:mustUnderstand='0'>
6
+ <authToken>
7
+ ***censured***
8
+ </authToken>
9
+ <userAgent>
10
+ Sem4r Adwords Ruby Client Library (http://github.com/sem4r/sem4r)
11
+ </userAgent>
12
+ <developerToken>
13
+ ***censured***
14
+ </developerToken>
15
+ </RequestHeader>
16
+ </env:Header>
17
+ <env:Body>
18
+ <get>
19
+ <selector/>
20
+ </get>
21
+ </env:Body>
22
+ </env:Envelope>
@@ -0,0 +1,73 @@
1
+ <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>
2
+ <soap:Header>
3
+ <ResponseHeader xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
4
+ <requestId>
5
+ 7839692e0e3dcacb217c8e8aac710566
6
+ </requestId>
7
+ <operations>
8
+ 1
9
+ </operations>
10
+ <responseTime>
11
+ 245
12
+ </responseTime>
13
+ <units>
14
+ 1
15
+ </units>
16
+ </ResponseHeader>
17
+ </soap:Header>
18
+ <soap:Body>
19
+ <getResponse xmlns='https://adwords.google.com/api/adwords/cm/v201008'>
20
+ <rval>
21
+ <entries>
22
+ <id>
23
+ 9257
24
+ </id>
25
+ <selector>
26
+ <fields>
27
+ AdGroupId
28
+ </fields>
29
+ <fields>
30
+ Id
31
+ </fields>
32
+ <fields>
33
+ KeywordText
34
+ </fields>
35
+ <fields>
36
+ KeywordMatchType
37
+ </fields>
38
+ <fields>
39
+ Impressions
40
+ </fields>
41
+ <fields>
42
+ Clicks
43
+ </fields>
44
+ <fields>
45
+ Cost
46
+ </fields>
47
+ </selector>
48
+ <reportName>
49
+ Keywords performance report #1290336379254
50
+ </reportName>
51
+ <reportType>
52
+ KEYWORDS_PERFORMANCE_REPORT
53
+ </reportType>
54
+ <hasAttachment>
55
+ false
56
+ </hasAttachment>
57
+ <dateRangeType>
58
+ LAST_WEEK
59
+ </dateRangeType>
60
+ <downloadFormat>
61
+ CSV
62
+ </downloadFormat>
63
+ <creationTime>
64
+ 20101210 105826 America/Los_Angeles
65
+ </creationTime>
66
+ </entries>
67
+ <totalNumEntries>
68
+ 1
69
+ </totalNumEntries>
70
+ </rval>
71
+ </getResponse>
72
+ </soap:Body>
73
+ </soap:Envelope>