add some tests

This commit is contained in:
David 2021-06-26 15:34:04 -04:00
parent f35a56507a
commit 32b4caf163
4 changed files with 168 additions and 13 deletions

View File

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) <year> <copyright holders> Copyright (c) 2021 David Ashby
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

View File

@ -1,3 +1,3 @@
# go-openlibrary # go-openlibrary
A simple Go wrapper around the OpenLibrary.org API: <https://openlibrary.org/dev/docs/api/books>. A simple Go wrapper around the OpenLibrary.org Books API: <https://openlibrary.org/dev/docs/api/books>.

View File

@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"io" "io"
"net/http" "net/http"
"net/url"
) )
var ( var (
@ -17,13 +18,6 @@ type Client struct {
apipath string apipath string
} }
// NewClient returns a new Client struct using http.DefaultClient and default api path.
func NewClient() (*Client, error) {
return &Client{
apipath: defaultAPI,
}, nil
}
// SetHTTPClient updates the httpClient on the client with a manually-configured one. // SetHTTPClient updates the httpClient on the client with a manually-configured one.
// If unset, the client will fall back to using http.DefaultClient. // If unset, the client will fall back to using http.DefaultClient.
func (c *Client) SetHTTPClient(h http.Client) { func (c *Client) SetHTTPClient(h http.Client) {
@ -38,24 +32,38 @@ func (c *Client) SetAPIPath(p string) {
// GetByISBN fetches details for a book based on its ISBN10 or ISBN13. // GetByISBN fetches details for a book based on its ISBN10 or ISBN13.
func (c *Client) GetByISBN(k string) (*BookDetails, error) { func (c *Client) GetByISBN(k string) (*BookDetails, error) {
if k == "" {
return nil, fmt.Errorf("ISBN cannot be empty")
} else if len(k) != 10 && len(k) != 13 {
return nil, fmt.Errorf("ISBN must be either 10 or 13 digits")
}
key := "ISBN:" + k key := "ISBN:" + k
return c.fetch(key) return c.fetch(key)
} }
// GetByOCLC fetches details for a book based on its WorldCat OCLC number. // GetByOCLC fetches details for a book based on its WorldCat OCLC number.
func (c *Client) GetByOCLC(k string) (*BookDetails, error) { func (c *Client) GetByOCLC(k string) (*BookDetails, error) {
if k == "" {
return nil, fmt.Errorf("OCLC cannot be empty")
}
key := "OCLC:" + k key := "OCLC:" + k
return c.fetch(key) return c.fetch(key)
} }
// GetByLCCN fetches details for a book based on its Library of Congress Control Number. // GetByLCCN fetches details for a book based on its Library of Congress Control Number.
func (c *Client) GetByLCCN(k string) (*BookDetails, error) { func (c *Client) GetByLCCN(k string) (*BookDetails, error) {
if k == "" {
return nil, fmt.Errorf("LCCN cannot be empty")
}
key := "LCCN:" + k key := "LCCN:" + k
return c.fetch(key) return c.fetch(key)
} }
// GetByOLID fetches details for a book based on its OpenLibrary ID number. // GetByOLID fetches details for a book based on its OpenLibrary ID number.
func (c *Client) GetByOLID(k string) (*BookDetails, error) { func (c *Client) GetByOLID(k string) (*BookDetails, error) {
if k == "" {
return nil, fmt.Errorf("OLID cannot be empty")
}
key := "OLID:" + k key := "OLID:" + k
return c.fetch(key) return c.fetch(key)
} }
@ -68,12 +76,21 @@ func (c *Client) GetByRawKey(k string) (*BookDetails, error) {
} }
func (c *Client) fetch(key string) (*BookDetails, error) { func (c *Client) fetch(key string) (*BookDetails, error) {
path := c.apipath h := c.apipath
if path == "" { if h == "" {
path = defaultAPI h = defaultAPI
} }
u, err := url.Parse(h)
if err != nil {
return nil, err
}
u.RawQuery = url.Values{
"bibkeys": []string{key},
"jscmd": []string{"data"},
"format": []string{"json"},
}.Encode()
resp, err := c.httpClient.Get(path + "?bibkeys=%s&jscmd=data&format=json") resp, err := c.httpClient.Get(u.String())
if err != nil { if err != nil {
return nil, err return nil, err
} }

138
client/client_test.go Normal file
View File

@ -0,0 +1,138 @@
package client
import (
"fmt"
"net/http"
"net/http/httptest"
"testing"
)
func testServer(expectedkey string) *httptest.Server {
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Query().Get("bibkeys") == expectedkey {
w.WriteHeader(http.StatusOK)
w.Write([]byte(fmt.Sprintf(exampleResponse, expectedkey)))
} else {
w.WriteHeader(http.StatusNotFound)
}
}))
}
func TestFetch(t *testing.T) {
r := testServer("ISBN:9780980200447")
defer r.Close()
c := Client{}
c.SetAPIPath(r.URL)
b, err := c.GetByISBN("9780980200447")
if err != nil {
t.Log(err)
t.Fail()
}
if b.Identifiers.Google[0] != "4LQU1YwhY6kC" {
t.Logf("wrong identifier in response: %s", b.Identifiers.Google[0])
t.Fail()
}
}
func TestFetchFailure(t *testing.T) {
r := testServer("ISBN:1234567890")
defer r.Close()
c := Client{}
c.SetAPIPath(r.URL)
_, err := c.GetByISBN("9780980200447")
if err == nil {
t.Log("expected error, received nil")
t.Fail()
}
}
var exampleResponse = `{
"%s": {
"publishers": [
{
"name": "Litwin Books"
}
],
"identifiers": {
"google": [
"4LQU1YwhY6kC"
],
"lccn": [
"2008054742"
],
"isbn_13": [
"9780980200447"
],
"amazon": [
"098020044X"
],
"isbn_10": [
"1234567890"
],
"oclc": [
"297222669"
],
"librarything": [
"8071257"
],
"project_gutenberg": [
"14916"
],
"goodreads": [
"6383507"
]
},
"classifications": {
"dewey_decimal_class": [
"028/.9"
],
"lc_classifications": [
"Z1003 .M58 2009"
]
},
"links": [
{
"url": "http://johnmiedema.ca",
"title": "Author's Website"
}
],
"weight": "1 grams",
"title": "Slow reading",
"url": "https://openlibrary.org/books/OL22853304M/Slow_reading",
"number_of_pages": 80,
"cover": {
"small": "https://covers.openlibrary.org/b/id/5546156-S.jpg",
"large": "https://covers.openlibrary.org/b/id/5546156-L.jpg",
"medium": "https://covers.openlibrary.org/b/id/5546156-M.jpg"
},
"subjects": [
{
"url": "https://openlibrary.org/subjects/books_and_reading",
"name": "Books and reading"
},
{
"url": "https://openlibrary.org/subjects/reading",
"name": "Reading"
}
],
"publish_date": "2009",
"authors": [
{
"url": "https://openlibrary.org/authors/OL6548935A/John_Miedema",
"name": "John Miedema"
}
],
"excerpts": [
{
"comment": "test purposes",
"text": "test first page"
}
],
"publish_places": [
{
"name": "Duluth, Minn"
}
]
}
}`