yanapi 0.1.1 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,62 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Wed, 03 Aug 2011 21:16:04 GMT
3
+ P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
4
+ Vary: Accept-Encoding
5
+ Connection: close
6
+ Transfer-Encoding: chunked
7
+ Content-Type: text/xml; charset=utf-8
8
+ Cache-Control: private
9
+
10
+ <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
11
+ <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:yahoo:answers" xsi:schemaLocation="urn:yahoo:answers http://answers.yahooapis.com/AnswersService/V1/QuestionResponse.xsd">
12
+ <Question id="20090824105131AAJyFeP" type="Answered">
13
+ <Subject>Does the Kool Haus in Toronto have chairs to sit on?</Subject>
14
+ <Content>I am planning to attend a concert there and I was searching for a seating chart.
15
+ But all it said was &quot;General Admission, No reserved seating.&quot;
16
+ Does that mean it is a concert where people stand the whole time?
17
+ Help me out here.
18
+ </Content>
19
+ <Date>2009-08-24 10:51:31</Date>
20
+ <Timestamp>1251136291</Timestamp>
21
+ <Link>http://answers.yahoo.com/question/?qid=20090824105131AAJyFeP</Link>
22
+ <Category id="396545505">Toronto</Category>
23
+ <UserId>gD3O45YZaa</UserId>
24
+ <UserNick>delightfullytacky</UserNick>
25
+ <UserPhotoURL>http://a323.yahoofs.com/coreid/4e2363ebi52bzws126ac4/hP26bOE3d6_X57.bKhIPA4pnocQMwRgQQuM-/3/tn48.jpeg?ciAAgGPBdR7XKuAK</UserPhotoURL>
26
+ <NumAnswers>2</NumAnswers>
27
+ <NumComments>0</NumComments>
28
+ <ChosenAnswer>*visits website* *watches several videos*
29
+
30
+ It looks like everyone is standing. You could call and ask: 416-869-0045
31
+ or email: clubevents@theguvernment.com</ChosenAnswer>
32
+ <ChosenAnswererId>vDGFRACaaa</ChosenAnswererId>
33
+ <ChosenAnswererNick>Clever Nickname</ChosenAnswererNick>
34
+ <ChosenAnswerTimestamp>1251150093</ChosenAnswerTimestamp>
35
+ <ChosenAnswerAwardTimestamp>1251218910</ChosenAnswerAwardTimestamp>
36
+ </Question>
37
+ <Question id="20110413211429AAGq456" type="Answered">
38
+ <Subject>what is the classical song used in hanna in the grimm haus scene?</Subject>
39
+ <Content>
40
+ Specifically the one Mr. Grimm dances to and explains to her how much she has missed by her father not teaching her music.
41
+ </Content>
42
+ <Date>2011-04-13 21:14:29</Date>
43
+ <Timestamp>1302754469</Timestamp>
44
+ <Link>http://answers.yahoo.com/question/?qid=20110413211429AAGq456</Link>
45
+ <Category id="2115500203">Jazz</Category>
46
+ <UserId>o51L3mQ0aa</UserId>
47
+ <UserNick>Raymond Lam</UserNick>
48
+ <UserPhotoURL>http://l.yimg.com/a/i/identity2/profile_48b.png</UserPhotoURL>
49
+ <NumAnswers>1</NumAnswers>
50
+ <NumComments>0</NumComments>
51
+ <ChosenAnswer>Grieg, In the Hall of the Mountain King
52
+
53
+
54
+
55
+ I searched for days for this thing....</ChosenAnswer>
56
+ <ChosenAnswererId>kF004Enxaa</ChosenAnswererId>
57
+ <ChosenAnswererNick>Matt Revels</ChosenAnswererNick>
58
+ <ChosenAnswerTimestamp>1303031285</ChosenAnswerTimestamp>
59
+ <ChosenAnswerAwardTimestamp>1303273986</ChosenAnswerAwardTimestamp>
60
+ </Question>
61
+ </ResultSet>
62
+ <!-- ws08.ydn.ac4.yahoo.com uncompressed/chunked Wed Aug 3 14:16:04 PDT 2011 -->
@@ -0,0 +1,62 @@
1
+ HTTP/1.1 200 OK
2
+ Date: Thu, 04 Aug 2011 12:39:12 GMT
3
+ P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
4
+ Vary: Accept-Encoding
5
+ Connection: close
6
+ Transfer-Encoding: chunked
7
+ Content-Type: text/xml; charset=utf-8
8
+ Cache-Control: private
9
+
10
+ <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
11
+ <ResultSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:yahoo:answers" xsi:schemaLocation="urn:yahoo:answers http://answers.yahooapis.com/AnswersService/V1/QuestionResponse.xsd">
12
+ <Question id="20110804051037AAY1a19" type="Open">
13
+ <Subject>Wie soll ich die Apps speichern?</Subject>
14
+ <Content>Hallo, ich habe den iPod Touch der 4. Generation gekauft. Davor hatte ich die 3. Gen..
15
+ Nun möchte ich die alten Apps auf den neuen iPod installieren, aber wie soll ich die Apps aus den alten iPod ziehen?
16
+ Auch Musik und Videos!
17
+ Bitte um Hilfe
18
+ Danke
19
+ </Content>
20
+ <Date>2011-08-04 05:10:37</Date>
21
+ <Timestamp>1312459837</Timestamp>
22
+ <Link>http://answers.yahoo.com/question/?qid=20110804051037AAY1a19</Link>
23
+ <Category id="396545664">Software</Category>
24
+ <UserId>J9jXNU1Oaa</UserId>
25
+ <UserNick>Yoyo</UserNick>
26
+ <UserPhotoURL>http://a323.yahoofs.com/coreid/4ca62b4ei2959zws135ac4/r0RWIek1cbZfVx7VFIjHJFx3/2/tn48.jpeg?ciAAgGPBxmucSNz4</UserPhotoURL>
27
+ <NumAnswers>1</NumAnswers>
28
+ <NumComments>0</NumComments>
29
+ <ChosenAnswer></ChosenAnswer>
30
+ <ChosenAnswererId></ChosenAnswererId>
31
+ <ChosenAnswererNick></ChosenAnswererNick>
32
+ <ChosenAnswerTimestamp></ChosenAnswerTimestamp>
33
+ <ChosenAnswerAwardTimestamp></ChosenAnswerAwardTimestamp>
34
+ </Question>
35
+ <Question id="20110727064904AAAbyLW" type="Answered">
36
+ <Subject>Ist mein Gutschein weg?</Subject>
37
+ <Content>Hallo, ich habe einen Gutschein im Wert von 50€ für Amazon.de gekauft.
38
+ Um zu testen, ob er noch gültig ist habe ich einen Artikel ausgewählt und den Gutschein eingelöst, aber die Bestellung nicht abgeschickt!
39
+
40
+ Ist mein Gutschein jetzt eingelöst oder nicht?
41
+ Ich möchte den Artikel nicht kaufen wollte nur testen?
42
+
43
+ Danke
44
+ </Content>
45
+ <Date>2011-07-27 06:49:04</Date>
46
+ <Timestamp>1311774544</Timestamp>
47
+ <Link>http://answers.yahoo.com/question/?qid=20110727064904AAAbyLW</Link>
48
+ <Category id="396545665">Other - Computers</Category>
49
+ <UserId>J9jXNU1Oaa</UserId>
50
+ <UserNick>Yoyo</UserNick>
51
+ <UserPhotoURL>http://a323.yahoofs.com/coreid/4ca62b4ei2959zws135ac4/r0RWIek1cbZfVx7VFIjHJFx3/2/tn48.jpeg?ciAAgGPBxmucSNz4</UserPhotoURL>
52
+ <NumAnswers>3</NumAnswers>
53
+ <NumComments>0</NumComments>
54
+ <ChosenAnswer>Vorher nachdenken? Nur so&#039;n Vorschlag.
55
+ Die Bestellung wird erst wirksam wenn du sie absendest. Amazon baut bei Bestellungen hin und wieder Mist. Einfach anschreiben. Der Kundenservice reagiert i.d.R. schnell und kundenfreundlich.</ChosenAnswer>
56
+ <ChosenAnswererId>82c64064ae238f0ce223f33036950a66aa</ChosenAnswererId>
57
+ <ChosenAnswererNick>another_nick_2006</ChosenAnswererNick>
58
+ <ChosenAnswerTimestamp>1311774821</ChosenAnswerTimestamp>
59
+ <ChosenAnswerAwardTimestamp>1312293814</ChosenAnswerAwardTimestamp>
60
+ </Question>
61
+ </ResultSet>
62
+ <!-- ws09.ydn.ac4.yahoo.com uncompressed/chunked Thu Aug 4 05:39:12 PDT 2011 -->
@@ -0,0 +1,154 @@
1
+ require 'test/unit'
2
+ require 'yanapi/api'
3
+ require 'test_helper'
4
+
5
+ class TestAPI < Test::Unit::TestCase
6
+
7
+ include TestHelper
8
+
9
+ def setup
10
+ @min_input = {
11
+ :method => 'questionSearch',
12
+ :query_params => {
13
+ :appid => 'YahooDemo',
14
+ :query => 'cars'
15
+ }
16
+ }
17
+ @superfluous_input = @min_input.merge({:some_key => 'some_value'})
18
+ end
19
+
20
+ def teardown
21
+ end
22
+
23
+ # It should declare the following constants.
24
+ def test_constant_declaration
25
+ defined_constants = [:REQUIRED_PARAMS,
26
+ :ACCEPTED_METHODS
27
+ ]
28
+
29
+ defined_constants.each do |const|
30
+ assert(YANAPI::API.const_defined?(const))
31
+ end
32
+ end
33
+
34
+ # It should have the following public methods.
35
+ def test_available_public_methods
36
+ methods = [:get, :version]
37
+ methods.each { |m| assert_respond_to(YANAPI::API.new(@min_input), m) }
38
+ end
39
+
40
+ # It should accept a hash.
41
+ def test_input_class
42
+ params = []
43
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(params) }
44
+ assert_match(/Params should be a Hash, not Array!/, e.message)
45
+ end
46
+
47
+ # It should reject an empty subhash <:query_params>.
48
+ def test_rejecting_empty_params
49
+ params = {}
50
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(params) }
51
+ assert_match(/The params hash is empty!/, e.message)
52
+ end
53
+
54
+ # It should accept a parameter hash with the keys
55
+ # <:method> and <:query_params>.
56
+ def test_presence_of_obligatory_keys
57
+ params = {:abc => 'questionSearch' }
58
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(params) }
59
+ assert_match(/You should provide: <:method>, <:query_params>!/,
60
+ e.message)
61
+ params = {:query_params => {:a => 'questionSearch'}}
62
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(params) }
63
+ assert_match(/You should provide: <:method>!/, e.message)
64
+
65
+ params = {:abc => 'questionSearch', :method => 'questionSearch'}
66
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(params) }
67
+ assert_match(/You should provide: <:query_params>!/, e.message)
68
+ end
69
+
70
+ # It should accept a two dimensional hash.
71
+ def test_dimensions_of_params
72
+ params = {:method => 'questionSearch', :query_params => [:abc, :cde]}
73
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(params) }
74
+ assert_match(/<:query_params> should be a Hash, not Array!/,
75
+ e.message)
76
+ params = {:method => 'getByUser', :query_params => {}}
77
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(params) }
78
+ assert_match(/<:query_params> is empty!/, e.message)
79
+ end
80
+
81
+ # It should accept four possible values for <:method>.
82
+ def test_possible_values_for_method
83
+ @min_input[:method] = 'no_method'
84
+ e = assert_raises(YANAPI::UserError) { YANAPI::API.new(@min_input) }
85
+ assert_match(/<no_method> is not a valid search method!/, e.message)
86
+ end
87
+
88
+ # It should warn about presence of other keys.
89
+ def test_warnings_about_ignored_keys
90
+ out, err = intercept_output do
91
+ YANAPI::API.new(@superfluous_input)
92
+ end
93
+ assert_match(/Keys ignored: <:some_key>!/, err)
94
+ out, err = intercept_output do
95
+ YANAPI::API.new(@superfluous_input.merge({:another_key => 'val'}))
96
+ end
97
+ assert_match(/Keys ignored: (<:some_key>|,| |<:another_key>)+!/,
98
+ err)
99
+ end
100
+
101
+ # It should create a query instance of the correct class.
102
+ def test_class_of_the_query_instance
103
+ input = {
104
+ :method => 'questionSearch',
105
+ :query_params => {
106
+ :appid => 'YahooDemo',
107
+ :query => 'cars'
108
+ }
109
+ }
110
+ obj = YANAPI::API.new(input)
111
+ query_obj = obj.instance_variable_get(:@query)
112
+ assert_instance_of(YANAPI::TermQuery, query_obj)
113
+
114
+ input = {
115
+ :method => 'getByUser',
116
+ :query_params => {
117
+ :appid => 'YahooDemo',
118
+ :user_id => 'cars'
119
+ }
120
+ }
121
+ obj = YANAPI::API.new(input)
122
+ query_obj = obj.instance_variable_get(:@query)
123
+ assert_instance_of(YANAPI::UserQuery, query_obj)
124
+
125
+ input = {
126
+ :method => 'getByCategory',
127
+ :query_params => {
128
+ :appid => 'YahooDemo',
129
+ :category_id => '123'
130
+ }
131
+ }
132
+ obj = YANAPI::API.new(input)
133
+ query_obj = obj.instance_variable_get(:@query)
134
+ assert_instance_of(YANAPI::CategoryQuery, query_obj)
135
+
136
+ input = {
137
+ :method => 'getQuestion',
138
+ :query_params => {
139
+ :appid => 'YahooDemo',
140
+ :question_id => '123'
141
+ }
142
+ }
143
+ obj = YANAPI::API.new(input)
144
+ query_obj = obj.instance_variable_get(:@query)
145
+ assert_instance_of(YANAPI::QuestionQuery, query_obj)
146
+ end
147
+
148
+ # It should return a string value for the version.
149
+ def test_version_class
150
+ obj = YANAPI::API.new(@min_input)
151
+ assert_equal(String, obj.version.class)
152
+ assert_equal(false, obj.version.empty?)
153
+ end
154
+ end
@@ -1,5 +1,5 @@
1
1
  require 'test/unit'
