sem4r 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. data/Gemfile +11 -0
  2. data/Gemfile.lock +36 -0
  3. data/README.rdoc +30 -0
  4. data/Rakefile +15 -12
  5. data/VERSION.yml +1 -1
  6. data/examples_blog/2009-11-29-hello-world.rb +0 -1
  7. data/examples_sem4r/01_get_account.rb +1 -1
  8. data/examples_sem4r/02_get_info.rb +6 -2
  9. data/examples_sem4r/03_list_ad.rb +1 -1
  10. data/examples_sem4r/04_list_keywords.rb +1 -1
  11. data/examples_sem4r/05_request_report.rb +1 -2
  12. data/examples_sem4r/05_request_report_2010.rb +19 -4
  13. data/examples_sem4r/06_create_campaigns.rb +1 -1
  14. data/examples_sem4r/07_create_campaigns_block.rb +1 -1
  15. data/examples_sem4r/07_create_campaigns_simple.rb +1 -1
  16. data/examples_sem4r/08_ad_params.rb +1 -1
  17. data/examples_sem4r/09_targeting_idea.rb +1 -1
  18. data/examples_sem4r/10_get_location.rb +1 -1
  19. data/examples_sem4r/11_submit_bulk_job.rb +1 -1
  20. data/examples_sem4r/12_list_bulk_job.rb +1 -1
  21. data/examples_sem4r/30_prune_empty_adgroup.rb +1 -1
  22. data/examples_sem4r/31_empty_accounts.rb +1 -1
  23. data/examples_sem4r/example_helper.rb +5 -10
  24. data/lib/sem4r/account.rb +3 -306
  25. data/lib/sem4r/ad_group/ad_group.rb +16 -14
  26. data/lib/sem4r/ad_group/ad_group_bids.rb +11 -10
  27. data/lib/sem4r/ad_group/ad_group_service.rb +5 -5
  28. data/lib/sem4r/ad_group_ad/ad_group_ad.rb +1 -1
  29. data/lib/sem4r/ad_group_ad/ad_group_ad_service.rb +5 -5
  30. data/lib/sem4r/ad_group_ad/ad_group_mobile_ad.rb +9 -9
  31. data/lib/sem4r/ad_group_ad/ad_group_text_ad.rb +9 -9
  32. data/lib/sem4r/ad_group_criterion/ad_group_criterion.rb +6 -6
  33. data/lib/sem4r/ad_group_criterion/ad_group_criterion_bids.rb +5 -6
  34. data/lib/sem4r/ad_group_criterion/ad_group_criterion_operations.rb +0 -1
  35. data/lib/sem4r/ad_group_criterion/ad_group_criterion_service.rb +4 -4
  36. data/lib/sem4r/ad_group_criterion/criterion.rb +3 -3
  37. data/lib/sem4r/ad_group_criterion/criterion_keyword.rb +3 -3
  38. data/lib/sem4r/ad_group_criterion/criterion_placement.rb +2 -2
  39. data/lib/sem4r/ad_param/ad_param.rb +3 -3
  40. data/lib/sem4r/ad_param/ad_param_service.rb +5 -5
  41. data/lib/sem4r/adwords.rb +1 -0
  42. data/lib/sem4r/api_counters.rb +1 -0
  43. data/lib/sem4r/base.rb +1 -0
  44. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job.rb +2 -2
  45. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_account_extension.rb +59 -0
  46. data/lib/sem4r/bulk_mutate_job/bulk_mutate_job_service.rb +5 -5
  47. data/lib/sem4r/campaign/campaign.rb +10 -10
  48. data/lib/sem4r/campaign/campaign_account_extension.rb +87 -0
  49. data/lib/sem4r/campaign/campaign_service.rb +6 -6
  50. data/lib/sem4r/campaign_target/campaign_target_service.rb +22 -22
  51. data/lib/sem4r/cli/cli_command.rb +1 -0
  52. data/lib/sem4r/cli/cli_common_args.rb +10 -3
  53. data/lib/sem4r/cli/cli_helpers.rb +1 -0
  54. data/lib/sem4r/cli/cli_sem.rb +1 -0
  55. data/lib/sem4r/cli/{cli_download_report.rb → commands/cli_download_report.rb} +2 -1
  56. data/lib/sem4r/cli/{cli_ideas.rb → commands/cli_ideas.rb} +1 -0
  57. data/lib/sem4r/cli/{cli_commands.rb → commands/cli_info.rb} +3 -23
  58. data/lib/sem4r/cli/{cli_list_ads.rb → commands/cli_list_ads.rb} +1 -0
  59. data/lib/sem4r/cli/commands/cli_list_campaign.rb +35 -0
  60. data/lib/sem4r/cli/commands/cli_list_client.rb +36 -0
  61. data/lib/sem4r/cli/{cli_list_keywords.rb → commands/cli_list_keywords.rb} +1 -0
  62. data/lib/sem4r/cli/commands/cli_list_report.rb +34 -0
  63. data/lib/sem4r/cli/commands/cli_repdef.rb +109 -0
  64. data/lib/sem4r/cli/commands/cli_report.rb +78 -0
  65. data/lib/sem4r/cli/{cli_request_report.rb → commands/cli_request_report.rb} +1 -0
  66. data/lib/sem4r/credentials.rb +1 -0
  67. data/lib/sem4r/extensions.rb +22 -1
  68. data/lib/sem4r/geo_location/geo_location_account_extension.rb +43 -0
  69. data/lib/sem4r/geo_location/geo_location_service.rb +4 -4
  70. data/lib/sem4r/info/info_account_extension.rb +48 -0
  71. data/lib/sem4r/info/info_selector.rb +108 -0
  72. data/lib/sem4r/info/info_service.rb +11 -66
  73. data/lib/sem4r/{common/operation.rb → operation.rb} +3 -1
  74. data/lib/sem4r/report_definition/report_definition.rb +75 -15
  75. data/lib/sem4r/report_definition/report_definition_account_extension.rb +79 -0
  76. data/lib/sem4r/report_definition/report_definition_operation.rb +3 -1
  77. data/lib/sem4r/report_definition/report_definition_service.rb +7 -7
  78. data/lib/sem4r/report_definition/report_field.rb +57 -0
  79. data/lib/sem4r/sem4r_error.rb +1 -0
  80. data/lib/sem4r/services/http_connector.rb +93 -0
  81. data/lib/sem4r/services/service.rb +1 -1
  82. data/lib/sem4r/services/soap_call.rb +27 -5
  83. data/lib/sem4r/services/soap_connector.rb +2 -147
  84. data/lib/sem4r/services/soap_dumper.rb +105 -0
  85. data/lib/sem4r/services/soap_message_v13.rb +15 -9
  86. data/lib/sem4r/services/{soap_message_v2009.rb → soap_message_v2010.rb} +26 -12
  87. data/lib/sem4r/targeting_idea/targeting_idea.rb +16 -11
  88. data/lib/sem4r/targeting_idea/targeting_idea_account_extension.rb +52 -0
  89. data/lib/sem4r/targeting_idea/targeting_idea_selector.rb +36 -10
  90. data/lib/sem4r/targeting_idea/targeting_idea_service.rb +5 -5
  91. data/lib/sem4r/v13_account/account_account_extension.rb +103 -0
  92. data/lib/sem4r/v13_account/billing_address.rb +10 -21
  93. data/lib/sem4r/v13_report/report.rb +8 -8
  94. data/lib/sem4r/v13_report/report_account_extension.rb +63 -0
  95. data/lib/sem4r/v13_report/report_job.rb +1 -1
  96. data/lib/sem4r.rb +27 -6
  97. data/lib/sem4r_cli.rb +4 -6
  98. data/lib/{sem4r → soap_helpers}/soap_attributes.rb +105 -13
  99. data/sem4r.gemspec +229 -190
  100. data/spec/{aggregates_spec_helper.rb → aggregates_rspec_helper.rb} +0 -0
  101. data/spec/build_fixtures.rb +84 -0
  102. data/spec/rspec_hash.rb +66 -0
  103. data/spec/{spec_helper.rb → rspec_helper.rb} +4 -2
  104. data/spec/rspec_matchers.rb +102 -0
  105. data/spec/rspec_sem4r_helper.rb +88 -0
  106. data/spec/sem4r/account_spec.rb +3 -4
  107. data/spec/sem4r/ad_group/ad_group_bids_spec.rb +4 -3
  108. data/spec/sem4r/ad_group/ad_group_service_spec.rb +8 -7
  109. data/spec/sem4r/ad_group/ad_group_spec.rb +5 -4
  110. data/spec/{fixtures/services/ad_group → sem4r/ad_group/fixtures}/get-first-req.xml +0 -0
  111. data/spec/{fixtures/services/ad_group → sem4r/ad_group/fixtures}/get-first-res.xml +0 -0
  112. data/spec/{fixtures/services/ad_group → sem4r/ad_group/fixtures}/get-manual-cpm-bids-req.xml +0 -0
  113. data/spec/{fixtures/services/ad_group → sem4r/ad_group/fixtures}/get-manual-cpm-bids-res.xml +0 -0
  114. data/spec/{fixtures/services/ad_group → sem4r/ad_group/fixtures}/mutate_add-req.xml +0 -0
  115. data/spec/{fixtures/services/ad_group → sem4r/ad_group/fixtures}/mutate_add-res.xml +0 -0
  116. data/spec/sem4r/ad_group_ad/ad_group_ad_operation_spec.rb +3 -3
  117. data/spec/sem4r/ad_group_ad/ad_group_ad_service_spec.rb +6 -5
  118. data/spec/sem4r/ad_group_ad/ad_group_ad_spec.rb +6 -5
  119. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/get_mobile_ad-req.xml +0 -0
  120. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/get_mobile_ad-res.xml +0 -0
  121. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/get_text_ad-req.xml +0 -0
  122. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/get_text_ad-res.xml +0 -0
  123. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/mutate_add_mobile_ad-req.xml +0 -0
  124. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/mutate_add_mobile_ad-res.xml +0 -0
  125. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/mutate_add_text_ad-req.xml +0 -0
  126. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/mutate_add_text_ad-res.xml +0 -0
  127. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/mutate_add_two_criterions-req.xml +0 -0
  128. data/spec/{fixtures/services/ad_group_ad → sem4r/ad_group_ad/fixtures}/mutate_add_two_criterions-res.xml +0 -0
  129. data/spec/sem4r/ad_group_criterion/ad_group_criterion_bids_spec.rb +5 -4
  130. data/spec/sem4r/ad_group_criterion/ad_group_criterion_service_spec.rb +6 -5
  131. data/spec/sem4r/ad_group_criterion/ad_group_criterion_spec.rb +6 -5
  132. data/spec/sem4r/ad_group_criterion/criterion_spec.rb +5 -4
  133. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/get-req.xml +0 -0
  134. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/get-res.xml +0 -0
  135. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/mutate_add_criterion_keyword-req.xml +0 -0
  136. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/mutate_add_criterion_keyword-res.xml +0 -0
  137. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/mutate_add_criterion_placement-req.xml +0 -0
  138. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/mutate_add_criterion_placement-res.xml +0 -0
  139. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/mutate_add_negative_keyword-req.xml +0 -0
  140. data/spec/{fixtures/services/ad_group_criterion → sem4r/ad_group_criterion/fixtures}/mutate_add_negative_keyword-res.xml +0 -0
  141. data/spec/sem4r/ad_param/ad_param_service_spec.rb +6 -5
  142. data/spec/sem4r/ad_param/ad_param_spec.rb +3 -2
  143. data/spec/{fixtures/services/ad_param → sem4r/ad_param/fixtures}/mutate_set-req.xml +0 -0
  144. data/spec/{fixtures/services/ad_param → sem4r/ad_param/fixtures}/mutate_set-res.xml +0 -0
  145. data/spec/sem4r/adwords_spec.rb +1 -1
  146. data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_service_spec.rb +6 -5
  147. data/spec/sem4r/bulk_mutate_job/bulk_mutate_job_spec.rb +4 -3
  148. data/spec/{fixtures/services/bulk_mutate_job → sem4r/bulk_mutate_job/fixtures}/get-req.xml +0 -0
  149. data/spec/{fixtures/services/bulk_mutate_job → sem4r/bulk_mutate_job/fixtures}/get-res.xml +0 -0
  150. data/spec/{fixtures/services/bulk_mutate_job → sem4r/bulk_mutate_job/fixtures}/mutate-req.xml +0 -0
  151. data/spec/{fixtures/services/bulk_mutate_job → sem4r/bulk_mutate_job/fixtures}/mutate-res.xml +0 -0
  152. data/spec/sem4r/bulk_mutate_job/job_operation_spec.rb +3 -2
  153. data/spec/sem4r/campaign/campaign_service_spec.rb +8 -7
  154. data/spec/sem4r/campaign/campaign_spec.rb +3 -2
  155. data/spec/{fixtures/services/campaign → sem4r/campaign/fixtures}/get-req.xml +0 -0
  156. data/spec/{fixtures/services/campaign → sem4r/campaign/fixtures}/get-res.xml +0 -0
  157. data/spec/{fixtures/services/campaign → sem4r/campaign/fixtures}/mutate_add-req.xml +0 -0
  158. data/spec/{fixtures/services/campaign → sem4r/campaign/fixtures}/mutate_add-res.xml +0 -0
  159. data/spec/sem4r/cli/cli_spec.rb +2 -3
  160. data/spec/sem4r/credentials_spec.rb +1 -1
  161. data/spec/sem4r/info/account_info_extension_spec.rb +51 -0
  162. data/spec/sem4r/info/fixtures/get_unit_count-req.xml +34 -0
  163. data/spec/sem4r/info/fixtures/get_unit_count-res.xml +27 -0
  164. data/spec/sem4r/nokogiri_parsing_spec.rb +105 -0
  165. data/spec/{fixtures/services/report_definition → sem4r/report_definition/fixtures}/mutate_add-req.xml +0 -0
  166. data/spec/{fixtures/services/report_definition → sem4r/report_definition/fixtures}/mutate_add-req_orig.xml +0 -0
  167. data/spec/sem4r/report_definition/report_definition_service_spec.rb +5 -3
  168. data/spec/sem4r/report_definition/report_definition_spec.rb +6 -3
  169. data/spec/sem4r/rexml_parsing_spec.rb +22 -22
  170. data/spec/sem4r/services/service_spec.rb +2 -1
  171. data/spec/sem4r/services/soap_call_spec.rb +6 -5
  172. data/spec/sem4r/services/soap_message_v13_spec.rb +5 -11
  173. data/spec/{fixtures/services/targeting_idea → sem4r/targeting_idea/fixtures}/get-req-all-options.xml +0 -0
  174. data/spec/{fixtures/services/targeting_idea → sem4r/targeting_idea/fixtures}/get-req.xml +9 -11
  175. data/spec/sem4r/targeting_idea/fixtures/get-res.xml +2276 -0
  176. data/spec/sem4r/targeting_idea/targeting_idea_selector_spec.rb +30 -11
  177. data/spec/sem4r/targeting_idea/targeting_idea_service_spec.rb +4 -3
  178. data/spec/sem4r/targeting_idea/targeting_idea_spec.rb +5 -4
  179. data/spec/sem4r/v13_account/account_account_extension_spec.rb +47 -0
  180. data/spec/sem4r/v13_account/account_service_spec.rb +6 -5
  181. data/spec/sem4r/v13_account/billing_address_spec.rb +40 -0
  182. data/spec/{fixtures/services/v13_account → sem4r/v13_account/fixtures}/get_account_info-req.xml +0 -0
  183. data/spec/{fixtures/services/v13_account → sem4r/v13_account/fixtures}/get_account_info-res.xml +0 -0
  184. data/spec/{fixtures/services/v13_account → sem4r/v13_account/fixtures}/get_client_accounts-req.xml +0 -0
  185. data/spec/{fixtures/services/v13_account → sem4r/v13_account/fixtures}/get_client_accounts-res.xml +0 -0
  186. data/spec/{fixtures/services/v13_report → sem4r/v13_report/fixtures}/get_all_jobs-req.xml +0 -0
  187. data/spec/{fixtures/services/v13_report → sem4r/v13_report/fixtures}/get_all_jobs-res.xml +2 -2
  188. data/spec/{fixtures/services/v13_report → sem4r/v13_report/fixtures}/schedule_report_job-req.xml +0 -0
  189. data/spec/{fixtures/services/v13_report → sem4r/v13_report/fixtures}/schedule_report_job-res.xml +0 -0
  190. data/spec/sem4r/v13_report/report_service_spec.rb +13 -11
  191. data/spec/sem4r/v13_report/report_spec.rb +4 -3
  192. data/spec/sem4r_stubs.rb +182 -0
  193. data/spec/soap_helpers/soap_attributes_spec.rb +129 -0
  194. metadata +225 -125
  195. data/spec/fixtures/services/info/get_unit_count-req.xml +0 -30
  196. data/spec/fixtures/services/info/get_unit_count-res.xml +0 -29
  197. data/spec/fixtures/services/targeting_idea/get-res.xml +0 -3601
  198. data/spec/sem4r/soap_attributes_spec.rb +0 -116
  199. data/spec/sem4r_spec_helper.rb +0 -353
