Skip to content

Commit 5db3b76

Browse files
authored
Merge pull request #14 from blue-core-lod/keycloak-provider
Adds Keycloak Provider for use in React Components
2 parents ca96579 + 94927ee commit 5db3b76

File tree

83 files changed

+679
-1493
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+679
-1493
lines changed

README.md

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
[![CircleCI](https://circleci.com/gh/LD4P/sinopia_editor.svg?style=svg)](https://circleci.com/gh/LD4P/sinopia_editor)
2-
[![Test Coverage Code Climate](https://api.codeclimate.com/v1/badges/27fe0fcbf342d0bca13b/test_coverage)](https://codeclimate.com/github/LD4P/sinopia_editor/test_coverage)
3-
[![Maintainability](https://api.codeclimate.com/v1/badges/27fe0fcbf342d0bca13b/maintainability)](https://codeclimate.com/github/LD4P/sinopia_editor/maintainability)
4-
[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/ld4p/sinopia_editor?sort=semver)](https://hub.docker.com/repository/docker/ld4p/sinopia_editor/tags?page=1&ordering=last_updated)
5-
6-
7-
# Sinopia Linked Data Editor
1+
# Blue Core's Sinopia Linked Data Editor
82

93
Technical documentation specific to the Sinopia Linked Data Editor may also be found in the [wiki](https://github.com/LD4P/sinopia_editor/wiki/Sinopia-Editor). The Sinopia Editor homepage is available [development.sinopia.io](http://development.sinopia.io), [stage.sinopia.io](https://stage.sinopia.io), and [sinopia.io](https://sinopia.io). The Sinopia Editor is a React application with all new user interfaces and functionality using React and the React ecosystem. Portions of the codebase originally extracted from the Library of Congress [bfe project](https://github.com/lcnetdev/bfe).
104

__tests__/actionCreators/authenticate.test.js

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,13 @@
11
// Copyright 2019 Stanford University see LICENSE for license
2-
let mockKeycloak
3-
4-
jest.mock("keycloak-js", () => {
5-
mockKeycloak = {
6-
init: jest.fn(() => Promise.resolve(true)),
7-
isTokenExpired: jest.fn(),
8-
updateToken: jest.fn(),
9-
login: jest.fn(() => Promise.resolve(true)),
10-
logout: jest.fn(() => Promise.resolve(true)),
11-
authenticated: false,
12-
}
13-
14-
return jest.fn().mockImplementation((config) => {
15-
return mockKeycloak
16-
})
17-
})
18-
192
import { authenticate, signIn, signOut } from "actionCreators/authenticate"
203
import configureMockStore from "redux-mock-store"
214
import thunk from "redux-thunk"
225
import * as sinopiaApi from "sinopiaApi"
236

7+
jest.mock("KeycloakContext", () => ({
8+
useKeycloak: jest.fn().mockReturnValue({}),
9+
}))
10+
2411
const mockStore = configureMockStore([thunk])
2512

2613
const userData = {
@@ -30,28 +17,34 @@ const userData = {
3017
describe("authenticate", () => {
3118
beforeEach(() => {
3219
jest.clearAllMocks()
33-
mockKeycloak.authenticated = false
3420
})
3521

3622
describe("user already in state", () => {
3723
it("does not authenticate", async () => {
24+
const mockKeycloak = {}
3825
const store = mockStore({
3926
authenticate: { user: { username: "havram" } },
4027
})
41-
await store.dispatch(authenticate())
28+
await store.dispatch(authenticate(mockKeycloak))
4229
expect(store.getActions()).toEqual([])
4330
})
4431
})
4532

4633
describe("successful", () => {
4734
sinopiaApi.fetchUser = jest.fn().mockResolvedValue(userData)
4835
it("dispatches actions to add user", async () => {
49-
mockKeycloak.authenticated = true
50-
mockKeycloak.tokenParsed = {
51-
preferred_username: "havram",
36+
const mockKeycloak = {
37+
authenticated: true,
38+
isTokenExpired: jest.fn(),
39+
updateToken: jest.fn(),
40+
login: jest.fn(() => Promise.resolve(true)),
41+
tokenParsed: {
42+
preferred_username: "havram",
43+
},
5244
}
45+
5346
const store = mockStore({ authenticate: { user: undefined } })
54-
await store.dispatch(authenticate())
47+
await store.dispatch(authenticate(mockKeycloak))
5548

5649
expect(store.getActions()).toHaveAction("SET_USER", {
5750
username: "havram",
@@ -62,8 +55,9 @@ describe("authenticate", () => {
6255
})
6356
describe("failure", () => {
6457
it("dispatches actions to remove user", async () => {
58+
const mockKeycloak = { authenticated: false }
6559
const store = mockStore({ authenticate: { user: undefined } })
66-
await store.dispatch(authenticate())
60+
await store.dispatch(authenticate(mockKeycloak))
6761
expect(store.getActions()).toHaveAction("REMOVE_USER")
6862
})
6963
})
@@ -72,21 +66,25 @@ describe("authenticate", () => {
7266
describe("signIn", () => {
7367
beforeEach(() => {
7468
jest.clearAllMocks()
75-
mockKeycloak.authenticated = false
7669
})
7770

7871
describe("successful", () => {
7972
sinopiaApi.fetchUser = jest.fn().mockResolvedValue(userData)
8073
it("dispatches actions to add user", async () => {
8174
let store = mockStore()
82-
await store.dispatch(signIn("havram", "m&rc", "testerrorkey"))
75+
const mockKeycloak = {
76+
login: jest.fn(() => Promise.resolve(true)),
77+
isTokenExpired: jest.fn(),
78+
updateToken: jest.fn(),
79+
}
80+
await store.dispatch(signIn(mockKeycloak, "testerrorkey"))
8381
// After successful signIn, redirected to Sinopia home-page
8482
mockKeycloak.authenticated = true
8583
mockKeycloak.tokenParsed = {
8684
preferred_username: "havram",
8785
}
8886
store = mockStore({ authenticate: { user: undefined } })
89-
await store.dispatch(authenticate())
87+
await store.dispatch(authenticate(mockKeycloak))
9088

9189
expect(store.getActions()).toHaveAction("SET_USER", {
9290
username: "havram",
@@ -98,13 +96,16 @@ describe("signIn", () => {
9896
describe("failure", () => {
9997
it("dispatches actions to remove user", async () => {
10098
let store = mockStore()
101-
await store.dispatch(signIn("mdewey", "amh&rst", "testerrorkey"))
99+
const mockKeycloak = {
100+
login: jest.fn(() => Promise.resolve(false)),
101+
}
102+
await store.dispatch(signIn(mockKeycloak, "testerrorkey"))
102103
expect(store.getActions()).toHaveAction("CLEAR_ERRORS", "testerrorkey")
103104

104105
// SignIn failures happen in Keycloak so can't test failures
105106
// directly, simulates user refreshing Sinopia
106107
store = mockStore({ authenticate: { user: undefined } })
107-
await store.dispatch(authenticate())
108+
await store.dispatch(authenticate(mockKeycloak))
108109

109110
expect(store.getActions()).toHaveAction("REMOVE_USER")
110111
})
@@ -115,7 +116,10 @@ describe("signOut", () => {
115116
describe("successful", () => {
116117
it("dispatches actions to remove user", async () => {
117118
const store = mockStore()
118-
await store.dispatch(signOut())
119+
const mockKeycloak = {
120+
logout: jest.fn(() => Promise.resolve(true)),
121+
}
122+
await store.dispatch(signOut(mockKeycloak))
119123

120124
expect(store.getActions()).toHaveAction("REMOVE_USER")
121125
})

__tests__/actionCreators/relationships.test.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
let mockKeycloak
2-
3-
jest.mock("keycloak-js", () => {
4-
mockKeycloak = {
5-
init: jest.fn(() => Promise.resolve(true)),
6-
token: "Secret-Token",
7-
authenticated: true,
8-
isTokenExpired: jest.fn(),
9-
updateToken: jest.fn(),
10-
tokenParsed: {
11-
preferred_username: "Foo McBar",
12-
},
13-
}
14-
15-
return jest.fn().mockImplementation((config) => {
16-
return mockKeycloak
17-
})
18-
})
19-
201
import {
212
loadRelationships,
223
loadSearchRelationships,
@@ -26,6 +7,10 @@ import configureMockStore from "redux-mock-store"
267
import thunk from "redux-thunk"
278
import { createState } from "stateUtils"
289

10+
jest.mock("KeycloakContext", () => ({
11+
useKeycloak: jest.fn().mockReturnValue({}),
12+
}))
13+
2914
const mockStore = configureMockStore([thunk])
3015

3116
const relationships = {

__tests__/actionCreators/resources.loadResource.test.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
let mockKeycloak
2-
3-
jest.mock("keycloak-js", () => {
4-
mockKeycloak = {
5-
init: jest.fn(() => Promise.resolve(true)),
6-
token: "Secret-Token",
7-
authenticated: true,
8-
isTokenExpired: jest.fn(),
9-
updateToken: jest.fn(),
10-
tokenParsed: {
11-
preferred_username: "Foo McBar",
12-
},
13-
}
14-
15-
return jest.fn().mockImplementation((config) => {
16-
return mockKeycloak
17-
})
18-
})
19-
201
import {
212
loadResourceForEditor,
223
loadResourceForPreview,
@@ -35,6 +16,10 @@ import expectedAction from "../__action_fixtures__/loadResource-ADD_SUBJECT"
3516
import expectedMultiplePropertyUrisAction from "../__action_fixtures__/loadResource-ADD_SUBJECT-multiple-property-uris"
3617
import { safeAction, cloneAddResourceActionAsNewResource } from "actionUtils"
3718

19+
jest.mock("KeycloakContext", () => ({
20+
useKeycloak: jest.fn().mockReturnValue({}),
21+
}))
22+
3823
jest.useFakeTimers({ now: new Date("2020-08-20T11:34:40.887Z") })
3924
jest.mock("nanoid")
4025

__tests__/actionCreators/resources.newResource.test.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
let mockKeycloak
2-
3-
jest.mock("keycloak-js", () => {
4-
mockKeycloak = {
5-
init: jest.fn(() => Promise.resolve(true)),
6-
token: "Secret-Token",
7-
authenticated: true,
8-
isTokenExpired: jest.fn(),
9-
updateToken: jest.fn(),
10-
tokenParsed: {
11-
preferred_username: "Foo McBar",
12-
},
13-
}
14-
15-
return jest.fn().mockImplementation((config) => {
16-
return mockKeycloak
17-
})
18-
})
19-
201
import { newResource } from "actionCreators/resources"
212
import mockConsole from "jest-mock-console"
223
import * as sinopiaApi from "sinopiaApi"
@@ -28,6 +9,10 @@ import { nanoid } from "nanoid"
289
import { safeAction } from "actionUtils"
2910
import expectedAction from "../__action_fixtures__/newResource-ADD_SUBJECT"
3011

12+
jest.mock("KeycloakContext", () => ({
13+
useKeycloak: jest.fn().mockReturnValue({}),
14+
}))
15+
3116
jest.useFakeTimers({ now: new Date("2020-08-20T11:34:40.887Z") })
3217
jest.mock("nanoid")
3318

__tests__/actionCreators/resources.newResourceCopy.test.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
let mockKeycloak
2-
3-
jest.mock("keycloak-js", () => {
4-
mockKeycloak = {
5-
init: jest.fn(() => Promise.resolve(true)),
6-
token: "Secret-Token",
7-
authenticated: true,
8-
isTokenExpired: jest.fn(),
9-
updateToken: jest.fn(),
10-
tokenParsed: {
11-
preferred_username: "Foo McBar",
12-
},
13-
}
14-
15-
return jest.fn().mockImplementation((config) => {
16-
return mockKeycloak
17-
})
18-
})
19-
201
import { newResourceCopy } from "actionCreators/resources"
212
import mockConsole from "jest-mock-console"
223
import Config from "Config"
@@ -27,6 +8,10 @@ import { nanoid } from "nanoid"
278
import expectedAction from "../__action_fixtures__/newResourceCopy-ADD_SUBJECT"
289
import { safeAction } from "actionUtils"
2910

11+
jest.mock("KeycloakContext", () => ({
12+
useKeycloak: jest.fn().mockReturnValue({}),
13+
}))
14+
3015
// This won't be required after Jest 27
3116
jest.useFakeTimers({ now: new Date("2020-08-20T11:34:40.887Z") })
3217
jest.mock("nanoid")

__tests__/actionCreators/resources.newResourceFromDataset.test.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
let mockKeycloak
2-
3-
jest.mock("keycloak-js", () => {
4-
mockKeycloak = {
5-
init: jest.fn(() => Promise.resolve(true)),
6-
token: "Secret-Token",
7-
authenticated: true,
8-
isTokenExpired: jest.fn(),
9-
updateToken: jest.fn(),
10-
tokenParsed: {
11-
preferred_username: "Foo McBar",
12-
},
13-
}
14-
15-
return jest.fn().mockImplementation((config) => {
16-
return mockKeycloak
17-
})
18-
})
19-
201
import { newResourceFromDataset } from "actionCreators/resources"
212
import mockConsole from "jest-mock-console"
223
import Config from "Config"
@@ -32,6 +13,10 @@ import expectedBadOrderedAction from "../__action_fixtures__/newResourceFromData
3213
import expectedNestedAction from "../__action_fixtures__/newResourceFromDataset-ADD_SUBJECT-nested"
3314
import { safeAction, cloneAddResourceActionAsNewResource } from "actionUtils"
3415

16+
jest.mock("KeycloakContext", () => ({
17+
useKeycloak: jest.fn().mockReturnValue({}),
18+
}))
19+
3520
jest.mock("nanoid")
3621

3722
nanoid.mockImplementation(() => "abc123")

__tests__/actionCreators/resources.test.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,3 @@
1-
let mockKeycloak
2-
3-
jest.mock("keycloak-js", () => {
4-
mockKeycloak = {
5-
init: jest.fn(() => Promise.resolve(true)),
6-
token: "Secret-Token",
7-
authenticated: true,
8-
isTokenExpired: jest.fn(),
9-
updateToken: jest.fn(),
10-
tokenParsed: {
11-
preferred_username: "Foo McBar",
12-
},
13-
}
14-
15-
return jest.fn().mockImplementation((config) => {
16-
return mockKeycloak
17-
})
18-
})
19-
201
import {
212
expandProperty,
223
addSiblingValueSubject,
@@ -38,6 +19,10 @@ import expectedExpandPropertyAddValueAction from "../__action_fixtures__/expandP
3819
import expectedExpandPropertyAddPropertyAction from "../__action_fixtures__/expandProperty-ADD_PROPERTY"
3920
import expectedAddSiblingAddValueAction from "../__action_fixtures__/addSiblingValueSubject-ADD_VALUE"
4021

22+
jest.mock("KeycloakContext", () => ({
23+
useKeycloak: jest.fn().mockReturnValue({}),
24+
}))
25+
4126
jest.useFakeTimers({ now: new Date("2020-08-20T11:34:40.887Z") })
4227
jest.mock("nanoid")
4328

__tests__/actionCreators/search.test.js

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,4 @@
11
// Copyright 2019 Stanford University see LICENSE for license
2-
let mockKeycloak
3-
4-
jest.mock("keycloak-js", () => {
5-
mockKeycloak = {
6-
init: jest.fn(() => Promise.resolve(true)),
7-
token: "Secret-Token",
8-
authenticated: true,
9-
isTokenExpired: jest.fn(),
10-
updateToken: jest.fn(),
11-
tokenParsed: {
12-
preferred_username: "Foo McBar",
13-
},
14-
}
15-
16-
return jest.fn().mockImplementation((config) => {
17-
return mockKeycloak
18-
})
19-
})
20-
212
import {
223
fetchSinopiaSearchResults,
234
fetchQASearchResults,
@@ -30,6 +11,10 @@ import { createState } from "stateUtils"
3011
import * as sinopiaApi from "sinopiaApi"
3112
import * as QuestioningAuthority from "utilities/QuestioningAuthority"
3213

14+
jest.mock("KeycloakContext", () => ({
15+
useKeycloak: jest.fn().mockReturnValue({}),
16+
}))
17+
3318
const mockStore = configureMockStore([thunk])
3419

3520
describe("fetchSinopiaSearchResults", () => {

0 commit comments

Comments
 (0)