Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/components/Error/ErrorFallback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ import { Container } from "../common";
import { FallbackRender } from "@sentry/react";

const ErrorFallback: FallbackRender = ({ error }) => {
const message = "There was an error!";
const button = null;

let message = "An unexpected error occurred.";
// eslint-disable-next-line no-console
console.error(error);

if (error instanceof ClickUpError) {
//...
if (error instanceof ClickUpError && typeof error.data.err === "string" && error.data.err.trim() !== "") {
message = error.data.err
} else if (error instanceof Error && error.message.trim() !== "") {
message = error.message
}

return (
Expand All @@ -21,7 +21,6 @@ const ErrorFallback: FallbackRender = ({ error }) => {
text={(
<Stack gap={6} vertical style={{ padding: "8px" }}>
{message}
{button}
</Stack>
)}
/>
Expand Down
85 changes: 50 additions & 35 deletions src/components/TaskForm/__tests__/TaskForm.test.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,58 @@
import { cleanup } from "@testing-library/react";
import { cleanup, screen, waitFor } from "@testing-library/react";
import { render } from "../../../../testing";
import { getWorkspacesService } from "../../../services/clickUp";
import { TaskForm } from "../TaskForm";
import { useFormDeps } from "../hooks";


jest.mock("../../../services/clickUp/getWorkspacesService");
jest.mock("../hooks");

describe("LinkTasks", () => {
const mockFormDeps = {
isLoading: false,
workspaceOptions: [],
spaceOptions: [],
listOptions: [],
statusOptions: [],
userOptions: [],
tagOptions: []
}

beforeEach(() => {
(useFormDeps as jest.Mock).mockReturnValue(mockFormDeps)
})

afterEach(() => {
jest.clearAllMocks();
cleanup();
});
jest.clearAllMocks()
cleanup()
})

test("render", async () => {
(getWorkspacesService as jest.Mock).mockResolvedValue([]);

const { findByText } = render((
<TaskForm onSubmit={jest.fn()} onCancel={jest.fn()} />
), { wrappers: { theme: true, query: true } });

expect(await findByText("Workspace")).toBeInTheDocument();
expect(await findByText("Space")).toBeInTheDocument();
expect(await findByText("List")).toBeInTheDocument();
expect(await findByText("Task name")).toBeInTheDocument();
expect(await findByText("Description")).toBeInTheDocument();
expect(await findByText("Status")).toBeInTheDocument();
expect(await findByText("Assignees")).toBeInTheDocument();
expect(await findByText("Due date")).toBeInTheDocument();
expect(await findByText("Tags")).toBeInTheDocument();

expect(await findByText("Create")).toBeVisible();
expect(await findByText("Cancel")).toBeVisible();
});

test("render error", () => {
const { queryByText } = render((
<TaskForm onSubmit={jest.fn()} error="some error" />
), { wrappers: { theme: true, query: true } });

expect(queryByText("some error")).toBeInTheDocument();
});
});
render(
<TaskForm onSubmit={jest.fn()} onCancel={jest.fn()} />,
{ wrappers: { theme: true, query: true } }
);

await waitFor(() => {
expect(screen.getByText("Workspace")).toBeInTheDocument()
expect(screen.getByText("Space")).toBeInTheDocument()
expect(screen.getByText("List")).toBeInTheDocument()
expect(screen.getByText("Task name")).toBeInTheDocument()
expect(screen.getByText("Description")).toBeInTheDocument()
expect(screen.getByText("Status")).toBeInTheDocument()
expect(screen.getByText("Assignees")).toBeInTheDocument()
expect(screen.getByText("Due date")).toBeInTheDocument()
expect(screen.getByText("Tags")).toBeInTheDocument()
})

expect(screen.getByText("Create")).toBeVisible()
expect(screen.getByText("Cancel")).toBeVisible()
})

test("render error", async () => {
render(
<TaskForm onSubmit={jest.fn()} error="some error" />,
{ wrappers: { theme: true, query: true } }
)

expect(await screen.findByText("some error")).toBeInTheDocument();
})
})
21 changes: 18 additions & 3 deletions src/components/TaskForm/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,22 @@ type UseFormDeps = (workspaceId?: Workspace["id"], spaceId?: Space["id"]) => {
const useFormDeps: UseFormDeps = (workspaceId, spaceId) => {
const workspaces = useQueryWithClient(
[QueryKey.WORKSPACES],
(client) => getWorkspacesService(client),
async (client) => {
const response = await getWorkspacesService(client)

if (response.success) {
return response.data.teams
}

// Ignore auth errors.
if (response.errorCode === "auth-error") {
return []
}

// Pass other errors to the error boundary.
throw response.error

},
);

const spaces = useQueryWithClient(
Expand Down Expand Up @@ -50,7 +65,7 @@ const useFormDeps: UseFormDeps = (workspaceId, spaceId) => {
}, [spaceId, spaces]);

const users = useMemo(() => {
const workspace = find(workspaces.data?.teams, { id: workspaceId });
const workspace = find(workspaces.data ?? [], { id: workspaceId });
Comment thread
HappyPaul55 marked this conversation as resolved.
const members = workspace?.members ?? [];

return members.map(member => member.user);
Expand All @@ -65,7 +80,7 @@ const useFormDeps: UseFormDeps = (workspaceId, spaceId) => {

return {
isLoading: [workspaces].some(({ isLoading }) => isLoading),
workspaceOptions: useMemo(() => getWorkspaceOptions(workspaces.data?.teams), [workspaces]),
workspaceOptions: useMemo(() => getWorkspaceOptions(workspaces.data ?? []), [workspaces]),
spaceOptions: useMemo(() => getSpaceOptions(spaces.data?.spaces), [spaces]),
listOptions: [
...useMemo(() => getListFromFolders(folders.data?.folders), [folders]),
Expand Down
34 changes: 31 additions & 3 deletions src/hooks/useLinkedTasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,40 @@ const useLinkedTasks: UseLinkedTasks = () => {

const workspaces = useQueryWithClient(
[QueryKey.WORKSPACES],
(client) => getWorkspacesService(client),
async (client) => {
const response = await getWorkspacesService(client)

if(response.success){
return response.data.teams
}

// Ignore auth errors.
if(response.errorCode === "auth-error"){
return []
}

// Pass other errors to the error boundary.
throw response.error
},
);

const fetchedTasks = useQueriesWithClient((linkedIds.data ?? []).map((taskId) => ({
queryKey: [QueryKey.TASK, taskId],
queryFn: (client) => getTaskService(client, taskId),
queryFn: async (client) => {
const response = await getTaskService(client, taskId)

if(response.success){
return response.data
}

// Ignore auth errors.
if(response.errorCode === "auth-error"){
return null
}

// Pass other errors to the error boundary.
throw response.error
},
enabled: Boolean(size(linkedIds)),
useErrorBoundary: false,
})));
Expand All @@ -54,7 +82,7 @@ const useLinkedTasks: UseLinkedTasks = () => {

return {
isLoading: [linkedIds, workspaces, ...fetchedTasks, ...spaces].some(({ isLoading }) => isLoading),
workspaces: workspaces.data?.teams ?? [],
workspaces: workspaces.data ?? [],
tasks: tasks as Task[],
spaces: spaces.map(({ data }) => data).filter(Boolean) as Space[],
};
Expand Down
Loading
Loading