@@ -0,0 +1,102 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+ # -------------------------------------------------------------------------
24
+
25
+ require 'rexml/document'
26
+ require 'differ'
27
+ require 'differ/string'
28
+
29
+ def pretty_xml(xml)
30
+ normalized = Class.new(REXML::Formatters::Pretty) do
31
+ def write_text(node, output)
32
+ super(node.to_s.strip, output)
33
+ end
34
+ end
35
+ normalized.new(0,false).write(xml, xml_pretty='')
36
+ xml_pretty
37
+ end
38
+
39
+ def normalize_xml(expected_xml)
40
+ if expected_xml.class != String
41
+ expected_xml = expected_xml.to_s
42
+ end
43
+
44
+ if expected_xml.class == String
45
+ # erase namespaces i.e. <ns1:tag> -> <tag>
46
+ expected_xml = expected_xml.gsub(/\b(ns\d:|xsi:|s:|soapenv:|env:|soap:|^\n)/, "").strip
47
+ begin
48
+ expected_xml = REXML::Document.new(expected_xml)
49
+ rescue RuntimeError
50
+ puts "----------------------------------"
51
+ puts xml
52
+ puts "----------------------------------"
53
+ raise
54
+ end
55
+ end
56
+ expected_normalized = pretty_xml(expected_xml)
57
+ # erase namespaces i.e. <ns1:tag> -> <tag>
58
+ expected_normalized.gsub(/(ns\d:|xsi:|s:|soapenv:|env:|soap:|^\n| {2,})/, "").strip
59
+ end
60
+
61
+ def diff_xml(expected_xml, xml)
62
+ expected_normalized = normalize_xml(expected_xml)
63
+ xml_normalized = normalize_xml(xml)
64
+
65
+ if xml_normalized != expected_normalized
66
+ puts "----differ start"
67
+
68
+ puts xml_normalized
69
+
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
80
+ end
81
+
82
+ def _xml_contains(expected_xml, xml)
83
+ expected_normalized = normalize_xml(expected_xml)
84
+ xml_normalized = normalize_xml(xml)
85
+ unless xml_normalized.match(expected_normalized)
86
+ false
87
+ else
88
+ true
89
+ end
90
+ end
91
+
92
+ RSpec::Matchers.define :xml_equivalent do |expected_xml|
93
+ match do |xml|
94
+ diff_xml(expected_xml, xml)
95
+ end
96
+ end
97
+
98
+ RSpec::Matchers.define :xml_contains do |expected_xml|
99
+ match do |xml|
100
+ _xml_contains(expected_xml, xml)
101
+ end
102
+ end
@@ -0,0 +1,88 @@
1
+ # -------------------------------------------------------------------------
2
+ # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #
23
+ # -------------------------------------------------------------------------
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
+ module Sem4rSpecHelper
32
+
33
+ require "stringio"
34
+ def with_stdout_captured
35
+ old_stdout = $stdout
36
+ out = StringIO.new
37
+ $stdout = out
38
+ begin
39
+ yield
40
+ ensure
41
+ $stdout = old_stdout
42
+ end
43
+ out.string
44
+ end
45
+
46
+ #############################################################################
47
+
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)
51
+ unless File.exist?(xml_filepath)
52
+ raise "file #{xml_filepath} not exists"
53
+ end
54
+ contents = File.open(xml_filepath).read
55
+ contents.gsub!(/\b(ns\d:|xsi:|s:|soapenv:|env:|soap:)/, "")
56
+ contents.gsub!(/xmlns=["'].*?['"]/, '')
57
+ contents
58
+ end
59
+
60
+ def read_model(xpath, service, xml_file, *args, &blk)
61
+ contents = read_xml(service, xml_file, *args)
62
+ xml_document = Nokogiri::XML::Document.parse(contents)
63
+ if xpath && blk
64
+ el = xml_document.xpath(xpath).each do |node|
65
+ yield node
66
+ end
67
+ elsif xpath
68
+ el = xml_document.xpath(xpath).first
69
+ else
70
+ el = xml_document.root.children.to_a.first
71
+ end
72
+ if el.nil?
73
+ raise "xml element not found '#{xpath}'"
74
+ end
75
+ el
76
+ end
77
+
78
+ def read_xml_document(service, xml_file, *args)
79
+ contents = read_xml(service, xml_file, *args)
80
+ Nokogiri::XML::Document.parse(contents)
81
+ end
82
+
83
+ def read_xml_document_with_rexml(service, xml_file, *args)
84
+ contents = read_xml(service, xml_file, *args)
85
+ REXML::Document.new(contents)
86
+ end
87
+
88
+ end
@@ -22,8 +22,7 @@
22
22
  #
