sem4r 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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,48 @@
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
+ module FixtureBulkMutateJob
26
+
27
+ def fixtures_bulk_mutate_job
28
+ @dump_interceptor.reset_and_stop
29
+ account = @adwords.account
30
+
31
+ campaign, ad_group = template_campaign_and_ad_group(account)
32
+
33
+ intercept("mutate-add_job") {
34
+ job = template_bulk_mutate_job(campaign, ad_group)
35
+ job.num_parts = 2 # create a pending job, so it is possible to see in list
36
+ result_job = account.job_mutate(JobOperation.add(job))
37
+ puts result_job.to_s
38
+ }
39
+
40
+ intercept("get-list_job") {
41
+ account.p_jobs
42
+ }
43
+
44
+ @dump_interceptor.intercept_to("report_definition", "getReportFields-{type}.xml")
45
+ @dump_interceptor.stop
46
+ end
47
+
48
+ end
@@ -0,0 +1,45 @@
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
+ module FixtureGeoLocation
26
+
27
+ def fixtures_geo_location
28
+ @dump_interceptor.reset_and_stop
29
+
30
+ intercept("get") {
31
+ selector = GeoLocationSelector.new
32
+ selector.address do
33
+ address "Via Nazionale, 10"
34
+ city "Rome"
35
+ country "IT"
36
+ end
37
+ selector.address do
38
+ city "Pisa"
39
+ country "IT"
40
+ end
41
+ @adwords.account.geo_location(selector)
42
+ }
43
+ end
44
+
45
+ end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -21,10 +22,13 @@
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23
  # -------------------------------------------------------------------
23
24
 
24
- module Sem4r
25
- class CampaignCriterionService
26
- def initialize
27
-
28
- end
25
+ module FixtureInfo
26
+
27
+ def fixtures_info
28
+ @dump_interceptor.reset_and_stop
29
+ intercept("get") {
30
+ @adwords.account.year_unit_cost(InfoSelector::UNIT_COUNT)
31
+ }
29
32
  end
30
- end
33
+
34
+ end
@@ -0,0 +1,65 @@
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
+ module FixtureReportDefinition
26
+
27
+ def fixtures_report_definition
28
+ account = @adwords.account
29
+
30
+ @dump_interceptor.reset_and_start
31
+
32
+ @dump_interceptor.intercept_to("report_definition", "getReportFields")
33
+ account.report_fields(ReportDefinition::KEYWORDS_PERFORMANCE_REPORT)
34
+
35
+ @dump_interceptor.stop
36
+ account.report_definition_delete_all
37
+
38
+
39
+ @dump_interceptor.start
40
+ @dump_interceptor.intercept_to("report_definition", "mutate-add-report")
41
+
42
+ rd = account.report_definition do
43
+ name "Keywords performance report #1290336379254"
44
+ type "KEYWORDS_PERFORMANCE_REPORT"
45
+ date_range "LAST_WEEK"
46
+ format "CSV"
47
+
48
+ field "AdGroupId"
49
+ field "Id"
50
+ field "KeywordText"
51
+ field "KeywordMatchType"
52
+ field "Impressions"
53
+ field "Clicks"
54
+ field "Cost"
55
+ end
56
+ rd.save
57
+ puts "created report id #{rd.id}"
58
+
59
+ @dump_interceptor.intercept_to("report_definition", "get-list-repdef")
60
+ account.report_definitions(true)
61
+
62
+ @dump_interceptor.stop
63
+ end
64
+
65
+ end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,20 +20,25 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  require 'rexml/document'
26
26
  require 'differ'
27
27
  require 'differ/string'
28
28
 
29
+ # comparing xml is always a b-i-a-t-c-h in any testing environment. here is a
30
+ # little snippet for ruby that, i think, it a good first pass at making it
31
+ # easier. comment with your improvements please!
32
+ #
33
+ # http://drawohara.com/post/89110816/ruby-comparing-xml
34
+
29
35
  def pretty_xml(xml)
30
36
  normalized = Class.new(REXML::Formatters::Pretty) do
31
37
  def write_text(node, output)
32
38
  super(node.to_s.strip, output)
33
39
  end
34
40
  end