2
- require 'yanapi'
2
+ require 'yanapi/category_query'
3
3
  require 'fakeweb'
4
4
 
5
5
  class TestCategoryQuery < Test::Unit::TestCase
@@ -12,6 +12,17 @@ class TestCategoryQuery < Test::Unit::TestCase
12
12
  def teardown
13
13
  end
14
14
 
15
+ # This class should declare the following constants.
16
+ def test_constants
17
+ defined_constants = [:VALID_PARAMS,
18
+ :REQUIRED_PARAMS
19
+ ]
20
+
21
+ defined_constants.each do |const|
22
+ assert(YANAPI::CategoryQuery.const_defined?(const))
23
+ end
24
+ end
25
+
15
26
  # getByCategory (CategorySearch) needs either :category_id or :category_name
16
27
  def test_missing_category
17
28
  @params.delete(:category_name)
@@ -1,5 +1,5 @@
1
1
  require 'test/unit'
2
- require 'yanapi'
2
+ require 'yanapi/common'
3
3
 
4
4
  class TestCommon < Test::Unit::TestCase
5
5
  def setup
@@ -0,0 +1,31 @@
1
+ module TestHelper
2
+ # It is a helper method, many testable units provide verbose output
3
+ # to stderr and/or stdout. It can suppress any kind of verbosity.
4
+ def quietly(&b)
5
+ begin
6
+ orig_stderr = $stderr.clone
7
+ orig_stdout = $stdout.clone
8
+ $stderr.reopen(File.new('/dev/null', 'w'))
9
+ $stdout.reopen(File.new('/dev/null', 'w'))
10
+ b.call
11
+ ensure
12
+ $stderr.reopen(orig_stderr)
13
+ $stdout.reopen(orig_stdout)
14
+ end
15
+ end
16
+
17
+ # It is a helper method for handling stdout and stderr as strings.
18
+ def intercept_output
19
+ orig_stdout = $stdout
20
+ orig_stderr = $stderr
21
+ $stdout = StringIO.new
22
+ $stderr = StringIO.new
23
+
24
+ yield
25
+
26
+ return $stdout.string, $stderr.string
27
+ ensure
28
+ $stdout = orig_stdout
29
+ $stderr = orig_stderr
30
+ end
31
+ end
@@ -0,0 +1,129 @@
1
+ require 'yanapi'
2
+ require 'fakeweb'
3
+ require 'test/unit'
4
+
5
+ class TestIntegration < Test::Unit::TestCase
6
+ def setup
7
+ end
8
+
9
+ def teardown
10
+ end
11
+
12
+ # It should find questions for given key words.
13
+ def test_term_query
14
+ params = {
15
+ :method => 'questionSearch',
16
+ :query_params => {
17
+ :appid => 'YahooDemo',
18
+ :query => 'Haus',
19
+ :search_in => 'question',
20
+ :type => 'resolved',
21
+ :results => 2,
22
+ :output => 'xml'
23
+ }
24
+ }
25
+ file = 'test_term_query'
26
+ exp, act = compare(params, file)
27
+ assert_equal(exp, act)
28
+ end
29
+
30
+ # It should find questions for a given category.
31
+ def test_category_query
32
+ params = {
33
+ :method => 'getByCategory',
34
+ :query_params => {
35
+ :appid => 'YahooDemo',
36
+ :category_id => '396545664',
37
+ :region => 'de',
38
+ :type => 'resolved',
39
+ :results => 2,
40
+ :output => 'xml'
41
+ }
42
+ }
43
+ file = 'test_term_query'
44
+ exp, act = compare(params, file)
45
+ assert_equal(exp, act)
46
+ end
47
+
48
+ # It should find questions for a given user ID.
49
+ def test_user_query
50
+ params = {
51
+ :method => 'getByUser',
52
+ :query_params => {
53
+ :appid => 'YahooDemo',
54
+ :user_id => 'J9jXNU1Oaa',
55
+ :filter => 'question',
56
+ :results => 2,
57
+ :output => 'xml'
58
+ }
59
+ }
60
+ file = 'test_term_query'
61
+ exp, act = compare(params, file)
62
+ assert_equal(exp, act)
63
+ end
64
+
65
+ # It should find a question given a question ID.
66
+ def test_question_query
67
+ params = {
68
+ :method => 'getQuestion',
69
+ :query_params => {
70
+ :appid => 'YahooDemo',
71
+ :question_id => '20110804051037AAY1a19',
72
+ :output => 'xml'
73
+ }
74
+ }
75
+ file = 'test_term_query'
76
+ exp, act = compare(params, file)
77
+ assert_equal(exp, act)
78
+ end
79
+
80
+ # It should return <nil> if nothing has been found.
81
+ def test_empty_response
82
+ params = {
83
+ :method => 'questionSearch',
84
+ :query_params => {
85
+ :appid => 'YahooDemo',
86
+ :query => 'Haus',
87
+ :category_id => '396545219',
88
+ :search_in => 'question',
89
+ :type => 'resolved'
90
+ }
91
+ }
92
+ file = 'test_empty_response'
93
+ exp, act = compare(params, file)
94
+ assert_equal(nil, act)
95
+ end
96
+
97
+ # It should exit with an exception given an invalid input.
98
+ def test_invalid_query
99
+ params = {
100
+ :method => 'questionSearch',
101
+ :query_params => {
102
+ :query => 'Haus',
103
+ :category_id => '396545219',
104
+ :search_in => 'question',
105
+ :type => 'resolved'
106
+ }
107
+ }
108
+ assert_raises(YANAPI::UserError) do
109
+ api = YANAPI::API.new(params)
110
+ end
111
+ end
112
+
113
+ # It is a helper method, it takes the params hash and the name
114
+ # of the file with a right answer and asserts their equality.
115
+ def compare(params, file)
116
+ file = 'test/integration_test_data/' + file + '.txt'
117
+ http_answer = File.open(file) { |f| f.read }
118
+ # Deleting the http answer header, leaving xml structure.
119
+ expected_api_answer = http_answer.sub(/^[^<]+/m, '')
120
+
121
+ api = YANAPI::API.new(params)
122
+ url = api.instance_variable_get(:@query).
123
+ instance_variable_get(:@url)
124
+ FakeWeb.register_uri(:get, url, :response => http_answer)
125
+
126
+ actual_api_answer = api.get
127
+ return expected_api_answer, actual_api_answer
128
+ end
129
+ end