23
23
  # -------------------------------------------------------------------------
24
24
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
26
-
25
+ require File.expand_path(File.dirname(__FILE__) + '/../rspec_helper')
27
26
 
28
27
  describe Account do
29
28
 
@@ -38,7 +37,7 @@ describe Account do
38
37
  @adwords = stub_adwords(services)
39
38
  @credentials = stub_credentials
40
39
 
41
- @account = Account.new(@adwords, @credentials)
40
+ @account = Account.new(@adwords, @credentials)
42
41
  end
43
42
 
44
43
  describe "account management" do
@@ -48,7 +47,7 @@ describe Account do
48
47
  end
49
48
 
50
49
  it "should retrieve cost" do
51
- @account.year_unit_cost("UNIT_COUNT").should == 100
50
+ @account.year_unit_cost("UNIT_COUNT").should == 0
52
51
  end
53
52
 
54
53
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
  describe AdGroupBids do
28
29
  include Sem4rSpecHelper
@@ -51,12 +52,12 @@ describe AdGroupBids do
51
52
  bids = ManualCPCAdGroupBids.new
52
53
  bids.keyword_max_cpc 20000000
53
54
  bids.site_max_cpc 30000000
54
- expected_xml = read_model("//bids", "services", "ad_group", "mutate_add-req.xml")
55
+ expected_xml = read_model("//bids", "ad_group", "mutate_add-req.xml")
55
56
  bids.to_xml.should xml_equivalent(expected_xml)
