mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
test(ui): type the query and SDK mock test helpers (#859)
This commit is contained in:
@@ -10,6 +10,7 @@ vi.mock("@/lib/signed-fetch", () => ({
|
||||
|
||||
import { getCredentials } from "@/lib/auth"
|
||||
import { signedFetch } from "@/lib/signed-fetch"
|
||||
import { callQueryFn } from "@/test/query"
|
||||
|
||||
import {
|
||||
adminNodesQueryOptions,
|
||||
@@ -20,15 +21,6 @@ import {
|
||||
const mockGetCredentials = vi.mocked(getCredentials)
|
||||
const mockSignedFetch = vi.mocked(signedFetch)
|
||||
|
||||
function getQueryFn(opts: {
|
||||
queryFn?: unknown
|
||||
}): (ctx: never) => Promise<unknown> {
|
||||
if (typeof opts.queryFn !== "function") {
|
||||
throw new TypeError("queryFn is not defined")
|
||||
}
|
||||
return opts.queryFn as (ctx: never) => Promise<unknown>
|
||||
}
|
||||
|
||||
describe("adminNodesQueryOptions", () => {
|
||||
it("has the correct query key", () => {
|
||||
expect(adminNodesQueryOptions.queryKey).toStrictEqual(["admin", "nodes"])
|
||||
@@ -36,9 +28,9 @@ describe("adminNodesQueryOptions", () => {
|
||||
|
||||
it("throws when not authenticated", async () => {
|
||||
mockGetCredentials.mockReturnValue(null)
|
||||
await expect(
|
||||
getQueryFn(adminNodesQueryOptions)({} as never),
|
||||
).rejects.toThrow("Not authenticated")
|
||||
await expect(callQueryFn(adminNodesQueryOptions)).rejects.toThrow(
|
||||
"Not authenticated",
|
||||
)
|
||||
})
|
||||
|
||||
it("calls signedFetch with GetNodes action", async () => {
|
||||
@@ -51,7 +43,7 @@ describe("adminNodesQueryOptions", () => {
|
||||
mockGetCredentials.mockReturnValue(creds)
|
||||
mockSignedFetch.mockResolvedValue({ nodes: [], cluster_mode: "single" })
|
||||
|
||||
await getQueryFn(adminNodesQueryOptions)({} as never)
|
||||
await callQueryFn(adminNodesQueryOptions)
|
||||
|
||||
expect(mockSignedFetch).toHaveBeenCalledWith({
|
||||
action: "GetNodes",
|
||||
@@ -67,7 +59,7 @@ describe("adminVMsQueryOptions", () => {
|
||||
|
||||
it("throws when not authenticated", async () => {
|
||||
mockGetCredentials.mockReturnValue(null)
|
||||
await expect(getQueryFn(adminVMsQueryOptions)({} as never)).rejects.toThrow(
|
||||
await expect(callQueryFn(adminVMsQueryOptions)).rejects.toThrow(
|
||||
"Not authenticated",
|
||||
)
|
||||
})
|
||||
@@ -82,7 +74,7 @@ describe("adminVMsQueryOptions", () => {
|
||||
mockGetCredentials.mockReturnValue(creds)
|
||||
mockSignedFetch.mockResolvedValue({ vms: [] })
|
||||
|
||||
await getQueryFn(adminVMsQueryOptions)({} as never)
|
||||
await callQueryFn(adminVMsQueryOptions)
|
||||
|
||||
expect(mockSignedFetch).toHaveBeenCalledWith({
|
||||
action: "GetVMs",
|
||||
@@ -101,9 +93,9 @@ describe("adminStorageStatusQueryOptions", () => {
|
||||
|
||||
it("throws when not authenticated", async () => {
|
||||
mockGetCredentials.mockReturnValue(null)
|
||||
await expect(
|
||||
getQueryFn(adminStorageStatusQueryOptions)({} as never),
|
||||
).rejects.toThrow("Not authenticated")
|
||||
await expect(callQueryFn(adminStorageStatusQueryOptions)).rejects.toThrow(
|
||||
"Not authenticated",
|
||||
)
|
||||
})
|
||||
|
||||
it("calls signedFetch with GetStorageStatus action", async () => {
|
||||
@@ -116,7 +108,7 @@ describe("adminStorageStatusQueryOptions", () => {
|
||||
mockGetCredentials.mockReturnValue(creds)
|
||||
mockSignedFetch.mockResolvedValue({})
|
||||
|
||||
await getQueryFn(adminStorageStatusQueryOptions)({} as never)
|
||||
await callQueryFn(adminStorageStatusQueryOptions)
|
||||
|
||||
expect(mockSignedFetch).toHaveBeenCalledWith({
|
||||
action: "GetStorageStatus",
|
||||
|
||||
@@ -6,6 +6,8 @@ vi.mock("@/lib/awsClient", () => ({
|
||||
getEc2Client: () => ({ send: mockSend }),
|
||||
}))
|
||||
|
||||
import { callQueryFn } from "@/test/query"
|
||||
|
||||
import {
|
||||
ec2AvailabilityZonesQueryOptions,
|
||||
ec2IamInstanceProfileAssociationsQueryOptions,
|
||||
@@ -225,17 +227,13 @@ describe("queryFn", () => {
|
||||
|
||||
it("ec2ImageQueryOptions returns empty result for undefined imageId", async () => {
|
||||
const options = ec2ImageQueryOptions(undefined)
|
||||
const queryFn = options.queryFn as (ctx: never) => Promise<unknown>
|
||||
const result = await queryFn({} as never)
|
||||
const result = await callQueryFn(options)
|
||||
expect(result).toStrictEqual({ Images: [], $metadata: {} })
|
||||
expect(mockSend).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("ec2ImageQueryOptions sends DescribeImagesCommand for valid imageId", async () => {
|
||||
const queryFn = ec2ImageQueryOptions("ami-123").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2ImageQueryOptions("ami-123"))
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
ImageIds: ["ami-123"],
|
||||
@@ -243,210 +241,142 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("ec2InstancesQueryOptions sends DescribeInstancesCommand", async () => {
|
||||
const queryFn = ec2InstancesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2InstancesQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("ec2LaunchTemplatesQueryOptions sends DescribeLaunchTemplatesCommand", async () => {
|
||||
const queryFn = ec2LaunchTemplatesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2LaunchTemplatesQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("ec2LaunchTemplateVersionsQueryOptions sends command with ID", async () => {
|
||||
const queryFn = ec2LaunchTemplateVersionsQueryOptions("lt-123").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2LaunchTemplateVersionsQueryOptions("lt-123"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
LaunchTemplateId: "lt-123",
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2InstanceQueryOptions sends DescribeInstancesCommand with ID", async () => {
|
||||
const queryFn = ec2InstanceQueryOptions("i-123").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2InstanceQueryOptions("i-123"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
InstanceIds: ["i-123"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2KeyPairsQueryOptions sends DescribeKeyPairsCommand", async () => {
|
||||
const queryFn = ec2KeyPairsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2KeyPairsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("ec2KeyPairQueryOptions sends DescribeKeyPairsCommand with ID", async () => {
|
||||
const queryFn = ec2KeyPairQueryOptions("kp-abc").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2KeyPairQueryOptions("kp-abc"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
KeyPairIds: ["kp-abc"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2VolumesQueryOptions sends DescribeVolumesCommand", async () => {
|
||||
const queryFn = ec2VolumesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2VolumesQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it("ec2VolumeQueryOptions sends DescribeVolumesCommand with ID", async () => {
|
||||
const queryFn = ec2VolumeQueryOptions("vol-1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2VolumeQueryOptions("vol-1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
VolumeIds: ["vol-1"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2SnapshotsQueryOptions sends DescribeSnapshotsCommand", async () => {
|
||||
const queryFn = ec2SnapshotsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2SnapshotsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it("ec2SnapshotQueryOptions sends DescribeSnapshotsCommand with ID", async () => {
|
||||
const queryFn = ec2SnapshotQueryOptions("snap-1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2SnapshotQueryOptions("snap-1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
SnapshotIds: ["snap-1"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2VpcsQueryOptions sends DescribeVpcsCommand", async () => {
|
||||
const queryFn = ec2VpcsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2VpcsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it("ec2VpcQueryOptions sends DescribeVpcsCommand with ID", async () => {
|
||||
const queryFn = ec2VpcQueryOptions("vpc-1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2VpcQueryOptions("vpc-1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
VpcIds: ["vpc-1"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2SubnetsQueryOptions sends DescribeSubnetsCommand", async () => {
|
||||
const queryFn = ec2SubnetsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2SubnetsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it("ec2SubnetQueryOptions sends DescribeSubnetsCommand with ID", async () => {
|
||||
const queryFn = ec2SubnetQueryOptions("subnet-1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2SubnetQueryOptions("subnet-1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
SubnetIds: ["subnet-1"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2AvailabilityZonesQueryOptions sends DescribeAvailabilityZonesCommand", async () => {
|
||||
const queryFn = ec2AvailabilityZonesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2AvailabilityZonesQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it("ec2RegionsQueryOptions sends DescribeRegionsCommand", async () => {
|
||||
const queryFn = ec2RegionsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2RegionsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it("ec2ImagesQueryOptions sends DescribeImagesCommand", async () => {
|
||||
const queryFn = ec2ImagesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2ImagesQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it("ec2InstanceTypesQueryOptions sends DescribeInstanceTypesCommand with filter", async () => {
|
||||
const queryFn = ec2InstanceTypesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2InstanceTypesQueryOptions)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
Filters: [{ Name: "capacity", Values: ["true"] }],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2PlacementGroupsQueryOptions sends DescribePlacementGroupsCommand", async () => {
|
||||
const queryFn = ec2PlacementGroupsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2PlacementGroupsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("ec2PlacementGroupQueryOptions sends DescribePlacementGroupsCommand with ID", async () => {
|
||||
const queryFn = ec2PlacementGroupQueryOptions("pg-123").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2PlacementGroupQueryOptions("pg-123"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
GroupIds: ["pg-123"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2SecurityGroupsQueryOptions sends DescribeSecurityGroupsCommand", async () => {
|
||||
const queryFn = ec2SecurityGroupsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2SecurityGroupsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("ec2SecurityGroupQueryOptions sends DescribeSecurityGroupsCommand with ID", async () => {
|
||||
const queryFn = ec2SecurityGroupQueryOptions("sg-123").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2SecurityGroupQueryOptions("sg-123"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
GroupIds: ["sg-123"],
|
||||
})
|
||||
})
|
||||
|
||||
it("ec2IamInstanceProfileAssociationsQueryOptions filters by instance-id", async () => {
|
||||
const queryFn = ec2IamInstanceProfileAssociationsQueryOptions("i-123")
|
||||
.queryFn as (ctx: never) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(ec2IamInstanceProfileAssociationsQueryOptions("i-123"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
Filters: [{ Name: "instance-id", Values: ["i-123"] }],
|
||||
})
|
||||
|
||||
@@ -6,6 +6,8 @@ vi.mock("@/lib/awsClient", () => ({
|
||||
getEksClient: () => ({ send: mockSend }),
|
||||
}))
|
||||
|
||||
import { callQueryFn } from "@/test/query"
|
||||
|
||||
import {
|
||||
eksAccessEntriesQueryOptions,
|
||||
eksAccessEntryQueryOptions,
|
||||
@@ -114,27 +116,18 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("clusters sends ListClustersCommand", async () => {
|
||||
const queryFn = eksClustersQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(eksClustersQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("cluster sends DescribeClusterCommand with name", async () => {
|
||||
const queryFn = eksClusterQueryOptions("c1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(eksClusterQueryOptions("c1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({ name: "c1" })
|
||||
})
|
||||
|
||||
it("nodegroup sends DescribeNodegroupCommand", async () => {
|
||||
const queryFn = eksNodegroupQueryOptions("c1", "ng1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(eksNodegroupQueryOptions("c1", "ng1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
clusterName: "c1",
|
||||
nodegroupName: "ng1",
|
||||
@@ -142,10 +135,7 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("access entry sends DescribeAccessEntryCommand", async () => {
|
||||
const queryFn = eksAccessEntryQueryOptions("c1", "arn:p").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(eksAccessEntryQueryOptions("c1", "arn:p"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
clusterName: "c1",
|
||||
principalArn: "arn:p",
|
||||
@@ -153,20 +143,14 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("addons sends ListAddonsCommand with cluster", async () => {
|
||||
const queryFn = eksAddonsQueryOptions("c1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(eksAddonsQueryOptions("c1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
clusterName: "c1",
|
||||
})
|
||||
})
|
||||
|
||||
it("addon sends DescribeAddonCommand", async () => {
|
||||
const queryFn = eksAddonQueryOptions("c1", "coredns").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(eksAddonQueryOptions("c1", "coredns"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
clusterName: "c1",
|
||||
addonName: "coredns",
|
||||
|
||||
@@ -6,6 +6,8 @@ vi.mock("@/lib/awsClient", () => ({
|
||||
getElbv2Client: () => ({ send: mockSend }),
|
||||
}))
|
||||
|
||||
import { callQueryFn } from "@/test/query"
|
||||
|
||||
import {
|
||||
elbv2ListenersQueryOptions,
|
||||
elbv2LoadBalancerAttributesQueryOptions,
|
||||
@@ -88,25 +90,17 @@ describe("elbv2 query keys", () => {
|
||||
})
|
||||
})
|
||||
|
||||
type QueryFnWithSignal = (ctx: { signal: AbortSignal }) => Promise<unknown>
|
||||
|
||||
async function callQueryFn(queryFn: unknown): Promise<unknown> {
|
||||
return await (queryFn as QueryFnWithSignal)({
|
||||
signal: new AbortController().signal,
|
||||
})
|
||||
}
|
||||
|
||||
describe("elbv2 implemented queries send the right command", () => {
|
||||
it("loadBalancers list sends DescribeLoadBalancersCommand", async () => {
|
||||
mockSend.mockResolvedValueOnce({ LoadBalancers: [] })
|
||||
await callQueryFn(elbv2LoadBalancersQueryOptions.queryFn)
|
||||
await callQueryFn(elbv2LoadBalancersQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("loadBalancer detail filters by ARN", async () => {
|
||||
mockSend.mockResolvedValueOnce({ LoadBalancers: [] })
|
||||
await callQueryFn(elbv2LoadBalancerQueryOptions("arn:lb").queryFn)
|
||||
await callQueryFn(elbv2LoadBalancerQueryOptions("arn:lb"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
LoadBalancerArns: ["arn:lb"],
|
||||
})
|
||||
@@ -114,7 +108,7 @@ describe("elbv2 implemented queries send the right command", () => {
|
||||
|
||||
it("loadBalancer attributes sends arn", async () => {
|
||||
mockSend.mockResolvedValueOnce({ Attributes: [] })
|
||||
await callQueryFn(elbv2LoadBalancerAttributesQueryOptions("arn:lb").queryFn)
|
||||
await callQueryFn(elbv2LoadBalancerAttributesQueryOptions("arn:lb"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
LoadBalancerArn: "arn:lb",
|
||||
})
|
||||
@@ -122,7 +116,7 @@ describe("elbv2 implemented queries send the right command", () => {
|
||||
|
||||
it("listeners filters by load balancer arn", async () => {
|
||||
mockSend.mockResolvedValueOnce({ Listeners: [] })
|
||||
await callQueryFn(elbv2ListenersQueryOptions("arn:lb").queryFn)
|
||||
await callQueryFn(elbv2ListenersQueryOptions("arn:lb"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
LoadBalancerArn: "arn:lb",
|
||||
})
|
||||
@@ -130,7 +124,7 @@ describe("elbv2 implemented queries send the right command", () => {
|
||||
|
||||
it("tags sends resource arns", async () => {
|
||||
mockSend.mockResolvedValueOnce({ TagDescriptions: [] })
|
||||
await callQueryFn(elbv2TagsQueryOptions(["arn:lb"]).queryFn)
|
||||
await callQueryFn(elbv2TagsQueryOptions(["arn:lb"]))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
ResourceArns: ["arn:lb"],
|
||||
})
|
||||
@@ -138,13 +132,13 @@ describe("elbv2 implemented queries send the right command", () => {
|
||||
|
||||
it("targetGroups list sends DescribeTargetGroupsCommand", async () => {
|
||||
mockSend.mockResolvedValueOnce({ TargetGroups: [] })
|
||||
await callQueryFn(elbv2TargetGroupsQueryOptions.queryFn)
|
||||
await callQueryFn(elbv2TargetGroupsQueryOptions)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("targetGroup detail filters by ARN", async () => {
|
||||
mockSend.mockResolvedValueOnce({ TargetGroups: [] })
|
||||
await callQueryFn(elbv2TargetGroupQueryOptions("arn:tg").queryFn)
|
||||
await callQueryFn(elbv2TargetGroupQueryOptions("arn:tg"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
TargetGroupArns: ["arn:tg"],
|
||||
})
|
||||
@@ -152,7 +146,7 @@ describe("elbv2 implemented queries send the right command", () => {
|
||||
|
||||
it("targetGroup attributes sends arn", async () => {
|
||||
mockSend.mockResolvedValueOnce({ Attributes: [] })
|
||||
await callQueryFn(elbv2TargetGroupAttributesQueryOptions("arn:tg").queryFn)
|
||||
await callQueryFn(elbv2TargetGroupAttributesQueryOptions("arn:tg"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
TargetGroupArn: "arn:tg",
|
||||
})
|
||||
@@ -160,7 +154,7 @@ describe("elbv2 implemented queries send the right command", () => {
|
||||
|
||||
it("targetHealth sends target group arn", async () => {
|
||||
mockSend.mockResolvedValueOnce({ TargetHealthDescriptions: [] })
|
||||
await callQueryFn(elbv2TargetHealthQueryOptions("arn:tg").queryFn)
|
||||
await callQueryFn(elbv2TargetHealthQueryOptions("arn:tg"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
TargetGroupArn: "arn:tg",
|
||||
})
|
||||
|
||||
@@ -6,6 +6,8 @@ vi.mock("@/lib/awsClient", () => ({
|
||||
getIamClient: () => ({ send: mockSend }),
|
||||
}))
|
||||
|
||||
import { callQueryFn } from "@/test/query"
|
||||
|
||||
import {
|
||||
iamAccessKeysQueryOptions,
|
||||
iamAttachedGroupPoliciesQueryOptions,
|
||||
@@ -225,57 +227,39 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("iamUsersQueryOptions sends ListUsersCommand", async () => {
|
||||
const queryFn = iamUsersQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamUsersQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("iamUserQueryOptions sends GetUserCommand with userName", async () => {
|
||||
const queryFn = iamUserQueryOptions("admin").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamUserQueryOptions("admin"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
UserName: "admin",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamAccessKeysQueryOptions sends ListAccessKeysCommand", async () => {
|
||||
const queryFn = iamAccessKeysQueryOptions("admin").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamAccessKeysQueryOptions("admin"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
UserName: "admin",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamPoliciesQueryOptions sends ListPoliciesCommand with Local scope", async () => {
|
||||
const queryFn = iamPoliciesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamPoliciesQueryOptions)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({ Scope: "Local" })
|
||||
})
|
||||
|
||||
it("iamPolicyQueryOptions sends GetPolicyCommand with policyArn", async () => {
|
||||
const queryFn = iamPolicyQueryOptions("arn:test").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamPolicyQueryOptions("arn:test"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
PolicyArn: "arn:test",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamPolicyVersionQueryOptions sends GetPolicyVersionCommand", async () => {
|
||||
const queryFn = iamPolicyVersionQueryOptions("arn:test", "v1").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamPolicyVersionQueryOptions("arn:test", "v1"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
PolicyArn: "arn:test",
|
||||
VersionId: "v1",
|
||||
@@ -283,112 +267,78 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("iamAttachedUserPoliciesQueryOptions sends ListAttachedUserPoliciesCommand", async () => {
|
||||
const queryFn = iamAttachedUserPoliciesQueryOptions("admin").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamAttachedUserPoliciesQueryOptions("admin"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
UserName: "admin",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamRolesQueryOptions sends ListRolesCommand", async () => {
|
||||
const queryFn = iamRolesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamRolesQueryOptions)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("iamRoleQueryOptions sends GetRoleCommand with roleName", async () => {
|
||||
const queryFn = iamRoleQueryOptions("my-role").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamRoleQueryOptions("my-role"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
RoleName: "my-role",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamAttachedRolePoliciesQueryOptions sends ListAttachedRolePoliciesCommand", async () => {
|
||||
const queryFn = iamAttachedRolePoliciesQueryOptions("my-role").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamAttachedRolePoliciesQueryOptions("my-role"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
RoleName: "my-role",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamInstanceProfilesQueryOptions sends ListInstanceProfilesCommand", async () => {
|
||||
const queryFn = iamInstanceProfilesQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamInstanceProfilesQueryOptions)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("iamInstanceProfileQueryOptions sends GetInstanceProfileCommand", async () => {
|
||||
const queryFn = iamInstanceProfileQueryOptions("my-profile").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamInstanceProfileQueryOptions("my-profile"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
InstanceProfileName: "my-profile",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamInstanceProfilesForRoleQueryOptions sends ListInstanceProfilesForRoleCommand", async () => {
|
||||
const queryFn = iamInstanceProfilesForRoleQueryOptions("my-role")
|
||||
.queryFn as (ctx: never) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamInstanceProfilesForRoleQueryOptions("my-role"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
RoleName: "my-role",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamGroupsQueryOptions sends ListGroupsCommand", async () => {
|
||||
const queryFn = iamGroupsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamGroupsQueryOptions)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("iamGroupQueryOptions sends GetGroupCommand with groupName", async () => {
|
||||
const queryFn = iamGroupQueryOptions("my-group").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamGroupQueryOptions("my-group"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
GroupName: "my-group",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamAttachedGroupPoliciesQueryOptions sends ListAttachedGroupPoliciesCommand", async () => {
|
||||
const queryFn = iamAttachedGroupPoliciesQueryOptions("my-group")
|
||||
.queryFn as (ctx: never) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamAttachedGroupPoliciesQueryOptions("my-group"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
GroupName: "my-group",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamGroupsForUserQueryOptions sends ListGroupsForUserCommand with userName", async () => {
|
||||
const queryFn = iamGroupsForUserQueryOptions("admin").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamGroupsForUserQueryOptions("admin"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
UserName: "admin",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamUserPoliciesQueryOptions sends ListUserPoliciesCommand", async () => {
|
||||
const queryFn = iamUserPoliciesQueryOptions("admin").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamUserPoliciesQueryOptions("admin"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
UserName: "admin",
|
||||
})
|
||||
@@ -398,10 +348,9 @@ describe("queryFn", () => {
|
||||
mockSend.mockResolvedValueOnce({
|
||||
PolicyDocument: encodeURIComponent('{"Version":"2012-10-17"}'),
|
||||
})
|
||||
const queryFn = iamUserPolicyQueryOptions("admin", "s3-read").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
const document = await queryFn({} as never)
|
||||
const document = await callQueryFn(
|
||||
iamUserPolicyQueryOptions("admin", "s3-read"),
|
||||
)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
UserName: "admin",
|
||||
PolicyName: "s3-read",
|
||||
@@ -410,10 +359,7 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("iamRolePoliciesQueryOptions sends ListRolePoliciesCommand", async () => {
|
||||
const queryFn = iamRolePoliciesQueryOptions("my-role").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamRolePoliciesQueryOptions("my-role"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
RoleName: "my-role",
|
||||
})
|
||||
@@ -423,10 +369,9 @@ describe("queryFn", () => {
|
||||
mockSend.mockResolvedValueOnce({
|
||||
PolicyDocument: '{"Version":"2012-10-17"}',
|
||||
})
|
||||
const queryFn = iamRolePolicyQueryOptions("my-role", "s3-read").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
const document = await queryFn({} as never)
|
||||
const document = await callQueryFn(
|
||||
iamRolePolicyQueryOptions("my-role", "s3-read"),
|
||||
)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
RoleName: "my-role",
|
||||
PolicyName: "s3-read",
|
||||
@@ -435,19 +380,14 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("iamGroupPoliciesQueryOptions sends ListGroupPoliciesCommand", async () => {
|
||||
const queryFn = iamGroupPoliciesQueryOptions("my-group").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamGroupPoliciesQueryOptions("my-group"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
GroupName: "my-group",
|
||||
})
|
||||
})
|
||||
|
||||
it("iamGroupPolicyQueryOptions sends GetGroupPolicyCommand with names", async () => {
|
||||
const queryFn = iamGroupPolicyQueryOptions("my-group", "s3-read")
|
||||
.queryFn as (ctx: never) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(iamGroupPolicyQueryOptions("my-group", "s3-read"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
GroupName: "my-group",
|
||||
PolicyName: "s3-read",
|
||||
|
||||
@@ -6,6 +6,8 @@ vi.mock("@/lib/awsClient", () => ({
|
||||
getRdsClient: () => ({ send: mockSend }),
|
||||
}))
|
||||
|
||||
import { callQueryFn } from "@/test/query"
|
||||
|
||||
import {
|
||||
rdsAutomatedBackupsQueryOptions,
|
||||
rdsDBInstanceQueryOptions,
|
||||
@@ -148,25 +150,17 @@ describe("rds query keys", () => {
|
||||
})
|
||||
})
|
||||
|
||||
type QueryFnWithSignal = (ctx: { signal: AbortSignal }) => Promise<unknown>
|
||||
|
||||
async function callQueryFn(queryFn: unknown): Promise<unknown> {
|
||||
return await (queryFn as QueryFnWithSignal)({
|
||||
signal: new AbortController().signal,
|
||||
})
|
||||
}
|
||||
|
||||
describe("rds queries send the right command", () => {
|
||||
it("dbInstances list sends an unfiltered describe", async () => {
|
||||
mockSend.mockResolvedValueOnce({ DBInstances: [] })
|
||||
await callQueryFn(rdsDBInstancesQueryOptions.queryFn)
|
||||
await callQueryFn(rdsDBInstancesQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("dbInstance detail filters by identifier", async () => {
|
||||
mockSend.mockResolvedValueOnce({ DBInstances: [] })
|
||||
await callQueryFn(rdsDBInstanceQueryOptions("orders-db").queryFn)
|
||||
await callQueryFn(rdsDBInstanceQueryOptions("orders-db"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
DBInstanceIdentifier: "orders-db",
|
||||
})
|
||||
@@ -174,7 +168,7 @@ describe("rds queries send the right command", () => {
|
||||
|
||||
it("events asks for the whole 14-day ring, not the default hour", async () => {
|
||||
mockSend.mockResolvedValueOnce({ Events: [] })
|
||||
await callQueryFn(rdsEventsQueryOptions("orders-db").queryFn)
|
||||
await callQueryFn(rdsEventsQueryOptions("orders-db"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
SourceIdentifier: "orders-db",
|
||||
SourceType: "db-instance",
|
||||
@@ -184,7 +178,7 @@ describe("rds queries send the right command", () => {
|
||||
|
||||
it("tags sends the resource name", async () => {
|
||||
mockSend.mockResolvedValueOnce({ TagList: [] })
|
||||
await callQueryFn(rdsTagsQueryOptions("arn:db").queryFn)
|
||||
await callQueryFn(rdsTagsQueryOptions("arn:db"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
ResourceName: "arn:db",
|
||||
})
|
||||
@@ -192,7 +186,7 @@ describe("rds queries send the right command", () => {
|
||||
|
||||
it("orderable options filter by engine", async () => {
|
||||
mockSend.mockResolvedValueOnce({ OrderableDBInstanceOptions: [] })
|
||||
await callQueryFn(rdsOrderableOptionsQueryOptions("mariadb").queryFn)
|
||||
await callQueryFn(rdsOrderableOptionsQueryOptions("mariadb"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
Engine: "mariadb",
|
||||
})
|
||||
@@ -200,18 +194,18 @@ describe("rds queries send the right command", () => {
|
||||
|
||||
it("subnet groups and parameter groups send unfiltered describes", async () => {
|
||||
mockSend.mockResolvedValueOnce({ DBSubnetGroups: [] })
|
||||
await callQueryFn(rdsSubnetGroupsQueryOptions.queryFn)
|
||||
await callQueryFn(rdsSubnetGroupsQueryOptions)
|
||||
mockSend.mockResolvedValueOnce({ DBParameterGroups: [] })
|
||||
await callQueryFn(rdsParameterGroupsQueryOptions.queryFn)
|
||||
await callQueryFn(rdsParameterGroupsQueryOptions)
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
expect(mockSend.mock.calls[1]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("the single group describes filter by name", async () => {
|
||||
mockSend.mockResolvedValueOnce({ DBSubnetGroups: [] })
|
||||
await callQueryFn(rdsSubnetGroupQueryOptions("orders-subnets").queryFn)
|
||||
await callQueryFn(rdsSubnetGroupQueryOptions("orders-subnets"))
|
||||
mockSend.mockResolvedValueOnce({ DBParameterGroups: [] })
|
||||
await callQueryFn(rdsParameterGroupQueryOptions("orders-pg").queryFn)
|
||||
await callQueryFn(rdsParameterGroupQueryOptions("orders-pg"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
DBSubnetGroupName: "orders-subnets",
|
||||
})
|
||||
@@ -222,7 +216,7 @@ describe("rds queries send the right command", () => {
|
||||
|
||||
it("snapshot events ask the db-snapshot ring", async () => {
|
||||
mockSend.mockResolvedValueOnce({ Events: [] })
|
||||
await callQueryFn(rdsSnapshotEventsQueryOptions("orders-snap").queryFn)
|
||||
await callQueryFn(rdsSnapshotEventsQueryOptions("orders-snap"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
SourceIdentifier: "orders-snap",
|
||||
SourceType: "db-snapshot",
|
||||
@@ -232,11 +226,11 @@ describe("rds queries send the right command", () => {
|
||||
|
||||
it("the snapshot describes filter by snapshot and by instance", async () => {
|
||||
mockSend.mockResolvedValueOnce({ DBSnapshots: [] })
|
||||
await callQueryFn(rdsDBSnapshotsQueryOptions.queryFn)
|
||||
await callQueryFn(rdsDBSnapshotsQueryOptions)
|
||||
mockSend.mockResolvedValueOnce({ DBSnapshots: [] })
|
||||
await callQueryFn(rdsDBSnapshotQueryOptions("orders-snap").queryFn)
|
||||
await callQueryFn(rdsDBSnapshotQueryOptions("orders-snap"))
|
||||
mockSend.mockResolvedValueOnce({ DBSnapshots: [] })
|
||||
await callQueryFn(rdsInstanceDBSnapshotsQueryOptions("orders-db").queryFn)
|
||||
await callQueryFn(rdsInstanceDBSnapshotsQueryOptions("orders-db"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
expect(mockSend.mock.calls[1]?.[0].input).toStrictEqual({
|
||||
DBSnapshotIdentifier: "orders-snap",
|
||||
@@ -248,7 +242,7 @@ describe("rds queries send the right command", () => {
|
||||
|
||||
it("automated backups filter by instance", async () => {
|
||||
mockSend.mockResolvedValueOnce({ DBInstanceAutomatedBackups: [] })
|
||||
await callQueryFn(rdsAutomatedBackupsQueryOptions("orders-db").queryFn)
|
||||
await callQueryFn(rdsAutomatedBackupsQueryOptions("orders-db"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
DBInstanceIdentifier: "orders-db",
|
||||
})
|
||||
@@ -258,7 +252,7 @@ describe("rds queries send the right command", () => {
|
||||
// set is one round trip and the split is a client-side filter.
|
||||
it("parameters are fetched unfiltered by source", async () => {
|
||||
mockSend.mockResolvedValueOnce({ Parameters: [] })
|
||||
await callQueryFn(rdsParametersQueryOptions("orders-pg").queryFn)
|
||||
await callQueryFn(rdsParametersQueryOptions("orders-pg"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
DBParameterGroupName: "orders-pg",
|
||||
})
|
||||
|
||||
@@ -6,6 +6,8 @@ vi.mock("@/lib/awsClient", () => ({
|
||||
getS3Client: () => ({ send: mockSend }),
|
||||
}))
|
||||
|
||||
import { callQueryFn } from "@/test/query"
|
||||
|
||||
import { s3BucketObjectsQueryOptions, s3BucketsQueryOptions } from "./s3"
|
||||
|
||||
describe("query keys", () => {
|
||||
@@ -36,19 +38,13 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("s3BucketsQueryOptions sends ListBucketsCommand", async () => {
|
||||
const queryFn = s3BucketsQueryOptions.queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(s3BucketsQueryOptions)
|
||||
expect(mockSend).toHaveBeenCalledOnce()
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({})
|
||||
})
|
||||
|
||||
it("s3BucketObjectsQueryOptions sends ListObjectsV2Command with bucket and delimiter", async () => {
|
||||
const queryFn = s3BucketObjectsQueryOptions("my-bucket").queryFn as (
|
||||
ctx: never,
|
||||
) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(s3BucketObjectsQueryOptions("my-bucket"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
Bucket: "my-bucket",
|
||||
Prefix: undefined,
|
||||
@@ -57,9 +53,7 @@ describe("queryFn", () => {
|
||||
})
|
||||
|
||||
it("s3BucketObjectsQueryOptions sends prefix when provided", async () => {
|
||||
const queryFn = s3BucketObjectsQueryOptions("my-bucket", "docs/")
|
||||
.queryFn as (ctx: never) => Promise<unknown>
|
||||
await queryFn({} as never)
|
||||
await callQueryFn(s3BucketObjectsQueryOptions("my-bucket", "docs/"))
|
||||
expect(mockSend.mock.calls[0]?.[0].input).toStrictEqual({
|
||||
Bucket: "my-bucket",
|
||||
Prefix: "docs/",
|
||||
|
||||
+12
-7
@@ -14,7 +14,8 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
@@ -22,7 +23,7 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
`No handler registered for SDK command ${command.constructor.name}`,
|
||||
)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: {
|
||||
@@ -31,7 +32,9 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
},
|
||||
sdk: {
|
||||
send,
|
||||
setHandler: (name: string, handler: (input: unknown) => unknown) => {
|
||||
// Handlers are keyed by command name, so each one declares the input type
|
||||
// of its own command; the shared registry cannot name them all.
|
||||
setHandler: (name: string, handler: SdkHandler) => {
|
||||
handlers.set(name, handler)
|
||||
},
|
||||
reset: () => {
|
||||
@@ -51,10 +54,12 @@ vi.mock("@tanstack/react-router", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("@tanstack/react-router")>()
|
||||
return {
|
||||
...actual,
|
||||
createFileRoute: () => (options: Record<string, unknown>) => ({
|
||||
...options,
|
||||
useParams: () => routerState.params,
|
||||
}),
|
||||
createFileRoute:
|
||||
() =>
|
||||
<TOptions,>(options: TOptions) => ({
|
||||
...options,
|
||||
useParams: () => routerState.params,
|
||||
}),
|
||||
useNavigate: () => routerState.navigate,
|
||||
Link: ({ children, to }: { children: React.ReactNode; to?: string }) => (
|
||||
<a href={to}>{children}</a>
|
||||
|
||||
+10
-4
@@ -11,7 +11,8 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
@@ -19,13 +20,15 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
`No handler registered for SDK command ${command.constructor.name}`,
|
||||
)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: { navigate: vi.fn() },
|
||||
sdk: {
|
||||
send,
|
||||
setHandler: (name: string, handler: (input: unknown) => unknown) => {
|
||||
// Handlers are keyed by command name, so each one declares the input type
|
||||
// of its own command; the shared registry cannot name them all.
|
||||
setHandler: (name: string, handler: SdkHandler) => {
|
||||
handlers.set(name, handler)
|
||||
},
|
||||
reset: () => {
|
||||
@@ -45,7 +48,10 @@ vi.mock("@tanstack/react-router", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("@tanstack/react-router")>()
|
||||
return {
|
||||
...actual,
|
||||
createFileRoute: () => (options: Record<string, unknown>) => options,
|
||||
createFileRoute:
|
||||
() =>
|
||||
<TOptions,>(options: TOptions): TOptions =>
|
||||
options,
|
||||
useNavigate: () => routerState.navigate,
|
||||
Link: ({
|
||||
children,
|
||||
|
||||
+10
-4
@@ -12,7 +12,8 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
@@ -20,13 +21,15 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
`No handler registered for SDK command ${command.constructor.name}`,
|
||||
)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: { navigate: vi.fn() },
|
||||
sdk: {
|
||||
send,
|
||||
setHandler: (name: string, handler: (input: unknown) => unknown) => {
|
||||
// Handlers are keyed by command name, so each one declares the input type
|
||||
// of its own command; the shared registry cannot name them all.
|
||||
setHandler: (name: string, handler: SdkHandler) => {
|
||||
handlers.set(name, handler)
|
||||
},
|
||||
reset: () => {
|
||||
@@ -46,7 +49,10 @@ vi.mock("@tanstack/react-router", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("@tanstack/react-router")>()
|
||||
return {
|
||||
...actual,
|
||||
createFileRoute: () => (options: Record<string, unknown>) => options,
|
||||
createFileRoute:
|
||||
() =>
|
||||
<TOptions,>(options: TOptions): TOptions =>
|
||||
options,
|
||||
useNavigate: () => routerState.navigate,
|
||||
Link: ({
|
||||
children,
|
||||
|
||||
+12
-7
@@ -13,7 +13,8 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
@@ -21,7 +22,7 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
`No handler registered for SDK command ${command.constructor.name}`,
|
||||
)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: {
|
||||
@@ -30,7 +31,9 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
},
|
||||
sdk: {
|
||||
send,
|
||||
setHandler: (name: string, handler: (input: unknown) => unknown) => {
|
||||
// Handlers are keyed by command name, so each one declares the input type
|
||||
// of its own command; the shared registry cannot name them all.
|
||||
setHandler: (name: string, handler: SdkHandler) => {
|
||||
handlers.set(name, handler)
|
||||
},
|
||||
reset: () => {
|
||||
@@ -50,10 +53,12 @@ vi.mock("@tanstack/react-router", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("@tanstack/react-router")>()
|
||||
return {
|
||||
...actual,
|
||||
createFileRoute: () => (options: Record<string, unknown>) => ({
|
||||
...options,
|
||||
useParams: () => routerState.params,
|
||||
}),
|
||||
createFileRoute:
|
||||
() =>
|
||||
<TOptions,>(options: TOptions) => ({
|
||||
...options,
|
||||
useParams: () => routerState.params,
|
||||
}),
|
||||
useNavigate: () => routerState.navigate,
|
||||
Link: ({ children, to }: { children: React.ReactNode; to?: string }) => (
|
||||
<a href={to}>{children}</a>
|
||||
|
||||
+10
-4
@@ -11,7 +11,8 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
@@ -19,13 +20,15 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
`No handler registered for SDK command ${command.constructor.name}`,
|
||||
)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: { navigate: vi.fn() },
|
||||
sdk: {
|
||||
send,
|
||||
setHandler: (name: string, handler: (input: unknown) => unknown) => {
|
||||
// Handlers are keyed by command name, so each one declares the input type
|
||||
// of its own command; the shared registry cannot name them all.
|
||||
setHandler: (name: string, handler: SdkHandler) => {
|
||||
handlers.set(name, handler)
|
||||
},
|
||||
reset: () => {
|
||||
@@ -45,7 +48,10 @@ vi.mock("@tanstack/react-router", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("@tanstack/react-router")>()
|
||||
return {
|
||||
...actual,
|
||||
createFileRoute: () => (options: Record<string, unknown>) => options,
|
||||
createFileRoute:
|
||||
() =>
|
||||
<TOptions,>(options: TOptions): TOptions =>
|
||||
options,
|
||||
useNavigate: () => routerState.navigate,
|
||||
Link: ({
|
||||
children,
|
||||
|
||||
+24
-15
@@ -12,7 +12,8 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
@@ -20,13 +21,15 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
`No handler registered for SDK command ${command.constructor.name}`,
|
||||
)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: { navigate: vi.fn() },
|
||||
sdk: {
|
||||
send,
|
||||
setHandler: (name: string, handler: (input: unknown) => unknown) => {
|
||||
// Handlers are keyed by command name, so each one declares the input type
|
||||
// of its own command; the shared registry cannot name them all.
|
||||
setHandler: (name: string, handler: SdkHandler) => {
|
||||
handlers.set(name, handler)
|
||||
},
|
||||
reset: () => {
|
||||
@@ -46,7 +49,10 @@ vi.mock("@tanstack/react-router", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("@tanstack/react-router")>()
|
||||
return {
|
||||
...actual,
|
||||
createFileRoute: () => (options: Record<string, unknown>) => options,
|
||||
createFileRoute:
|
||||
() =>
|
||||
<TOptions,>(options: TOptions): TOptions =>
|
||||
options,
|
||||
useNavigate: () => routerState.navigate,
|
||||
Link: ({
|
||||
children,
|
||||
@@ -90,18 +96,21 @@ describe("describe-target-groups list route", () => {
|
||||
afterEach(() => vi.clearAllMocks())
|
||||
|
||||
it("renders target-group rows with health summaries from the mocked SDK", async () => {
|
||||
sdk.setHandler("DescribeTargetHealthCommand", (input) => {
|
||||
const arn = (input as { TargetGroupArn: string }).TargetGroupArn
|
||||
if (arn === "arn:tg:1") {
|
||||
return {
|
||||
TargetHealthDescriptions: [
|
||||
{ TargetHealth: { State: "healthy" } },
|
||||
{ TargetHealth: { State: "unhealthy" } },
|
||||
],
|
||||
sdk.setHandler(
|
||||
"DescribeTargetHealthCommand",
|
||||
(input: { TargetGroupArn: string }) => {
|
||||
const arn = input.TargetGroupArn
|
||||
if (arn === "arn:tg:1") {
|
||||
return {
|
||||
TargetHealthDescriptions: [
|
||||
{ TargetHealth: { State: "healthy" } },
|
||||
{ TargetHealth: { State: "unhealthy" } },
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
return { TargetHealthDescriptions: [] }
|
||||
})
|
||||
return { TargetHealthDescriptions: [] }
|
||||
},
|
||||
)
|
||||
|
||||
const qc = createTestQueryClient()
|
||||
qc.setQueryData(["elbv2", "targetGroups"], { TargetGroups: TGS })
|
||||
|
||||
+3
-2
@@ -12,13 +12,14 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
throw new Error(`No handler for ${command.constructor.name}`)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: { navigate: vi.fn() },
|
||||
|
||||
+3
-2
@@ -12,13 +12,14 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
throw new Error(`No handler for ${command.constructor.name}`)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: { navigate: vi.fn() },
|
||||
|
||||
+3
-2
@@ -12,13 +12,14 @@ const { routerState, sdk } = vi.hoisted(() => {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
}
|
||||
const handlers = new Map<string, (input: unknown) => unknown>()
|
||||
type SdkHandler = (input: never) => unknown
|
||||
const handlers = new Map<string, SdkHandler>()
|
||||
const send = vi.fn(async (command: Command): Promise<unknown> => {
|
||||
const handler = handlers.get(command.constructor.name)
|
||||
if (!handler) {
|
||||
throw new Error(`No handler for ${command.constructor.name}`)
|
||||
}
|
||||
return handler(command.input)
|
||||
return handler(command.input as never)
|
||||
})
|
||||
return {
|
||||
routerState: { navigate: vi.fn() },
|
||||
|
||||
@@ -32,7 +32,7 @@ const { sdk } = vi.hoisted(() => {
|
||||
}
|
||||
interface Command {
|
||||
readonly constructor: { name: string }
|
||||
readonly input: unknown
|
||||
readonly input: object
|
||||
}
|
||||
|
||||
const state = {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import {
|
||||
QueryClient,
|
||||
type QueryFunction,
|
||||
type QueryKey,
|
||||
type SkipToken,
|
||||
skipToken,
|
||||
} from "@tanstack/react-query"
|
||||
|
||||
interface CallableQueryOptions<TData, TQueryKey extends QueryKey> {
|
||||
queryKey: TQueryKey
|
||||
queryFn?: QueryFunction<TData, TQueryKey> | SkipToken
|
||||
}
|
||||
|
||||
function createQueryClient() {
|
||||
return new QueryClient({
|
||||
defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
|
||||
})
|
||||
}
|
||||
|
||||
// Calls a query's fetcher with a real context, so a query that starts reading
|
||||
// signal or client fails loudly here instead of silently taking another branch.
|
||||
// The return type is preserved, so callers can assert on the response.
|
||||
export async function callQueryFn<TData, TQueryKey extends QueryKey>(
|
||||
options: CallableQueryOptions<TData, TQueryKey>,
|
||||
client: QueryClient = createQueryClient(),
|
||||
): Promise<TData> {
|
||||
const { queryFn, queryKey } = options
|
||||
if (queryFn === undefined || queryFn === skipToken) {
|
||||
throw new TypeError(
|
||||
`query options ${JSON.stringify(queryKey)} have no callable queryFn`,
|
||||
)
|
||||
}
|
||||
return await queryFn({
|
||||
client,
|
||||
meta: undefined,
|
||||
queryKey,
|
||||
signal: new AbortController().signal,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user