mirror of
https://github.com/status-im/sourcecred.git
synced 2025-02-25 02:35:32 +00:00
Load repo registry even when hosted at non-root (#678)
Summary: This commit is the next step in #643. It makes the `RepositorySelect` robust to being hosted at arbitrary gateways by accepting `Assets` and resolving the repository registry API route appropriately. Test Plan: Unit tests modified, but it would be good to also manually test this. Run `./scripts/build_static_site.sh` to build the site to, say, `/tmp/gateway/`. Then spin up a static HTTP server serving `/tmp/` and navigate to `/gateway/` in the browser. Note that you can navigate around the application and load the repository registry on the prototype without any console warnings or errors, although you cannot yet load actual graph data. wchargin-branch: use-assets-in-RepositorySelect
This commit is contained in:
parent
19af47a664
commit
b252a6b5de
@ -84,6 +84,7 @@ export function createApp(
|
||||
<div style={{maxWidth: 900, margin: "0 auto", padding: "0 10px"}}>
|
||||
<div style={{marginBottom: 10}}>
|
||||
<RepositorySelect
|
||||
assets={this.props.assets}
|
||||
localStore={localStore}
|
||||
onChange={(repo) => this.stateTransitionMachine.setRepo(repo)}
|
||||
/>
|
||||
|
@ -6,6 +6,7 @@ import deepEqual from "lodash.isequal";
|
||||
|
||||
import * as NullUtil from "../../util/null";
|
||||
import type {LocalStore} from "../localStore";
|
||||
import type {Assets} from "../assets";
|
||||
|
||||
import {fromJSON, REPO_REGISTRY_API} from "./repoRegistry";
|
||||
import {type Repo, stringToRepo, repoToString} from "../../core/repo";
|
||||
@ -22,6 +23,7 @@ export type Status =
|
||||
| {|+type: "FAILURE"|};
|
||||
|
||||
type Props = {|
|
||||
+assets: Assets,
|
||||
+onChange: (x: Repo) => void,
|
||||
+localStore: LocalStore,
|
||||
|};
|
||||
@ -35,7 +37,8 @@ export default class RepositorySelect extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
loadStatus(this.props.localStore).then((status) => {
|
||||
const {assets, localStore} = this.props;
|
||||
loadStatus(assets, localStore).then((status) => {
|
||||
this.setState({status});
|
||||
if (status.type === "VALID") {
|
||||
this.props.onChange(status.selectedRepo);
|
||||
@ -67,9 +70,12 @@ export default class RepositorySelect extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadStatus(localStore: LocalStore): Promise<Status> {
|
||||
export async function loadStatus(
|
||||
assets: Assets,
|
||||
localStore: LocalStore
|
||||
): Promise<Status> {
|
||||
try {
|
||||
const response = await fetch(REPO_REGISTRY_API);
|
||||
const response = await fetch(assets.resolve(REPO_REGISTRY_API));
|
||||
if (response.status === 404) {
|
||||
return {type: "NO_REPOS"};
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import RepositorySelect, {
|
||||
type Status,
|
||||
REPO_KEY,
|
||||
} from "./RepositorySelect";
|
||||
import {Assets} from "../assets";
|
||||
|
||||
import {toJSON, type RepoRegistry, REPO_REGISTRY_API} from "./repoRegistry";
|
||||
import {makeRepo} from "../../core/repo";
|
||||
@ -106,14 +107,15 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
});
|
||||
|
||||
describe("loadStatus", () => {
|
||||
const assets = new Assets("/my/gateway/");
|
||||
function expectLoadValidStatus(
|
||||
localStore,
|
||||
expectedAvailableRepos,
|
||||
expectedSelectedRepo
|
||||
) {
|
||||
const result = loadStatus(localStore);
|
||||
const result = loadStatus(assets, localStore);
|
||||
expect(fetch).toHaveBeenCalledTimes(1);
|
||||
expect(fetch).toHaveBeenCalledWith(REPO_REGISTRY_API);
|
||||
expect(fetch).toHaveBeenCalledWith("/my/gateway" + REPO_REGISTRY_API);
|
||||
expect.assertions(7);
|
||||
return result.then((status) => {
|
||||
expect(status.type).toBe("VALID");
|
||||
@ -142,7 +144,7 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
it("returns FAILURE on invalid fetch response", () => {
|
||||
fetch.mockResponseOnce(JSON.stringify(["hello"]));
|
||||
expect.assertions(4);
|
||||
return loadStatus(testLocalStore()).then((status) => {
|
||||
return loadStatus(assets, testLocalStore()).then((status) => {
|
||||
expect(status).toEqual({type: "FAILURE"});
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
// $ExpectFlowError
|
||||
@ -152,7 +154,7 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
it("returns FAILURE on fetch failure", () => {
|
||||
fetch.mockReject(new Error("some failure"));
|
||||
expect.assertions(4);
|
||||
return loadStatus(testLocalStore()).then((status) => {
|
||||
return loadStatus(assets, testLocalStore()).then((status) => {
|
||||
expect(status).toEqual({type: "FAILURE"});
|
||||
expect(console.error).toHaveBeenCalledTimes(1);
|
||||
// $ExpectFlowError
|
||||
@ -162,7 +164,7 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
it("returns NO_REPOS on fetch 404", () => {
|
||||
fetch.mockResponseOnce("irrelevant", {status: 404});
|
||||
expect.assertions(3);
|
||||
return loadStatus(testLocalStore()).then((status) => {
|
||||
return loadStatus(assets, testLocalStore()).then((status) => {
|
||||
expect(status).toEqual({type: "NO_REPOS"});
|
||||
});
|
||||
});
|
||||
@ -264,10 +266,31 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
});
|
||||
|
||||
describe("RepositorySelect", () => {
|
||||
const assets = new Assets("/my/gateway/");
|
||||
|
||||
it("calls `loadStatus` with the proper assets", () => {
|
||||
mockRegistry([makeRepo("irrelevant", "unused")]);
|
||||
shallow(
|
||||
<RepositorySelect
|
||||
assets={assets}
|
||||
onChange={jest.fn()}
|
||||
localStore={testLocalStore()}
|
||||
/>
|
||||
);
|
||||
// A bit of overlap with tests for `loadStatus` directly---it'd be
|
||||
// nicer to spy on `loadStatus`, but that's at module top level,
|
||||
// so `RepositorySelect` closes over it directly.
|
||||
expect(fetch).toHaveBeenCalledWith("/my/gateway" + REPO_REGISTRY_API);
|
||||
});
|
||||
|
||||
it("initially renders a LocalStoreRepositorySelect with status LOADING", () => {
|
||||
mockRegistry([makeRepo("irrelevant", "unused")]);
|
||||
const e = shallow(
|
||||
<RepositorySelect onChange={jest.fn()} localStore={testLocalStore()} />
|
||||
<RepositorySelect
|
||||
assets={assets}
|
||||
onChange={jest.fn()}
|
||||
localStore={testLocalStore()}
|
||||
/>
|
||||
);
|
||||
const child = e.find(LocalStoreRepositorySelect);
|
||||
const status = child.props().status;
|
||||
@ -291,7 +314,11 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
const selectedRepo = makeRepo("foo", "bar");
|
||||
mockRegistry([selectedRepo]);
|
||||
const e = shallow(
|
||||
<RepositorySelect onChange={onChange} localStore={testLocalStore()} />
|
||||
<RepositorySelect
|
||||
assets={assets}
|
||||
onChange={onChange}
|
||||
localStore={testLocalStore()}
|
||||
/>
|
||||
);
|
||||
await waitForUpdate(e);
|
||||
const childStatus = e.props().status;
|
||||
@ -308,7 +335,11 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
const repo = makeRepo("foo", "bar");
|
||||
mockRegistry([repo]);
|
||||
const e = shallow(
|
||||
<RepositorySelect onChange={onChange} localStore={testLocalStore()} />
|
||||
<RepositorySelect
|
||||
assets={assets}
|
||||
onChange={onChange}
|
||||
localStore={testLocalStore()}
|
||||
/>
|
||||
);
|
||||
await waitForUpdate(e);
|
||||
expect(onChange).toHaveBeenCalledTimes(1);
|
||||
@ -320,7 +351,11 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
fetch.mockReject(new Error("something bad"));
|
||||
|
||||
const e = shallow(
|
||||
<RepositorySelect onChange={onChange} localStore={testLocalStore()} />
|
||||
<RepositorySelect
|
||||
assets={assets}
|
||||
onChange={onChange}
|
||||
localStore={testLocalStore()}
|
||||
/>
|
||||
);
|
||||
await waitForUpdate(e);
|
||||
expect(onChange).toHaveBeenCalledTimes(0);
|
||||
@ -334,7 +369,11 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
const repo = makeRepo("foo", "bar");
|
||||
mockRegistry([repo]);
|
||||
const e = mount(
|
||||
<RepositorySelect onChange={onChange} localStore={testLocalStore()} />
|
||||
<RepositorySelect
|
||||
assets={assets}
|
||||
onChange={onChange}
|
||||
localStore={testLocalStore()}
|
||||
/>
|
||||
);
|
||||
const child = e.find(PureRepositorySelect);
|
||||
child.props().onChange(repo);
|
||||
@ -347,7 +386,11 @@ describe("app/credExplorer/RepositorySelect", () => {
|
||||
const repos = [makeRepo("foo", "bar"), makeRepo("z", "a")];
|
||||
mockRegistry(repos);
|
||||
const e = mount(
|
||||
<RepositorySelect onChange={onChange} localStore={testLocalStore()} />
|
||||
<RepositorySelect
|
||||
assets={assets}
|
||||
onChange={onChange}
|
||||
localStore={testLocalStore()}
|
||||
/>
|
||||
);
|
||||
await waitForUpdate(e);
|
||||
const child = e.find(PureRepositorySelect);
|
||||
|
Loading…
x
Reference in New Issue
Block a user