56
57
  end
57
58
 
58
59
  it "should parse xml (produced by google)" do
59
- el = read_model("//bids", "services", "ad_group", "get-first-res.xml")
60
+ el = read_model("//bids", "ad_group", "get-first-res.xml")
60
61
  bids = AdGroupBids.from_element(el)
61
62
  bids.keyword_max_cpc.should == 20000000
62
63
  bids.site_max_cpc.should == 30000000
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
  describe AdGroupService do
28
29
  include Sem4rSpecHelper
@@ -32,34 +33,34 @@ describe AdGroupService do
32
33
  end
33
34
 
34
35
  it "should define 'all'" do
35
- response_xml = read_xml_file("services", "ad_group", "get-first-res.xml")
36
+ response_xml = read_xml("ad_group", "get-first-res.xml")
36
37
  connector = mock("connector")
37
38
  connector.should_receive(:send).and_return(response_xml)
38
39
  service = AdGroupService.new(connector)
39
40
  soap_message = service.all( @credentials, "campaign_id" )
40
- els = REXML::XPath.match( soap_message.response, "//getResponse")
41
+ els = soap_message.response.xpath("//getResponse")
41
42
  els.should_not be_empty
42
43
  end
43
44
 
44
45
  it "should define 'create'" do
45
46
  @credentials.should_receive(:mutable?).and_return(true)
