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,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