Skip to content

Commit

Permalink
[UI v2] feat: Adds global concurrency limit query definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
devinvillarosa committed Dec 4, 2024
1 parent bd19554 commit af3a2d9
Show file tree
Hide file tree
Showing 2 changed files with 182 additions and 0 deletions.
119 changes: 119 additions & 0 deletions ui-v2/src/hooks/global-concurrency-limits.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import {
QueryClient,
QueryClientProvider,
useQuery,
} from "@tanstack/react-query";
import { renderHook, waitFor } from "@testing-library/react";
import { http, HttpResponse } from "msw";
import { describe, expect, it } from "vitest";

import {
type GlobalConcurrencyLimit,
buildGetGlobalConcurrencyLimitQuery,
buildListGlobalConcurrencyLimitsQuery,
} from "./global-concurrency-limits";

import { server } from "../../tests/mocks/node";

describe("global concurrency limits hooks", () => {
const seedGlobalConcurrencyLimits = () => [
{
id: "0",
created: "2021-01-01T00:00:00Z",
updated: "2021-01-01T00:00:00Z",
active: false,
name: "global concurrency limit 0",
limit: 0,
active_slots: 0,
slot_decay_per_second: 0,
},
];

const seedGlobalConcurrencyLimitDetails = () => ({
id: "0",
created: "2021-01-01T00:00:00Z",
updated: "2021-01-01T00:00:00Z",
active: false,
name: "global concurrency limit 0",
limit: 0,
active_slots: 0,
slot_decay_per_second: 0,
});

const mockFetchGlobalConcurrencyLimitsAPI = (
globalConcurrencyLimits: Array<GlobalConcurrencyLimit>,
) => {
server.use(
http.post(
"http://localhost:4200/api/v2/concurrency_limits/filter",
() => {
return HttpResponse.json(globalConcurrencyLimits);
},
),
);
};

const mockFetchGlobalConcurrencyLimitDetailsAPI = (
globalConcurrencyLimit: GlobalConcurrencyLimit,
) => {
server.use(
http.get(
"http://localhost:4200/api/v2/concurrency_limits/:id_or_name",
() => {
return HttpResponse.json(globalConcurrencyLimit);
},
),
);
};

const createQueryWrapper = ({ queryClient = new QueryClient() }) => {
const QueryWrapper = ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
return QueryWrapper;
};

const filter = {
offset: 0,
};

/**
* Data Management:
* - Asserts global concurrency limit list data is fetched based on the APIs invoked for the hook
*/
it("is stores list data into the appropriate list query when using useQuery()", async () => {
// ------------ Mock API requests when cache is empty
const mockList = seedGlobalConcurrencyLimits();
mockFetchGlobalConcurrencyLimitsAPI(mockList);

// ------------ Initialize hooks to test
const { result } = renderHook(
() => useQuery(buildListGlobalConcurrencyLimitsQuery(filter)),
{ wrapper: createQueryWrapper({}) },
);

// ------------ Assert
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(result.current.data).toEqual(mockList);
});

/**
* Data Management:
* - Asserts global concurrency limit details data is fetched based on the APIs invoked for the hook
*/
it("is stores details data into the appropriate details query when using useQuery()", async () => {
// ------------ Mock API requests when cache is empty
const mockDetails = seedGlobalConcurrencyLimitDetails();
mockFetchGlobalConcurrencyLimitDetailsAPI(mockDetails);

// ------------ Initialize hooks to test
const { result } = renderHook(
() => useQuery(buildGetGlobalConcurrencyLimitQuery(mockDetails.id)),
{ wrapper: createQueryWrapper({}) },
);

// ------------ Assert
await waitFor(() => expect(result.current.isSuccess).toBe(true));
expect(result.current.data).toEqual(mockDetails);
});
});
63 changes: 63 additions & 0 deletions ui-v2/src/hooks/global-concurrency-limits.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { components } from "@/api/prefect";
import { getQueryService } from "@/api/service";
import { queryOptions } from "@tanstack/react-query";

export type GlobalConcurrencyLimit =
components["schemas"]["GlobalConcurrencyLimitResponse"];
export type GlobalConcurrencyLimitsFilter =
components["schemas"]["Body_read_all_concurrency_limits_v2_v2_concurrency_limits_filter_post"];

/**
* ```
* 🏗️ Variable queries construction 👷
* all => ['global-concurrency-limits'] // key to match ['global-concurrency-limits', ...
* list => ['global-concurrency-limits', 'list'] // key to match ['global-concurrency-limits', 'list', ...
* ['global-concurrency-limits', 'list', { ...filter1 }]
* ['global-concurrency-limits', 'list', { ...filter2 }]
* details => ['global-concurrency-limits', 'details'] // key to match ['global-concurrency-limits', 'details', ...]
* ['global-concurrency-limits', 'details', { ...globalConcurrencyLimit1 }]
* ['global-concurrency-limits', 'details', { ...globalConcurrencyLimit2 }]
* ```
* */
const queryKeyFactory = {
all: () => ["global-concurrency-limits"] as const,
lists: () => [...queryKeyFactory.all(), "list"] as const,
list: (filter: GlobalConcurrencyLimitsFilter) =>
[...queryKeyFactory.lists(), filter] as const,
details: () => [...queryKeyFactory.all(), "details"] as const,
detail: (id_or_name: string) =>
[...queryKeyFactory.details(), id_or_name] as const,
};

// ----- 🔑 Queries 🗄️
// ----------------------------
export const buildListGlobalConcurrencyLimitsQuery = (
filter: GlobalConcurrencyLimitsFilter,
) =>
queryOptions({
queryKey: queryKeyFactory.list(filter),
queryFn: async () => {
const res = await getQueryService().POST(
"/v2/concurrency_limits/filter",
{ body: filter },
);
return res.data ?? [];
},
});

export const buildGetGlobalConcurrencyLimitQuery = (id_or_name: string) =>
queryOptions({
queryKey: queryKeyFactory.detail(id_or_name),
queryFn: async () => {
const res = await getQueryService().GET(
"/v2/concurrency_limits/{id_or_name}",
{ params: { path: { id_or_name } } },
);
return res.data ?? null;
},
});

// ----- ✍🏼 Mutations 🗄️
// ----------------------------

// TODO:

0 comments on commit af3a2d9

Please sign in to comment.