46
- response_xml = read_xml_file("services", "ad_group", "mutate_add-res.xml")
47
+ response_xml = read_xml("ad_group", "mutate_add-res.xml")
47
48
  connector = mock("connector")
48
49
  connector.should_receive(:send).and_return(response_xml)
49
50
  service = AdGroupService.new(connector)
50
51
  soap_message = service.create( @credentials, "xml" )
51
- els = REXML::XPath.match( soap_message.response, "//mutateResponse")
52
+ els = soap_message.response.xpath("//mutateResponse")
52
53
  els.should_not be_empty
53
54
  end
54
55
 
55
56
  it "should define 'delete'" do
56
57
  @credentials.should_receive(:mutable?).and_return(true)
57
- response_xml = read_xml_file("services", "ad_group", "mutate_add-res.xml")
58
+ response_xml = read_xml("ad_group", "mutate_add-res.xml")
58
59
  connector = mock("connector")
59
60
  connector.should_receive(:send).and_return(response_xml)
60
61
  service = AdGroupService.new(connector)
61
62
  soap_message = service.delete( @credentials, "id" )
62
- els = REXML::XPath.match( soap_message.response, "//mutateResponse")
63
+ els = soap_message.response.xpath("//mutateResponse")
63
64
  els.should_not be_empty
