alexandrite 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e1d0a59468bf1b22e33d17848c07d9af25172aadbc78723fbf014d42021bcd55
4
+ data.tar.gz: ffb2f6b45788d233ebb91b601f1ea256ba21b54da4bad154e548f4e20bb9f59b
5
+ SHA512:
6
+ metadata.gz: a706821501297809cad6e2c88c917ae8ea4fd276b5d9fde402b0fddf3aeac0094fdc13f42ac48edd551e397f0b7d34cadab6f3aed3ffa1c21abd1b8c02f7526c
7
+ data.tar.gz: f448f181f9980721ef93df28392ffcd8210687033c8257b470cde53693b07c63015f14807a15a70ce649f45789034c2d10fb3e306e007e96d9f083b77dd6d64e
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ .idea
24
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in alexandrite_base.gemspec
6
+ gemspec
7
+
8
+ gem 'faraday'
9
+ gem 'faraday-decode_xml'
10
+ gem 'rubocop'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Juan Paulo Pérez-Tejada
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,115 @@
1
+ # gisbn GEM [![Build Status](https://travis-ci.org/eftakhairul/gisbn.svg?branch=master)](https://travis-ci.org/eftakhairul/gisbn) [![GitHub issues](https://img.shields.io/github/issues/eftakhairul/gisbn.svg)](https://github.com/eftakhairul/gisbn/issues) [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/eftakhairul/gisbn/master/LICENSE.txt)
2
+
3
+ It fetches book's information by ISBN number based on Google Book API.
4
+
5
+ - Easy to get all information by ISBN
6
+ - Structure data
7
+
8
+ You don't have to call manually Google API with ISBN number. This gem will do everything for you.
9
+
10
+
11
+
12
+ ### Version
13
+ 0.0.1
14
+
15
+
16
+ ### Installation
17
+ Add this line to your application's Gemfile:
18
+
19
+ ```ruby
20
+ gem 'alexandrite'
21
+ ```
22
+
23
+ And then execute:
24
+
25
+ ```sh
26
+ $ bundle
27
+ ```
28
+
29
+ Or install it yourself as globally:
30
+
31
+ ```sh
32
+ gem install alexandrite
33
+ ```
34
+
35
+
36
+ ## Examples
37
+ book = Gisbn::Book.new "0262033844", "AIzaSyDKepjfaVBRcgsnPALw5s2UNyfOk-1FHUU", "ca"
38
+
39
+ book.title
40
+ #=> "Introduction to Algorithms"
41
+
42
+ book.description
43
+ #=> "A new edition of the essential text and professional reference, with substantial newmaterial on such topics as vEB trees, multithreaded algorithms, dynamic programming, and edge-baseflow."
44
+
45
+ book.publisher
46
+ #=> "MIT Press"
47
+
48
+ book.published_date
49
+ #=> <Date: 2001-02-03 ...>
50
+
51
+ book.isbn_10
52
+ #=> 0262033844
53
+
54
+ book.isbn_13
55
+ #=> 9780262033848
56
+
57
+ book.thumbnail
58
+ #=> http://books.google.com/books/content?id=i-bUBQAAQBAJ&printsec=frontcover&img=1&zoom=1&edge=curl&source=gbs_api
59
+
60
+ book.preview
61
+ #=> http://books.google.ca/books?id=i-bUBQAAQBAJ&printsec=frontcover&dq=isbn:0262033844&hl=&cd=1&source=gbs_api
62
+
63
+
64
+ book.gisbn.isbn = 9780321573513
65
+ book.fetch.title => "Algorithms"
66
+
67
+
68
+
69
+ ## Methods
70
+ title >> Returns Book's title as string
71
+ description >> Returns the description of book as string
72
+ isbn(isbn_number) >> Set new isbn
73
+ fetch >> Call to Google Book API and process book information on provided ISBN
74
+ authors >> Return authors' name as comma separated as string
75
+ authors_as_array >> Return authors' name as ruby array. If no book is associated with ISBN number,
76
+ then it return empty array
77
+ publisher >> Return publisher name as string
78
+ isbn_10 >> Return 10 digit ISBN numbers as string
79
+ isbn_13 >> Return 13 digit ISBN numbers as string
80
+ categories >> Return category names as comma separated as string
81
+ categories_as_array >> Return category names as ruby array. If no book is associated with ISBN number,
82
+ then it return empty array
83
+ thumbnail_small >> Return the link of small thumnail
84
+ thumbnail >> Return the link of standard thumnail
85
+ preview_link >> Return the link for previewing the book
86
+ page_count >> Return page count as integer
87
+ published_date >> Return the published date as Ruby object
88
+
89
+
90
+ ### Development
91
+
92
+ Want to contribute? Great!
93
+
94
+ 1. Fork it ( https://github.com/eftakhairul/gisbn/fork )
95
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
96
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
97
+ 4. Push to the branch (`git push origin my-new-feature`)
98
+ 5. Create a new Pull Request
99
+
100
+
101
+ Author
102
+ -----------
103
+ [Eftakhairul Islam](https://eftakhairul.com)
104
+
105
+ Contributors
106
+ -----------
107
+ [Matt Seeberger](https://github.com/thebeardedgeek)
108
+
109
+ License
110
+ ----
111
+ MIT
112
+
113
+
114
+
115
+
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ Dir.glob('tasks/**/*.rake').each(&method(:import))
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/alexandrite/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'alexandrite'
7
+ spec.version = Alexandrite::VERSION
8
+ spec.authors = ['J. P. Pérez-Tejada']
9
+ spec.email = ['jpereztejada@apexsystems.com', 'juan@daiuk.com']
10
+ spec.summary = 'Tools for fetching books data from Google and OCLC'
11
+ spec.description = "Alexandrite is a gem that fetches public book's information by different params based
12
+ on Google Book API and OCLC API . Powered by Faraday."
13
+ spec.homepage = 'https://github.com/maclenn77/alexandrite'
14
+ spec.required_ruby_version = Gem::Requirement.new('>= 3.0')
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '>= 2.1.0'
23
+ spec.add_development_dependency 'faraday'
24
+ spec.add_development_dependency 'rake'
25
+
26
+ # #dependency for testing automation
27
+ spec.add_development_dependency 'factory_bot'
28
+ spec.add_development_dependency 'pry-byebug'
29
+ spec.add_development_dependency 'rspec'
30
+ spec.add_development_dependency 'rspec-nc'
31
+ spec.add_development_dependency 'vcr'
32
+ spec.add_development_dependency 'webmock'
33
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alexandrite
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'alexandrite_books'
4
+ require_relative 'alexandrite_google'
5
+ require_relative 'alexandrite_oclc'
6
+ require_relative 'error_type/errors'
7
+
8
+ # Main gem methods for creating books from ISBN
9
+ module Alexandrite
10
+ include ErrorType
11
+
12
+ # Get and Process data from Google API
13
+ class Google
14
+ extend Alexandrite::GoogleAPI
15
+
16
+ attr_reader :result
17
+
18
+ def initialize(key, query)
19
+ @result = search_by(key, query)
20
+ end
21
+
22
+ # @return [Alexandrite::Book]
23
+ def self.create_book(isbn)
24
+ volume_info = get_volume_info(isbn)
25
+ Alexandrite::Book.new(volume_info)
26
+ end
27
+ end
28
+
29
+ # Get and Process data from OCLC API
30
+ class OCLC
31
+ extend Alexandrite::OCLCAPI
32
+
33
+ attr_reader :result
34
+
35
+ # return [Alexandrite::OCLC]
36
+ def initialize(key, query, api: :oclc)
37
+ @result = search_by(key, query, api: api)
38
+ end
39
+
40
+ # @return [Alexandrite::Book]
41
+ def self.create_book(type, identifier)
42
+ query = Alexandrite::OCLC.new(type, identifier)
43
+ response_code = get_response_code(query.result)
44
+
45
+ response(response_code, query)
46
+ end
47
+ end
48
+
49
+ API = {
50
+ google: Alexandrite::Google,
51
+ oclc: Alexandrite::OCLC
52
+ }.freeze
53
+
54
+ def search_by(key, query, api: :google)
55
+ API[api].search_by(key, query)
56
+ end
57
+
58
+ def create_book(key, query)
59
+ book = API[:google].create_book(query)
60
+ return API[:oclc].create_book(key, query) if book.error_message
61
+
62
+ book
63
+ end
64
+
65
+ # @param isbns [Array]
66
+ # @return [Nil]
67
+ def bulk_create(isbns)
68
+ isbns.each do |isbn|
69
+ volume_info = volume_info(isbn)
70
+ book = Alexandrite::Book.new(volume_info)
71
+ add_to_collection(book)
72
+ end
73
+ nil
74
+ end
75
+
76
+ private
77
+
78
+ def get_volume_info(isbn)
79
+ query = search_by(:isbn, isbn)
80
+ return query[:books].first[:volume_info] unless query[:error_message]
81
+
82
+ query
83
+ end
84
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'alexandrite'
4
+
5
+ module Alexandrite
6
+ # Create a book objects
7
+ class Book
8
+ attr_accessor :title, :authors, :publisher, :published_date, :page_count, :description, :categories, :language,
9
+ :country, :isbn10, :isbn13, :error_message, :ddc, :lcc, :suggested_classifications
10
+
11
+ # @param volume_info [Hash]
12
+ # @return [Alexandrite::Books]
13
+ def initialize(volume_info)
14
+ add_origin(volume_info)
15
+ add_basic_values(volume_info)
16
+ add_industry_identifiers(volume_info, @origin)
17
+ @error_message = volume_info[:error_message]
18
+ end
19
+
20
+ def self.collection = @@collection
21
+
22
+ def self.add_to_collection(book)
23
+ @@collection.push(book)
24
+ end
25
+
26
+ # @param [String] ddc_code
27
+ # @return [NilClass]
28
+ def add_ddc(ddc_code) = @ddc = ddc_code
29
+
30
+ # @param [String] lcc_code
31
+ # @return [NilClass]
32
+ def add_lcc(lcc_code) = @lcc = lcc_code
33
+
34
+ # @param [Array<String>] suggestions
35
+ # @return [NilClass]
36
+ def add_classification_suggested(suggestions) = @suggested_classifications = suggestions
37
+
38
+ private
39
+
40
+ def add_basic_values(volume_info)
41
+ @title = volume_info['title']
42
+ @authors = volume_info['authors']
43
+ @publisher = volume_info['publisher']
44
+ @published_date = volume_info['publishedDate']
45
+ @page_count = volume_info['pageCount']
46
+ @description = volume_info['description']
47
+ @categories = volume_info['categories']
48
+ @language = volume_info['language']
49
+ end
50
+
51
+ # @param [Hash] volume_info
52
+ # @return [String]
53
+ def add_origin(volume_info) = @origin = volume_info['origin'] || 'Google API'
54
+
55
+ # @param [Hash] volume_info
56
+ # @param [String] origin
57
+ # @return [NilClass]
58
+ def add_industry_identifiers(volume_info, origin)
59
+ return nil unless volume_info[:error_message].nil?
60
+
61
+ if origin == 'OCLC API'
62
+ @isbn10 = volume_info['ISBN_10']
63
+ @isbn13 = volume_info['ISBN_13']
64
+ return
65
+ end
66
+
67
+ volume_info['industryIdentifiers'].each do |identifier|
68
+ @isbn10 = identifier['identifier'] if identifier['type'] == 'ISBN_10'
69
+ @isbn13 = identifier['identifier'] if identifier['type'] == 'ISBN_13'
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'alexandrite'
4
+ require_relative 'book'
5
+
6
+ # Create, Read, Update and Delete books in a book collection
7
+ module Alexandrite
8
+ # Create a collection of books
9
+ class Bookshelf
10
+ def initialize
11
+ @book_collection = []
12
+ end
13
+ end
14
+ def add_book(book) = @book_collection << book if book.instance_of?(Alexandrite::Book)
15
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require all files
4
+ require_relative 'alexandrite/version'
5
+ require 'rubygems'
6
+ require 'faraday'
7
+ require 'json'
8
+ require_relative 'helpers/format'
9
+ require_relative 'helpers/validation'
10
+ require 'pry'
11
+
12
+ module Alexandrite
13
+ # Methods for consuming Google API
14
+ module GoogleAPI
15
+ include Alexandrite::Helpers::Format
16
+ include Alexandrite::Helpers::Validation
17
+
18
+ attr_reader :result, :isbn
19
+
20
+ BASE_URL = 'https://www.googleapis.com/books/v1/volumes?q='
21
+
22
+ FILTERS = {
23
+ author: 'inauthor:',
24
+ isbn: 'isbn:',
25
+ lccn: 'lccn:',
26
+ oclc: 'oclc:',
27
+ publisher: 'inpublisher:',
28
+ subject: 'subject:',
29
+ title: 'intitle:'
30
+ }.freeze
31
+
32
+ FIELDS = {
33
+ title: 'volumeInfo/title',
34
+ authors: 'volumeInfo/authors'
35
+ }.freeze
36
+
37
+ # @param query [String]
38
+ # @return [Faraday::Response]
39
+ def search(query, projection: 'lite')
40
+ conn = Faraday.new("#{BASE_URL}#{query}&projection=#{projection}") do |r|
41
+ r.response :json
42
+ end
43
+
44
+ conn.get.body
45
+ end
46
+
47
+ # @param key [Symbol]
48
+ # @param query [String]
49
+ # @param fields [Array<String>]
50
+ # @return [Faraday::Response]
51
+ def search_by(key, query, projection: 'lite', **fields)
52
+ projection = "&projection=#{projection}"
53
+ url = fields.any? ? "#{BASE_URL}#{FILTERS[key]}#{query}#{add_fields(fields)}#{projection}" : "#{BASE_URL}#{FILTERS[key]}#{query}"
54
+ conn = Faraday.new(url) do |r|
55
+ r.response :json
56
+ end
57
+
58
+ response = conn.get.body
59
+
60
+ process_response(response)
61
+ end
62
+
63
+ private
64
+
65
+ def zero_results?(response_body) = response_body['totalItems'].zero?
66
+
67
+ def process_response(response)
68
+ if zero_results?(response)
69
+ { error_message: 'Not results' }
70
+ else
71
+ { results_size: response['totalItems'],
72
+ books: response['items'] }
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ # require all files
4
+ require_relative 'alexandrite/version'
5
+ require 'rubygems'
6
+ require 'faraday'
7
+ require 'faraday/decode_xml'
8
+ require 'json'
9
+ require_relative 'helpers/format'
10
+ require_relative 'helpers/validation'
11
+ require 'pry'
12
+ require 'nokogiri'
13
+
14
+ module Alexandrite
15
+ # Consume OCLC API
16
+ module OCLCAPI
17
+ include Nokogiri
18
+ include Alexandrite::Helpers::Format
19
+ include Alexandrite::Helpers::Validation
20
+
21
+ BASE_URL = 'http://classify.oclc.org/classify2/Classify?'
22
+
23
+ # @param query [String]
24
+ # @return [Faraday::Response]
25
+ def search_by(key, query, summary: true)
26
+ search = "#{BASE_URL}#{key}=#{query}&summary=#{summary}"
27
+ conn = Faraday.new(search) do |r|
28
+ r.get(search).body
29
+ end
30
+ Nokogiri::XML(conn.get(search).body)
31
+ end
32
+
33
+ def get_book_data(result)
34
+ isbn = result.css('input').children.text
35
+ isbn_type = define_isbn_type(isbn)
36
+ {
37
+ 'origin' => 'OCLC API',
38
+ 'title' => result.css('work').attribute('title').value,
39
+ 'authors' => result.css('work').attribute('author').value,
40
+ 'ddc' => result.css('mostPopular').attribute('nsfa').value,
41
+ isbn_type => isbn
42
+ }
43
+ end
44
+
45
+ def recommend_classification(key, query, length = 5, mode: 'ddc')
46
+ results = search_by(key, query)
47
+
48
+ response_cases(results, length, mode)
49
+ end
50
+
51
+ private
52
+
53
+ def get_response_code(result) = result.css('response').attribute('code').value.to_i
54
+
55
+ def get_owis(result, length)
56
+ owis = []
57
+ result.css('work').map { |work| owis << work.attribute('owi').value }
58
+
59
+ owis[0...length]
60
+ end
61
+
62
+ def get_recommendations(owis, mode)
63
+ results = []
64
+ classifications_recommended = []
65
+
66
+ owis.map { |owi_value| results << search_by('owi', owi_value) }
67
+
68
+ results.each do |classification|
69
+ classifications_recommended << get_classification(classification, mode)
70
+ end
71
+
72
+ classifications_recommended
73
+ end
74
+
75
+ def get_classification(result, mode)
76
+ acronym = { 'ddc': 'Dewey Decimal Classification',
77
+ 'lcc': 'Library of Congress Classification' }
78
+
79
+ result.css(mode).css('mostPopular').attribute('nsfa').value
80
+ rescue NoMethodError
81
+ "A #{acronym[mode.to_sym]} is not available for this book"
82
+ end
83
+
84
+ def create_new_book(query)
85
+ volume_info = get_book_data(query.result)
86
+ Alexandrite::Book.new(volume_info)
87
+ end
88
+
89
+ def retry_create_new_book(query)
90
+ owi = get_owis(query.result, 1)[0]
91
+ new_query = Alexandrite::OCLC.new('owi', owi)
92
+ volume_info = get_book_data(new_query.result)
93
+ Alexandrite::Book.new(volume_info)
94
+ end
95
+
96
+ def handle_error_creating_book(query)
97
+ raise ErrorType::DataNotFound, response_cases(query, 0, 'none')
98
+ rescue StandardError => e
99
+ Alexandrite::Book.new('error_message' => e.message)
100
+ end
101
+
102
+ # @param [Nokogiri::XML] result
103
+ # @param [Integer] length
104
+ # @param [String] mode Possible: 'ddc' or 'lcc'
105
+ # @return [String]
106
+ def response_cases(result, length, mode)
107
+ code = get_response_code(result).to_i
108
+ case code
109
+ when 0
110
+ get_classification(result, mode)
111
+ when 2
112
+ get_classification(result, mode)
113
+ when 4
114
+ get_recommendations(get_owis(result, length), mode)
115
+ when 100
116
+ 'No input. The method requires an input argument.'
117
+ when 101
118
+ 'Invalid input. The standard number argument is invalid.'
119
+ when 102
120
+ 'Not found. No data found for the input argument.'
121
+ when 200
122
+ 'Unexpected error.'
123
+ end
124
+ end
125
+
126
+ def response(response_code, query)
127
+ case response_code
128
+ when 0, 2
129
+ create_new_book(query)
130
+ when 4
131
+ retry_create_new_book(query)
132
+ else
133
+ handle_error_creating_book(query)
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ErrorType
4
+ class InvalidFormatError < StandardError; end
5
+
6
+ class DataNotFound < StandardError; end
7
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alexandrite
4
+ module Helpers
5
+ # Format inputs and options
6
+ module Format
7
+ # @param string [String]
8
+ # @return [String]
9
+ def remove_non_digits(string)
10
+ string.gsub!(/[^+\d]/, '')
11
+ end
12
+
13
+ def add_fields(*fields)
14
+ "&fields=items(volumeInfo/#{fields.join(',volumeInfo/')})"
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alexandrite
4
+ module Helpers
5
+ # Validate inputs
6
+ module Validation
7
+ # @param
8
+ # @return
9
+ def valid_isbn_length?(isbn) = isbn.size == 10 || isbn.size == 13
10
+
11
+ # @param
12
+ # @return [String] or [Nil]
13
+ def validate_isbn(isbn)
14
+ remove_non_digits(isbn.to_s)
15
+ return isbn if valid_isbn_length?(isbn)
16
+
17
+ 'ISBN should have 10 or 13 digits'
18
+ end
19
+
20
+ def define_isbn_type(isbn) = "ISBN_#{isbn.length}"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'spec_helper'
4
+ require 'book'
5
+
6
+ RSpec.describe Alexandrite::Book do
7
+ subject { Alexandrite::Book.new('0262033844') }
8
+
9
+ describe 'alexandrite_base' do
10
+ describe '#process' do
11
+ let(:expected_title) { 'Introduction to Algorithms, Third Edition' }
12
+ let(:expected_pages) { 1314 }
13
+ let(:result) { subject.fetch }
14
+
15
+ VCR.use_cassette('get_book') do
16
+ it 'book title' do
17
+ expect(result.title.downcase).to eq(expected_title.downcase)
18
+ end
19
+
20
+ it 'book page count' do
21
+ expect(result.page_count.to_i).to eq(expected_pages)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create a book
4
+ FactoryBot.define do
5
+ factory :book do
6
+ isbn { '0262033844' }
7
+ end
8
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'spec_helper'
4
+ require 'pry'
5
+
6
+ describe 'validate ISBN format' do
7
+ let(:book_class) { Class.new }
8
+
9
+ describe 'valid ISBNs' do
10
+ let(:valid_isbn10) { '0123456789' }
11
+ let(:valid_isbn13) { '1234567890123' }
12
+ let(:valid_isbn_non_digit) { '1-23456789012-3' }
13
+
14
+ it 'valid ISBN of 13 digits' do
15
+ isbn = valid_isbn13
16
+ result = book_class.validate_isbn(isbn)
17
+ expect(result).to eq(valid_isbn13)
18
+ end
19
+
20
+ it 'valid ISBN of 10 digits' do
21
+ result = book_class.validate_isbn(valid_isbn10)
22
+ expect(result).to eq(valid_isbn10)
23
+ end
24
+
25
+ it 'valid ISBN with dashes' do
26
+ result = book_class.validate_isbn(valid_isbn_non_digit)
27
+ expect(result).to eq(valid_isbn13)
28
+ end
29
+ end
30
+
31
+ describe 'invalid ISBNs' do
32
+ let(:error_message) { 'ISBN should have 10 or 13 digits' }
33
+ let(:valid_isbn_white_spaces) { '1234567890123 ' }
34
+ let(:invalid_isbn_non_digit) { 'ABCDEFGHIJ ' }
35
+ let(:invalid_isbn_too_short) { '1234' }
36
+ let(:invalid_isbn_too_long) { '123456789123456789' }
37
+
38
+ it 'ISBN without digits is invalid' do
39
+ result = book_class.validate_isbn(invalid_isbn_non_digit)
40
+ expect(result).to eq(error_message)
41
+ end
42
+
43
+ it 'ISBN is invalid because is too short' do
44
+ result = book_class.validate_isbn(invalid_isbn_too_short)
45
+ expect(result).to eq(error_message)
46
+ end
47
+
48
+ it 'ISBN is invalid because is too long' do
49
+ result = book_class.validate_isbn(invalid_isbn_too_short)
50
+ expect(result).to eq(error_message)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ # frozen_string_literal: tru
3
+
4
+ require 'rspec'
5
+ require 'net/http'
6
+ require 'json'
7
+ require 'factory_bot'
8
+ require 'vcr'
9
+ require 'pry-byebug'
10
+ require 'helpers/format'
11
+ require 'support/vcr_setup'
12
+ require 'alexandrite'
13
+
14
+ RSpec.configure do |config|
15
+ config.include FactoryBot::Syntax::Methods
16
+
17
+ config.before(:suite) do
18
+ FactoryBot.find_definitions
19
+ end
20
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'vcr'
4
+
5
+ VCR.configure do |c|
6
+ c.configure_rspec_metadata!
7
+ c.cassette_library_dir = 'vcr/cassettes'
8
+ c.hook_into :webmock
9
+ c.default_cassette_options = {
10
+ erb: true,
11
+ record: :once,
12
+ decode_compressed_response: false,
13
+ match_requests_on: %i[method uri body]
14
+ }
15
+ end
metadata ADDED
@@ -0,0 +1,197 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alexandrite
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - J. P. Pérez-Tejada
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-01-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: factory_bot
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-byebug
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-nc
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: vcr
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: webmock
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: |-
140
+ Alexandrite is a gem that fetches public book's information by different params based
141
+ on Google Book API and OCLC API . Powered by Faraday.
142
+ email:
143
+ - jpereztejada@apexsystems.com
144
+ - juan@daiuk.com
145
+ executables: []
146
+ extensions: []
147
+ extra_rdoc_files: []
148
+ files:
149
+ - ".gitignore"
150
+ - Gemfile
151
+ - LICENSE
152
+ - README.md
153
+ - Rakefile
154
+ - alexandrite.gemspec
155
+ - lib/alexandrite.rb
156
+ - lib/alexandrite/version.rb
157
+ - lib/alexandrite_books.rb
158
+ - lib/alexandrite_bookshelf.rb
159
+ - lib/alexandrite_google.rb
160
+ - lib/alexandrite_oclc.rb
161
+ - lib/error_type/errors.rb
162
+ - lib/helpers/format.rb
163
+ - lib/helpers/validation.rb
164
+ - spec/alexandrite_spec.rb
165
+ - spec/factories/book.rb
166
+ - spec/helpers/format_spec.rb
167
+ - spec/spec_helper.rb
168
+ - spec/support/vcr_setup.rb
169
+ homepage: https://github.com/maclenn77/alexandrite
170
+ licenses:
171
+ - MIT
172
+ metadata: {}
173
+ post_install_message:
174
+ rdoc_options: []
175
+ require_paths:
176
+ - lib
177
+ required_ruby_version: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '3.0'
182
+ required_rubygems_version: !ruby/object:Gem::Requirement
183
+ requirements:
184
+ - - ">="
185
+ - !ruby/object:Gem::Version
186
+ version: '0'
187
+ requirements: []
188
+ rubygems_version: 3.3.3
189
+ signing_key:
190
+ specification_version: 4
191
+ summary: Tools for fetching books data from Google and OCLC
192
+ test_files:
193
+ - spec/alexandrite_spec.rb
194
+ - spec/factories/book.rb
195
+ - spec/helpers/format_spec.rb
196
+ - spec/spec_helper.rb
197
+ - spec/support/vcr_setup.rb