Skip to content

Commit 7f1dea0

Browse files
committed
fix: update rules and add tests case
1 parent f0773b8 commit 7f1dea0

File tree

5 files changed

+98
-28
lines changed

5 files changed

+98
-28
lines changed

src/features/workspace/components/__tests__/workspace-preferred-model.test.tsx

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,115 @@ import { screen, waitFor } from "@testing-library/react";
33
import { WorkspacePreferredModel } from "../workspace-preferred-model";
44
import userEvent from "@testing-library/user-event";
55

6-
// next commit, I needs to refactor it
7-
test.skip("render model overrides", async () => {
6+
test("render model overrides", async () => {
87
render(
98
<WorkspacePreferredModel
109
isArchived={false}
1110
workspaceName="fake-workspace"
1211
/>,
1312
);
14-
expect(screen.getByText(/preferred model/i)).toBeVisible();
13+
expect(screen.getByText(/model muxing/i)).toBeVisible();
1514
expect(
1615
screen.getByText(
17-
/select the model you would like to use in this workspace./i,
16+
/filters will be applied in order \(top to bottom\), empty filters will apply to all\./i,
1817
),
1918
).toBeVisible();
2019
expect(
21-
screen.getByRole("button", { name: /select the model/i }),
20+
screen.getByRole("link", {
21+
name: /learn more/i,
22+
}),
2223
).toBeVisible();
2324

24-
await waitFor(() => {
25-
expect(screen.getByRole("button", { name: /save/i })).toBeVisible();
26-
});
25+
await userEvent.type(
26+
screen.getByRole("textbox", {
27+
name: /filter by/i,
28+
}),
29+
".tsx",
30+
);
31+
32+
await userEvent.click(screen.getByTestId(/workspace-models-dropdown/i));
33+
await userEvent.click(
34+
screen.getByRole("option", {
35+
name: /claude-3.6/i,
36+
}),
37+
);
38+
39+
expect(screen.getByRole("button", { name: /add filter/i })).toBeVisible();
40+
expect(
41+
screen.getByRole("button", { name: /manage providers/i }),
42+
).toBeVisible();
43+
expect(screen.getByRole("button", { name: /revert changes/i })).toBeVisible();
44+
expect(screen.getByRole("button", { name: /save/i })).toBeVisible();
45+
});
46+
47+
test("disabled muxing fields and buttons for archived workspace", async () => {
48+
render(
49+
<WorkspacePreferredModel
50+
isArchived={true}
51+
workspaceName="fake-workspace"
52+
/>,
53+
);
54+
55+
expect(await screen.findByRole("button", { name: /save/i })).toBeDisabled();
56+
expect(screen.getByTestId(/workspace-models-dropdown/i)).toBeDisabled();
57+
expect(
58+
await screen.findByRole("button", { name: /add filter/i }),
59+
).toBeDisabled();
2760
});
2861

29-
// next commit, I needs to refactor it
30-
test.skip("submit preferred model", async () => {
62+
test("submit additional model overrides", async () => {
3163
render(
3264
<WorkspacePreferredModel
3365
isArchived={false}
3466
workspaceName="fake-workspace"
3567
/>,
3668
);
3769

70+
expect(screen.getAllByRole("textbox", { name: /filter by/i }).length).toEqual(
71+
1,
72+
);
73+
await userEvent.type(
74+
screen.getByRole("textbox", {
75+
name: /filter by/i,
76+
}),
77+
".tsx",
78+
);
79+
await userEvent.click(screen.getByTestId(/workspace-models-dropdown/i));
80+
await userEvent.click(
81+
screen.getByRole("option", {
82+
name: /claude-3.6/i,
83+
}),
84+
);
85+
86+
await userEvent.click(screen.getByRole("button", { name: /add filter/i }));
87+
88+
const textFields = await screen.findAllByRole("textbox", {
89+
name: /filter by/i,
90+
});
91+
expect(textFields.length).toEqual(2);
92+
const modelsButton = await screen.findAllByTestId(
93+
/workspace-models-dropdown/i,
94+
);
95+
expect(modelsButton.length).toEqual(2);
96+
97+
await userEvent.type(textFields[1] as HTMLFormElement, ".ts");
3898
await userEvent.click(
39-
screen.getByRole("button", { name: /select the model/i }),
99+
(await screen.findByRole("button", {
100+
name: /select a model/i,
101+
})) as HTMLFormElement,
40102
);
41103

42104
await userEvent.click(
43105
screen.getByRole("option", {
44-
name: "anthropic/claude-3.5",
106+
name: /chatgpt-4p/i,
45107
}),
46108
);
47109

48110
await userEvent.click(screen.getByRole("button", { name: /save/i }));
49111

50112
await waitFor(() => {
51-
expect(screen.getByText(/preferred model for fake-workspace updated/i));
113+
expect(
114+
screen.getByText(/muxing rules for fake-workspace updated/i),
115+
).toBeVisible();
52116
});
53117
});

src/features/workspace/components/workspace-models-dropdown.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { useState } from "react";
1818

1919
type Props = {
2020
rule: MuxRule & { id: string };
21+
isArchived: boolean;
2122
models: V1ListAllModelsForAllProvidersResponse;
2223
onChange: ({
2324
model,
@@ -80,6 +81,7 @@ function filterModels({
8081

8182
export function WorkspaceModelsDropdown({
8283
rule,
84+
isArchived,
8385
models = [],
8486
onChange,
8587
}: Props) {
@@ -99,10 +101,12 @@ export function WorkspaceModelsDropdown({
99101
<DialogTrigger isOpen={isOpen} onOpenChange={(test) => setIsOpen(test)}>
100102
<Button
101103
variant="secondary"
104+
isDisabled={isArchived}
105+
data-testid="workspace-models-dropdown"
102106
className="flex justify-between cursor-pointer bg-gray-25 border-gray-400 shadow-none font-normal w-full"
103107
>
104-
{currentModel}
105-
<ChevronDown />
108+
<span>{currentModel || "Select a model"}</span>
109+
<ChevronDown className="shrink-0" />
106110
</Button>
107111

108112
<Popover className="w-[32rem] p-3" placement="top end">

src/features/workspace/components/workspace-preferred-model.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ type SortableItemProps = {
5454
index: number;
5555
rule: PreferredMuxRule;
5656
models: V1ListAllModelsForAllProvidersResponse;
57+
isArchived: boolean;
5758
showRemoveButton: boolean;
5859
setRuleItem: (rule: PreferredMuxRule) => void;
5960
removeRule: (index: number) => void;
@@ -66,6 +67,7 @@ function SortableItem({
6667
removeRule,
6768
models,
6869
showRemoveButton,
70+
isArchived,
6971
}: SortableItemProps) {
7072
return (
7173
<div className="flex items-center gap-2" key={rule.id}>
@@ -74,6 +76,7 @@ function SortableItem({
7476
aria-labelledby="filter-by-label-id"
7577
onFocus={(event) => event.preventDefault()}
7678
value={rule?.matcher ?? ""}
79+
isDisabled={isArchived}
7780
name="matcher"
7881
onChange={(matcher) => {
7982
setRuleItem({ ...rule, matcher });
@@ -85,6 +88,7 @@ function SortableItem({
8588
<div className="flex w-3/5 gap-2">
8689
<WorkspaceModelsDropdown
8790
rule={rule}
91+
isArchived={isArchived}
8892
models={models}
8993
onChange={({ model, provider_id }) =>
9094
setRuleItem({ ...rule, provider_id, model })
@@ -142,7 +146,7 @@ export function WorkspacePreferredModel({
142146
return (
143147
<Card className={twMerge(className, "shrink-0")}>
144148
<CardBody className="flex flex-col gap-2">
145-
<Text className="text-primary">Preferred Model</Text>
149+
<Text className="text-primary">Model Muxing</Text>
146150
<MissingProviderBanner />
147151
</CardBody>
148152
</Card>
@@ -193,6 +197,7 @@ export function WorkspacePreferredModel({
193197
removeRule={removeRule}
194198
models={providerModels}
195199
showRemoveButton={showRemoveButton}
200+
isArchived={isArchived}
196201
/>
197202
)}
198203
</SortableArea>

src/features/workspace/hooks/use-muxing-rules-form-workspace.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ export const useMuxingRulesFormState = (initialValues: MuxRule[]) => {
1717
const formState = useFormState<{
1818
rules: PreferredMuxRule[];
1919
}>({
20-
rules: initialValues.map((item) => ({ ...item, id: uuidv4() })) ?? [
21-
{ ...DEFAULT_STATE, id: uuidv4() },
22-
],
20+
rules: [{ ...DEFAULT_STATE, id: uuidv4() }],
2321
});
2422
const { values, updateFormValues } = formState;
2523

2624
useEffect(() => {
25+
if (initialValues.length === 0) return;
26+
2727
updateFormValues({
2828
rules: initialValues.map((item) => ({ ...item, id: uuidv4() })),
2929
});

src/hooks/useFormState.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,12 @@ export function useFormState<Values extends Record<string, unknown>>(
2323
// this could be replaced with some form library later
2424
const [values, setValues] = useState<Values>(memoizedInitialValues);
2525

26-
const updateFormValues = useCallback(
27-
(newState: Partial<Values>) => {
28-
setValues((prevState: Values) => ({
29-
...prevState,
30-
...newState,
31-
}));
32-
},
33-
[setValues],
34-
);
26+
const updateFormValues = useCallback((newState: Partial<Values>) => {
27+
setValues((prevState: Values) => {
28+
if (isEqual(newState, prevState)) return prevState;
29+
return { ...prevState, ...newState };
30+
});
31+
}, []);
3532

3633
const resetForm = useCallback(() => {
3734
setValues(memoizedInitialValues);

0 commit comments

Comments
 (0)