64
65
  end
65
66
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
 
28
29
  describe AdGroup do
@@ -85,12 +86,12 @@ describe AdGroup do
85
86
  site_max_cpc 30000000
86
87
  end
87
88
  end
88
- exepected_xml = read_model("//operand", "services", "ad_group", "mutate_add-req.xml")
89
+ exepected_xml = read_model("//operand", "ad_group", "mutate_add-req.xml")
89
90
  adgroup.to_xml("operand").should xml_equivalent(exepected_xml)
90
91
  end
91
92
 
92
93
  it "should parse xml (produced by google)" do
93
- el = read_model("//entries", "services", "ad_group", "get-first-res.xml")
94
+ el = read_model("//entries", "ad_group", "get-first-res.xml")
94
95
  adgroup = AdGroup.from_element(@campaign, el)
95
96
  adgroup.id.should == 3060217923
96
97
  adgroup.name.should == "test adgroup"
@@ -98,7 +99,7 @@ describe AdGroup do
98
99
  end
99
100
 
100
101
  it "should parse xml (produced by google) with manual cpm bids" do
101
- el = read_model("//entries", "services", "ad_group", "get-manual-cpm-bids-res.xml")
102
+ el = read_model("//entries", "ad_group", "get-manual-cpm-bids-res.xml")
102
103
  adgroup = AdGroup.from_element(@campaign, el)
103
104
  adgroup.bids.should be_instance_of(ManualCPMAdGroupBids)
104
105
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,8 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
-
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
27
27
 
28
28
  describe AdGroupAdOperation do
29
29
  include Sem4rSpecHelper
@@ -51,7 +51,7 @@ describe AdGroupAdOperation do
51
51
  text_ad.url = "http://www.example.com"
52
52
  @ad_operation.add text_ad
53
53
 
54
- expected_xml = read_model("//operations", "services", "bulk_mutate_job", "mutate-req.xml")
54
+ expected_xml = read_model("//operations", "bulk_mutate_job", "mutate-req.xml")
55
55
  @ad_operation.to_xml('operations').should xml_equivalent(expected_xml)
56
56
  end
57
57
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
  describe AdGroupAdService do
28
29
  include Sem4rSpecHelper
@@ -32,23 +33,23 @@ describe AdGroupAdService do
32
33
  end
33
34
 
34
35
  it "should define 'all'" do
35
- response_xml = read_xml_file("services", "ad_group_ad", "get_mobile_ad-res.xml")
36
+ response_xml = read_xml("ad_group_ad", "get_mobile_ad-res.xml")
36
37
  connector = mock("connector")
37
38
  connector.should_receive(:send).and_return(response_xml)
38
39
  service = AdGroupAdService.new(connector)
39
40
  soap_message = service.all( @credentials, "ad_group_id" )
40
- els = REXML::XPath.match( soap_message.response, "//getResponse")
41
+ els = soap_message.response.xpath("//getResponse")
41
42
  els.should_not be_empty
42
43
  end
43
44
 
44
45
  it "should define 'mutate'" do
45
46
  @credentials.should_receive(:mutable?).and_return(true)
