Skip to content

Commit

Permalink
Replace swagger-based QA client with simple fetch calls
Browse files Browse the repository at this point in the history
Fixes #3262

This commit replaces the swagger-based QA client. Why?

1. the API specification is incomplete;
2. it's not clear there is a plan in place to keep the specification up to date; and
3. we only use a fraction of the QA API in the Sinopia editor

In short, it's to pay down technical debt. This commit otherwise retains the same interface for interacting with the QA API, returning a promise that resolves to the HTTP response.
  • Loading branch information
mjgiarlo committed Nov 8, 2021
1 parent 8a4e1b2 commit 40c0d9a
Show file tree
Hide file tree
Showing 7 changed files with 213 additions and 2,290 deletions.
125 changes: 64 additions & 61 deletions __tests__/actionCreators/search.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import {
fetchQASearchResults,
} from "actionCreators/search"
import * as server from "sinopiaSearch"
import Swagger from "swagger-client"
import configureMockStore from "redux-mock-store"
import thunk from "redux-thunk"
import { createState } from "stateUtils"
import * as sinopiaApi from "sinopiaApi"

jest.mock("swagger-client")

const mockStore = configureMockStore([thunk])

describe("fetchSinopiaSearchResults", () => {
Expand Down Expand Up @@ -88,7 +85,8 @@ describe("fetchSinopiaSearchResults", () => {
describe("fetchQASearchResults", () => {
const query = "*"
const uri = "urn:ld4p:qa:sharevde_stanford_ld4l_cache:all"
it("dispatches action", async () => {

describe("when happy path", () => {
const mockSearchResults = [
{
uri: "http://share-vde.org/sharevde/rdfBibframe/Work/3107365",
Expand Down Expand Up @@ -147,77 +145,82 @@ describe("fetchQASearchResults", () => {
],
},
]
const mockActionFunction = jest.fn().mockResolvedValue({
const mockResponse = {
body: {
results: mockSearchResults,
response_header: { total_records: 15 },
},
})
const client = {
apis: { SearchQuery: { GET_searchAuthority: mockActionFunction } },
}
Swagger.mockResolvedValue(client)
sinopiaApi.putUserHistory = jest.fn().mockResolvedValue()

const store = mockStore(createState())
await store.dispatch(fetchQASearchResults(query, uri, "testerrorkey"))
beforeEach(() => {
global.fetch = jest
.fn()
.mockImplementation(() => Promise.resolve(mockResponse))
})

const actions = store.getActions()
it("dispatches action", async () => {
sinopiaApi.putUserHistory = jest.fn().mockResolvedValue()

expect(actions).toHaveLength(3)
expect(actions).toHaveAction("CLEAR_ERRORS")
expect(actions).toHaveAction("SET_SEARCH_RESULTS", {
searchType: "resource",
uri,
query,
results: mockSearchResults,
totalResults: 15,
options: {},
error: undefined,
facetResults: {},
})
expect(actions).toHaveAction("ADD_SEARCH_HISTORY", {
authorityUri: uri,
authorityLabel: "SHAREVDE STANFORD (QA)",
query,
const store = mockStore(createState())
await store.dispatch(fetchQASearchResults(query, uri, "testerrorkey"))

const actions = store.getActions()

expect(actions).toHaveLength(3)
expect(actions).toHaveAction("CLEAR_ERRORS")
expect(actions).toHaveAction("SET_SEARCH_RESULTS", {
searchType: "resource",
uri,
query,
results: mockSearchResults,
totalResults: 15,
options: {},
error: undefined,
facetResults: {},
})
expect(actions).toHaveAction("ADD_SEARCH_HISTORY", {
authorityUri: uri,
authorityLabel: "SHAREVDE STANFORD (QA)",
query,
})
expect(sinopiaApi.putUserHistory).toHaveBeenCalledWith(
"Foo McBar",
"search",
"4682c287952df68172c6c4a63bdc2887",
'{"authorityUri":"urn:ld4p:qa:sharevde_stanford_ld4l_cache:all","query":"*"}'
)
})
expect(sinopiaApi.putUserHistory).toHaveBeenCalledWith(
"Foo McBar",
"search",
"4682c287952df68172c6c4a63bdc2887",
'{"authorityUri":"urn:ld4p:qa:sharevde_stanford_ld4l_cache:all","query":"*"}'
)
})

it("dispatches action when error", async () => {
const mockActionFunction = jest
.fn()
.mockRejectedValue(new Error("Ooops..."))
const client = {
apis: { SearchQuery: { GET_searchAuthority: mockActionFunction } },
}
Swagger.mockResolvedValue(client)
describe("when error occurs", () => {
beforeEach(() => {
global.fetch = jest
.fn()
.mockImplementation(() => Promise.reject(new Error("Ooops...")))
})

const store = mockStore(createState())
await store.dispatch(fetchQASearchResults(query, uri, "testerrorkey"))
it("dispatches action when error", async () => {
const store = mockStore(createState())
await store.dispatch(fetchQASearchResults(query, uri, "testerrorkey"))

const actions = store.getActions()
const actions = store.getActions()

expect(actions).toHaveLength(3)
expect(actions).toHaveAction("CLEAR_ERRORS")
expect(actions).toHaveAction("SET_SEARCH_RESULTS", {
searchType: "resource",
uri,
query,
results: [],
totalResults: 0,
options: {},
facetResults: {},
error: "Ooops...",
})
expect(actions).toHaveAction("ADD_ERROR", {
errorKey: "testerrorkey",
error: ["An error occurred while searching: Ooops..."],
expect(actions).toHaveLength(3)
expect(actions).toHaveAction("CLEAR_ERRORS")
expect(actions).toHaveAction("SET_SEARCH_RESULTS", {
searchType: "resource",
uri,
query,
results: [],
totalResults: 0,
options: {},
facetResults: {},
error: "Ooops...",
})
expect(actions).toHaveAction("ADD_ERROR", {
errorKey: "testerrorkey",
error: ["An error occurred while searching: Ooops..."],
})
})
})
})
89 changes: 43 additions & 46 deletions __tests__/components/search/Search.test.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,56 @@
import { renderApp } from "testUtils"
import { fireEvent, waitFor, screen } from "@testing-library/react"
import * as server from "sinopiaSearch"
import Swagger from "swagger-client"
import Config from "Config"
import * as sinopiaApi from "sinopiaApi"

jest.mock("swagger-client")

describe("<Search />", () => {
jest.spyOn(sinopiaApi, "putUserHistory").mockResolvedValue()

it("requests a QA search", async () => {
const mockSearchResults = [
{
uri: "http://share-vde.org/sharevde/rdfBibframe/Work/3107365",
id: "http://share-vde.org/sharevde/rdfBibframe/Work/3107365",
label: "These twain",
context: [
{
property: "Title",
values: [" These twain"],
selectable: true,
drillable: false,
},
{
property: "Type",
values: [
"http://id.loc.gov/ontologies/bflc/Hub",
"http://id.loc.gov/ontologies/bibframe/Work",
],
selectable: false,
drillable: false,
},
{
property: "Contributor",
values: ["Bennett, Arnold,1867-1931."],
selectable: false,
drillable: false,
},
],
},
]
const mockActionFunction = jest.fn().mockResolvedValue({
body: {
results: mockSearchResults,
response_header: { total_records: 15 },
},
})
const client = {
apis: {
SearchQuery: { GET_nonldSearchWithSubauthority: mockActionFunction },
},
}
Swagger.mockResolvedValue(client)
const mockSearchResults = [
{
uri: "http://share-vde.org/sharevde/rdfBibframe/Work/3107365",
id: "http://share-vde.org/sharevde/rdfBibframe/Work/3107365",
label: "These twain",
context: [
{
property: "Title",
values: [" These twain"],
selectable: true,
drillable: false,
},
{
property: "Type",
values: [
"http://id.loc.gov/ontologies/bflc/Hub",
"http://id.loc.gov/ontologies/bibframe/Work",
],
selectable: false,
drillable: false,
},
{
property: "Contributor",
values: ["Bennett, Arnold,1867-1931."],
selectable: false,
drillable: false,
},
],
},
]
const mockResponse = {
body: {
results: mockSearchResults,
response_header: { total_records: 15 },
},
}

beforeEach(() => {
global.fetch = jest
.fn()
.mockImplementation(() => Promise.resolve(mockResponse))
})

it("requests a QA search", async () => {
renderApp()
fireEvent.click(screen.getByText("Linked Data Editor", { selector: "a" }))

Expand Down
Loading

0 comments on commit 40c0d9a

Please sign in to comment.