npr 0.0.0 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (148) hide show
  1. data/.travis.yml +13 -0
  2. data/{LICENSE → MIT-LICENSE} +1 -1
  3. data/README.md +115 -3
  4. data/Rakefile +6 -0
  5. data/gemfiles/Gemfile.rb-1.8.7 +6 -0
  6. data/lib/npr/api/client.rb +87 -0
  7. data/lib/npr/api/message.rb +38 -0
  8. data/lib/npr/api/query_builder.rb +222 -0
  9. data/lib/npr/api/response.rb +32 -0
  10. data/lib/npr/api.rb +7 -0
  11. data/lib/npr/concern/attr_typecast.rb +59 -0
  12. data/lib/npr/concern/relation.rb +103 -0
  13. data/lib/npr/concern/shallow_attributes.rb +71 -0
  14. data/lib/npr/concern.rb +9 -0
  15. data/lib/npr/configuration.rb +120 -0
  16. data/lib/npr/core_ext/array/wrap.rb +15 -0
  17. data/lib/npr/entity/audio.rb +28 -0
  18. data/lib/npr/entity/author.rb +22 -0
  19. data/lib/npr/entity/base.rb +19 -0
  20. data/lib/npr/entity/book.rb +21 -0
  21. data/lib/npr/entity/book_edition.rb +26 -0
  22. data/lib/npr/entity/byline.rb +18 -0
  23. data/lib/npr/entity/collection.rb +11 -0
  24. data/lib/npr/entity/crop.rb +20 -0
  25. data/lib/npr/entity/enlargement.rb +20 -0
  26. data/lib/npr/entity/formats.rb +19 -0
  27. data/lib/npr/entity/image.rb +33 -0
  28. data/lib/npr/entity/intro_text.rb +21 -0
  29. data/lib/npr/entity/link.rb +23 -0
  30. data/lib/npr/entity/list.rb +28 -0
  31. data/lib/npr/entity/list_text.rb +19 -0
  32. data/lib/npr/entity/member.rb +23 -0
  33. data/lib/npr/entity/member_byline.rb +17 -0
  34. data/lib/npr/entity/member_promo_art.rb +17 -0
  35. data/lib/npr/entity/mp3.rb +23 -0
  36. data/lib/npr/entity/organization.rb +18 -0
  37. data/lib/npr/entity/paragraph.rb +27 -0
  38. data/lib/npr/entity/permissions.rb +18 -0
  39. data/lib/npr/entity/program.rb +24 -0
  40. data/lib/npr/entity/promo_art.rb +17 -0
  41. data/lib/npr/entity/promo_art_book_edition.rb +18 -0
  42. data/lib/npr/entity/provider.rb +23 -0
  43. data/lib/npr/entity/pull_quote.rb +16 -0
  44. data/lib/npr/entity/related_link.rb +21 -0
  45. data/lib/npr/entity/show.rb +19 -0
  46. data/lib/npr/entity/story.rb +179 -0
  47. data/lib/npr/entity/text.rb +22 -0
  48. data/lib/npr/entity/title.rb +21 -0
  49. data/lib/npr/entity/transcript.rb +16 -0
  50. data/lib/npr/entity.rb +7 -0
  51. data/lib/npr/errors.rb +17 -0
  52. data/lib/npr/version.rb +1 -1
  53. data/lib/npr.rb +64 -3
  54. data/npr.gemspec +12 -2
  55. data/spec/fixtures/README.md +30 -0
  56. data/spec/fixtures/atom/01_story_full_media.atom +36 -0
  57. data/spec/fixtures/atom/02_story_multiple_images.atom +32 -0
  58. data/spec/fixtures/atom/03_no_results.atom +10 -0
  59. data/spec/fixtures/atom/04_invalid_id.atom +344 -0
  60. data/spec/fixtures/atom/05_no_api_key.atom +9 -0
  61. data/spec/fixtures/atom/06_story_multiple_ids.atom +59 -0
  62. data/spec/fixtures/fetch_formats.rb +65 -0
  63. data/spec/fixtures/html/01_story_full_media.html +54 -0
  64. data/spec/fixtures/html/02_story_multiple_images.html +55 -0
  65. data/spec/fixtures/html/03_no_results.html +38 -0
  66. data/spec/fixtures/html/04_invalid_id.html +82 -0
  67. data/spec/fixtures/html/05_no_api_key.html +8 -0
  68. data/spec/fixtures/html/06_story_multiple_ids.html +69 -0
  69. data/spec/fixtures/js/01_story_full_media.js +1 -0
  70. data/spec/fixtures/js/02_story_multiple_images.js +1 -0
  71. data/spec/fixtures/js/03_no_results.js +1 -0
  72. data/spec/fixtures/js/04_invalid_id.js +1 -0
  73. data/spec/fixtures/js/05_no_api_key.js +8 -0
  74. data/spec/fixtures/js/06_story_multiple_ids.js +1 -0
  75. data/spec/fixtures/json/01_story_full_media.json +1 -0
  76. data/spec/fixtures/json/02_story_multiple_images.json +1 -0
  77. data/spec/fixtures/json/03_no_results.json +1 -0
  78. data/spec/fixtures/json/04_invalid_id.json +1 -0
  79. data/spec/fixtures/json/05_no_api_key.json +1 -0
  80. data/spec/fixtures/json/06_story_multiple_ids.json +1 -0
  81. data/spec/fixtures/json/list.json +1 -0
  82. data/spec/fixtures/mediarss/01_story_full_media.rss +31 -0
  83. data/spec/fixtures/mediarss/02_story_multiple_images.rss +40 -0
  84. data/spec/fixtures/mediarss/03_no_results.rss +17 -0
  85. data/spec/fixtures/mediarss/04_invalid_id.rss +279 -0
  86. data/spec/fixtures/mediarss/05_no_api_key.rss +31 -0
  87. data/spec/fixtures/mediarss/06_story_multiple_ids.rss +65 -0
  88. data/spec/fixtures/nprml/01_story_full_media.xml +271 -0
  89. data/spec/fixtures/nprml/02_story_multiple_images.xml +165 -0
  90. data/spec/fixtures/nprml/03_no_results.xml +14 -0
  91. data/spec/fixtures/nprml/04_invalid_id.xml +1780 -0
  92. data/spec/fixtures/nprml/05_no_api_key.xml +9 -0
  93. data/spec/fixtures/nprml/06_story_multiple_ids.xml +435 -0
  94. data/spec/fixtures/nprml/list.xml +440 -0
  95. data/spec/fixtures/podcast/01_story_full_media.rss +30 -0
  96. data/spec/fixtures/podcast/02_story_multiple_images.rss +32 -0
  97. data/spec/fixtures/podcast/03_no_results.rss +19 -0
  98. data/spec/fixtures/podcast/04_invalid_id.rss +186 -0
  99. data/spec/fixtures/podcast/05_no_api_key.rss +31 -0
  100. data/spec/fixtures/podcast/06_story_multiple_ids.rss +43 -0
  101. data/spec/fixtures/rss/01_story_full_media.rss +25 -0
  102. data/spec/fixtures/rss/02_story_multiple_images.rss +25 -0
  103. data/spec/fixtures/rss/03_no_results.rss +17 -0
  104. data/spec/fixtures/rss/04_invalid_id.rss +137 -0
  105. data/spec/fixtures/rss/05_no_api_key.rss +31 -0
  106. data/spec/fixtures/rss/06_story_multiple_ids.rss +33 -0
  107. data/spec/spec_helper.rb +23 -0
  108. data/spec/support/config_helper.rb +64 -0
  109. data/spec/support/fake_response.rb +54 -0
  110. data/spec/support/fixture_helper.rb +23 -0
  111. data/spec/unit/api/client_spec.rb +42 -0
  112. data/spec/unit/api/message_spec.rb +68 -0
  113. data/spec/unit/api/query_builder_spec.rb +195 -0
  114. data/spec/unit/api/response_spec.rb +45 -0
  115. data/spec/unit/configuration_spec.rb +63 -0
  116. data/spec/unit/entity/audio_spec.rb +75 -0
  117. data/spec/unit/entity/author_spec.rb +30 -0
  118. data/spec/unit/entity/base_spec.rb +87 -0
  119. data/spec/unit/entity/book_edition_spec.rb +57 -0
  120. data/spec/unit/entity/book_spec.rb +31 -0
  121. data/spec/unit/entity/byline_spec.rb +23 -0
  122. data/spec/unit/entity/collection_spec.rb +39 -0
  123. data/spec/unit/entity/crop_spec.rb +25 -0
  124. data/spec/unit/entity/englargement_spec.rb +21 -0
  125. data/spec/unit/entity/formats_spec.rb +41 -0
  126. data/spec/unit/entity/image_spec.rb +82 -0
  127. data/spec/unit/entity/intro_text_spec.rb +25 -0
  128. data/spec/unit/entity/link_spec.rb +25 -0
  129. data/spec/unit/entity/list_spec.rb +22 -0
  130. data/spec/unit/entity/list_text_spec.rb +31 -0
  131. data/spec/unit/entity/member_byline_spec.rb +21 -0
  132. data/spec/unit/entity/member_promo_art_spec.rb +21 -0
  133. data/spec/unit/entity/member_spec.rb +59 -0
  134. data/spec/unit/entity/mp3_spec.rb +25 -0
  135. data/spec/unit/entity/organization_spec.rb +29 -0
  136. data/spec/unit/entity/paragraph_spec.rb +25 -0
  137. data/spec/unit/entity/permissions_spec.rb +56 -0
  138. data/spec/unit/entity/program_spec.rb +27 -0
  139. data/spec/unit/entity/promo_art_book_edition_spec.rb +21 -0
  140. data/spec/unit/entity/promo_art_spec.rb +42 -0
  141. data/spec/unit/entity/pull_quote_spec.rb +29 -0
  142. data/spec/unit/entity/related_link_spec.rb +55 -0
  143. data/spec/unit/entity/show_spec.rb +41 -0
  144. data/spec/unit/entity/story_spec.rb +154 -0
  145. data/spec/unit/entity/text_spec.rb +54 -0
  146. data/spec/unit/entity/title_spec.rb +25 -0
  147. data/spec/unit/entity/transcript_spec.rb +22 -0
  148. metadata +340 -8