46
- response_xml = read_xml_file("services", "ad_group_ad", "mutate_add_mobile_ad-res.xml")
47
+ response_xml = read_xml("ad_group_ad", "mutate_add_mobile_ad-res.xml")
47
48
  connector = mock("connector")
48
49
  connector.should_receive(:send).and_return(response_xml)
49
50
  service = AdGroupAdService.new(connector)
50
51
  soap_message = service.mutate( @credentials, "xml" )
51
- els = REXML::XPath.match( soap_message.response, "//mutateResponse")
52
+ els = soap_message.response.xpath("//mutateResponse")
52
53
  els.should_not be_empty
53
54
  end
54
55
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
  describe AdGroupAd do
28
29
 
@@ -38,7 +39,7 @@ describe AdGroupAd do
38
39
  describe AdGroupAd do
39
40
 
40
41
  it "should parse xml (output from google)" do
41
- el = read_model("//ad", "services", "ad_group_ad", "get_text_ad-res.xml")
42
+ el = read_model("//ad", "ad_group_ad", "get_text_ad-res.xml")
42
43
  ad = AdGroupAd.from_element(@adgroup, el)
43
44
  # ad.id.should == 218770
44
45
  ad.url.should == "http://www.pluto.com"
@@ -108,7 +109,7 @@ describe AdGroupAd do
108
109
  url "http://www.pluto.com"
109
110
  display_url "www.Pluto.com"
110
111
  end
111
- expected_xml = read_model("//operand", "services", "ad_group_ad", "mutate_add_text_ad-req.xml")
112
+ expected_xml = read_model("//operand", "ad_group_ad", "mutate_add_text_ad-req.xml")
112
113
  text_ad.to_xml("operand").should xml_equivalent(expected_xml)
113
114
  end
114
115
 
@@ -158,12 +159,12 @@ describe AdGroupAd do
158
159
  phone_number "0612345"
159
160
  end
160
161
 
161
- expected_xml = read_model("//operand", "services", "ad_group_ad", "mutate_add_mobile_ad-req.xml")
162
+ expected_xml = read_model("//operand", "ad_group_ad", "mutate_add_mobile_ad-req.xml")
162
163
  mobile_ad.to_xml("operand").should xml_equivalent(expected_xml)
163
164
  end
164
165
 
165
166
  it "should parse xml (output from google)" do
166
- el = read_model("//ad", "services", "ad_group_ad", "get_mobile_ad-res.xml")
167
+ el = read_model("//ad", "ad_group_ad", "get_mobile_ad-res.xml")
167
168
  ad = AdGroupAd.from_element(@adgroup, el)
168
169
  ad.headline.should == "sem4r"
169
170
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,13 +23,13 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
  describe AdGroupCriterionBids do
28
29
  include Sem4rSpecHelper
29
30
 
30
31
  it "should parse xml (produced by google)" do
31
- el = read_model("//bids", "services", "ad_group_criterion", "get-res.xml")
32
+ el = read_model("//bids", "ad_group_criterion", "get-res.xml")
32
33
  bids = AdGroupCriterionBids.from_element(el)
33
34
  bids.should be_instance_of ManualCPCAdGroupCriterionBids
34
35
  end
@@ -44,12 +45,12 @@ describe AdGroupCriterionBids do
44
45
  it "should build xml (input for google)" do
45
46
  bids = ManualCPCAdGroupCriterionBids.new
46
47
  bids.max_cpc 10000000
47
- expected_xml = read_model("//bids", "services", "ad_group_criterion", "mutate_add_criterion_keyword-req.xml")
48
+ expected_xml = read_model("//bids", "ad_group_criterion", "mutate_add_criterion_keyword-req.xml")
48
49
  bids.to_xml.should xml_equivalent( expected_xml )
49
50
  end
50
51
 
51
52
  it "should parse xml (produced by google)" do
52
- el = read_model("//bids", "services", "ad_group_criterion", "get-res.xml")
53
+ el = read_model("//bids", "ad_group_criterion", "get-res.xml")
53
54
  bids = ManualCPCAdGroupCriterionBids.from_element(el)
54
55
  bids.bid_source.should == "ADGROUP"
55
56
  bids.max_cpc.should == 10000000
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
  describe AdGroupCriterionService do
28
29
  include Sem4rSpecHelper
@@ -32,23 +33,23 @@ describe AdGroupCriterionService do
32
33
  end
33
34
 
34
35
  it "should define 'all'" do
35
- response_xml = read_xml_file("services", "ad_group_criterion", "get-res.xml")
36
+ response_xml = read_xml("ad_group_criterion", "get-res.xml")
36
37
  connector = mock("connector")
37
38
  connector.should_receive(:send).and_return(response_xml)
38
39
  service = AdGroupCriterionService.new(connector)
39
40
  soap_message = service.all( @credentials, "ad_group_id" )
40
- els = REXML::XPath.match( soap_message.response, "//getResponse")
41
+ els = soap_message.response.xpath("//getResponse")
41
42
  els.should_not be_empty
42
43
  end
