mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-12-21 15:59:48 +01:00
Fix HalRepresentationWithEmbedded type (#1793)
Fix HalRepresentationWithEmbedded type since _embedded can be null. Co-authored-by: Sebastian Sdorra <sebastian.sdorra@cloudogu.com>
This commit is contained in:
2
gradle/changelog/hal_embedded_type.yaml
Normal file
2
gradle/changelog/hal_embedded_type.yaml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
- type: Fixed
|
||||||
|
description: Fix HalRepresentationWithEmbedded type ([#1793](https://github.com/scm-manager/scm-manager/pull/1793))
|
||||||
@@ -51,7 +51,7 @@ const CloneInformation: FC<Props> = ({ url, repository }) => {
|
|||||||
|
|
||||||
const error = changesetsError || defaultBranchError;
|
const error = changesetsError || defaultBranchError;
|
||||||
const branch = defaultBranchData?.defaultBranch;
|
const branch = defaultBranchData?.defaultBranch;
|
||||||
const emptyRepository = changesets?._embedded.changesets.length === 0;
|
const emptyRepository = (changesets?._embedded?.changesets.length || 0) === 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="content">
|
<div className="content">
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ const ProtocolInformation: FC<Props> = ({ repository }) => {
|
|||||||
return <Loading />;
|
return <Loading />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const emptyRepository = data?._embedded.changesets.length === 0;
|
const emptyRepository = (data?._embedded?.changesets.length || 0) === 0;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="content">
|
||||||
<ErrorNotification error={error} />
|
<ErrorNotification error={error} />
|
||||||
<h4>{t("scm-hg-plugin.information.clone")}</h4>
|
<h4>{t("scm-hg-plugin.information.clone")}</h4>
|
||||||
<pre>
|
<pre>
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class ProtocolInformation extends React.Component<Props> {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="content">
|
||||||
<h4>{t("scm-svn-plugin.information.checkout")}</h4>
|
<h4>{t("scm-svn-plugin.information.checkout")}</h4>
|
||||||
<pre>
|
<pre>
|
||||||
<code>svn checkout {href}</code>
|
<code>svn checkout {href}</code>
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ describe("Test changeset hooks", () => {
|
|||||||
type: "hg",
|
type: "hg",
|
||||||
_links: {
|
_links: {
|
||||||
changesets: {
|
changesets: {
|
||||||
href: "/r/c"
|
href: "/r/c",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const develop: Branch = {
|
const develop: Branch = {
|
||||||
@@ -45,9 +45,9 @@ describe("Test changeset hooks", () => {
|
|||||||
revision: "42",
|
revision: "42",
|
||||||
_links: {
|
_links: {
|
||||||
history: {
|
history: {
|
||||||
href: "/r/b/c"
|
href: "/r/b/c",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeset: Changeset = {
|
const changeset: Changeset = {
|
||||||
@@ -55,23 +55,23 @@ describe("Test changeset hooks", () => {
|
|||||||
description: "Awesome change",
|
description: "Awesome change",
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
author: {
|
author: {
|
||||||
name: "Arthur Dent"
|
name: "Arthur Dent",
|
||||||
},
|
},
|
||||||
_embedded: {},
|
_embedded: {},
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const changesets: ChangesetCollection = {
|
const changesets: ChangesetCollection = {
|
||||||
page: 1,
|
page: 1,
|
||||||
pageTotal: 1,
|
pageTotal: 1,
|
||||||
_embedded: {
|
_embedded: {
|
||||||
changesets: [changeset]
|
changesets: [changeset],
|
||||||
},
|
},
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const expectChangesetCollection = (result?: ChangesetCollection) => {
|
const expectChangesetCollection = (result?: ChangesetCollection) => {
|
||||||
expect(result?._embedded.changesets[0].id).toBe(changesets._embedded.changesets[0].id);
|
expect(result?._embedded?.changesets[0].id).toBe(changesets._embedded?.changesets[0].id);
|
||||||
};
|
};
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
@@ -85,7 +85,7 @@ describe("Test changeset hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useChangesets(repository), {
|
const { result, waitFor } = renderHook(() => useChangesets(repository), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
@@ -98,14 +98,14 @@ describe("Test changeset hooks", () => {
|
|||||||
it("should return changesets for page", async () => {
|
it("should return changesets for page", async () => {
|
||||||
fetchMock.getOnce("/api/v2/r/c", changesets, {
|
fetchMock.getOnce("/api/v2/r/c", changesets, {
|
||||||
query: {
|
query: {
|
||||||
page: 42
|
page: 42,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useChangesets(repository, { page: 42 }), {
|
const { result, waitFor } = renderHook(() => useChangesets(repository, { page: 42 }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
@@ -121,7 +121,7 @@ describe("Test changeset hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useChangesets(repository, { branch: develop }), {
|
const { result, waitFor } = renderHook(() => useChangesets(repository, { branch: develop }), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
@@ -137,7 +137,7 @@ describe("Test changeset hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useChangesets(repository), {
|
const { result, waitFor } = renderHook(() => useChangesets(repository), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
@@ -149,7 +149,7 @@ describe("Test changeset hooks", () => {
|
|||||||
"hitchhiker",
|
"hitchhiker",
|
||||||
"heart-of-gold",
|
"heart-of-gold",
|
||||||
"changeset",
|
"changeset",
|
||||||
"42"
|
"42",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect(changeset?.id).toBe("42");
|
expect(changeset?.id).toBe("42");
|
||||||
@@ -163,7 +163,7 @@ describe("Test changeset hooks", () => {
|
|||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useChangeset(repository, "42"), {
|
const { result, waitFor } = renderHook(() => useChangeset(repository, "42"), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ export const useChangesets = (
|
|||||||
const key = branchQueryKey(repository, branch, "changesets", request?.page || 0);
|
const key = branchQueryKey(repository, branch, "changesets", request?.page || 0);
|
||||||
return useQuery<ChangesetCollection, Error>(key, () => apiClient.get(link).then((response) => response.json()), {
|
return useQuery<ChangesetCollection, Error>(key, () => apiClient.get(link).then((response) => response.json()), {
|
||||||
onSuccess: (changesetCollection) => {
|
onSuccess: (changesetCollection) => {
|
||||||
changesetCollection._embedded.changesets.forEach((changeset) => {
|
changesetCollection._embedded?.changesets.forEach((changeset) => {
|
||||||
queryClient.setQueryData(changesetQueryKey(repository, changeset.id), changeset);
|
queryClient.setQueryData(changesetQueryKey(repository, changeset.id), changeset);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const useHistory = (
|
|||||||
{
|
{
|
||||||
keepPreviousData: true,
|
keepPreviousData: true,
|
||||||
onSuccess: (changesets: ChangesetCollection) => {
|
onSuccess: (changesets: ChangesetCollection) => {
|
||||||
changesets._embedded.changesets.forEach((changeset: Changeset) =>
|
changesets._embedded?.changesets.forEach((changeset: Changeset) =>
|
||||||
queryClient.setQueryData(changesetQueryKey(repository, changeset.id), changeset)
|
queryClient.setQueryData(changesetQueryKey(repository, changeset.id), changeset)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -34,21 +34,21 @@ export const useNotifications = () => {
|
|||||||
const link = (me?._links["notifications"] as Link)?.href;
|
const link = (me?._links["notifications"] as Link)?.href;
|
||||||
const { data, error, isLoading, refetch } = useQuery<NotificationCollection, Error>(
|
const { data, error, isLoading, refetch } = useQuery<NotificationCollection, Error>(
|
||||||
"notifications",
|
"notifications",
|
||||||
() => apiClient.get(link).then(response => response.json()),
|
() => apiClient.get(link).then((response) => response.json()),
|
||||||
{
|
{
|
||||||
enabled: !!link
|
enabled: !!link,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const memoizedRefetch = useCallback(() => {
|
const memoizedRefetch = useCallback(() => {
|
||||||
return refetch().then(r => r.data);
|
return refetch().then((r) => r.data);
|
||||||
}, [refetch]);
|
}, [refetch]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
error,
|
error,
|
||||||
isLoading,
|
isLoading,
|
||||||
refetch: memoizedRefetch
|
refetch: memoizedRefetch,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,13 +58,13 @@ export const useDismissNotification = (notification: Notification) => {
|
|||||||
const { data, isLoading, error, mutate } = useMutation<Response, Error>(() => apiClient.delete(link), {
|
const { data, isLoading, error, mutate } = useMutation<Response, Error>(() => apiClient.delete(link), {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries("notifications");
|
queryClient.invalidateQueries("notifications");
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
dismiss: () => mutate(),
|
dismiss: () => mutate(),
|
||||||
isCleared: !!data
|
isCleared: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,13 +74,13 @@ export const useClearNotifications = (notificationCollection: NotificationCollec
|
|||||||
const { data, isLoading, error, mutate } = useMutation<Response, Error>(() => apiClient.delete(link), {
|
const { data, isLoading, error, mutate } = useMutation<Response, Error>(() => apiClient.delete(link), {
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
queryClient.invalidateQueries("notifications");
|
queryClient.invalidateQueries("notifications");
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
clear: () => mutate(),
|
clear: () => mutate(),
|
||||||
isCleared: !!data
|
isCleared: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -99,13 +99,13 @@ export const useNotificationSubscription = (
|
|||||||
const onVisible = useCallback(() => {
|
const onVisible = useCallback(() => {
|
||||||
// we don't need to catch the error,
|
// we don't need to catch the error,
|
||||||
// because if the refetch throws an error the parent useNotifications should catch it
|
// because if the refetch throws an error the parent useNotifications should catch it
|
||||||
refetch().then(collection => {
|
refetch().then((collection) => {
|
||||||
if (collection) {
|
if (collection) {
|
||||||
const newNotifications = collection._embedded.notifications.filter(n => {
|
const newNotifications = collection._embedded?.notifications.filter((n) => {
|
||||||
return disconnectedAt && disconnectedAt < new Date(n.createdAt);
|
return disconnectedAt && disconnectedAt < new Date(n.createdAt);
|
||||||
});
|
});
|
||||||
if (newNotifications.length > 0) {
|
if (newNotifications && newNotifications.length > 0) {
|
||||||
setNotifications(previous => [...previous, ...newNotifications]);
|
setNotifications((previous) => [...previous, ...newNotifications]);
|
||||||
}
|
}
|
||||||
setDisconnectedAt(undefined);
|
setDisconnectedAt(undefined);
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ export const useNotificationSubscription = (
|
|||||||
|
|
||||||
const received = useCallback(
|
const received = useCallback(
|
||||||
(notification: Notification) => {
|
(notification: Notification) => {
|
||||||
setNotifications(previous => [...previous, notification]);
|
setNotifications((previous) => [...previous, notification]);
|
||||||
refetch();
|
refetch();
|
||||||
},
|
},
|
||||||
[refetch]
|
[refetch]
|
||||||
@@ -137,9 +137,9 @@ export const useNotificationSubscription = (
|
|||||||
const connect = () => {
|
const connect = () => {
|
||||||
disconnect();
|
disconnect();
|
||||||
cancel = apiClient.subscribe(link, {
|
cancel = apiClient.subscribe(link, {
|
||||||
notification: event => {
|
notification: (event) => {
|
||||||
received(JSON.parse(event.data));
|
received(JSON.parse(event.data));
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ export const useNotificationSubscription = (
|
|||||||
|
|
||||||
const remove = useCallback(
|
const remove = useCallback(
|
||||||
(notification: Notification) => {
|
(notification: Notification) => {
|
||||||
setNotifications(oldNotifications => [...oldNotifications.filter(n => !isEqual(n, notification))]);
|
setNotifications((oldNotifications) => [...oldNotifications.filter((n) => !isEqual(n, notification))]);
|
||||||
},
|
},
|
||||||
[setNotifications]
|
[setNotifications]
|
||||||
);
|
);
|
||||||
@@ -178,6 +178,6 @@ export const useNotificationSubscription = (
|
|||||||
return {
|
return {
|
||||||
notifications,
|
notifications,
|
||||||
remove,
|
remove,
|
||||||
clear
|
clear,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import {
|
|||||||
Repository,
|
Repository,
|
||||||
RepositoryRole,
|
RepositoryRole,
|
||||||
RepositoryRoleCollection,
|
RepositoryRoleCollection,
|
||||||
RepositoryVerbs
|
RepositoryVerbs,
|
||||||
} from "@scm-manager/ui-types";
|
} from "@scm-manager/ui-types";
|
||||||
import fetchMock from "fetch-mock-jest";
|
import fetchMock from "fetch-mock-jest";
|
||||||
import { renderHook } from "@testing-library/react-hooks";
|
import { renderHook } from "@testing-library/react-hooks";
|
||||||
@@ -41,7 +41,7 @@ import {
|
|||||||
useDeletePermission,
|
useDeletePermission,
|
||||||
usePermissions,
|
usePermissions,
|
||||||
useRepositoryVerbs,
|
useRepositoryVerbs,
|
||||||
useUpdatePermission
|
useUpdatePermission,
|
||||||
} from "./permissions";
|
} from "./permissions";
|
||||||
import { act } from "react-test-renderer";
|
import { act } from "react-test-renderer";
|
||||||
|
|
||||||
@@ -49,21 +49,21 @@ describe("permission hooks test", () => {
|
|||||||
const readRole: RepositoryRole = {
|
const readRole: RepositoryRole = {
|
||||||
name: "READ",
|
name: "READ",
|
||||||
verbs: ["read", "pull"],
|
verbs: ["read", "pull"],
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const roleCollection: RepositoryRoleCollection = {
|
const roleCollection: RepositoryRoleCollection = {
|
||||||
_embedded: {
|
_embedded: {
|
||||||
repositoryRoles: [readRole]
|
repositoryRoles: [readRole],
|
||||||
},
|
},
|
||||||
_links: {},
|
_links: {},
|
||||||
page: 1,
|
page: 1,
|
||||||
pageTotal: 1
|
pageTotal: 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const verbCollection: RepositoryVerbs = {
|
const verbCollection: RepositoryVerbs = {
|
||||||
verbs: ["read", "pull"],
|
verbs: ["read", "pull"],
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const readPermission: Permission = {
|
const readPermission: Permission = {
|
||||||
@@ -73,9 +73,9 @@ describe("permission hooks test", () => {
|
|||||||
groupPermission: false,
|
groupPermission: false,
|
||||||
_links: {
|
_links: {
|
||||||
update: {
|
update: {
|
||||||
href: "/p/trillian"
|
href: "/p/trillian",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const writePermission: Permission = {
|
const writePermission: Permission = {
|
||||||
@@ -85,32 +85,32 @@ describe("permission hooks test", () => {
|
|||||||
groupPermission: false,
|
groupPermission: false,
|
||||||
_links: {
|
_links: {
|
||||||
delete: {
|
delete: {
|
||||||
href: "/p/dent"
|
href: "/p/dent",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const permissionsRead: PermissionCollection = {
|
const permissionsRead: PermissionCollection = {
|
||||||
_embedded: {
|
_embedded: {
|
||||||
permissions: [readPermission]
|
permissions: [readPermission],
|
||||||
},
|
},
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const permissionsWrite: PermissionCollection = {
|
const permissionsWrite: PermissionCollection = {
|
||||||
_embedded: {
|
_embedded: {
|
||||||
permissions: [writePermission]
|
permissions: [writePermission],
|
||||||
},
|
},
|
||||||
_links: {}
|
_links: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
const namespace: Namespace = {
|
const namespace: Namespace = {
|
||||||
namespace: "spaceships",
|
namespace: "spaceships",
|
||||||
_links: {
|
_links: {
|
||||||
permissions: {
|
permissions: {
|
||||||
href: "/ns/spaceships/permissions"
|
href: "/ns/spaceships/permissions",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const repository: Repository = {
|
const repository: Repository = {
|
||||||
@@ -119,9 +119,9 @@ describe("permission hooks test", () => {
|
|||||||
type: "git",
|
type: "git",
|
||||||
_links: {
|
_links: {
|
||||||
permissions: {
|
permissions: {
|
||||||
href: "/r/heart-of-gold/permissions"
|
href: "/r/heart-of-gold/permissions",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const queryClient = createInfiniteCachingClient();
|
const queryClient = createInfiniteCachingClient();
|
||||||
@@ -137,7 +137,7 @@ describe("permission hooks test", () => {
|
|||||||
fetchMock.get("/api/v2/verbs", verbCollection);
|
fetchMock.get("/api/v2/verbs", verbCollection);
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useRepositoryVerbs(), {
|
const { result, waitFor } = renderHook(() => useRepositoryVerbs(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
@@ -152,23 +152,23 @@ describe("permission hooks test", () => {
|
|||||||
version: "x.y.z",
|
version: "x.y.z",
|
||||||
_links: {
|
_links: {
|
||||||
repositoryRoles: {
|
repositoryRoles: {
|
||||||
href: "/roles"
|
href: "/roles",
|
||||||
},
|
},
|
||||||
repositoryVerbs: {
|
repositoryVerbs: {
|
||||||
href: "/verbs"
|
href: "/verbs",
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
fetchMock.get("/api/v2/roles", roleCollection);
|
fetchMock.get("/api/v2/roles", roleCollection);
|
||||||
fetchMock.get("/api/v2/verbs", verbCollection);
|
fetchMock.get("/api/v2/verbs", verbCollection);
|
||||||
|
|
||||||
const { result, waitFor } = renderHook(() => useAvailablePermissions(), {
|
const { result, waitFor } = renderHook(() => useAvailablePermissions(), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
});
|
});
|
||||||
expect(result.current.data?.repositoryRoles).toEqual(roleCollection._embedded.repositoryRoles);
|
expect(result.current.data?.repositoryRoles).toEqual(roleCollection._embedded?.repositoryRoles);
|
||||||
expect(result.current.data?.repositoryVerbs).toEqual(verbCollection.verbs);
|
expect(result.current.data?.repositoryVerbs).toEqual(verbCollection.verbs);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -176,7 +176,7 @@ describe("permission hooks test", () => {
|
|||||||
describe("usePermissions tests", () => {
|
describe("usePermissions tests", () => {
|
||||||
const fetchPermissions = async (namespaceOrRepository: Namespace | Repository) => {
|
const fetchPermissions = async (namespaceOrRepository: Namespace | Repository) => {
|
||||||
const { result, waitFor } = renderHook(() => usePermissions(namespaceOrRepository), {
|
const { result, waitFor } = renderHook(() => usePermissions(namespaceOrRepository), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
return !!result.current.data;
|
return !!result.current.data;
|
||||||
@@ -216,14 +216,14 @@ describe("permission hooks test", () => {
|
|||||||
fetchMock.postOnce("/api/v2/ns/spaceships/permissions", {
|
fetchMock.postOnce("/api/v2/ns/spaceships/permissions", {
|
||||||
status: 201,
|
status: 201,
|
||||||
headers: {
|
headers: {
|
||||||
Location: "/ns/spaceships/permissions/42"
|
Location: "/ns/spaceships/permissions/42",
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
fetchMock.getOnce("/api/v2/ns/spaceships/permissions/42", readPermission);
|
fetchMock.getOnce("/api/v2/ns/spaceships/permissions/42", readPermission);
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreatePermission(namespace), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreatePermission(namespace), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -241,11 +241,11 @@ describe("permission hooks test", () => {
|
|||||||
|
|
||||||
it("should fail without location header", async () => {
|
it("should fail without location header", async () => {
|
||||||
fetchMock.postOnce("/api/v2/ns/spaceships/permissions", {
|
fetchMock.postOnce("/api/v2/ns/spaceships/permissions", {
|
||||||
status: 201
|
status: 201,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useCreatePermission(namespace), {
|
const { result, waitForNextUpdate } = renderHook(() => useCreatePermission(namespace), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -270,11 +270,11 @@ describe("permission hooks test", () => {
|
|||||||
describe("useDeletePermission tests", () => {
|
describe("useDeletePermission tests", () => {
|
||||||
const deletePermission = async () => {
|
const deletePermission = async () => {
|
||||||
fetchMock.deleteOnce("/api/v2/p/dent", {
|
fetchMock.deleteOnce("/api/v2/p/dent", {
|
||||||
status: 204
|
status: 204,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useDeletePermission(repository), {
|
const { result, waitForNextUpdate } = renderHook(() => useDeletePermission(repository), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
@@ -308,11 +308,11 @@ describe("permission hooks test", () => {
|
|||||||
describe("useUpdatePermission tests", () => {
|
describe("useUpdatePermission tests", () => {
|
||||||
const updatePermission = async () => {
|
const updatePermission = async () => {
|
||||||
fetchMock.putOnce("/api/v2/p/trillian", {
|
fetchMock.putOnce("/api/v2/p/trillian", {
|
||||||
status: 204
|
status: 204,
|
||||||
});
|
});
|
||||||
|
|
||||||
const { result, waitForNextUpdate } = renderHook(() => useUpdatePermission(repository), {
|
const { result, waitForNextUpdate } = renderHook(() => useUpdatePermission(repository), {
|
||||||
wrapper: createWrapper(undefined, queryClient)
|
wrapper: createWrapper(undefined, queryClient),
|
||||||
});
|
});
|
||||||
|
|
||||||
await act(() => {
|
await act(() => {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const useAvailablePermissions = () => {
|
|||||||
if (roles.data && verbs.data) {
|
if (roles.data && verbs.data) {
|
||||||
data = {
|
data = {
|
||||||
repositoryVerbs: verbs.data.verbs,
|
repositoryVerbs: verbs.data.verbs,
|
||||||
repositoryRoles: roles.data._embedded.repositoryRoles,
|
repositoryRoles: roles.data._embedded?.repositoryRoles || [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -308,7 +308,7 @@ describe("Test repository hooks", () => {
|
|||||||
});
|
});
|
||||||
expect(result.current.data).toBeDefined();
|
expect(result.current.data).toBeDefined();
|
||||||
if (result.current?.data) {
|
if (result.current?.data) {
|
||||||
expect(result.current?.data._embedded.repositoryTypes[0].name).toEqual("git");
|
expect(result.current?.data._embedded?.repositoryTypes[0].name).toEqual("git");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export const useRepositories = (request?: UseRepositoriesRequest): ApiResult<Rep
|
|||||||
enabled: !request?.disabled,
|
enabled: !request?.disabled,
|
||||||
onSuccess: (repositories: RepositoryCollection) => {
|
onSuccess: (repositories: RepositoryCollection) => {
|
||||||
// prepare single repository cache
|
// prepare single repository cache
|
||||||
repositories._embedded.repositories.forEach((repository: Repository) => {
|
repositories._embedded?.repositories.forEach((repository: Repository) => {
|
||||||
queryClient.setQueryData(["repository", repository.namespace, repository.name], repository);
|
queryClient.setQueryData(["repository", repository.namespace, repository.name], repository);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@@ -363,7 +363,7 @@ export const useRenameRepository = (repository: Repository) => {
|
|||||||
const { mutate, isLoading, error, data } = useMutation<unknown, Error, RenameRepositoryRequest>(
|
const { mutate, isLoading, error, data } = useMutation<unknown, Error, RenameRepositoryRequest>(
|
||||||
({ name, namespace }) => apiClient.post(url, { namespace, name }, "application/vnd.scmm-repository+json;v=2"),
|
({ name, namespace }) => apiClient.post(url, { namespace, name }, "application/vnd.scmm-repository+json;v=2"),
|
||||||
{
|
{
|
||||||
onSuccess: () => queryClient.removeQueries(repoQueryKey(repository))
|
onSuccess: () => queryClient.removeQueries(repoQueryKey(repository)),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -43,13 +43,13 @@ export const useRepositoryRoles = (request?: UseRepositoryRolesRequest): ApiResu
|
|||||||
|
|
||||||
return useQuery<RepositoryRoleCollection, Error>(
|
return useQuery<RepositoryRoleCollection, Error>(
|
||||||
["repositoryRoles", request?.page || 0],
|
["repositoryRoles", request?.page || 0],
|
||||||
() => apiClient.get(`${indexLink}?${createQueryString(queryParams)}`).then(response => response.json()),
|
() => apiClient.get(`${indexLink}?${createQueryString(queryParams)}`).then((response) => response.json()),
|
||||||
{
|
{
|
||||||
onSuccess: (repositoryRoles: RepositoryRoleCollection) => {
|
onSuccess: (repositoryRoles: RepositoryRoleCollection) => {
|
||||||
repositoryRoles._embedded.repositoryRoles.forEach((repositoryRole: RepositoryRole) =>
|
repositoryRoles._embedded?.repositoryRoles.forEach((repositoryRole: RepositoryRole) =>
|
||||||
queryClient.setQueryData(["repositoryRole", repositoryRole.name], repositoryRole)
|
queryClient.setQueryData(["repositoryRole", repositoryRole.name], repositoryRole)
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -57,7 +57,7 @@ export const useRepositoryRoles = (request?: UseRepositoryRolesRequest): ApiResu
|
|||||||
export const useRepositoryRole = (name: string): ApiResult<RepositoryRole> => {
|
export const useRepositoryRole = (name: string): ApiResult<RepositoryRole> => {
|
||||||
const indexLink = useRequiredIndexLink("repositoryRoles");
|
const indexLink = useRequiredIndexLink("repositoryRoles");
|
||||||
return useQuery<RepositoryRole, Error>(["repositoryRole", name], () =>
|
return useQuery<RepositoryRole, Error>(["repositoryRole", name], () =>
|
||||||
apiClient.get(urls.concat(indexLink, name)).then(response => response.json())
|
apiClient.get(urls.concat(indexLink, name)).then((response) => response.json())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -65,14 +65,14 @@ const createRepositoryRole = (link: string) => {
|
|||||||
return (repositoryRole: RepositoryRoleCreation) => {
|
return (repositoryRole: RepositoryRoleCreation) => {
|
||||||
return apiClient
|
return apiClient
|
||||||
.post(link, repositoryRole, "application/vnd.scmm-repositoryRole+json;v=2")
|
.post(link, repositoryRole, "application/vnd.scmm-repositoryRole+json;v=2")
|
||||||
.then(response => {
|
.then((response) => {
|
||||||
const location = response.headers.get("Location");
|
const location = response.headers.get("Location");
|
||||||
if (!location) {
|
if (!location) {
|
||||||
throw new Error("Server does not return required Location header");
|
throw new Error("Server does not return required Location header");
|
||||||
}
|
}
|
||||||
return apiClient.get(location);
|
return apiClient.get(location);
|
||||||
})
|
})
|
||||||
.then(response => response.json());
|
.then((response) => response.json());
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -82,24 +82,24 @@ export const useCreateRepositoryRole = () => {
|
|||||||
const { mutate, data, isLoading, error } = useMutation<RepositoryRole, Error, RepositoryRoleCreation>(
|
const { mutate, data, isLoading, error } = useMutation<RepositoryRole, Error, RepositoryRoleCreation>(
|
||||||
createRepositoryRole(link),
|
createRepositoryRole(link),
|
||||||
{
|
{
|
||||||
onSuccess: repositoryRole => {
|
onSuccess: (repositoryRole) => {
|
||||||
queryClient.setQueryData(["repositoryRole", repositoryRole.name], repositoryRole);
|
queryClient.setQueryData(["repositoryRole", repositoryRole.name], repositoryRole);
|
||||||
return queryClient.invalidateQueries(["repositoryRoles"]);
|
return queryClient.invalidateQueries(["repositoryRoles"]);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
create: (repositoryRole: RepositoryRoleCreation) => mutate(repositoryRole),
|
create: (repositoryRole: RepositoryRoleCreation) => mutate(repositoryRole),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
repositoryRole: data
|
repositoryRole: data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useUpdateRepositoryRole = () => {
|
export const useUpdateRepositoryRole = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { mutate, isLoading, error, data } = useMutation<unknown, Error, RepositoryRole>(
|
const { mutate, isLoading, error, data } = useMutation<unknown, Error, RepositoryRole>(
|
||||||
repositoryRole => {
|
(repositoryRole) => {
|
||||||
const updateUrl = requiredLink(repositoryRole, "update");
|
const updateUrl = requiredLink(repositoryRole, "update");
|
||||||
return apiClient.put(updateUrl, repositoryRole, "application/vnd.scmm-repositoryRole+json;v=2");
|
return apiClient.put(updateUrl, repositoryRole, "application/vnd.scmm-repositoryRole+json;v=2");
|
||||||
},
|
},
|
||||||
@@ -107,21 +107,21 @@ export const useUpdateRepositoryRole = () => {
|
|||||||
onSuccess: async (_, repositoryRole) => {
|
onSuccess: async (_, repositoryRole) => {
|
||||||
await queryClient.invalidateQueries(["repositoryRole", repositoryRole.name]);
|
await queryClient.invalidateQueries(["repositoryRole", repositoryRole.name]);
|
||||||
await queryClient.invalidateQueries(["repositoryRoles"]);
|
await queryClient.invalidateQueries(["repositoryRoles"]);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
update: (repositoryRole: RepositoryRole) => mutate(repositoryRole),
|
update: (repositoryRole: RepositoryRole) => mutate(repositoryRole),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
isUpdated: !!data
|
isUpdated: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useDeleteRepositoryRole = () => {
|
export const useDeleteRepositoryRole = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { mutate, isLoading, error, data } = useMutation<unknown, Error, RepositoryRole>(
|
const { mutate, isLoading, error, data } = useMutation<unknown, Error, RepositoryRole>(
|
||||||
repositoryRole => {
|
(repositoryRole) => {
|
||||||
const deleteUrl = requiredLink(repositoryRole, "delete");
|
const deleteUrl = requiredLink(repositoryRole, "delete");
|
||||||
return apiClient.delete(deleteUrl);
|
return apiClient.delete(deleteUrl);
|
||||||
},
|
},
|
||||||
@@ -129,13 +129,13 @@ export const useDeleteRepositoryRole = () => {
|
|||||||
onSuccess: async (_, name) => {
|
onSuccess: async (_, name) => {
|
||||||
await queryClient.invalidateQueries(["repositoryRole", name]);
|
await queryClient.invalidateQueries(["repositoryRole", name]);
|
||||||
await queryClient.invalidateQueries(["repositoryRoles"]);
|
await queryClient.invalidateQueries(["repositoryRoles"]);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
remove: (repositoryRole: RepositoryRole) => mutate(repositoryRole),
|
remove: (repositoryRole: RepositoryRole) => mutate(repositoryRole),
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
isDeleted: !!data
|
isDeleted: !!data,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
import { ApiResult, useRequiredIndexLink } from "./base";
|
import { ApiResult, useRequiredIndexLink } from "./base";
|
||||||
import { useMutation, useQuery, useQueryClient } from "react-query";
|
import { useMutation, useQuery, useQueryClient } from "react-query";
|
||||||
import {Link, Me, User, UserCollection, UserCreation} from "@scm-manager/ui-types";
|
import { Link, Me, User, UserCollection, UserCreation } from "@scm-manager/ui-types";
|
||||||
import { apiClient } from "./apiclient";
|
import { apiClient } from "./apiclient";
|
||||||
import { createQueryString } from "./utils";
|
import { createQueryString } from "./utils";
|
||||||
import { concat } from "./urls";
|
import { concat } from "./urls";
|
||||||
@@ -52,7 +52,7 @@ export const useUsers = (request?: UseUsersRequest): ApiResult<UserCollection> =
|
|||||||
() => apiClient.get(`${indexLink}?${createQueryString(queryParams)}`).then((response) => response.json()),
|
() => apiClient.get(`${indexLink}?${createQueryString(queryParams)}`).then((response) => response.json()),
|
||||||
{
|
{
|
||||||
onSuccess: (users: UserCollection) => {
|
onSuccess: (users: UserCollection) => {
|
||||||
users._embedded.users.forEach((user: User) => queryClient.setQueryData(["user", user.name], user));
|
users._embedded?.users.forEach((user: User) => queryClient.setQueryData(["user", user.name], user));
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -215,7 +215,7 @@ export const useSetUserPassword = (user: User) => {
|
|||||||
passwordOverwritten: !!data,
|
passwordOverwritten: !!data,
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
reset
|
reset,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -235,6 +235,6 @@ export const useChangeUserPassword = (user: User | Me) => {
|
|||||||
passwordChanged: !!data,
|
passwordChanged: !!data,
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
reset
|
reset,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ type Props = {
|
|||||||
class ChangesetTags extends React.Component<Props> {
|
class ChangesetTags extends React.Component<Props> {
|
||||||
getTags = () => {
|
getTags = () => {
|
||||||
const { changeset } = this.props;
|
const { changeset } = this.props;
|
||||||
return changeset._embedded.tags || [];
|
return changeset._embedded?.tags || [];
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export type HalRepresentation = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type HalRepresentationWithEmbedded<T extends Embedded> = HalRepresentation & {
|
export type HalRepresentationWithEmbedded<T extends Embedded> = HalRepresentation & {
|
||||||
_embedded: T;
|
_embedded?: T;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PagedCollection<T extends Embedded = Embedded> = HalRepresentationWithEmbedded<T> & {
|
export type PagedCollection<T extends Embedded = Embedded> = HalRepresentationWithEmbedded<T> & {
|
||||||
|
|||||||
Reference in New Issue
Block a user