35
- normalized.new(0,false).write(xml, xml_pretty='')
41
+ normalized.new(0, false).write(xml, xml_pretty='')
36
42
  xml_pretty
37
43
  end
38
44
 
@@ -43,7 +49,7 @@ def normalize_xml(expected_xml)
43
49
 
44
50
  if expected_xml.class == String
45
51
  # erase namespaces i.e. <ns1:tag> -> <tag>
46
- expected_xml = expected_xml.gsub(/\b(ns\d:|xsi:|s:|soapenv:|env:|soap:|^\n)/, "").strip
52
+ expected_xml = expected_xml.gsub(/\b(ns\d:|xsi:|s:|soapenv:|env:|soap:|^\n)/, "").strip
47
53
  begin
48
54
  expected_xml = REXML::Document.new(expected_xml)
49
55
  rescue RuntimeError
@@ -60,28 +66,28 @@ end
60
66
 
61
67
  def diff_xml(expected_xml, xml)
62
68
  expected_normalized = normalize_xml(expected_xml)
63
- xml_normalized = normalize_xml(xml)
69
+ xml_normalized = normalize_xml(xml)
64
70
 
65
- if xml_normalized != expected_normalized
66
- puts "----differ start"
71
+ if xml_normalized == expected_normalized
72
+ return nil
73
+ end
74
+ str = "--- this xml \n"
75
+ str << xml_normalized
76
+ str << "\n--- expected to be equals to\n"
77
+ str << expected_normalized
67
78
 
68
- puts xml_normalized
79
+ str << "\n--- difference are:\n"
69
80
 
70
- puts "---"
71
- puts expected_normalized
72
- puts "---"
73
- diff = Differ.diff_by_line(xml_normalized, expected_normalized)
74
- puts diff.format_as(:ascii)
75
- puts "----differ end"
76
- false
77
- else
78
- true
79
- end
81
+ diff = Differ.diff_by_line(xml_normalized, expected_normalized)
82
+
83
+ str << diff.format_as(:ascii)
84
+ str << "\n----differ end"
85
+ str
80
86
  end
81
87
 
82
88
  def _xml_contains(expected_xml, xml)
83
89
  expected_normalized = normalize_xml(expected_xml)
84
- xml_normalized = normalize_xml(xml)
90
+ xml_normalized = normalize_xml(xml)
85
91
  unless xml_normalized.match(expected_normalized)
86
92
  false
87
93
  else
@@ -90,13 +96,34 @@ def _xml_contains(expected_xml, xml)
90
96
  end
91
97
 
92
98
  RSpec::Matchers.define :xml_equivalent do |expected_xml|
99
+ description do
100
+ "checks if two xml are equivalent"
101
+ end
102
+
93
103
  match do |xml|
94
- diff_xml(expected_xml, xml)
104
+ if xml.respond_to? :to_xml
105
+ xml = xml.to_xml
106
+ end
107
+ if expected_xml.respond_to? :to_xml
108
+ expected_xml = expected_xml.to_xml
109
+ end
110
+ @diff_result = diff_xml(expected_xml, xml)
111
+ @diff_result.nil? # no diff
112
+ end
113
+
114
+ failure_message_for_should do |expected_xml|
115
+ "#{@diff_result}"
95
116
  end
96
117
  end
97
118
 
98
119
  RSpec::Matchers.define :xml_contains do |expected_xml|
99
120
  match do |xml|
121
+ if xml.respond_to? :to_xml
122
+ xml = xml.to_xml
123
+ end
124
+ if expected_xml.respond_to? :to_xml
125
+ expected_xml = expected_xml.to_xml
126
+ end
100
127
  _xml_contains(expected_xml, xml)
101
128
  end
102
129
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,15 +20,8 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
- # comparing xml is always a b-i-a-t-c-h in any testing environment. here is a
26
- # little snippet for ruby that, i think, it a good first pass at making it
27
- # easier. comment with your improvements please!
28
- #
29
- # http://drawohara.com/post/89110816/ruby-comparing-xml
30
-
31
25
  module Sem4rSpecHelper
32
26
 
33
27
  require "stringio"
@@ -45,9 +39,8 @@ module Sem4rSpecHelper
45
39
 