43
44
 
44
45
  it "should define 'mutate'" do
45
46
  @credentials.should_receive(:mutable?).and_return(true)
46
- response_xml = read_xml_file("services", "ad_group_criterion", "mutate_add_criterion_keyword-res.xml")
47
+ response_xml = read_xml("ad_group_criterion", "mutate_add_criterion_keyword-res.xml")
47
48
  connector = mock("connector")
48
49
  connector.should_receive(:send).and_return(response_xml)
49
50
  service = AdGroupCriterionService.new(connector)
50
51
  soap_message = service.mutate( @credentials, "xml" )
51
- els = REXML::XPath.match( soap_message.response, "//mutateResponse")
52
+ els = soap_message.response.xpath("//mutateResponse")
52
53
  els.should_not be_empty
53
54
  end
54
55
 
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
 
28
29
  describe AdGroupCriterion do
@@ -59,12 +60,12 @@ describe AdGroupCriterion do
59
60
  biddable_criterion.criterion keyword
60
61
  biddable_criterion.bids bids
61
62
 
62
- xml_expected = read_model("//operand", "services", "ad_group_criterion", "mutate_add_criterion_keyword-req.xml")
63
+ xml_expected = read_model("//operand", "ad_group_criterion", "mutate_add_criterion_keyword-req.xml")
63
64
  biddable_criterion.to_xml("operand").should xml_equivalent(xml_expected)
64
65
  end
65
66
 
66
67
  it "should parse xml (produced by google)" do
67
- el = read_model("//entries", "services", "ad_group_criterion", "get-res.xml")
68
+ el = read_model("//entries", "ad_group_criterion", "get-res.xml")
68
69
  biddable_criterion = BiddableAdGroupCriterion.from_element(@ad_group, el)
69
70
  biddable_criterion.bids.should be_instance_of(ManualCPCAdGroupCriterionBids)
70
71
  biddable_criterion.criterion.should be_instance_of(CriterionKeyword)
@@ -87,12 +88,12 @@ describe AdGroupCriterion do
87
88
  end
88
89
  biddable_criterion = NegativeAdGroupCriterion.new(@ad_group)
89
90
  biddable_criterion.criterion keyword
90
- xml_expected = read_model("//operand", "services", "ad_group_criterion", "mutate_add_negative_keyword-req.xml")
91
+ xml_expected = read_model("//operand", "ad_group_criterion", "mutate_add_negative_keyword-req.xml")
91
92
  biddable_criterion.to_xml("operand").should xml_equivalent(xml_expected)
92
93
  end
93
94
 
94
95
  it "should parse xml (produced by google)" do
95
- el = read_model("//value", "services", "ad_group_criterion", "mutate_add_negative_keyword-res.xml")
96
+ el = read_model("//value", "ad_group_criterion", "mutate_add_negative_keyword-res.xml")
96
97
  negative = AdGroupCriterion.from_element(@ad_group, el)
97
98
  negative.criterion.text.should == "java api library"
98
99
  negative.criterion.match.should == "BROAD"
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  # -------------------------------------------------------------------------
2
3
  # Copyright (c) 2009-2010 Sem4r sem4ruby@gmail.com
3
4
  #
@@ -22,7 +23,7 @@
22
23
  #
23
24
  # -------------------------------------------------------------------------
24
25
 
25
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
26
+ require File.expand_path(File.dirname(__FILE__) + '/../../rspec_helper')
26
27
 
27
28
 
28
29
  describe Criterion do
@@ -50,12 +51,12 @@ describe Criterion do
50
51
  text "sem4r adwords api"
51
52
  match "BROAD"
52
53
  end
53
- xml_expected = read_model("//criterion", "services", "ad_group_criterion", "mutate_add_criterion_keyword-req.xml")
54
+ xml_expected = read_model("//criterion", "ad_group_criterion", "mutate_add_criterion_keyword-req.xml")
54
55
  keyword.to_xml("criterion").should xml_equivalent(xml_expected)
55
56
  end
56
57
 
57
58
  it "should parse xml (produced by google)" do
58
- el = read_model("//entries/criterion", "services", "ad_group_criterion", "get-res.xml")
59
+ el = read_model("//entries/criterion", "ad_group_criterion", "get-res.xml")
59
60
  keyword = CriterionKeyword.from_element(@ad_group, el)
60
61
  keyword.id.should == 11536082
61
62
  keyword.text.should == "pippo"
@@ -74,7 +75,7 @@ describe Criterion do
74
75
  end
75
76
 
76
77
  it "should parse xml (produced by google)" do
77
- el = read_model("//criterion", "services", "ad_group_criterion", "mutate_add_criterion_placement-res.xml")
78
+ el = read_model("//criterion", "ad_group_criterion", "mutate_add_criterion_placement-res.xml")
78
79
  placement = CriterionPlacement.from_element(@ad_group, el)
79
80
  placement.id.should == 11536085
80
81
  placement.url.should == "github.com"