diff --git a/kolibri/core/assets/src/views/ExamReport/AttemptIconDiff.vue b/kolibri/core/assets/src/views/ExamReport/AttemptIconDiff.vue index 8e8285d1251..4d1ead5cfd9 100644 --- a/kolibri/core/assets/src/views/ExamReport/AttemptIconDiff.vue +++ b/kolibri/core/assets/src/views/ExamReport/AttemptIconDiff.vue @@ -2,6 +2,7 @@ diff --git a/kolibri/core/assets/src/views/ExamReport/AttemptTextDiff.vue b/kolibri/core/assets/src/views/ExamReport/AttemptTextDiff.vue index d1ecea8c92f..465373aeeac 100644 --- a/kolibri/core/assets/src/views/ExamReport/AttemptTextDiff.vue +++ b/kolibri/core/assets/src/views/ExamReport/AttemptTextDiff.vue @@ -1,6 +1,6 @@ diff --git a/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue b/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue index 39decc83496..83a3b85a4ff 100644 --- a/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue +++ b/kolibri/core/assets/src/views/ExamReport/TriesOverview.vue @@ -6,7 +6,11 @@ {{ coreString('statusLabel') }} - + diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/AttemptIconDiff.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/AttemptIconDiff.spec.js new file mode 100644 index 00000000000..394a8744b4b --- /dev/null +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/AttemptIconDiff.spec.js @@ -0,0 +1,39 @@ +import { render, screen } from '@testing-library/vue'; +import '@testing-library/jest-dom'; +import VueRouter from 'vue-router'; +import { themeTokens } from 'kolibri-design-system/lib/styles/theme'; +import AttemptIconDiff from '../AttemptIconDiff.vue'; + +const successThemeColor = themeTokens().correct; + +// Helper function to render the component with some default props +const renderComponent = props => { + return render(AttemptIconDiff, { + props: { + correct: 1, + diff: 1, + ...props, + }, + routes: new VueRouter(), + }); +}; + +describe('AttemptIconDiff', () => { + test('renders KIcon with correct styles when correct and diff conditions are met', () => { + renderComponent(); + + const kIcon = screen.getByTestId('correct-icon'); + expect(kIcon).toBeInTheDocument(); + expect(kIcon).toHaveStyle({ fill: successThemeColor }); + }); + + test('does not render KIcon when correct condition is not met', () => { + renderComponent({ correct: 0 }); + expect(screen.queryByTestId('correct-icon')).not.toBeInTheDocument(); + }); + + test('does not render KIcon when diff condition is not met', () => { + renderComponent({ diff: 0 }); + expect(screen.queryByTestId('k-icon')).not.toBeInTheDocument(); + }); +}); diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/AttemptTextDiff.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/AttemptTextDiff.spec.js new file mode 100644 index 00000000000..f780ab3a544 --- /dev/null +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/AttemptTextDiff.spec.js @@ -0,0 +1,75 @@ +import { render, screen } from '@testing-library/vue'; +import '@testing-library/jest-dom'; +import VueRouter from 'vue-router'; +import AttemptTextDiff from '../AttemptTextDiff.vue'; + +const renderComponent = props => { + return render(AttemptTextDiff, { + routes: new VueRouter(), + props, + store: { + getters: { + currentUserId: () => 'mockUser1', + }, + }, + }); +}; + +const testCases = [ + { + caseName: 'Second Person Perspective: Answer Improved', + correct: 1, + diff: 1, + userId: 'mockUser1', + expectedMessage: 'You improved your incorrect answer from the previous attempt', + }, + { + caseName: 'Second Person Perspective: Incorrect Answer', + correct: 0, + diff: 0, + userId: 'mockUser1', + expectedMessage: 'You also answered this incorrectly on the previous attempt', + }, + { + caseName: 'Second Person Perspective: Correct Answer', + correct: 0, + diff: -1, + userId: 'mockUser1', + expectedMessage: 'You answered this correctly on the previous attempt', + }, + { + caseName: 'Third Person Perspective: Answer Improved', + correct: 1, + diff: 1, + userId: 'mockUser2', + expectedMessage: 'Learner improved their incorrect answer from the previous attempt', + }, + { + caseName: 'Third Person Perspective: Incorrect Answer', + correct: 0, + diff: 0, + userId: 'mockUser2', + expectedMessage: 'Learner also answered this incorrectly on the previous attempt', + }, + { + caseName: 'Third Person Perspective: Correct Answer', + correct: 0, + diff: -1, + userId: 'mockUser2', + expectedMessage: 'Learner answered this correctly on the previous attempt', + }, +]; + +describe('AttemptTextDiff', () => { + testCases.forEach(({ caseName, correct, diff, userId, expectedMessage }) => { + test(caseName, () => { + renderComponent({ correct, diff, userId }); + expect(screen.getByText(expectedMessage)).toBeInTheDocument(); + }); + }); + + test('No text is shown when the props are invalid', () => { + renderComponent({ correct: 1, diff: 0, userId: 'mockUser1' }); + expect(screen.queryByTestId('attempt-text-diff')).not.toBeInTheDocument(); + }); +}); diff --git a/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js new file mode 100644 index 00000000000..05acce0b770 --- /dev/null +++ b/kolibri/core/assets/src/views/ExamReport/__tests__/TriesOverview.spec.js @@ -0,0 +1,68 @@ +import { render, screen } from '@testing-library/vue'; +import '@testing-library/jest-dom'; +import VueRouter from 'vue-router'; +import TriesOverview from '../TriesOverview.vue'; +import * as tryValidatorModule from '../utils'; + +// Mock the tryValidator namespace as the same is used in the component +// eslint-disable-next-line import/namespace +tryValidatorModule.tryValidator = jest.fn(() => true); + +// Helper function to render the component with some default props +const renderComponent = props => { + const commonCoreStrings = { + methods: { + coreString: x => x, + }, + }; + + const defaultProps = { + pastTries: [], + totalQuestions: 20, + suggestedTime: 240, + ...props, + }; + + return render(TriesOverview, { + props: { + ...defaultProps, + ...props, + }, + routes: new VueRouter(), + mixins: [commonCoreStrings], + }); +}; + +describe('TriesOverview', () => { + describe('Test the progress icon and label', () => { + test('renders progress icon and completed label when there is a completed try', () => { + renderComponent({ + pastTries: [ + { + id: '1', + completion_timestamp: 100, + }, + ], + }); + + expect(screen.getByTestId('progress-icon-1')).toBeInTheDocument(); + expect(screen.getByText('completedLabel')).toBeInTheDocument(); + }); + + test('renders progress icon and in-progress label when there is an in-progress try', () => { + renderComponent({ + pastTries: [{ id: '2' }], + }); + + expect(screen.getByTestId('progress-icon-0.5')).toBeInTheDocument(); + expect(screen.getByText('inProgressLabel')).toBeInTheDocument(); + }); + + test('renders progress icon and not started label when there are no past tries', () => { + renderComponent(); + + expect(screen.getByTestId('progress-icon-0')).toBeInTheDocument(); + expect(screen.getByText('notStartedLabel')).toBeInTheDocument(); + }); + }); +}); diff --git a/kolibri/plugins/epub_viewer/assets/tests/SearchSideBar.spec.js b/kolibri/plugins/epub_viewer/assets/tests/SearchSideBar.spec.js index c5e744aac17..8f17d7cb1e4 100644 --- a/kolibri/plugins/epub_viewer/assets/tests/SearchSideBar.spec.js +++ b/kolibri/plugins/epub_viewer/assets/tests/SearchSideBar.spec.js @@ -24,6 +24,6 @@ describe('Search side bar', () => { const wrapper = createWrapper(); wrapper.vm.focusOnInput(); const elementThatIsFocused = document.activeElement; - expect(elementThatIsFocused.classList.contains('search-input')).toBe(true); + expect(elementThatIsFocused).toHaveClass('search-input'); }); }); diff --git a/kolibri/plugins/epub_viewer/assets/tests/TopBar.spec.js b/kolibri/plugins/epub_viewer/assets/tests/TopBar.spec.js index 28c7878a6ee..e83a9fca975 100644 --- a/kolibri/plugins/epub_viewer/assets/tests/TopBar.spec.js +++ b/kolibri/plugins/epub_viewer/assets/tests/TopBar.spec.js @@ -33,19 +33,19 @@ describe('Top bar', () => { const wrapper = createWrapper(); wrapper.vm.focusOnTocButton(); const elementThatIsFocused = document.activeElement; - expect(elementThatIsFocused.getAttribute('data-test')).toEqual('toc button'); + expect(elementThatIsFocused).toHaveAttribute('data-test', 'toc button'); }); it('should allow parent to focus on settings button', () => { const wrapper = createWrapper(); wrapper.vm.focusOnSettingsButton(); const elementThatIsFocused = document.activeElement; - expect(elementThatIsFocused.getAttribute('data-test')).toEqual('settings button'); + expect(elementThatIsFocused).toHaveAttribute('data-test', 'settings button'); }); it('should allow parent to focus on search button', () => { const wrapper = createWrapper(); wrapper.vm.focusOnSearchButton(); const elementThatIsFocused = document.activeElement; - expect(elementThatIsFocused.getAttribute('data-test')).toEqual('search button'); + expect(elementThatIsFocused).toHaveAttribute('data-test', 'search button'); }); it('should emit and event when the table of contents button is clicked', () => { diff --git a/kolibri/plugins/setup_wizard/assets/test/views/FacilityPermissionsForm.spec.js b/kolibri/plugins/setup_wizard/assets/test/views/FacilityPermissionsForm.spec.js index 2e302c16c3b..00fb6c4059c 100644 --- a/kolibri/plugins/setup_wizard/assets/test/views/FacilityPermissionsForm.spec.js +++ b/kolibri/plugins/setup_wizard/assets/test/views/FacilityPermissionsForm.spec.js @@ -36,6 +36,6 @@ describe('FacilityPermissionsForm', () => { expect(wrapper.vm.selected).toEqual('nonformal'); expect(els.nonFormalRadioButton().vm.isChecked).toEqual(true); const elementThatIsFocused = document.activeElement; - expect(elementThatIsFocused.classList.contains('ui-textbox-input')).toBe(true); + expect(elementThatIsFocused).toHaveClass('ui-textbox-input'); }); }); diff --git a/kolibri/plugins/user_auth/assets/test/views/sign-up-page.spec.js b/kolibri/plugins/user_auth/assets/test/views/sign-up-page.spec.js index e46cf5bb3a6..238346a3dc9 100644 --- a/kolibri/plugins/user_auth/assets/test/views/sign-up-page.spec.js +++ b/kolibri/plugins/user_auth/assets/test/views/sign-up-page.spec.js @@ -37,8 +37,8 @@ describe('multiFacility signUpPage component', () => { it('right facility', async () => { const wrapper = makeWrapper(); const facilityLabel = wrapper.find('[data-test="facilityLabel"]').element; - expect(facilityLabel.textContent).toMatch(/Facility 1/); + expect(facilityLabel).toHaveTextContent(/Facility 1/); await wrapper.vm.$store.commit('SET_FACILITY_ID', 2); - expect(facilityLabel.textContent).toMatch(/Facility 2/); + expect(facilityLabel).toHaveTextContent(/Facility 2/); }); }); diff --git a/packages/kolibri-tools/.eslintrc.js b/packages/kolibri-tools/.eslintrc.js index 5c7d00a9ba2..0bb5bd5b9e2 100644 --- a/packages/kolibri-tools/.eslintrc.js +++ b/packages/kolibri-tools/.eslintrc.js @@ -56,9 +56,10 @@ module.exports = { 'plugin:vue/recommended', 'plugin:import/errors', 'plugin:import/warnings', + 'plugin:jest-dom/recommended', 'prettier', ], - plugins: ['import', 'vue', 'kolibri'], + plugins: ['import', 'vue', 'kolibri', 'jest-dom'], settings: { 'import/resolver': { [path.resolve(path.join(path.dirname(__filename), './lib/alias_import_resolver.js'))]: { @@ -68,7 +69,7 @@ module.exports = { }, rules: { 'comma-style': ERROR, - "no-console": ERROR, + 'no-console': ERROR, 'max-len': [ ERROR, 100, @@ -221,9 +222,12 @@ module.exports = { 'kolibri/vue-no-undefined-string-uses': ERROR, 'kolibri/vue-string-objects-formatting': ERROR, - 'prefer-const': [ERROR, { - destructuring: 'any', - ignoreReadBeforeAssign: false - }] + 'prefer-const': [ + ERROR, + { + destructuring: 'any', + ignoreReadBeforeAssign: false, + }, + ], }, }; diff --git a/packages/kolibri-tools/package.json b/packages/kolibri-tools/package.json index f461644ac23..ca3842a9179 100644 --- a/packages/kolibri-tools/package.json +++ b/packages/kolibri-tools/package.json @@ -18,7 +18,6 @@ "@babel/plugin-syntax-import-assertions": "^7.22.5", "@babel/plugin-transform-runtime": "^7.23.9", "@babel/preset-env": "^7.23.9", - "@testing-library/jest-dom": "^6.1.6", "@vue/test-utils": "^1.3.6", "ast-traverse": "^0.1.1", "autoprefixer": "10.4.16", @@ -44,6 +43,7 @@ "eslint-plugin-import": "^2.29.1", "eslint-plugin-jest": "^23.3.0", "eslint-plugin-kolibri": "0.16.0-dev.7", + "eslint-plugin-jest-dom": "^5.1.0", "eslint-plugin-vue": "^7.3.0", "espree": "9.6.1", "esquery": "^1.5.0", @@ -81,6 +81,7 @@ "stylelint-config-standard": "24.0.0", "stylelint-csstree-validator": "3.0.0", "stylelint-scss": "5.3.2", + "rewire": "^6.0.0", "temp": "^0.8.3", "terser-webpack-plugin": "^5.3.10", "toml": "^3.0.0", @@ -92,13 +93,12 @@ "webpack": "^5.89.0", "webpack-cli": "^5.1.4", "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.10.0" + "webpack-merge": "^5.10.0", + "@testing-library/jest-dom": "^6.4.1", + "@testing-library/vue": "^5" }, "engines": { "node": "18.x", "npm": ">= 8" - }, - "devDependencies": { - "rewire": "^6.0.0" } } \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 853040efc97..cbe55b99f03 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,7 +22,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== @@ -1020,6 +1020,13 @@ dependencies: regenerator-runtime "^0.13.11" +"@babel/runtime@^7.16.3": + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" + integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.22.15", "@babel/template@^7.22.5", "@babel/template@^7.23.9", "@babel/template@^7.3.3": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" @@ -1465,20 +1472,43 @@ dependencies: "@sinonjs/commons" "^2.0.0" -"@testing-library/jest-dom@^6.1.6": - version "6.1.6" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.1.6.tgz#d9a3ce61cd74ea792622d3da78a830f6786e8d93" - integrity sha512-YwuiOdYEcxhfC2u5iNKlvg2Q5MgbutovP6drq7J1HrCbvR+G58BbtoCoq+L/kNlrNFsu2Kt3jaFAviLVxYHJZg== +"@testing-library/dom@^9.0.0": + version "9.3.4" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.3.4.tgz#50696ec28376926fec0a1bf87d9dbac5e27f60ce" + integrity sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.1.3" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" + +"@testing-library/jest-dom@^6.4.1": + version "6.4.1" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.4.1.tgz#1b0cc222c3a59f9cba2cc7947dc5fadc01210a37" + integrity sha512-Z7qMM3J2Zw5H/nC2/5CYx5YcuaD56JmDFKNIozZ89VIo6o6Y9FMhssics4e2madEKYDNEpZz3+glPGz0yWMOag== dependencies: "@adobe/css-tools" "^4.3.2" "@babel/runtime" "^7.9.2" aria-query "^5.0.0" chalk "^3.0.0" css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" + dom-accessibility-api "^0.6.3" lodash "^4.17.15" redent "^3.0.0" +"@testing-library/vue@^5": + version "5.9.0" + resolved "https://registry.yarnpkg.com/@testing-library/vue/-/vue-5.9.0.tgz#d33c52ae89e076808abe622f70dcbccb1b5d080c" + integrity sha512-HWvI4s6FayFLmiqGcEMAMfTSO1SV12NukdoyllYMBobFqfO0TalQmfofMtiO+eRz+Amej8Z26dx4/WYIROzfVw== + dependencies: + "@babel/runtime" "^7.21.0" + "@testing-library/dom" "^9.0.0" + "@vue/test-utils" "^1.3.0" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" @@ -1494,6 +1524,11 @@ resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== +"@types/aria-query@^5.0.1": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== + "@types/babel__core@^7.1.14": version "7.1.14" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.14.tgz#faaeefc4185ec71c389f4501ee5ec84b170cc402" @@ -1883,7 +1918,7 @@ resolved "https://registry.yarnpkg.com/@vue/composition-api/-/composition-api-1.7.2.tgz#0b656f3ec39fefc2cf40aaa8c12426bcfeae1b44" integrity sha512-M8jm9J/laYrYT02665HkZ5l2fWTK4dcVg3BsDHm/pfz+MjDYwX+9FUaZyGwEyXEDonQYRCo0H7aLgdklcIELjw== -"@vue/test-utils@^1.3.6": +"@vue/test-utils@^1.3.0", "@vue/test-utils@^1.3.6": version "1.3.6" resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.3.6.tgz#6656bd8fa44dd088b4ad80ff1ee28abe7e5ddf87" integrity sha512-udMmmF1ts3zwxUJEIAj5ziioR900reDrt6C9H3XpWPsLBx2lpHKoA4BTdd9HNIYbkGltWw+JjWJ+5O6QBwiyEw== @@ -2353,6 +2388,13 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +aria-query@5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + aria-query@^5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.2.tgz#0b8a744295271861e1d933f8feca13f9b70cfdc1" @@ -3650,7 +3692,7 @@ caniuse-lite@^1.0.30001565: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001568.tgz#53fa9297273c9a977a560663f48cbea1767518b7" integrity sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A== -chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.2: +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -4408,6 +4450,30 @@ dedent@^1.0.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.3.0.tgz#15d6809eb15b581d5587a2dc208f34118e35bee3" integrity sha512-7glNLfvdsMzZm3FpRY1CHuI2lbYDR+71YmrhmTZjYFD5pfT0ACgnGRdrrC9Mk2uICnzkcdelCx5at787UDGOvg== +deep-equal@^2.0.5: + version "2.2.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.5" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.2" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.13" + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -4581,10 +4647,15 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-accessibility-api@^0.5.6: - version "0.5.14" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56" - integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg== +dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + +dom-accessibility-api@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" + integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== dom-converter@^0.2.0: version "0.2.0" @@ -4885,6 +4956,21 @@ es-abstract@^1.22.1: unbox-primitive "^1.0.2" which-typed-array "^1.1.13" +es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + es-module-lexer@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.2.1.tgz#ba303831f63e6a394983fde2f97ad77b22324527" @@ -5046,6 +5132,14 @@ eslint-plugin-import@^2.29.1: semver "^6.3.1" tsconfig-paths "^3.15.0" +eslint-plugin-jest-dom@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-5.1.0.tgz#b285cd1cc71c084c8ee897f0f85599758d7cb933" + integrity sha512-JIXZp+E/h/aGlP/rQc4tuOejiHlZXg65qw8JAJMIJA5VsdjOkss/SYcRSqBrQuEOytEM8JvngUjcz31d1RrCrA== + dependencies: + "@babel/runtime" "^7.16.3" + requireindex "^1.2.0" + eslint-plugin-jest@^23.3.0: version "23.13.2" resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-23.13.2.tgz#7b7993b4e09be708c696b02555083ddefd7e4cc7" @@ -6567,6 +6661,15 @@ inquirer@^7.0.0: strip-ansi "^6.0.0" through "^2.3.6" +internal-slot@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== + dependencies: + get-intrinsic "^1.2.2" + hasown "^2.0.0" + side-channel "^1.0.4" + internal-slot@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" @@ -6647,7 +6750,7 @@ iri@^1.3.1: resolved "https://registry.yarnpkg.com/iri/-/iri-1.3.1.tgz#66f66cfc70b7bf3c01eb1bf8e46f9185320e36ed" integrity sha512-CpzxCf3ycTphqF2hQRQAp25yK7+XM1iMJHUoJbFiQDLt70hYC+vUlrgQXuhzPrLNMuejhV0VelFp8zQmtqgAxA== -is-arguments@^1.0.4: +is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -6718,6 +6821,13 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== +is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" @@ -6784,6 +6894,11 @@ is-language-code@^3.1.0: dependencies: "@babel/runtime" "^7.14.0" +is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + is-nan@^1.2.1: version "1.3.2" resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" @@ -6854,6 +6969,11 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" +is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -6915,6 +7035,11 @@ is-typed-array@^1.1.12, is-typed-array@^1.1.9: dependencies: which-typed-array "^1.1.11" +is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -6922,6 +7047,14 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" +is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + is-whitespace@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" @@ -7884,6 +8017,11 @@ lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.0.tgz#b9e2a6a72a129d81ab317202d93c7691df727e61" integrity sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw== +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + m3u8-parser@4.8.0: version "4.8.0" resolved "https://registry.yarnpkg.com/m3u8-parser/-/m3u8-parser-4.8.0.tgz#4a2d591fdf6f2579d12a327081198df8af83083d" @@ -8549,7 +8687,7 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== -object-is@^1.0.1: +object-is@^1.0.1, object-is@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== @@ -9299,6 +9437,15 @@ pretty-error@^4.0.0: lodash "^4.17.20" renderkid "^3.0.0" +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" @@ -9534,6 +9681,11 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-is@^18.0.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" @@ -9689,6 +9841,11 @@ regenerator-runtime@^0.13.11: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== + regenerator-transform@^0.10.0: version "0.10.1" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" @@ -9821,7 +9978,7 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== -requireindex@^1.1.0: +requireindex@^1.1.0, requireindex@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== @@ -10532,6 +10689,13 @@ stdout-stream@^1.4.0: dependencies: readable-stream "^2.0.1" +stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + stream-browserify@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" @@ -11901,6 +12065,16 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + which-typed-array@^1.1.11: version "1.1.11" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a"