@@ -0,0 +1,33 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <rss xmlns:npr="http://www.npr.org/rss/" xmlns:nprml="http://api.npr.org/nprml" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:content="http://purl.org/rss/1.0/modules/content/" version="2.0">
3
+ <channel>
4
+ <title>NPR: Stories from NPR</title>
5
+ <link>http://www.npr.org</link>
6
+ <description>Assorted stories from NPR</description>
7
+ <language>en</language>
8
+ <copyright>Copyright 2012 NPR - For Personal Use Only</copyright>
9
+ <generator>NPR API RSS Generator 0.94</generator>
10
+ <lastBuildDate>Thu, 13 Dec 2012 14:53:00 -0500</lastBuildDate>
11
+ <image>
12
+ <url>http://media.npr.org/images/npr_news_123x20.gif</url>
13
+ <title>NPR: Stories from NPR</title>
14
+ <link>http://www.npr.org</link>
15
+ </image>
16
+ <item>
17
+ <title>Why Legos Are So Expensive — And So Popular</title>
18
+ <description>Legos often cost twice as much as similar blocks from a rival toymaker. So why are Legos so much more popular than other brands?</description>
19
+ <pubDate>Thu, 13 Dec 2012 14:53:00 -0500</pubDate>
20
+ <link>http://www.npr.org/blogs/money/2012/12/13/167055503/why-legos-are-so-expensive-and-so-popular?ft=1&amp;f=166956822,167055503</link>
21
+ <guid>http://www.npr.org/blogs/money/2012/12/13/167055503/why-legos-are-so-expensive-and-so-popular?ft=1&amp;f=166956822,167055503</guid>
22
+ <content:encoded><![CDATA[<p>Legos often cost twice as much as similar blocks from a rival toymaker. So why are Legos so much more popular than other brands?</p><p><a href="http://www.npr.org/templates/email/emailAFriend.php?storyId=167055503">&raquo; E-Mail This</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://del.icio.us/post?url=http%3A%2F%2Fwww.npr.org%2Ftemplates%2Fstory%2Fstory.php%3FstoryId%3D167055503">&raquo; Add to Del.icio.us</a></p>]]></content:encoded>
23
+ </item>
24
+ <item>
25
+ <title>How The Rich Feel About Paying More Taxes</title>
26
+ <description>Many people earning more than $250,000 a year — the 2 percent — admit they can afford to pay more in taxes. However, they don't necessarily like the idea, especially when they're made to feel like skinflints even though they're already sending significant sums to Washington.</description>
27
+ <pubDate>Thu, 13 Dec 2012 11:22:00 -0500</pubDate>
28
+ <link>http://www.npr.org/2012/12/11/166956822/how-the-rich-feel-about-paying-more-taxes?ft=1&amp;f=166956822,167055503</link>
29
+ <guid>http://www.npr.org/2012/12/11/166956822/how-the-rich-feel-about-paying-more-taxes?ft=1&amp;f=166956822,167055503</guid>
30
+ <content:encoded><![CDATA[<p>Many people earning more than $250,000 a year — the 2 percent — admit they can afford to pay more in taxes. However, they don't necessarily like the idea, especially when they're made to feel like skinflints even though they're already sending significant sums to Washington.</p><p><a href="http://www.npr.org/templates/email/emailAFriend.php?storyId=166956822">&raquo; E-Mail This</a>&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://del.icio.us/post?url=http%3A%2F%2Fwww.npr.org%2Ftemplates%2Fstory%2Fstory.php%3FstoryId%3D166956822">&raquo; Add to Del.icio.us</a></p>]]></content:encoded>
31
+ </item>
32
+ </channel>
33
+ </rss>
@@ -0,0 +1,23 @@
1
+ require 'bundler/setup'
2
+ Bundler.require
3
+
4
+ SPEC_ROOT = File.dirname(__FILE__)
5
+ FIXTURE_ROOT = File.join SPEC_ROOT, "fixtures"
6
+
7
+ # Require the support files
8
+ Dir["#{SPEC_ROOT}/support/**/*.rb"].each { |f| require f }
9
+
10
+ # Disallow real network connections
11
+ require 'fakeweb'
12
+ FakeWeb.allow_net_connect = false
13
+
14
+ # Configuration
15
+ RSpec.configure do |config|
16
+ config.include FakeResponse
17
+ config.include ConfigHelper
18
+ config.include FixtureHelper
19
+
20
+ config.before do
21
+ FakeWeb.clean_registry
22
+ end
23
+ end
@@ -0,0 +1,64 @@
1
+ ##
2
+ # ConfigHelper
3
+ #
4
+ module ConfigHelper
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ #------------------
10
+
11
+ def config(options)
12
+ @_config_reset = NPR.config
13
+ NPR.config.merge(options)
14
+ end
15
+
16
+ #------------------
17
+
18
+ def reset_config
19
+ NPR.instance_variable_set(:@config, @_config_reset)
20
+ end
21
+
22
+ #------------------
23
+
24
+ def config!(options)
25
+ config = NPR::Configuration.new(options)
26
+ NPR.instance_variable_set(:@config, config)
27
+ end
28
+
29
+ #------------------
30
+
31
+ def clear_config
32
+ NPR.instance_variable_set(:@config, nil)
33
+ end
34
+
35
+ #------------------
36
+
37
+ module ClassMethods
38
+ # Merge the options into whatever the config
39
+ # currently is, and reset it to its previous
40
+ # state after.
41
+ def config(options)
42
+ before :all do
43
+ config(options)
44
+ end
45
+
46
+ after :all do
47
+ reset_config
48
+ end
49
+ end
50
+
51
+ #--------------------
52
+ # Set the config to ONLY the provided options,
53
+ # and set to nil after.
54
+ def config!(options)
55
+ before :all do
56
+ config!(options)
57
+ end
58
+
59
+ after :all do
60
+ reset_config
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,54 @@
1
+ ##
2
+ # FakeResponse
3
+ #
4
+ # Helpers for faking responses from the API
5
+ #
6
+ module FakeResponse
7
+ #---------------------
8
+ # Takes the filename to respond with,
9
+ # and (optionally) any options to be passed to
10
+ # +FakeWeb.register_uri+.
11
+ #
12
+ # If no block is given, the registry will not be cleaned
13
+ # by this method.
14
+ #
15
+ # If passed a block, it will clean the registry after
16
+ # the block has been run.
17
+ #
18
+ def mock_response(filename, options={}, &block)
19
+ respond_with(filename, options)
20
+
21
+ response = yield
22
+ FakeWeb.clean_registry
23
+
24
+ response
25
+ end
26
+
27
+ #---------------------
28
+ # Register the NPR root with FakeWeb, and set its
29
+ # response body to the contents of the requested file.
30
+ def respond_with(filename, options)
31
+ content_type = options[:content_type] || "application/json"
32
+
33
+ FakeWeb.register_uri(:get,
34
+ %r{^#{NPR::Configuration::API_ROOT}},
35
+ { :body => load_fixture(filename),
36
+ :content_type => content_type
37
+ }.merge(options))
38
+ end
39
+
40
+ #---------------------
41
+ # Read a fixure file
42
+ def load_fixture(filename)
43
+ file = filename == :random ? random_filename : filename
44
+ File.read(File.join FIXTURE_ROOT, file)
45
+ end
46
+
47
+ #---------------------
48
+ # Select a random response fixture
49
+ def random_filename
50
+ filename = Dir["#{FIXTURE_ROOT}/**/*story*.rb"].sample
51
+ puts "Responding with #{filename}"
52
+ filename
53
+ end
54
+ end # FakeResponse
@@ -0,0 +1,23 @@
1
+ ##
2
+ # FixtureHelper
3
+ #
4
+ # Helps with doing inline fixtures for JSON strings
5
+ #
6
+ module FixtureHelper
7
+ def self.included(base)
8
+ base.extend ClassMethods
9
+ end
10
+
11
+ module ClassMethods
12
+ def json_fixture(&block)
13
+ before :all do
14
+ @json = yield
15
+ @fixture = JSON.parse(@json)
16
+ end
17
+
18
+ after :all do
19
+ @json, @fixture = nil, nil
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,42 @@
1
+ require "spec_helper"
2
+
3
+ describe NPR::API::Client do
4
+ describe "params" do
5
+ it "sets @apiKey on initialize and removes it from the params if passed in" do
6
+ client = NPR::API::Client.new(:apiKey => "key")
7
+ client.instance_variable_get(:@apiKey).should eq "key"
8
+ client.params.keys.should_not include :apiKey
9
+ end
10
+
11
+ it "uses global config" do
12
+ NPR.config.sort = "super sort"
13
+ client = NPR::API::Client.new
14
+ client.params[:sort].should eq "super sort"
15
+ end
16
+
17
+ it "passed-in params take precedence over global config" do
18
+ NPR.config.sort = "global sort"
19
+ client = NPR::API::Client.new(:sort => "local sort")
20
+ client.params[:sort].should eq "local sort"
21
+ end
22
+ end
23
+
24
+ #-----------------
25
+
26
+ describe "#query" do
27
+ it "raises NotConfiguredError if apiKey is blank" do
28
+ client = NPR::API::Client.new
29
+ lambda { client.query }.should raise_error NPR::NotConfiguredError
30
+ end
31
+
32
+ context "nprml" do
33
+ it "returns a result in hash format" do
34
+ end
35
+ end
36
+
37
+ context "json" do
38
+ it "returns a result in hash format" do
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,68 @@
1
+ require "spec_helper"
2
+
3
+ describe NPR::API::Message do
4
+ describe "warning" do
5
+ json_fixture do
6
+ <<-JSON
7
+ {
8
+ "id": "203",
9
+ "level": "warning",
10
+ "text": {
11
+ "$text": "Query parameter id='000' is invalid because it is not an integer and was ignored."
12
+ },
13
+ "timestamp": {
14
+ "$text": "1355552691.56"
15
+ }
16
+ }
17
+ JSON
18
+ end
19
+
20
+ before :each do
21
+ @message = NPR::API::Message.new(@fixture)
22
+ end
23
+
24
+ it "sets level and id" do
25
+ @message.id.should eq "203"
26
+ @message.level.should eq "warning"
27
+ end
28
+
29
+ it "returns true for #warning?" do
30
+ @message.warning?.should eq true
31
+ end
32
+
33
+ it "sets text" do
34
+ @message.text.should match /^Query/
35
+ end
36
+
37
+ it "sets timestamp" do
38
+ @message.timestamp.should be_a Time
39
+ end
40
+ end
41
+
42
+ #---------------------------
43
+
44
+ describe "error" do
45
+ json_fixture do
46
+ <<-JSON
47
+ {
48
+ "id": "310",
49
+ "level": "error",
50
+ "text": {
51
+ "$text": "The API key passed in () was invalid or no API key was passed in. Please register for a valid API key."
52
+ },
53
+ "timestamp": {
54
+ "$text": "1355554389.89"
55
+ }
56
+ }
57
+ JSON
58
+ end
59
+
60
+ before :each do
61
+ @message = NPR::API::Message.new(@fixture)
62
+ end
63
+
64
+ it "is an error" do
65
+ @message.error?.should eq true
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,195 @@
1
+ require "spec_helper"
2
+
3
+ describe NPR::API::QueryBuilder do
4
+ describe "#to_params" do
5
+ before :each do
6
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
7
+ end
8
+
9
+ it "turns the query builder in params that the API can understand" do
10
+ @builder.where(:id => 5).order("date descending").limit(10).offset(100)
11
+ @builder.to_params.should eq Hash[
12
+ :id => 5 ,
13
+ :sort => "date descending",
14
+ :numResults => 10,
15
+ :startNum => 100
16
+ ]
17
+ end
18
+
19
+ it "merges in @builder[:extra] last, which overrides anything" do
20
+ @builder.set(:id => 5).where(:id => 10)
21
+ @builder.to_params.should eq Hash[:id => 5]
22
+ end
23
+
24
+ it "doesn't create params if the value was not set" do
25
+ @builder.where(:id => 5).to_params.keys.should eq [:id]
26
+ end
27
+
28
+ it "is an empty hash if no params are set" do
29
+ @builder.to_params.should eq Hash.new
30
+ end
31
+ end
32
+
33
+ #----------------------
34
+
35
+ describe "#to_a" do
36
+ config!(:apiKey => "key")
37
+
38
+ before :each do
39
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
40
+ @builder.set(:apiKey => "key")
41
+ end
42
+
43
+ it "returns an array of stories if present" do
44
+ @builder.where(:id => 5).order("date descending").limit(10).offset(100)
45
+
46
+ stories = mock_response "json/06_story_multiple_ids.json" do
47
+ @builder.to_a
48
+ end
49
+
50
+ stories.should be_a Array
51
+ stories.should_not be_empty
52
+ stories.first.should be_a NPR::Story
53
+ end
54
+
55
+ it "returns an empty array if no list or no stories were found" do
56
+ @builder.where(:id => 5).order("date descending").limit(10).offset(100)
57
+
58
+ stories = mock_response "json/05_no_api_key.json" do
59
+ @builder.to_a
60
+ end
61
+
62
+ stories.should be_a Array
63
+ stories.should be_empty
64
+ end
65
+ end
66
+
67
+ #----------------------
68
+
69
+ describe "#query" do
70
+ config!(:apiKey => "key")
71
+
72
+ before :each do
73
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
74
+ end
75
+
76
+ it "sends off a query and returns the response object" do
77
+ response = mock_response "json/01_story_full_media.json" do
78
+ @builder.where(:id => 100).query
79
+ end
80
+
81
+ response.should be_a NPR::API::Response
82
+ end
83
+ end
84
+
85
+ #----------------------
86
+
87
+ describe "#set" do
88
+ before :each do
89
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
90
+ end
91
+
92
+ it "sets arbitrary parameters" do
93
+ @builder.set(:whatever => "something cool")
94
+ @builder.builder[:extra].should eq Hash[
95
+ :whatever => "something cool"
96
+ ]
97
+ end
98
+
99
+ it "returns itself" do
100
+ @builder.set(:a => "b").should eq @builder
101
+ end
102
+ end
103
+
104
+ #----------------------
105
+
106
+ describe "#where" do
107
+ before :each do
108
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
109
+ end
110
+
111
+ it "adds the conditions to the query builder" do
112
+ @builder.where(:id => 9999)
113
+ @builder.where(:origId => 100)
114
+
115
+ @builder.builder.should eq Hash[
116
+ :conditions => {
117
+ :id => 9999,
118
+ :origId => 100
119
+ }]
120
+ end
121
+
122
+ it "returns itself" do
123
+ @builder.where(:id => 0).should eq @builder
124
+ end
125
+ end
126
+
127
+ #----------------------
128
+
129
+ describe "#order" do
130
+ before :each do
131
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
132
+ end
133
+
134
+ it "adds the order to the query builder" do
135
+ @builder.order("date descending")
136
+ @builder.builder.should eq Hash[:order => "date descending"]
137
+ end
138
+
139
+ it "returns itself" do
140
+ @builder.order("date ascending").should eq @builder
141
+ end
142
+ end
143
+
144
+ #----------------------
145
+
146
+ describe "#limit" do
147
+ before :each do
148
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
149
+ end
150
+
151
+ it "adds the limit to the query builder" do
152
+ @builder.limit(10)
153
+ @builder.builder.should eq Hash[:limit => 10]
154
+ end
155
+
156
+ it "returns itself" do
157
+ @builder.limit(0).should eq @builder
158
+ end
159
+ end
160
+
161
+ #----------------------
162
+
163
+ describe "#offset" do
164
+ before :each do
165
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
166
+ end
167
+
168
+ it "adds the offset to the query builder" do
169
+ @builder.offset(100)
170
+ @builder.builder.should eq Hash[:offset => 100]
171
+ end
172
+
173
+ it "returns itself" do
174
+ @builder.offset(0).should eq @builder
175
+ end
176
+ end
177
+
178
+ #----------------------
179
+
180
+ describe "chaining queries" do
181
+ before :each do
182
+ @builder = NPR::API::QueryBuilder.new(NPR::Story)
183
+ end
184
+
185
+ it "can chain the queries" do
186
+ @builder.where(:id => 5).order("date descending").limit(10).offset(100)
187
+ @builder.builder.should eq Hash[
188
+ :conditions => { :id => 5 },
189
+ :order => "date descending",
190
+ :limit => 10,
191
+ :offset => 100
192
+ ]
193
+ end
194
+ end
195
+ end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+ require "json"
3
+
4
+ describe NPR::API::Response do
5
+ before :each do
6
+ @client = NPR::API::Client.new(:apiKey => "key")
7
+ end
8
+
9
+ describe "messages" do
10
+ it "generates messages" do
11
+ response = mock_response "json/04_invalid_id.json" do
12
+ @client.query(:id => 999)
13
+ end
14
+
15
+ response.messages.size.should eq 1
16
+ response.messages.first.id.should eq "201"
17
+ end
18
+
19
+ it "adds the messages association even if there aren't any" do
20
+ response = mock_response "json/01_story_full_media.json" do
21
+ @client.query(:id => 999)
22
+ end
23
+
24
+ response.messages.should eq []
25
+ end
26
+ end
27
+
28
+ describe "list" do
29
+ it "is generated" do
30
+ response = mock_response "json/01_story_full_media.json" do
31
+ @client.query(:id => 999)
32
+ end
33
+
34
+ response.list.should be_a NPR::Entity::List
35
+ end
36
+
37
+ it "isn't generated no list node was present" do
38
+ response = mock_response "json/05_no_api_key.json" do
39
+ @client.query(:id => 999)
40
+ end
41
+
42
+ response.list.should eq nil
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,63 @@
1
+ require "spec_helper"
2
+
3
+ describe NPR::Configuration do
4
+ describe "NPR.configure" do
5
+ after :each do
6
+ NPR.instance_variable_set :@config, nil
7
+ end
8
+
9
+ it "takes a block to set global configuration" do
10
+ NPR.configure do |config|
11
+ config.sort = "cool sorting, bro"
12
+ end
13
+
14
+ NPR.config.sort.should eq "cool sorting, bro"
15
+ NPR.config.apiKey.should eq nil
16
+ end
17
+ end
18
+
19
+ describe "NPR.config" do
20
+ it "creates a new NPR::Configure object" do
21
+ config = NPR.config
22
+ config.should be_a NPR::Configuration
23
+ NPR.config.should equal config
24
+ end
25
+ end
26
+
27
+ #------------------
28
+
29
+ describe "with options" do
30
+ it "assigns the passed-in options using the setter" do
31
+ config = NPR::Configuration.new(:apiKey => "hello")
32
+ config.apiKey.should eq "hello"
33
+ end
34
+ end
35
+
36
+ #------------------
37
+
38
+ describe "#to_hash" do
39
+ it "converts the config to a hash" do
40
+ config = NPR::Configuration.new
41
+ config.sort = "date"
42
+ config.apiKey = "key"
43
+
44
+ config.to_hash.should eq Hash[:sort => "date", :apiKey => "key"]
45
+ end
46
+ end
47
+
48
+ #------------------
49
+
50
+ describe "#merge" do
51
+ it "turns it into a hash and merges it with the passed-in hash" do
52
+ config = NPR::Configuration.new
53
+ config.sort = "date"
54
+ config.apiKey = "key"
55
+
56
+ config.merge(:title => "List").should eq Hash[
57
+ :title => "List",
58
+ :sort => "date",
59
+ :apiKey => "key"
60
+ ]
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,75 @@
1
+ require "spec_helper"
2
+
3
+ describe NPR::Entity::Audio do
4
+ json_fixture do
5
+ <<-JSON
6
+ {
7
+ "id": "167255688",
8
+ "type": "primary",
9
+ "title": {},
10
+ "duration": {
11
+ "$text": "465"
12
+ },
13
+ "description": {},
14
+ "format": {
15
+ "mp3": [
16
+ {
17
+ "type": "mp3",
18
+ "$text": "http://pd.npr.org/anon.npr-mp3/npr/totn/2012/12/20121214_totn_01.mp3?orgId=1&topicId=1007&ft=3&f="
19
+ },
20
+ {
21
+ "type": "m3u",
22
+ "$text": "http://api.npr.org/m3u/1167255688-5265f3.m3u?orgId=1&topicId=1007&ft=3&f="
23
+ }
24
+ ],
25
+ "wm": {
26
+ "$text": "http://www.npr.org/templates/dmg/dmg_wmref_em.php?id=167255688&type=1&mtype=WM&orgId=1&topicId=1007&ft=3&f="
27
+ },
28
+ "mediastream": {
29
+ "$text": "rtmp://flash.npr.org/ondemand/mp3:anon.npr-mp3/npr/totn/2012/12/20121214_totn_01.mp3"
30
+ }
31
+ },
32
+ "rightsHolder": {},
33
+ "permissions": {
34
+ "download": {
35
+ "allow": "true"
36
+ },
37
+ "stream": {
38
+ "allow": "true"
39
+ },
40
+ "embed": {
41
+ "allow": "true"
42
+ }
43
+ },
44
+ "stream": {
45
+ "active": "false"
46
+ }
47
+ }
48
+ JSON
49
+ end
50
+
51
+ before :each do
52
+ @audio = NPR::Entity::Audio.new(@fixture)
53
+ end
54
+
55
+ it "sets attributes" do
56
+ @audio.id.should eq 167255688
57
+ @audio.type.should eq "primary"
58
+ @audio.title.should eq ""
59
+ @audio.duration.should eq 465
60
+ @audio.description.should eq ""
61
+ @audio.rightsHolder.should eq ""
62
+ end
63
+
64
+ it "sets permissions" do
65
+ @audio.permissions.should be_a NPR::Entity::Permissions
66
+ end
67
+
68
+ it "sets stream" do
69
+ @audio.stream.should eq false
70
+ end
71
+
72
+ it "sets format" do
73
+ @audio.formats.should be_a NPR::Entity::Formats
74
+ end
75
+ end