46
40
  #############################################################################
47
41
 
48
- def read_xml(service, xml_file, *args)
49
- # xml_filepath = File.join(File.dirname(__FILE__), "fixtures", *args)
50
- xml_filepath = File.join(File.dirname(__FILE__), "sem4r", service, "fixtures", xml_file)
42
+ def read_xml(service, file_name)
43
+ xml_filepath = File.expand_path File.join(File.dirname(__FILE__), "..", "sem4r", service, "fixtures", file_name)
51
44
  unless File.exist?(xml_filepath)
52
45
  raise "file #{xml_filepath} not exists"
53
46
  end
@@ -57,8 +50,18 @@ module Sem4rSpecHelper
57
50
  contents
58
51
  end
59
52
 
60
- def read_model(xpath, service, xml_file, *args, &blk)
61
- contents = read_xml(service, xml_file, *args)
53
+ def write_xml(service, file_name, xml)
54
+ fixture_dir = File.expand_path File.join(File.dirname(__FILE__), "..", "sem4r", service, "fixtures")
55
+ FileUtils.mkdir_p(fixture_dir) unless File.directory?(fixture_dir)
56
+ pathname = File.join(fixture_dir, file_name)
57
+ puts "writing to #{pathname}"
58
+ File.open(pathname, "w") { |f|
59
+ f.puts xml
60
+ }
61
+ end
62
+
63
+ def read_model(xpath, service, xml_file, &blk)
64
+ contents = read_xml(service, xml_file)
62
65
  xml_document = Nokogiri::XML::Document.parse(contents)
63
66
  if xpath && blk
64
67
  el = xml_document.xpath(xpath).each do |node|
@@ -75,13 +78,13 @@ module Sem4rSpecHelper
75
78
  el
76
79
  end
77
80
 
78
- def read_xml_document(service, xml_file, *args)
79
- contents = read_xml(service, xml_file, *args)
81
+ def read_xml_document(service, xml_file)
82
+ contents = read_xml(service, xml_file)
80
83
  Nokogiri::XML::Document.parse(contents)
81
84
  end
82
85
 
83
- def read_xml_document_with_rexml(service, xml_file, *args)
84
- contents = read_xml(service, xml_file, *args)
86
+ def read_xml_document_with_rexml(service, xml_file)
87
+ contents = read_xml(service, xml_file)
85
88
  REXML::Document.new(contents)
86
89
  end
87
90
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,10 +20,8 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
-
26
25
  module Sem4rSpecHelper
27
26
 
28
27
  #############################################################################
@@ -107,7 +106,9 @@ module Sem4rSpecHelper
107
106
  end
108
107
 
109
108
  def stub_service_report_definition(service)
110
- service_report_definition = stub("service_report_definition")
109
+ xml_document = read_xml_document("report_definition", "mutate-add-report-res.xml")
110
+ soap_message = stub("soap_message", :response => xml_document, :counters => nil)
111
+ service_report_definition = stub("service_report_definition", :mutate => soap_message )
111
112
  service.stub(:report_definition).and_return(service_report_definition)
112
113
  end
113
114
 
@@ -179,4 +180,4 @@ module Sem4rSpecHelper
179
180
  :id => 1000,
180
181
  :ad_group => stub_adgroup(services))
181
182
  end
182
- end
183
+ end
data/spec/rspec_helper.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
3
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
4
 
@@ -5,10 +6,9 @@ require 'sem4r'
5
6
  require 'sem4r_cli'
6
7
  include Sem4r
7
8
 
8
- require 'rspec_sem4r_helper'
9
- require 'rspec_matchers'
10
- require 'sem4r_stubs'
11
- require 'aggregates_rspec_helper'
9
+ require 'helpers/rspec_sem4r_helper'
10
+ require 'helpers/rspec_matchers'
11
+ require 'helpers/sem4r_stubs'
12
12
 
13
13
  # Spec::Runner.configure do |config|
14
14
  # end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,7 +20,6 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  require File.expand_path(File.dirname(__FILE__) + '/../rspec_helper')
@@ -76,10 +76,9 @@ describe Account do
76
76
  end
77
77
 
