Merge branch 'development' into tweak/better-withTranslation-mock

This commit is contained in:
Mark Drobnak
2019-06-28 11:35:18 -04:00
committed by GitHub
4 changed files with 50 additions and 32 deletions
@@ -11,6 +11,7 @@
import React, { ReactNode } from "react";
import { WithAPIData } from "../WithAPIData";
import api from "../../../util/api";
import config from "../../../config";
/**
* The data shared by the preferences context
@@ -56,18 +57,18 @@ export const loadInitialPreferences = (): ApiPreferences => {
};
/**
* The context which will be used initially, until the API responds with the
* real preferences. These preferences are loaded from cache if available.
* Load the context which will be used initially, until the API responds with
* the real preferences. These preferences are loaded from cache if available.
*/
const initialContext: PreferencesContextType = {
export const loadInitialContext = (): PreferencesContextType => ({
settings: loadInitialPreferences(),
refresh: () => {}
};
});
/**
* The React context which provides the preferences to consumers
*/
export const PreferencesContext = React.createContext(initialContext);
export const PreferencesContext = React.createContext(loadInitialContext());
/**
* Provide the web interface preferences via React context.
@@ -81,9 +82,13 @@ export const PreferencesProvider = ({
children: ReactNode;
}) => (
<WithAPIData
apiCall={api.getPreferences}
apiCall={
config.fakeAPI
? () => Promise.resolve(loadInitialPreferences())
: api.getPreferences
}
renderInitial={() => (
<PreferencesContext.Provider value={initialContext} {...props}>
<PreferencesContext.Provider value={loadInitialContext()} {...props}>
{children}
</PreferencesContext.Provider>
)}
@@ -8,16 +8,20 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
import React from "react";
import React, { ProviderProps } from "react";
import {
defaultPreferences,
loadInitialPreferences,
WEB_PREFERENCES_STORAGE_KEY,
PreferencesContextType,
PreferencesProvider,
PreferencesContextType
WEB_PREFERENCES_STORAGE_KEY
} from "../PreferencesContext";
import { shallow } from "enzyme";
import { WithAPIData } from "../../WithAPIData";
import config from "../../../../config";
import api from "../../../../util/api";
jest.mock("../../../../util/api");
it("loads the default preferences if none are cached", () => {
const preferences = loadInitialPreferences();
@@ -59,6 +63,27 @@ it("provides the initial settings while loading", () => {
expect(wrapper.props().value.settings).toEqual(expectedPreferences);
});
it("should use the cached settings instead of the API when in fakeAPI mode", async () => {
const expectedPreferences: ApiPreferences = {
language: "testLang",
layout: "boxed"
};
config.fakeAPI = true;
localStorage.setItem(
WEB_PREFERENCES_STORAGE_KEY,
JSON.stringify(expectedPreferences)
);
const wrapper = shallow(
<PreferencesProvider>{null}</PreferencesProvider>
).dive();
const props = wrapper.props() as ProviderProps<PreferencesContextType>;
expect(props.value.settings).toEqual(expectedPreferences);
expect(api.getPreferences).not.toHaveBeenCalled();
});
it("caches the settings after loading and provides the new settings", () => {
const expectedPreferences: ApiPreferences = {
language: "testLang",
+7 -21
View File
@@ -20,6 +20,7 @@ import Alert, { AlertType } from "../common/Alert";
import { Button, Col, Form, FormGroup, Input, Label } from "reactstrap";
import { PreferencesContext } from "../common/context/PreferencesContext";
import languages from "../../languages.json";
import config from "../../config";
export interface PreferenceSettingsProps {
settings: ApiPreferences;
@@ -51,27 +52,9 @@ class PreferenceSettings extends Component<
settings: this.props.settings
};
private loadHandler: undefined | CancelablePromise<ApiPreferences>;
private updateHandler: undefined | CancelablePromise<ApiSuccessResponse>;
loadPreferences = () => {
this.loadHandler = makeCancelable(api.getPreferences());
this.loadHandler.promise
.then(res => {
this.setState({ settings: res });
})
.catch(ignoreCancel);
};
componentDidMount() {
this.loadPreferences();
}
componentWillUnmount() {
if (this.loadHandler) {
this.loadHandler.cancel();
}
if (this.updateHandler) {
this.updateHandler.cancel();
}
@@ -116,9 +99,12 @@ class PreferenceSettings extends Component<
translateMessage: true
});
this.updateHandler = makeCancelable(
api.updatePreferences(this.state.settings)
);
// Allow preference changes when using the fake API
const apiPromise = config.fakeAPI
? Promise.resolve({ status: "success" } as ApiSuccessResponse)
: api.updatePreferences(this.state.settings);
this.updateHandler = makeCancelable(apiPromise);
this.updateHandler.promise
.then(() => {
this.setState({
+3 -1
View File
@@ -16,6 +16,7 @@ import api from "./util/api";
import fetchMock from "fetch-mock";
import "jest-localstorage-mock";
import i18next from "i18next";
import config from "./config";
// Setup enzyme
configure({ adapter: new Adapter() });
@@ -32,10 +33,11 @@ jest.mock("react-i18next", () => ({
}));
beforeEach(() => {
// Temporary fix to reset logged in state for each test.
// Temporary fix to reset global state for each test.
// The permanent fix would be to not use a global variable, and instead give this information to components through
// props. Redux would be good for this, if we want to add it to the project.
api.loggedIn = false;
config.fakeAPI = false;
// Clear local storage mock
localStorage.clear();