An Elixir library for searching and fetching controlled vocabulary authority terms, inspired by the Samvera Community's Questioning Authority.
Authoritex
provides an Elixir behaviour that defines a specification for creating authorities. Each authority is a module which has to implement at least 5 public functions: can_resolve?/1
, code/0
, description/0
, fetch/1
, and search/2
.
can_resolve?/1
Returns true if the module can resolve the given identifiercode/0
Returns the unique short code for the authoritydescription/0
Returns a human-readable description of the authorityfetch/1
Fetches a label (and optional hint string) for a specified resourcesearch/2
Returns a list of search results (and optional hints) matching a query
Mix.install([
{:authoritex, "~> 0.7.0"},
{:kino, "~> 0.5.2"}
])
Application.put_env(:authoritex, :authorities, [
Authoritex.FAST.CorporateName,
Authoritex.FAST.EventName,
Authoritex.FAST.Form,
Authoritex.FAST.Geographic,
Authoritex.FAST.Personal,
Authoritex.FAST.Topical,
Authoritex.FAST.UniformTitle,
Authoritex.FAST,
Authoritex.GeoNames,
Authoritex.Getty.AAT,
Authoritex.Getty.TGN,
Authoritex.Getty.ULAN,
Authoritex.Getty,
Authoritex.LOC.Languages,
Authoritex.LOC.Names,
Authoritex.LOC.SubjectHeadings
])
Authoritex.authorities/0
returns a list of tuples describing all configured authorities.
Authoritex.authorities()
Authoritex.fetch/1
returns a map with the :label
, :id
, :hint
, and :qualified_label
for an authority record given an id (must be a string).
# Known authority and record identifier
Authoritex.fetch("http://id.loc.gov/authorities/names/no2011087251")
Authoritex.fetch/1
returns the error tuple {:error, 404}
given an unknown id for a properly configured authority.
# Known authority with unknown record identifier
Authoritex.fetch("http://id.loc.gov/authorities/names/unknown-id")
Authoritex.fetch/1
returns the error tuple {:error, :unknown_authority}
given an id for an unknown authority.
# Unknown authority
Authoritex.fetch("http://fake.authority.org/not-a-real-thing")
Authoritex.search/2
performs a search with an authority and a search term. The following select menu lets you choose a supported authority:
search_authority =
Kino.Input.select(
"Select Authority",
[
{"aat", "Getty Art & Architecture Thesaurus (AAT)"},
{"fast", "Faceted Application of Subject Terminology (FAST) -- Base"},
{"fast-corporate-name", "Faceted Application of Subject Terminology -- Corporate Name"},
{"fast-event-name", "Faceted Application of Subject Terminology -- Event Name"},
{"fast-form", "Faceted Application of Subject Terminology -- Form/Genre"},
{"fast-geographic", "Faceted Application of Subject Terminology -- Geographic"},
{"fast-personal", "Faceted Application of Subject Terminology -- Personal"},
{"fast-topical", "Faceted Application of Subject Terminology -- Topical"},
{"fast-uniform-title", "Faceted Application of Subject Terminology -- Uniform Title"},
{"getty", "Getty -- Base"},
{"lclang", "Library of Congress MARC List for Languages"},
{"lcnaf", "Library of Congress Name Authority File"},
{"lcsh", "Library of Congress Subject Headings"},
{"tgn", "Getty Thesaurus of Geographic Names (TGN)"},
{"ulan", "Getty Union List of Artist Names (ULAN)"}
]
)
Enter a search term in the text input:
search_term = Kino.Input.text("Search term")
Perform the search using the values chosen above:
Authoritex.search(Kino.Input.read(search_authority), Kino.Input.read(search_term))
Authoritex.search/3
takes the same arguments as Authoritex.search/2
along with a third argument (must be an integer) to limit the result count of the search.
Authoritex.search("lcsh", "library", 3)
# Error recevied when searching an unknown authority
Authoritex.search("not-an-authority", "test")
Authoritex
provides a mock for testing purposes in consuming applications.
Configure the mock with a few lines of code:
# In test.exs:
config :authoritex, authorities: [Authoritex.Mock]
# In test_helper.exs:
Authoritex.Mock.init()
Use the Authoritex.Mock.set_data/1
function to add data for testing purposes, typically in a setup
block. The example module below demonstrates an ExUnit
test using the Authoritex.Mock
. The Authoritex.Mock.search/1
function returns all mock data regardless of the string passed to the function. (Note: the following code is a code sample that is not runnable like the examples above):
defmodule MyTest do
alias Authoritex.Mock
use ExUnit.Case, async: true
@data [
%{
id: "mock:result1",
label: "First Result",
qualified_label: "First Result (1)",
hint: "(1)"
},
%{
id: "mock:result2",
label: "Second Result",
qualified_label: "Second Result (2)",
hint: "(2)"
},
%{id: "mock:result3", label: "Third Result", qualified_label: "Third Result (3)", hint: "(3)"}
]
setup do
Mock.set_data(@data)
:ok
end
test "results" do
with {:ok, results} <- Mock.search("any") do
assert length(results) == length(@data)
end
end
end