78
78
  describe "reports management" do
79
-
80
79
  it "should show reports " do
81
80
  @account.should have(4).reports
82
81
  end
83
-
84
82
  end
83
+
85
84
  end
@@ -37,7 +37,7 @@ describe AdGroupService do
37
37
  connector = mock("connector")
38
38
  connector.should_receive(:send).and_return(response_xml)
39
39
  service = AdGroupService.new(connector)
40
- soap_message = service.all( @credentials, "campaign_id" )
40
+ soap_message = service.all(@credentials, "campaign_id" )
41
41
  els = soap_message.response.xpath("//getResponse")
42
42
  els.should_not be_empty
43
43
  end
@@ -181,7 +181,7 @@ describe AdGroup do
181
181
  describe "ad_param management" do
182
182
 
183
183
  it "should create a AdParam with method 'ad_param' + block" do
184
- criterion = @criterion # it is necessary to pass to following block
184
+ criterion = @criterion # it is necessary to the following block
185
185
  adgroup = AdGroup.new(@campaign) do
186
186
  name "adgroup"
187
187
  ad_param(criterion) do
@@ -56,7 +56,7 @@ describe AdGroupAdOperation do
56
56
  end
57
57
 
58
58
  it "should produce xml (input for google) with two operation" do
59
- pending "test"
59
+ pending "waiting to finish build fixture"
60
60
  @adgroup = stub_adgroup
61
61
 
62
62
  text_ad_1 = AdGroupTextAd.new(@adgroup) do
@@ -75,8 +75,8 @@ describe AdGroupAdOperation do
75
75
  url "http://www.Sem4R.com"
76
76
  end
77
77
 
78
- ad_operation_1 = AdGroupAdOperation.new.add text_ad_1
79
- ad_operation_2 = AdGroupAdOperation.new.add text_ad_2
78
+ ad_operation_1 = AdGroupAdOperation.add text_ad_1
79
+ ad_operation_2 = AdGroupAdOperation.add text_ad_2
80
80
 
81
81
  puts ad_operation_1.to_xml("operations")
82
82
  puts ad_operation_2.to_xml("operations")
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -19,7 +20,6 @@
19
20
  # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
21
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
22
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
25
  require File.expand_path(File.dirname(__FILE__) + '/../rspec_helper')
@@ -27,37 +27,38 @@ require File.expand_path(File.dirname(__FILE__) + '/../rspec_helper')
27
27
  describe Adwords do
28
28
 
29
29
  before(:each) do
