diff --git a/.eslintrc.js b/.eslintrc.js
index f45636d57..4c79c9337 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -55,6 +55,7 @@ module.exports = {
],
'prefer-destructuring': ['error', { array: false }],
'prefer-object-spread': 'error',
+ 'no-console': 'error',
'react/function-component-definition': [
'error',
diff --git a/assets/images/index.ts b/assets/images/index.ts
index fd525776a..ef188ebca 100644
--- a/assets/images/index.ts
+++ b/assets/images/index.ts
@@ -64,9 +64,10 @@ import StarCircleIconGrey from './star-circle-icon-grey.svg'
import StarIconGreyFilled from './star-icon-grey-filled.svg'
import StarIconGrey from './star-icon-grey.svg'
import StarIconWhite from './star-icon-white.svg'
+import ThumbsDownIcon from './thumbs-down.svg'
+import ThumbsUpIcon from './thumbs-up.svg'
import TrashIconWhite from './trash-bin-icon-white.svg'
import TrashIcon from './trash-bin-icon.svg'
-import TrophyIcon from './trophy-icon.svg'
import VolumeUpCircleIcon from './volume-up-circle-icon.svg'
export {
@@ -138,6 +139,7 @@ export {
StarIconWhite,
TrashIcon,
TrashIconWhite,
- TrophyIcon,
VolumeUpCircleIcon,
+ ThumbsUpIcon,
+ ThumbsDownIcon,
}
diff --git a/assets/images/thumbs-down.svg b/assets/images/thumbs-down.svg
new file mode 100644
index 000000000..1b00be3c4
--- /dev/null
+++ b/assets/images/thumbs-down.svg
@@ -0,0 +1,7 @@
+
diff --git a/assets/images/thumbs-up.svg b/assets/images/thumbs-up.svg
new file mode 100644
index 000000000..10785c304
--- /dev/null
+++ b/assets/images/thumbs-up.svg
@@ -0,0 +1,6 @@
+
diff --git a/assets/images/trophy-icon.svg b/assets/images/trophy-icon.svg
deleted file mode 100644
index e13fb4b65..000000000
--- a/assets/images/trophy-icon.svg
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
diff --git a/release-notes/unreleased/LUN-407-add-evaluation-of-levels.yml b/release-notes/unreleased/LUN-407-add-evaluation-of-levels.yml
new file mode 100644
index 000000000..2fb37e16c
--- /dev/null
+++ b/release-notes/unreleased/LUN-407-add-evaluation-of-levels.yml
@@ -0,0 +1,6 @@
+issue_key: LUN-407
+show_in_stores: true
+platforms:
+ - android
+ - ios
+de: Zeige Feedback zu bereits abgeschlossenen Leveln
diff --git a/src/components/AudioPlayer.tsx b/src/components/AudioPlayer.tsx
index 120cedbe2..99f987c4a 100644
--- a/src/components/AudioPlayer.tsx
+++ b/src/components/AudioPlayer.tsx
@@ -54,8 +54,10 @@ const AudioPlayer = ({ document, disabled, submittedAlternative }: AudioPlayerPr
}
})
.catch(async (error: TtsError) => {
+ /* eslint-disable-next-line no-console */
console.error(`Tts-Error: ${error.code}`)
if (error.code === 'no_engine') {
+ /* eslint-disable-next-line no-console */
await Tts.requestInstallEngine().catch(e => console.error('Failed to install tts engine: ', e))
}
})
diff --git a/src/components/ErrorMessage.tsx b/src/components/ErrorMessage.tsx
index dffe9504c..6c1cbc8d3 100644
--- a/src/components/ErrorMessage.tsx
+++ b/src/components/ErrorMessage.tsx
@@ -65,7 +65,7 @@ const ErrorMessage = ({ error, refresh, contained }: ErrorMessageProps): JSX.Ele
return (
-
+
{error.message === NetworkError && (
diff --git a/src/components/FeedbackBadge.tsx b/src/components/FeedbackBadge.tsx
new file mode 100644
index 000000000..518137e4c
--- /dev/null
+++ b/src/components/FeedbackBadge.tsx
@@ -0,0 +1,58 @@
+import React, { ReactElement } from 'react'
+import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-native-responsive-screen'
+import styled from 'styled-components/native'
+
+import { ThumbsDownIcon, ThumbsUpIcon } from '../../assets/images'
+import { EXERCISE_FEEDBACK } from '../constants/data'
+import { getLabels } from '../services/helpers'
+import { ContentSecondaryLight } from './text/Content'
+
+const BadgeContainer = styled.View`
+ display: flex;
+ flex-flow: row nowrap;
+ padding: ${props => props.theme.spacings.xxs} ${props => props.theme.spacings.sm};
+ background-color: ${props => props.theme.colors.lightGreyBackground};
+ width: 100%;
+`
+const BadgeText = styled(ContentSecondaryLight)`
+ font-style: italic;
+ margin-left: ${props => props.theme.spacings.xs};
+ align-self: center;
+`
+
+const BadgeIcon = styled.View`
+ height: ${hp('3.5%')}px;
+ max-height: ${wp('5%')}px;
+`
+
+interface FeedbackBadgeProps {
+ feedback: EXERCISE_FEEDBACK
+}
+
+const FeedbackBadge = ({ feedback }: FeedbackBadgeProps): ReactElement | null => {
+ const { positive, negative } = { ...getLabels().exercises.feedback }
+ if (feedback === EXERCISE_FEEDBACK.POSITIVE) {
+ return (
+
+
+
+
+ {positive}
+
+ )
+ }
+
+ if (feedback === EXERCISE_FEEDBACK.NEGATIVE) {
+ return (
+
+
+
+
+ {negative}
+
+ )
+ }
+
+ return null
+}
+export default FeedbackBadge
diff --git a/src/components/ListItem.tsx b/src/components/ListItem.tsx
index 26f50cf04..d47a6d5ad 100644
--- a/src/components/ListItem.tsx
+++ b/src/components/ListItem.tsx
@@ -4,28 +4,59 @@ import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-nat
import styled, { useTheme } from 'styled-components/native'
import { ChevronRight } from '../../assets/images'
+import { EXERCISE_FEEDBACK } from '../constants/data'
+import FeedbackBadge from './FeedbackBadge'
import { ContentSecondaryLight } from './text/Content'
export const GenericListItemContainer = styled.Pressable`
margin-bottom: ${props => props.theme.spacings.xxs};
- align-self: center;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-radius: 2px;
`
-
-const Container = styled(GenericListItemContainer)<{ pressed: boolean; disabled: boolean }>`
+const Container = styled(GenericListItemContainer)<{
+ pressed: boolean
+ disabled: boolean
+ feedback: EXERCISE_FEEDBACK
+}>`
min-height: ${hp('12%')}px;
+ justify-content: center;
+ flex-direction: column;
+ border-top-width: 1px;
+ border-top-color: ${prop => (prop.pressed ? prop.theme.colors.primary : prop.theme.colors.disabled)};
+ border-right-width: 1px;
+ border-right-color: ${prop => (prop.pressed ? prop.theme.colors.primary : prop.theme.colors.disabled)};
+ border-bottom-width: 1px;
+ border-bottom-color: ${prop => (prop.pressed ? prop.theme.colors.primary : prop.theme.colors.disabled)};
+ border-left-color: ${props => {
+ if (props.feedback === EXERCISE_FEEDBACK.POSITIVE) {
+ return props.theme.colors.correct
+ }
+ if (props.feedback === EXERCISE_FEEDBACK.NEGATIVE) {
+ return props.theme.colors.incorrect
+ }
+ if (props.pressed) {
+ return props.theme.colors.primary
+ }
+ return props.theme.colors.disabled
+ }};
+ border-left-radius: 0;
+ border-left-width: ${props => (props.feedback !== EXERCISE_FEEDBACK.NONE ? '4px' : '1px')};
background-color: ${prop => {
if (prop.disabled) {
return prop.theme.colors.disabled
}
return prop.pressed ? prop.theme.colors.primary : prop.theme.colors.backgroundAccent
}};
- border: 1px solid ${prop => (prop.pressed ? prop.theme.colors.primary : prop.theme.colors.disabled)};
+`
+
+const ContentContainer = styled.View<{ pressed: boolean; disabled: boolean }>`
+ display: flex;
+ flex-direction: row;
padding: ${props =>
`${props.theme.spacings.sm} ${props.theme.spacings.xs} ${props.theme.spacings.sm} ${props.theme.spacings.sm}`};
+ align-items: center;
`
const Title = styled.Text<{ pressed: boolean }>`
@@ -87,6 +118,7 @@ interface ListItemProps {
hideRightChildren?: boolean
arrowDisabled?: boolean
disabled?: boolean
+ feedback?: EXERCISE_FEEDBACK
}
const ListItem = ({
@@ -100,6 +132,7 @@ const ListItem = ({
hideRightChildren = false,
arrowDisabled = false,
disabled = false,
+ feedback = EXERCISE_FEEDBACK.NONE,
}: ListItemProps): ReactElement => {
const [pressInY, setPressInY] = useState(null)
const [pressed, setPressed] = useState(false)
@@ -160,17 +193,21 @@ const ListItem = ({
onLongPress={() => updatePressed(true)}
pressed={pressed}
delayLongPress={200}
+ feedback={feedback}
testID='list-item'>
- {iconToRender}
-
- {titleToRender}
-
- {badgeLabel && {badgeLabel}}
- {description && description.length > 0 && {description}}
-
- {children}
-
- {rightChildrenToRender}
+
+
+ {iconToRender}
+
+ {titleToRender}
+
+ {badgeLabel && {badgeLabel}}
+ {description && description.length > 0 && {description}}
+
+ {children}
+
+ {rightChildrenToRender}
+
)
}
diff --git a/src/components/NotAuthorisedView.tsx b/src/components/NotAuthorisedView.tsx
index 78ee673b4..08230a12f 100644
--- a/src/components/NotAuthorisedView.tsx
+++ b/src/components/NotAuthorisedView.tsx
@@ -6,6 +6,7 @@ import { BUTTONS_THEME } from '../constants/data'
import { getLabels } from '../services/helpers'
import Button from './Button'
import { ContentSecondary } from './text/Content'
+import { reportError } from '../services/sentry'
const Container = styled.View`
display: flex;
@@ -25,7 +26,7 @@ interface Props {
const NotAuthorisedView = ({ setVisible }: Props): ReactElement => {
const openSettings = () => {
- Linking.openSettings().catch(() => console.error('Unable to open Settings'))
+ Linking.openSettings().catch(reportError)
}
return (
diff --git a/src/components/Trophy.tsx b/src/components/Trophy.tsx
deleted file mode 100644
index 6b6b0b84e..000000000
--- a/src/components/Trophy.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import React, { ReactElement } from 'react'
-import { heightPercentageToDP as hp, widthPercentageToDP as wp } from 'react-native-responsive-screen'
-import styled from 'styled-components/native'
-
-import { TrophyIcon } from '../../assets/images'
-
-const TrophyContainer = styled.View`
- margin-top: ${props => props.theme.spacings.xs};
- display: flex;
- flex-direction: row;
-`
-
-const TrophyIconStyled = styled(TrophyIcon)`
- margin-right: ${props => props.theme.spacings.xxs};
-`
-
-interface PropsType {
- level: number
-}
-
-const Trophy = ({ level }: PropsType): ReactElement => {
- const trophies = []
- for (let i = 0; i < level; i += 1) {
- trophies.push()
- }
- return {trophies}
-}
-
-export default Trophy
diff --git a/src/components/__tests__/FeedbackBadge.spec.tsx b/src/components/__tests__/FeedbackBadge.spec.tsx
new file mode 100644
index 000000000..e978ad025
--- /dev/null
+++ b/src/components/__tests__/FeedbackBadge.spec.tsx
@@ -0,0 +1,38 @@
+import { waitFor } from '@testing-library/react-native'
+import React from 'react'
+
+import { SCORE_THRESHOLD_POSITIVE_FEEDBACK, EXERCISE_FEEDBACK } from '../../constants/data'
+import { getLabels } from '../../services/helpers'
+import render from '../../testing/render'
+import FeedbackBadge from '../FeedbackBadge'
+
+describe('FeedbackBadge', () => {
+ beforeEach(() => {
+ jest.clearAllMocks()
+ })
+
+ const renderFeedbackBadge = (feedback: EXERCISE_FEEDBACK) => render()
+
+ it('should not show badge for no feedback', async () => {
+ const { queryByTestId } = renderFeedbackBadge(EXERCISE_FEEDBACK.NONE)
+
+ await waitFor(() => expect(queryByTestId('positive-badge')).toBeNull())
+ await waitFor(() => expect(queryByTestId('negative-badge')).toBeNull())
+ })
+
+ it('should show badge for positive feedback', async () => {
+ const { queryByText, queryByTestId } = renderFeedbackBadge(EXERCISE_FEEDBACK.POSITIVE)
+
+ await waitFor(() => expect(queryByTestId('negative-badge')).toBeNull())
+ await waitFor(() => expect(queryByTestId('positive-badge')).not.toBeNull())
+ await waitFor(() => expect(queryByText(getLabels().exercises.feedback.positive)).not.toBeNull())
+ })
+
+ it('should show badge for negative feedback', async () => {
+ const { queryByText, queryByTestId } = renderFeedbackBadge(EXERCISE_FEEDBACK.NEGATIVE)
+
+ await waitFor(() => expect(queryByTestId('positive-badge')).toBeNull())
+ await waitFor(() => expect(queryByTestId('negative-badge')).not.toBeNull())
+ await waitFor(() => expect(queryByText(getLabels().exercises.feedback.negative)).not.toBeNull())
+ })
+})
diff --git a/src/components/__tests__/ListItem.spec.tsx b/src/components/__tests__/ListItem.spec.tsx
index 12eff6ded..7210a083f 100644
--- a/src/components/__tests__/ListItem.spec.tsx
+++ b/src/components/__tests__/ListItem.spec.tsx
@@ -5,6 +5,7 @@ import { COLORS } from '../../constants/theme/colors'
import render from '../../testing/render'
import ListItem from '../ListItem'
+jest.mock('@react-navigation/native')
describe('ListItem', () => {
const onPress = jest.fn()
const description = 'Wörter'
diff --git a/src/components/__tests__/Trophy.spec.tsx b/src/components/__tests__/Trophy.spec.tsx
deleted file mode 100644
index 16d5a67ad..000000000
--- a/src/components/__tests__/Trophy.spec.tsx
+++ /dev/null
@@ -1,25 +0,0 @@
-import React from 'react'
-
-import renderWithTheme from '../../testing/render'
-import Trophy from '../Trophy'
-
-describe('Trophy', () => {
- it('should show no trophy when level is 0', () => {
- const { queryByTestId } = renderWithTheme()
- expect(queryByTestId('trophy-0')).toBeNull()
- })
-
- it('should show one trophy when level is 1', () => {
- const { queryByTestId } = renderWithTheme()
- expect(queryByTestId('trophy-0')).not.toBeNull()
- expect(queryByTestId('trophy-1')).toBeNull()
- })
-
- it('should show three trophies when level is 3', () => {
- const { queryByTestId } = renderWithTheme()
- expect(queryByTestId('trophy-0')).not.toBeNull()
- expect(queryByTestId('trophy-1')).not.toBeNull()
- expect(queryByTestId('trophy-2')).not.toBeNull()
- expect(queryByTestId('trophy-3')).toBeNull()
- })
-})
diff --git a/src/constants/data.ts b/src/constants/data.ts
index 25b56e315..38a449d02 100644
--- a/src/constants/data.ts
+++ b/src/constants/data.ts
@@ -166,3 +166,9 @@ export const numberOfMaxRetries = 3
export const SCORE_THRESHOLD_POSITIVE_FEEDBACK = 4
export const SCORE_THRESHOLD_UNLOCK = 2
+
+export const enum EXERCISE_FEEDBACK {
+ POSITIVE,
+ NONE,
+ NEGATIVE,
+}
diff --git a/src/constants/labels.json b/src/constants/labels.json
index 65e583140..13454d225 100644
--- a/src/constants/labels.json
+++ b/src/constants/labels.json
@@ -98,6 +98,10 @@
"cancelModal": {
"cancelAsk": "Möchtest du diese Übung wirklich beenden?",
"cancel": "Beenden"
+ },
+ "feedback": {
+ "positive": "Weiter so, das war super!",
+ "negative": "Das geht besser. Probier es nochmal."
}
},
"results": {
diff --git a/src/constants/theme/colors.ts b/src/constants/theme/colors.ts
index 4c38e5e28..d0e6f0b7d 100644
--- a/src/constants/theme/colors.ts
+++ b/src/constants/theme/colors.ts
@@ -22,7 +22,7 @@ export const COLORS = {
articleFeminine: '#faa7a7',
articleMasculine: '#8cc8f3',
link: 'blue',
- networkErrorBackground: '#e0e4ed',
+ lightGreyBackground: '#e0e4ed',
}
export type Color = typeof COLORS[keyof typeof COLORS]
diff --git a/src/routes/__tests__/VocabularyListScreen.spec.tsx b/src/routes/__tests__/VocabularyListScreen.spec.tsx
index 69e03752e..4f5a9e014 100644
--- a/src/routes/__tests__/VocabularyListScreen.spec.tsx
+++ b/src/routes/__tests__/VocabularyListScreen.spec.tsx
@@ -24,6 +24,8 @@ jest.mock('../../components/AudioPlayer', () => {
return () => AudioPlayer
})
+jest.mock('../../components/FeedbackBadge', () => () => null)
+
describe('VocabularyListScreen', () => {
const documents = new DocumentBuilder(2).build()
const route: RouteProp = {
diff --git a/src/routes/exercises/ExercisesScreen.tsx b/src/routes/exercises/ExercisesScreen.tsx
index aac37c605..9f5a0f09b 100644
--- a/src/routes/exercises/ExercisesScreen.tsx
+++ b/src/routes/exercises/ExercisesScreen.tsx
@@ -1,6 +1,6 @@
-import { CommonActions, RouteProp, useFocusEffect } from '@react-navigation/native'
+import { CommonActions, RouteProp, useIsFocused, useFocusEffect } from '@react-navigation/native'
import { StackNavigationProp } from '@react-navigation/stack'
-import React, { useCallback, useState } from 'react'
+import React, { useCallback, useEffect, useState } from 'react'
import { FlatList } from 'react-native'
import { widthPercentageToDP as wp } from 'react-native-responsive-screen'
import styled from 'styled-components/native'
@@ -10,11 +10,12 @@ import Modal from '../../components/Modal'
import RouteWrapper from '../../components/RouteWrapper'
import ServerResponseHandler from '../../components/ServerResponseHandler'
import Title from '../../components/Title'
-import Trophy from '../../components/Trophy'
import { ContentTextBold, ContentTextLight } from '../../components/text/Content'
-import { Exercise, EXERCISES } from '../../constants/data'
+import { Exercise, EXERCISES, SCORE_THRESHOLD_POSITIVE_FEEDBACK, EXERCISE_FEEDBACK } from '../../constants/data'
+import { useLoadAsync } from '../../hooks/useLoadAsync'
import useLoadDocuments from '../../hooks/useLoadDocuments'
import { RoutesParams } from '../../navigation/NavigationTypes'
+import { getExerciseProgress } from '../../services/AsyncStorage'
import { getLabels, getDoneExercises, wordsDescription } from '../../services/helpers'
import { reportError } from '../../services/sentry'
import LockingLane from './components/LockingLane'
@@ -22,6 +23,7 @@ import LockingLane from './components/LockingLane'
const Container = styled.View`
display: flex;
flex-direction: row;
+ align-items: center;
`
const ListItemResizer = styled.View`
@@ -42,7 +44,10 @@ const ExercisesScreen = ({ route, navigation }: ExercisesScreenProps): JSX.Eleme
const { discipline, disciplineTitle, disciplineId } = route.params
const [isModalVisible, setIsModalVisible] = useState(false)
const [nextExercise, setNextExercise] = useState(EXERCISES[0])
-
+ const [feedback, setFeedback] = useState([])
+ const [isFeedbackSet, setIsFeedbackSet] = useState(false)
+ const { data: scores, loading: loadingFeedback, refresh: refreshFeedback } = useLoadAsync(getExerciseProgress, null)
+ const isFocused = useIsFocused()
const {
data: documents,
error,
@@ -53,6 +58,21 @@ const ExercisesScreen = ({ route, navigation }: ExercisesScreenProps): JSX.Eleme
apiKey: discipline.apiKey,
})
+ useEffect(() => {
+ if (!loadingFeedback && !isFeedbackSet) {
+ const exerciseScores = scores?.[disciplineId] ?? {}
+ const updatedFeedback: EXERCISE_FEEDBACK[] = Object.values(exerciseScores).map(score => {
+ if (!score) {
+ return EXERCISE_FEEDBACK.NONE
+ }
+ return score > SCORE_THRESHOLD_POSITIVE_FEEDBACK ? EXERCISE_FEEDBACK.POSITIVE : EXERCISE_FEEDBACK.NEGATIVE
+ })
+ updatedFeedback[0] = EXERCISE_FEEDBACK.NONE
+ setFeedback(updatedFeedback)
+ setIsFeedbackSet(true)
+ }
+ }, [loadingFeedback, isFeedbackSet, disciplineId, scores])
+
useFocusEffect(
useCallback(() => {
getDoneExercises(disciplineId)
@@ -61,6 +81,13 @@ const ExercisesScreen = ({ route, navigation }: ExercisesScreenProps): JSX.Eleme
}, [disciplineId])
)
+ useEffect(() => {
+ if (isFocused) {
+ refreshFeedback()
+ setIsFeedbackSet(false)
+ }
+ }, [isFocused, refreshFeedback])
+
const handleNavigation = (item: Exercise): void => {
if (nextExercise && item.level > nextExercise.level) {
setIsModalVisible(true)
@@ -90,9 +117,9 @@ const ExercisesScreen = ({ route, navigation }: ExercisesScreenProps): JSX.Eleme
title={item.title}
description={item.description}
onPress={() => handleNavigation(item)}
- arrowDisabled={nextExercise === null || item.level > nextExercise.level}>
-
-
+ arrowDisabled={nextExercise === null || item.level > nextExercise.level}
+ feedback={feedback[item.level] ?? EXERCISE_FEEDBACK.NONE}
+ />
)
diff --git a/src/routes/exercises/__tests__/ExercisesScreen.spec.tsx b/src/routes/exercises/__tests__/ExercisesScreen.spec.tsx
index 68d076575..5056a64af 100644
--- a/src/routes/exercises/__tests__/ExercisesScreen.spec.tsx
+++ b/src/routes/exercises/__tests__/ExercisesScreen.spec.tsx
@@ -1,16 +1,17 @@
import RNAsyncStorage from '@react-native-async-storage/async-storage'
import { RouteProp } from '@react-navigation/native'
-import { fireEvent } from '@testing-library/react-native'
+import { fireEvent, waitFor } from '@testing-library/react-native'
import { mocked } from 'jest-mock'
import React from 'react'
-import { EXERCISES } from '../../../constants/data'
+import { EXERCISES, SCORE_THRESHOLD_POSITIVE_FEEDBACK } from '../../../constants/data'
import useLoadDocuments from '../../../hooks/useLoadDocuments'
import { RoutesParams } from '../../../navigation/NavigationTypes'
import DocumentBuilder from '../../../testing/DocumentBuilder'
import createNavigationMock from '../../../testing/createNavigationPropMock'
import { getReturnOf } from '../../../testing/helper'
import { mockDisciplines } from '../../../testing/mockDiscipline'
+import { mockUseLoadAsyncWithData } from '../../../testing/mockUseLoadFromEndpoint'
import render from '../../../testing/render'
import ExercisesScreen from '../ExercisesScreen'
@@ -37,6 +38,13 @@ describe('ExercisesScreen', () => {
},
}
+ mockUseLoadAsyncWithData({
+ [route.params.disciplineId]: {
+ '0': SCORE_THRESHOLD_POSITIVE_FEEDBACK - 1,
+ '1': SCORE_THRESHOLD_POSITIVE_FEEDBACK + 1,
+ },
+ })
+
it('should render correctly', () => {
const { getAllByText } = render()
EXERCISES.forEach(exercise => {
@@ -65,4 +73,14 @@ describe('ExercisesScreen', () => {
documents,
})
})
+
+ it('should show feedback badge for done levels', async () => {
+ const { queryByTestId } = render()
+ await waitFor(() => expect(queryByTestId('positive-badge')).not.toBeNull())
+ })
+
+ it('should not show feedback badge for wordlist level', async () => {
+ const { queryByTestId } = render()
+ await waitFor(() => expect(queryByTestId('negative-badge')).toBeNull())
+ })
})