View Source Getting Started With Authoritex

About

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 identifier
  • code/0 Returns the unique short code for the authority
  • description/0 Returns a human-readable description of the authority
  • fetch/1 Fetches a label (and optional hint string) for a specified resource
  • search/2 Returns a list of search results (and optional hints) matching a query

Installation

Mix.install([
  {:authoritex, "~> 0.7.0"},
  {:kino, "~> 0.5.2"}
])

Configuration

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
])

List configured authorities

Authoritex.authorities/0 returns a list of tuples describing all configured authorities.

Authoritex.authorities()

Fetch records by id

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")

Search an authority

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")

Testing

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