30
- @test_config_filename = File.expand_path(File.dirname(__FILE__) + "/../fixtures/sem4r.example.yml")
31
-
32
- @environment = "sandbox"
33
- @email = "pippo"
34
- @password = "password"
35
- @developer_token = "developer_token"
36
-
37
- @options = {
38
- :environment => @environment,
39
- :email => @email,
40
- :password => @password,
41
- :developer_token => @developer_token,
30
+ @test_config_filename = File.expand_path(File.dirname(__FILE__) + "/../fixtures/sem4r.example.yml")
31
+ @test_password_filename = File.expand_path(File.dirname(__FILE__) + "/../fixtures/password.example.yml")
32
+
33
+ @environment = "sandbox"
34
+ @email = "sem4ruby@sem4r.com"
35
+ @password = "password"
36
+ @developer_token = "developer_token"
37
+
38
+ @options = {
39
+ :environment => @environment,
40
+ :email => @email,
41
+ :password => @password,
42
+ :developer_token => @developer_token,
42
43
  }
43
44
  end
44
45
 
45
46
  it "should take an hash as configuration" do
46
- adwords = Adwords.new( @options )
47
+ adwords = Adwords.new(@options)
47
48
  adwords.should_not_receive(:load_config)
48
49
  credentials = adwords.account.credentials
49
50
 
50
- adwords.profile.should == "anonymous_" + @environment
51
- credentials.environment.should == @environment
52
- credentials.email.should == @email
53
- credentials.password.should == @password
54
- credentials.developer_token.should == @developer_token
51
+ adwords.profile.should == "anonymous_" + @environment
52
+ credentials.environment.should == @environment
53
+ credentials.email.should == @email
54
+ credentials.password.should == @password
55
+ credentials.developer_token.should == @developer_token
55
56
  credentials.should_not be_mutable
56
57
  end
57
58
 
58
59
  it "should be mutable" do
59
60
  @options[:mutable] = true
60
- adwords = Adwords.new( @options )
61
+ adwords = Adwords.new(@options)
61
62
  adwords.should_not_receive(:load_config)
62
63
  credentials = adwords.account.credentials
63
64
  credentials.should be_mutable
@@ -65,46 +66,68 @@ describe Adwords do
65
66
 
66
67
  it "should set the right environment (sandbox)" do
67
68
  @options.delete(:environment)
68
-
69
- adwords = Adwords.sandbox( @options )
69
+ adwords = Adwords.sandbox(@options)
70
70
  credentials = adwords.account.credentials
71
- credentials.environment.should == "sandbox"
72
- credentials.email.should == @email
71
+ credentials.environment.should == "sandbox"
72
+ credentials.email.should == @email
73
73
  end
74
74
 
75
75
  it "should set the right environment (production)" do
76
76
  @options.delete(:environment)
77
- adwords = Adwords.production( @options )
77
+ adwords = Adwords.production(@options)
78
78
  credentials = adwords.account.credentials
79
- credentials.environment.should == "production"
80
- credentials.email.should == @email
79
+ credentials.environment.should == "production"
80
+ credentials.email.should == @email
81
81
  end
82
-
82
+
83
83
  it "should raise an exception when profile is sandbox and env is production" do
84
- @options[:environment] = "prodution"
85
- lambda { adwords = Adwords.sandbox( @options ) }.should raise_error(RuntimeError)
84
+ @options[:environment] = "production"
85
+ expect {
86
+ Adwords.sandbox(@options)
87
+ }.to raise_error("you cannot use profile 'sandbox' with environment 'production'")
86
88
 
87
89
  @options[:environment] = "sandbox"
88
- lambda { adwords = Adwords.production( @options ) }.should raise_error(RuntimeError)
90
+ expect {
91
+ Adwords.production(@options)
92
+ }.to raise_error("you cannot use profile 'production' with environment 'sandbox'")
89
93
  end
90
94
 
91
95
  it "should read config file (profile file)" do
92
- adwords = Adwords.new( "sandbox", {:config_file => @test_config_filename} )
96
+ adwords = Adwords.new("sandbox", {:config_file => @test_config_filename})
93
97
  credentials = adwords.account.credentials
94
- credentials.environment.should == "sandbox"
95
- credentials.developer_token.should == "example@gmail.com++EUR"
98
+ credentials.environment.should == "sandbox"
99
+ credentials.developer_token.should == "example@gmail.com++EUR"
96
100
 
97
- adwords = Adwords.new( "production1", {:config_file => @test_config_filename} )
101
+ adwords = Adwords.new("production1", {:config_file => @test_config_filename})
98
102
  credentials = adwords.account.credentials
99
- credentials.environment.should == "production"
100
- credentials.developer_token.should == "productiondevelopertoken"
103
+ credentials.environment.should == "production"
104
+ credentials.developer_token.should == "productiondevelopertoken"
101
105
  end
102
106
 
103
-
104
107
  it "should list profiles" do
105
108
  values = Adwords.profiles(@test_config_filename)
106
- values.should have(4).profiles
109
+ values.should have(5).profiles
107
110
  end
108
111
 
112
+ it "should need a password" do
113
+ @options.delete(:password)
114
+ adwords = Adwords.new(@options)
115
+ adwords.should_not have_password
116
+ adwords.password= "prova"
117
+ adwords.should have_password
118
+ end
119
+
120
+ it "should use password file" do
121
+ adwords = Adwords.new("env_wo_password", {
122
+ :config_file => @test_config_filename,
123
+ :password_file => @test_password_filename
124
+ })
125
+ credentials = adwords.account.credentials
126
+ credentials.environment.should == "sandbox"
127
+ credentials.developer_token.should == "env_wo_password@gmail.com++EUR"
128
+ credentials.password.should == "env_password"
129
+
130
+ # adwords.save_passwords
131
+ end
109
132
  end
110
133