-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[UI v2] feat: Adds global concurrency limit query definitions
- Loading branch information
1 parent
bd19554
commit 2704a60
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import { QueryClient, QueryClientProvider } 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, | ||
useGetGlobalConcurrencyLimit, | ||
useListGlobalConcurrencyLimits, | ||
} 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( | ||
() => useListGlobalConcurrencyLimits(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( | ||
() => useGetGlobalConcurrencyLimit(mockDetails.id), | ||
{ wrapper: createQueryWrapper({}) }, | ||
); | ||
|
||
// ------------ Assert | ||
await waitFor(() => expect(result.current.isSuccess).toBe(true)); | ||
expect(result.current.data).toEqual(mockDetails); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import type { components } from "@/api/prefect"; | ||
import { getQueryService } from "@/api/service"; | ||
import { queryOptions, useQuery } 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; | ||
}, | ||
}); | ||
|
||
export const useListGlobalConcurrencyLimits = ( | ||
filter: GlobalConcurrencyLimitsFilter, | ||
) => useQuery(buildListGlobalConcurrencyLimitsQuery(filter)); | ||
|
||
export const useGetGlobalConcurrencyLimit = (id_or_name: string) => | ||
useQuery(buildGetGlobalConcurrencyLimitQuery(id_or_name)); | ||
|
||
// ----- ✍🏼 Mutations 🗄️ | ||
// ---------------------------- | ||
|
||
// TODO: |