lexile 0.0.2

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.
data/lib/lexile.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'json'
2
+ require 'hashie/mash'
3
+ require 'httparty'
4
+
5
+ require 'lexile/configuration'
6
+ require 'lexile/version'
7
+ require 'lexile/api/client'
8
+ require 'lexile/errors'
9
+
10
+ # Data Models
11
+ require 'lexile/model'
12
+ require 'lexile/book'
13
+
14
+ #API Operations
15
+ require 'lexile/api/resource'
16
+ require 'lexile/api/books'
17
+ require 'lexile/api/endpoints'
18
+
19
+ module Lexile
20
+ extend Configuration
21
+ extend Api::Endpoints
22
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lexile::Api::Books, :vcr => { :cassette_name => "books" } do
4
+
5
+ before { set_testing_configuration }
6
+
7
+
8
+ context '#show' do
9
+ let(:book){ Lexile.books.show(lexile_book_id) }
10
+
11
+ it "should return result" do
12
+ expect(book).to_not be_nil
13
+ end
14
+
15
+ it 'should be book' do
16
+ expect(book).to be_an_instance_of( Lexile::Book )
17
+ end
18
+
19
+ it 'should have id key' do
20
+ expect(book).to respond_to(:id)
21
+ end
22
+
23
+ it 'should have lexile key' do
24
+ expect(book).to respond_to(:lexile)
25
+ end
26
+
27
+ it 'should have lexile_display key' do
28
+ expect(book).to respond_to(:lexile_display)
29
+ end
30
+
31
+ it 'should have pages key' do
32
+ expect(book).to respond_to(:pages)
33
+ end
34
+ end
35
+
36
+ context '#find_by_isbn13' do
37
+ let(:books){ Lexile.books.find_by_isbn13(lexile_book_isbn13) }
38
+
39
+ it "should return not empty array" do
40
+ expect(books).to_not be_nil
41
+ end
42
+
43
+ it 'should be array' do
44
+ expect(books).to be_an_instance_of( Array )
45
+ end
46
+
47
+ it 'length should be > 0' do
48
+ expect(books.length).to_not be_zero
49
+ end
50
+
51
+ it 'should be array of Lexile::Book' do
52
+ books.each do |book|
53
+ expect(book).to be_an_instance_of( Lexile::Book )
54
+ end
55
+ end
56
+
57
+ it 'should have id key' do
58
+ expect(books[0]).to respond_to(:id)
59
+ end
60
+
61
+ it 'should have lexile key' do
62
+ expect(books[0]).to respond_to(:lexile)
63
+ end
64
+
65
+ it 'should have lexile_display key' do
66
+ expect(books[0]).to respond_to(:lexile_display)
67
+ end
68
+
69
+ it 'should have pages key' do
70
+ expect(books[0]).to respond_to(:pages)
71
+ end
72
+ end
73
+
74
+ context '#find_by_title' do
75
+ let(:books){ Lexile.books.find_by_title(lexile_book_title) }
76
+
77
+ it "should return not empty array" do
78
+ expect(books).to_not be_nil
79
+ end
80
+
81
+ it 'should be array' do
82
+ expect(books).to be_an_instance_of( Array )
83
+ end
84
+
85
+ it 'length should be > 0' do
86
+ expect(books.length).to_not be_zero
87
+ end
88
+
89
+ it 'should be array of Lexile::Book' do
90
+ books.each do |book|
91
+ expect(book).to be_an_instance_of( Lexile::Book )
92
+ end
93
+ end
94
+
95
+ it 'should have id key' do
96
+ expect(books[0]).to respond_to(:id)
97
+ end
98
+
99
+ it 'should have lexile key' do
100
+ expect(books[0]).to respond_to(:lexile)
101
+ end
102
+
103
+ it 'should have lexile_display key' do
104
+ expect(books[0]).to respond_to(:lexile_display)
105
+ end
106
+
107
+ it 'should have pages key' do
108
+ expect(books[0]).to respond_to(:pages)
109
+ end
110
+ end
111
+
112
+
113
+ end
@@ -0,0 +1,97 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lexile::API::Client do
4
+
5
+ let(:client){
6
+ set_testing_configuration
7
+ Lexile::API::Client.new( Lexile )
8
+ }
9
+
10
+ it "should have a VERSION" do
11
+ Lexile::VERSION.should_not be_nil
12
+ end
13
+
14
+ describe 'initialization' do
15
+ describe 'via configure' do
16
+ context "should be initialized by config" do
17
+ before do
18
+ set_testing_configuration
19
+ @cli = Lexile.configure do |c |
20
+ c.username = lexile_username
21
+ c.password = lexile_password
22
+ c.testing = true
23
+ end
24
+ @options_hash = @cli.class.default_options
25
+ end
26
+
27
+ it { expect(@cli).to_not be_nil }
28
+ it { expect(@options_hash[:base_uri]).to eq Lexile.api_url }
29
+ it { expect(@options_hash[:default_params]).to be_nil }
30
+ it { expect(@options_hash[:debug_output]).to_not be_nil }
31
+ it { expect(@options_hash[:headers]).to_not be_nil }
32
+ it { expect(@options_hash[:headers]['User-Agent']).to_not be_nil }
33
+ end
34
+ end
35
+
36
+ context 'should be initialized via hash' do
37
+ before do
38
+ configuration_hash = {
39
+ endpoint: 'https://example.com',
40
+ api_version: 'v52',
41
+ username: 'my_lexile_username',
42
+ password: 'my_lexile_password',
43
+ testing: true
44
+ }
45
+ @options_hash = client.class.default_options
46
+ @client = Lexile::API::Client.new( configuration_hash )
47
+ end
48
+
49
+ it{ expect(@client).to_not be_nil }
50
+ it{ expect(@options_hash[:base_uri]).to eq 'https://example.com/v52' }
51
+ it{ expect(@options_hash[:default_params]).to be_nil }
52
+ it{ expect(@options_hash[:debug_output]).to_not be_nil }
53
+ end
54
+ end
55
+
56
+ describe "get" do
57
+ it "should not raise an exception with response status 200" do
58
+ VCR.use_cassette("errors") do
59
+ expect{ client.get("/book") }.not_to raise_error
60
+ end
61
+ end
62
+
63
+
64
+ it "should raise Lexile::AuthenticationFailed with response status is 401" do
65
+ VCR.use_cassette("errors") do
66
+ expect{ client.get("/401") }.to raise_error Lexile::AuthenticationFailed
67
+ end
68
+ end
69
+
70
+
71
+ it "should raise Lexile::NotFound with response status is 404" do
72
+ VCR.use_cassette("errors") do
73
+ expect{ client.get("/404") }.to raise_error Lexile::NotFound
74
+ end
75
+ end
76
+
77
+
78
+
79
+ [
80
+ {status: 400, ex: Lexile::BadRequest },
81
+ {status: 401, ex: Lexile::AuthenticationFailed},
82
+ {status: 404, ex: Lexile::NotFound},
83
+ {status: 500, ex: Lexile::ServerError},
84
+ {status: 502, ex: Lexile::Unavailable},
85
+ {status: 503, ex: Lexile::RateLimited},
86
+ {status: 504, ex: Lexile::RateLimited},
87
+ {status: 999, ex: Lexile::UnknownStatusCode}
88
+ ].each do |test_args|
89
+ it "should raise #{test_args[:ex].name} when status code is #{test_args[:status]}" do
90
+ client.class.stub(:get){ mock = double; mock.stub(:code){test_args[:status]}; mock }
91
+ expect{
92
+ client.get("/something")
93
+ }.to raise_error test_args[:ex]
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lexile::Configuration do
4
+
5
+ before do
6
+ set_testing_configuration
7
+ end
8
+
9
+ describe '.configure' do
10
+ Lexile::Configuration::VALID_CONFIG_KEYS.each do |key|
11
+ it "should set the #{key}" do
12
+ Lexile.configure do |config|
13
+ if key == :timeout
14
+ config.send("#{key}=", 10)
15
+ expect(Lexile.send(key)).to eq 10
16
+ else
17
+ config.send("#{key}=", key)
18
+ expect(Lexile.send(key)).to eq key
19
+ end
20
+ end
21
+ end
22
+ end
23
+ it "should configure the client with this configuration" do
24
+ client = Lexile.configure do |config|
25
+ config.api_version = "V74_5_5"
26
+ end
27
+ client.should_not be_nil
28
+ client.class.default_options[:base_uri].should match /V74_5_5/
29
+ end
30
+
31
+ it "should return a cliend configured with this configuration" do
32
+ client = Lexile.configure do |config|
33
+ config.api_version = "V74_5_5"
34
+ end
35
+ client = Lexile.send(:client)
36
+ client.should_not be_nil
37
+ client.class.default_options[:base_uri].should match /V74_5_5/
38
+ end
39
+ end
40
+
41
+ describe "default values" do
42
+ before{ Lexile.reset! }
43
+ Lexile::Configuration::VALID_CONFIG_KEYS.each do |key|
44
+ describe ".#{key}" do
45
+ it 'should return the default value' do
46
+ expect(Lexile.send(key)).to eq Lexile::Configuration.const_get("DEFAULT_#{key.upcase}")
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lexile::HTTPError do
4
+ let(:response){
5
+ mock_response = double()
6
+ mock_response.stub(:code){ 259 }
7
+ mock_response.stub(:body){"<html><head></head><body>Hello World!</body></html>"}
8
+ mock_response
9
+ }
10
+
11
+ subject{ Lexile::HTTPError.new( response )}
12
+
13
+ it "should format correctly as a string" do
14
+ subject.to_s.should match /Lexile::HTTPError/
15
+ subject.to_s.should match /259/
16
+ subject.to_s.should match /Hello World/
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lexile::Model do
4
+
5
+
6
+ describe "#parse" do
7
+ # We will use a Lexile::Book which is a model to test model properties
8
+ let(:single_object_response){ { 'a' => 'ONE', 'b' => 'TWO', 'c' => 'THREE'} }
9
+ let(:multi_object_response){{ 'objects' =>[{ 'a' => 'ONE', 'b' => 'TWO', 'c' => 'THREE'},{ 'a' => 'UNO', 'b' => 'DOS', 'c' => 'TRES'},{ 'a' => 'UNE', 'b' => 'DEUX', 'c' => 'TROIS'}] }}
10
+ let(:invalid_json){ "{\"objects\":\"Most Definetly not an array of objects\"}" }
11
+
12
+ it "should raise an exception if a mult-object response does not contain an array" do
13
+ expect{
14
+ Lexile::Book.parse( invalid_json )
15
+ }.to raise_error Lexile::CannotProcessResponse, /is present in response but it does not contain an Array/
16
+ end
17
+
18
+ it "should parse a single object response" do
19
+ soj = Lexile::Book.parse( single_object_response.to_json )
20
+ single_object_response.each do |key|
21
+ soj[key].should eq single_object_response[key]
22
+ end
23
+ end
24
+
25
+ it "should parse a multi object response" do
26
+ books = Lexile::Book.parse( multi_object_response.to_json )
27
+ objs = multi_object_response['objects']
28
+ books.length.should eq objs.length
29
+ #deep compare of books
30
+ objs.each do |obj|
31
+ index = books.find_index{|book| book['a']== obj['a']}
32
+ index.should_not be_nil
33
+ book = books[index]
34
+ obj.each do |key|
35
+ book[key].should eq obj[key]
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,39 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require "codeclimate-test-reporter"
5
+ CodeClimate::TestReporter.start
6
+
7
+ require 'rspec'
8
+ require 'vcr'
9
+ require 'webmock/rspec'
10
+ require 'hashie'
11
+ require 'lexile'
12
+
13
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
14
+
15
+ WebMock.disable_net_connect!
16
+
17
+ VCR.configure do |c|
18
+ c.cassette_library_dir = 'spec/vcr_tapes'
19
+ c.hook_into :webmock
20
+ c.configure_rspec_metadata!
21
+ c.default_cassette_options = {
22
+ #record: (ENV['TRAVIS'] ? :none : :once)
23
+ #record: :new_episodes
24
+ #record: :all
25
+ record: :none
26
+ }
27
+
28
+ c.ignore_hosts 'codeclimate.com'
29
+ c.filter_sensitive_data("<USERNAME>") { Lexile.options[:username] }
30
+ c.filter_sensitive_data("<PASSWORD>") { Lexile.options[:password] }
31
+ end
32
+
33
+ RSpec.configure do |config|
34
+ config.include LexileHelper
35
+ config.color = true
36
+ config.tty = true
37
+ config.treat_symbols_as_metadata_keys_with_true_values = true
38
+ config.order = "random"
39
+ end
@@ -0,0 +1,29 @@
1
+ module LexileHelper
2
+ def set_testing_configuration
3
+ Lexile.reset!
4
+ Lexile.username = lexile_username
5
+ Lexile.password = lexile_password
6
+ Lexile.testing = true
7
+ end
8
+
9
+ def lexile_username
10
+ 'AUSERNAME'
11
+ end
12
+
13
+ def lexile_password
14
+ 'APASSWORD'
15
+ end
16
+
17
+ def lexile_book_id
18
+ 315833 #ISBN 9780062012722 Title: It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary
19
+ end
20
+
21
+ def lexile_book_isbn13
22
+ 9780062012722 #id: 315833 Title: It Happened to Nancy: By An Anonymous Teenager: A True Story from Her Diary
23
+ end
24
+
25
+ def lexile_book_title
26
+ "Malala"
27
+ end
28
+
29
+ end