Pause adding multi-edit to workouts
Got up to the point where i'm find/replacing the old names with new names, and I got confused about the purpose of this feature.
This commit is contained in:
parent
79cde3a219
commit
dc5434991a
|
@ -23,16 +23,16 @@ export default function EditWorkout() {
|
|||
const { params } = useRoute<RouteProp<WorkoutsPageParams, "EditWorkout">>();
|
||||
const [removeImage, setRemoveImage] = useState(false);
|
||||
const [showRemove, setShowRemove] = useState(false);
|
||||
const [name, setName] = useState(params.value.name);
|
||||
const [steps, setSteps] = useState(params.value.steps);
|
||||
const [uri, setUri] = useState(params.value.image);
|
||||
const [name, setName] = useState(params.gymSet.name);
|
||||
const [steps, setSteps] = useState(params.gymSet.steps);
|
||||
const [uri, setUri] = useState(params.gymSet.image);
|
||||
const [minutes, setMinutes] = useState(
|
||||
params.value.minutes?.toString() ?? "3"
|
||||
params.gymSet.minutes?.toString() ?? "3"
|
||||
);
|
||||
const [seconds, setSeconds] = useState(
|
||||
params.value.seconds?.toString() ?? "30"
|
||||
params.gymSet.seconds?.toString() ?? "30"
|
||||
);
|
||||
const [sets, setSets] = useState(params.value.sets?.toString() ?? "3");
|
||||
const [sets, setSets] = useState(params.gymSet.sets?.toString() ?? "3");
|
||||
const navigation = useNavigation();
|
||||
const setsRef = useRef<TextInput>(null);
|
||||
const stepsRef = useRef<TextInput>(null);
|
||||
|
@ -48,9 +48,9 @@ export default function EditWorkout() {
|
|||
|
||||
const update = async () => {
|
||||
await setRepo.update(
|
||||
{ name: params.value.name },
|
||||
{ name: params.gymSet.name },
|
||||
{
|
||||
name: name || params.value.name,
|
||||
name: name || params.gymSet.name,
|
||||
sets: Number(sets),
|
||||
minutes: +minutes,
|
||||
seconds: +seconds,
|
||||
|
@ -62,7 +62,7 @@ export default function EditWorkout() {
|
|||
`UPDATE plans
|
||||
SET workouts = REPLACE(workouts, $1, $2)
|
||||
WHERE workouts LIKE $3`,
|
||||
[params.value.name, name, `%${params.value.name}%`]
|
||||
[params.gymSet.name, name, `%${params.gymSet.name}%`]
|
||||
);
|
||||
navigation.goBack();
|
||||
};
|
||||
|
@ -84,7 +84,7 @@ export default function EditWorkout() {
|
|||
};
|
||||
|
||||
const save = async () => {
|
||||
if (params.value.name) return update();
|
||||
if (params.gymSet.name) return update();
|
||||
return add();
|
||||
};
|
||||
|
||||
|
@ -109,7 +109,9 @@ export default function EditWorkout() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<StackHeader title={params.value.name ? "Edit workout" : "Add workout"} />
|
||||
<StackHeader
|
||||
title={params.gymSet.name ? "Edit workout" : "Add workout"}
|
||||
/>
|
||||
<View style={{ padding: PADDING, flex: 1 }}>
|
||||
<ScrollView style={{ flex: 1 }}>
|
||||
<AppInput
|
||||
|
|
223
EditWorkouts.tsx
Normal file
223
EditWorkouts.tsx
Normal file
|
@ -0,0 +1,223 @@
|
|||
import {
|
||||
RouteProp,
|
||||
useFocusEffect,
|
||||
useNavigation,
|
||||
useRoute,
|
||||
} from "@react-navigation/native";
|
||||
import { useCallback, useRef, useState } from "react";
|
||||
import { ScrollView, TextInput, View } from "react-native";
|
||||
import DocumentPicker from "react-native-document-picker";
|
||||
import { Button, Card, TouchableRipple } from "react-native-paper";
|
||||
import { In } from "typeorm";
|
||||
import AppInput from "./AppInput";
|
||||
import ConfirmDialog from "./ConfirmDialog";
|
||||
import { MARGIN, PADDING } from "./constants";
|
||||
import { getNow, planRepo, setRepo, settingsRepo } from "./db";
|
||||
import { fixNumeric } from "./fix-numeric";
|
||||
import { defaultSet } from "./gym-set";
|
||||
import Settings from "./settings";
|
||||
import StackHeader from "./StackHeader";
|
||||
import { toast } from "./toast";
|
||||
import { WorkoutsPageParams } from "./WorkoutsPage";
|
||||
|
||||
export default function EditWorkouts() {
|
||||
const { params } = useRoute<RouteProp<WorkoutsPageParams, "EditWorkouts">>();
|
||||
const [removeImage, setRemoveImage] = useState(false);
|
||||
const [showRemove, setShowRemove] = useState(false);
|
||||
const [name, setName] = useState("");
|
||||
const [oldNames, setOldNames] = useState(params.names.join(", "));
|
||||
const [steps, setSteps] = useState("");
|
||||
const [oldSteps, setOldSteps] = useState("");
|
||||
const [uri, setUri] = useState("");
|
||||
const [oldUri, setOldUri] = useState("");
|
||||
const [minutes, setMinutes] = useState("");
|
||||
const [oldMinutes, setOldMinutes] = useState("");
|
||||
const [seconds, setSeconds] = useState("");
|
||||
const [oldSeconds, setOldSeconds] = useState("");
|
||||
const [sets, setSets] = useState("");
|
||||
const [oldSets, setOldSets] = useState("");
|
||||
const navigation = useNavigation();
|
||||
const setsRef = useRef<TextInput>(null);
|
||||
const stepsRef = useRef<TextInput>(null);
|
||||
const minutesRef = useRef<TextInput>(null);
|
||||
const secondsRef = useRef<TextInput>(null);
|
||||
const [settings, setSettings] = useState<Settings>();
|
||||
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
settingsRepo.findOne({ where: {} }).then(setSettings);
|
||||
setRepo
|
||||
.createQueryBuilder()
|
||||
.select()
|
||||
.where("name IN (:...names)", { names: params.names })
|
||||
.groupBy("name")
|
||||
.getMany()
|
||||
.then((gymSets) => {
|
||||
console.log({ gymSets });
|
||||
setOldNames(gymSets.map((set) => set.name).join(", "));
|
||||
setOldSteps(gymSets.map((set) => set.steps).join(", "));
|
||||
setOldUri(gymSets.map((set) => set.steps).join(", "));
|
||||
});
|
||||
}, [params.names])
|
||||
);
|
||||
|
||||
const update = async () => {
|
||||
await setRepo.update(
|
||||
{ name: In(params.names) },
|
||||
{
|
||||
name: name || undefined,
|
||||
sets: sets ? Number(sets) : undefined,
|
||||
minutes: minutes ? Number(minutes) : undefined,
|
||||
seconds: seconds ? Number(seconds) : undefined,
|
||||
steps: steps || undefined,
|
||||
image: removeImage ? "" : uri,
|
||||
}
|
||||
);
|
||||
await planRepo
|
||||
.createQueryBuilder()
|
||||
.update()
|
||||
.set({
|
||||
workouts: () => `REPLACE(workouts, '${params.gymSet.name}', '${name}')`,
|
||||
})
|
||||
.where("workouts LIKE :name", { name: `%${params.gymSet.name}%` })
|
||||
.execute();
|
||||
navigation.goBack();
|
||||
};
|
||||
|
||||
const add = async () => {
|
||||
const now = await getNow();
|
||||
await setRepo.save({
|
||||
...defaultSet,
|
||||
name,
|
||||
hidden: true,
|
||||
image: uri,
|
||||
minutes: minutes ? +minutes : 3,
|
||||
seconds: seconds ? +seconds : 30,
|
||||
sets: sets ? +sets : 3,
|
||||
steps,
|
||||
created: now,
|
||||
});
|
||||
navigation.goBack();
|
||||
};
|
||||
|
||||
const save = async () => {
|
||||
if (params.gymSet.name) return update();
|
||||
return add();
|
||||
};
|
||||
|
||||
const changeImage = useCallback(async () => {
|
||||
const { fileCopyUri } = await DocumentPicker.pickSingle({
|
||||
type: DocumentPicker.types.images,
|
||||
copyTo: "documentDirectory",
|
||||
});
|
||||
if (fileCopyUri) setUri(fileCopyUri);
|
||||
}, []);
|
||||
|
||||
const handleRemove = useCallback(async () => {
|
||||
setUri("");
|
||||
setRemoveImage(true);
|
||||
setShowRemove(false);
|
||||
}, []);
|
||||
|
||||
const submitName = () => {
|
||||
if (settings.steps) stepsRef.current?.focus();
|
||||
else setsRef.current?.focus();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<StackHeader
|
||||
title={params.gymSet.name ? "Edit workout" : "Add workout"}
|
||||
/>
|
||||
<View style={{ padding: PADDING, flex: 1 }}>
|
||||
<ScrollView style={{ flex: 1 }}>
|
||||
<AppInput
|
||||
autoFocus
|
||||
label="Name"
|
||||
value={name}
|
||||
onChangeText={setName}
|
||||
onSubmitEditing={submitName}
|
||||
/>
|
||||
{settings?.steps && (
|
||||
<AppInput
|
||||
innerRef={stepsRef}
|
||||
selectTextOnFocus={false}
|
||||
value={steps}
|
||||
onChangeText={setSteps}
|
||||
label="Steps"
|
||||
multiline
|
||||
onSubmitEditing={() => setsRef.current?.focus()}
|
||||
/>
|
||||
)}
|
||||
<AppInput
|
||||
innerRef={setsRef}
|
||||
value={sets}
|
||||
onChangeText={(newSets) => {
|
||||
const fixed = fixNumeric(newSets);
|
||||
setSets(fixed);
|
||||
if (fixed.length !== newSets.length)
|
||||
toast("Sets must be a number");
|
||||
}}
|
||||
label="Sets per workout"
|
||||
keyboardType="numeric"
|
||||
onSubmitEditing={() => minutesRef.current?.focus()}
|
||||
/>
|
||||
{settings?.alarm && (
|
||||
<>
|
||||
<AppInput
|
||||
innerRef={minutesRef}
|
||||
onSubmitEditing={() => secondsRef.current?.focus()}
|
||||
value={minutes}
|
||||
onChangeText={(newMinutes) => {
|
||||
const fixed = fixNumeric(newMinutes);
|
||||
setMinutes(fixed);
|
||||
if (fixed.length !== newMinutes.length)
|
||||
toast("Reps must be a number");
|
||||
}}
|
||||
label="Rest minutes"
|
||||
keyboardType="numeric"
|
||||
/>
|
||||
<AppInput
|
||||
innerRef={secondsRef}
|
||||
value={seconds}
|
||||
onChangeText={setSeconds}
|
||||
label="Rest seconds"
|
||||
keyboardType="numeric"
|
||||
blurOnSubmit
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{settings?.images && uri && (
|
||||
<TouchableRipple
|
||||
style={{ marginBottom: MARGIN }}
|
||||
onPress={changeImage}
|
||||
onLongPress={() => setShowRemove(true)}
|
||||
>
|
||||
<Card.Cover source={{ uri }} />
|
||||
</TouchableRipple>
|
||||
)}
|
||||
{settings?.images && !uri && (
|
||||
<Button
|
||||
style={{ marginBottom: MARGIN }}
|
||||
onPress={changeImage}
|
||||
icon="add-photo-alternate"
|
||||
>
|
||||
Image
|
||||
</Button>
|
||||
)}
|
||||
</ScrollView>
|
||||
<Button disabled={!name} mode="outlined" icon="save" onPress={save}>
|
||||
Save
|
||||
</Button>
|
||||
<ConfirmDialog
|
||||
title="Remove image"
|
||||
onOk={handleRemove}
|
||||
show={showRemove}
|
||||
setShow={setShowRemove}
|
||||
>
|
||||
Are you sure you want to remove the image?
|
||||
</ConfirmDialog>
|
||||
</View>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -11,11 +11,11 @@ export default function ListMenu({
|
|||
ids,
|
||||
}: {
|
||||
onEdit: () => void;
|
||||
onCopy: () => void;
|
||||
onCopy?: () => void;
|
||||
onClear: () => void;
|
||||
onDelete: () => void;
|
||||
onSelect: () => void;
|
||||
ids?: number[];
|
||||
ids?: unknown[];
|
||||
}) {
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
const [showRemove, setShowRemove] = useState(false);
|
||||
|
@ -64,12 +64,14 @@ export default function ListMenu({
|
|||
onPress={edit}
|
||||
disabled={ids?.length === 0}
|
||||
/>
|
||||
{onCopy && (
|
||||
<Menu.Item
|
||||
leadingIcon="content-copy"
|
||||
title="Copy"
|
||||
onPress={copy}
|
||||
disabled={ids?.length === 0}
|
||||
/>
|
||||
)}
|
||||
<Divider />
|
||||
<Menu.Item
|
||||
leadingIcon="delete"
|
||||
|
|
|
@ -16,7 +16,6 @@ export default function SetItem({
|
|||
setIds,
|
||||
}: {
|
||||
item: GymSet;
|
||||
onRemove: () => void;
|
||||
settings: Settings;
|
||||
ids: number[];
|
||||
setIds: (value: number[]) => void;
|
||||
|
|
|
@ -52,12 +52,11 @@ export default function SetList() {
|
|||
settings={settings}
|
||||
item={item}
|
||||
key={item.id}
|
||||
onRemove={() => refresh(term)}
|
||||
ids={ids}
|
||||
setIds={setIds}
|
||||
/>
|
||||
),
|
||||
[refresh, term, settings, ids]
|
||||
[settings, ids]
|
||||
);
|
||||
|
||||
const next = useCallback(async () => {
|
||||
|
|
|
@ -1,39 +1,26 @@
|
|||
import { NavigationProp, useNavigation } from "@react-navigation/native";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
import { GestureResponderEvent, Image } from "react-native";
|
||||
import { List, Menu, Text } from "react-native-paper";
|
||||
import ConfirmDialog from "./ConfirmDialog";
|
||||
import { setRepo } from "./db";
|
||||
import { useCallback, useMemo } from "react";
|
||||
import { Image } from "react-native";
|
||||
import { List } from "react-native-paper";
|
||||
import { DARK_RIPPLE } from "./constants";
|
||||
import { LIGHT_RIPPLE } from "./constants";
|
||||
import GymSet from "./gym-set";
|
||||
import useDark from "./use-dark";
|
||||
import { WorkoutsPageParams } from "./WorkoutsPage";
|
||||
|
||||
export default function WorkoutItem({
|
||||
item,
|
||||
onRemove,
|
||||
setNames,
|
||||
names,
|
||||
images,
|
||||
}: {
|
||||
item: GymSet;
|
||||
onRemove: () => void;
|
||||
images: boolean;
|
||||
setNames: (value: string[]) => void;
|
||||
names: string[];
|
||||
}) {
|
||||
const [showMenu, setShowMenu] = useState(false);
|
||||
const [anchor, setAnchor] = useState({ x: 0, y: 0 });
|
||||
const [showRemove, setShowRemove] = useState("");
|
||||
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>();
|
||||
|
||||
const remove = useCallback(async () => {
|
||||
await setRepo.delete({ name: item.name });
|
||||
setShowMenu(false);
|
||||
onRemove();
|
||||
}, [setShowMenu, onRemove, item.name]);
|
||||
|
||||
const longPress = useCallback(
|
||||
(e: GestureResponderEvent) => {
|
||||
setAnchor({ x: e.nativeEvent.pageX, y: e.nativeEvent.pageY });
|
||||
setShowMenu(true);
|
||||
},
|
||||
[setShowMenu, setAnchor]
|
||||
);
|
||||
const dark = useDark();
|
||||
|
||||
const description = useMemo(() => {
|
||||
const seconds = item.seconds?.toString().padStart(2, "0");
|
||||
|
@ -47,50 +34,33 @@ export default function WorkoutItem({
|
|||
);
|
||||
}, [item.image, images]);
|
||||
|
||||
const right = useCallback(() => {
|
||||
return (
|
||||
<Text
|
||||
style={{
|
||||
alignSelf: "center",
|
||||
}}
|
||||
>
|
||||
<Menu
|
||||
anchor={anchor}
|
||||
visible={showMenu}
|
||||
onDismiss={() => setShowMenu(false)}
|
||||
>
|
||||
<Menu.Item
|
||||
leadingIcon="delete"
|
||||
onPress={() => {
|
||||
setShowRemove(item.name);
|
||||
setShowMenu(false);
|
||||
}}
|
||||
title="Delete"
|
||||
/>
|
||||
</Menu>
|
||||
</Text>
|
||||
);
|
||||
}, [anchor, showMenu, item.name]);
|
||||
const long = useCallback(() => {
|
||||
if (names.length > 0) return;
|
||||
setNames([item.name]);
|
||||
}, [names.length, item.name, setNames]);
|
||||
|
||||
const backgroundColor = useMemo(() => {
|
||||
if (!names.includes(item.name)) return;
|
||||
if (dark) return DARK_RIPPLE;
|
||||
return LIGHT_RIPPLE;
|
||||
}, [dark, names, item.name]);
|
||||
|
||||
const press = useCallback(() => {
|
||||
if (names.length === 0)
|
||||
return navigation.navigate("EditWorkout", { gymSet: item });
|
||||
const removing = names.find((name) => name === item.name);
|
||||
if (removing) setNames(names.filter((name) => name !== item.name));
|
||||
else setNames([...names, item.name]);
|
||||
}, [names, item, navigation, setNames]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<List.Item
|
||||
onPress={() => navigation.navigate("EditWorkout", { value: item })}
|
||||
onPress={press}
|
||||
title={item.name}
|
||||
description={description}
|
||||
onLongPress={longPress}
|
||||
onLongPress={long}
|
||||
left={left}
|
||||
right={right}
|
||||
style={{ backgroundColor }}
|
||||
/>
|
||||
<ConfirmDialog
|
||||
title={`Delete ${showRemove}`}
|
||||
show={!!showRemove}
|
||||
setShow={(show) => (show ? null : setShowRemove(""))}
|
||||
onOk={remove}
|
||||
>
|
||||
This irreversibly deletes ALL sets related to this workout. Are you
|
||||
sure?
|
||||
</ConfirmDialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import { LIMIT } from "./constants";
|
|||
import { setRepo, settingsRepo } from "./db";
|
||||
import DrawerHeader from "./DrawerHeader";
|
||||
import GymSet from "./gym-set";
|
||||
import ListMenu from "./ListMenu";
|
||||
import Page from "./Page";
|
||||
import SetList from "./SetList";
|
||||
import Settings from "./settings";
|
||||
|
@ -22,6 +23,7 @@ export default function WorkoutList() {
|
|||
const [term, setTerm] = useState("");
|
||||
const [end, setEnd] = useState(false);
|
||||
const [settings, setSettings] = useState<Settings>();
|
||||
const [names, setNames] = useState<string[]>([]);
|
||||
const navigation = useNavigation<NavigationProp<WorkoutsPageParams>>();
|
||||
|
||||
const refresh = useCallback(async (value: string) => {
|
||||
|
@ -52,13 +54,14 @@ export default function WorkoutList() {
|
|||
images={settings?.images}
|
||||
item={item}
|
||||
key={item.name}
|
||||
onRemove={() => refresh(term)}
|
||||
names={names}
|
||||
setNames={setNames}
|
||||
/>
|
||||
),
|
||||
[refresh, term, settings?.images]
|
||||
[settings?.images, names]
|
||||
);
|
||||
|
||||
const next = useCallback(async () => {
|
||||
const next = async () => {
|
||||
if (end) return;
|
||||
const newOffset = offset + LIMIT;
|
||||
console.log(`${SetList.name}.next:`, {
|
||||
|
@ -81,11 +84,11 @@ export default function WorkoutList() {
|
|||
setWorkouts([...workouts, ...newWorkouts]);
|
||||
if (newWorkouts.length < LIMIT) return setEnd(true);
|
||||
setOffset(newOffset);
|
||||
}, [term, end, offset, workouts]);
|
||||
};
|
||||
|
||||
const onAdd = useCallback(async () => {
|
||||
navigation.navigate("EditWorkout", {
|
||||
value: new GymSet(),
|
||||
gymSet: new GymSet(),
|
||||
});
|
||||
}, [navigation]);
|
||||
|
||||
|
@ -97,9 +100,33 @@ export default function WorkoutList() {
|
|||
[refresh]
|
||||
);
|
||||
|
||||
const clear = useCallback(() => {
|
||||
setNames([]);
|
||||
}, []);
|
||||
|
||||
const remove = async () => {
|
||||
setNames([]);
|
||||
await setRepo.delete(names.length > 0 ? names : {});
|
||||
await refresh(term);
|
||||
};
|
||||
|
||||
const select = () => {
|
||||
setNames(workouts.map((workout) => workout.name));
|
||||
};
|
||||
|
||||
const edit = useCallback(() => {}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<DrawerHeader name="Workouts" />
|
||||
<DrawerHeader name="Workouts">
|
||||
<ListMenu
|
||||
onClear={clear}
|
||||
onDelete={remove}
|
||||
onEdit={edit}
|
||||
ids={names}
|
||||
onSelect={select}
|
||||
/>
|
||||
</DrawerHeader>
|
||||
<Page onAdd={onAdd} term={term} search={search}>
|
||||
{workouts?.length === 0 ? (
|
||||
<List.Item
|
||||
|
|
|
@ -6,7 +6,10 @@ import WorkoutList from "./WorkoutList";
|
|||
export type WorkoutsPageParams = {
|
||||
WorkoutList: {};
|
||||
EditWorkout: {
|
||||
value: GymSet;
|
||||
gymSet: GymSet;
|
||||
};
|
||||
EditWorkouts: {
|
||||
names: string[];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { createStackNavigator } from '@react-navigation/stack'
|
||||
import React from 'react'
|
||||
import 'react-native'
|
||||
import { render, waitFor } from '@testing-library/react-native'
|
||||
import EditWorkout from '../EditWorkout'
|
||||
import GymSet from '../gym-set'
|
||||
import { MockProviders } from '../mock-providers'
|
||||
import Settings from '../settings'
|
||||
import { WorkoutsPageParams } from '../WorkoutsPage'
|
||||
import { createStackNavigator } from "@react-navigation/stack";
|
||||
import React from "react";
|
||||
import "react-native";
|
||||
import { render, waitFor } from "@testing-library/react-native";
|
||||
import EditWorkout from "../EditWorkout";
|
||||
import GymSet from "../gym-set";
|
||||
import { MockProviders } from "../mock-providers";
|
||||
import Settings from "../settings";
|
||||
import { WorkoutsPageParams } from "../WorkoutsPage";
|
||||
|
||||
jest.mock('../db.ts', () => ({
|
||||
jest.mock("../db.ts", () => ({
|
||||
settingsRepo: {
|
||||
findOne: () =>
|
||||
Promise.resolve({
|
||||
|
@ -16,28 +16,28 @@ jest.mock('../db.ts', () => ({
|
|||
alarm: true,
|
||||
} as Settings),
|
||||
},
|
||||
}))
|
||||
}));
|
||||
|
||||
test('renders correctly', async () => {
|
||||
const Stack = createStackNavigator<WorkoutsPageParams>()
|
||||
test("renders correctly", async () => {
|
||||
const Stack = createStackNavigator<WorkoutsPageParams>();
|
||||
const { getByText, getAllByText } = render(
|
||||
<MockProviders>
|
||||
<Stack.Navigator>
|
||||
<Stack.Screen
|
||||
initialParams={{
|
||||
value: { name: 'Bench press' } as GymSet,
|
||||
gymSet: { name: "Bench press" } as GymSet,
|
||||
}}
|
||||
name='EditWorkout'
|
||||
name="EditWorkout"
|
||||
component={EditWorkout}
|
||||
/>
|
||||
</Stack.Navigator>
|
||||
</MockProviders>,
|
||||
)
|
||||
const title = await waitFor(() => getByText(/Edit workout/i))
|
||||
expect(title).toBeDefined()
|
||||
expect(getAllByText(/Name/i).length).toBeGreaterThan(0)
|
||||
expect(getAllByText(/Sets/i).length).toBeGreaterThan(0)
|
||||
expect(getAllByText(/Minutes/i).length).toBeGreaterThan(0)
|
||||
expect(getAllByText(/Seconds/i).length).toBeGreaterThan(0)
|
||||
expect(getAllByText(/Save/i).length).toBeGreaterThan(0)
|
||||
})
|
||||
</MockProviders>
|
||||
);
|
||||
const title = await waitFor(() => getByText(/Edit workout/i));
|
||||
expect(title).toBeDefined();
|
||||
expect(getAllByText(/Name/i).length).toBeGreaterThan(0);
|
||||
expect(getAllByText(/Sets/i).length).toBeGreaterThan(0);
|
||||
expect(getAllByText(/Minutes/i).length).toBeGreaterThan(0);
|
||||
expect(getAllByText(/Seconds/i).length).toBeGreaterThan(0);
|
||||
expect(getAllByText(/Save/i).length).toBeGreaterThan(0);
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user