From 2dee35ac67e776288e5121133b27640f3f71056f Mon Sep 17 00:00:00 2001 From: vinu-deriv <100689171+vinu-deriv@users.noreply.github.com> Date: Thu, 21 Sep 2023 11:58:52 +0400 Subject: [PATCH] Test coverage dbot (#9825) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sync with master to get latest update (#9750) * translations: 📚 sync translations with crowdin (#9672) Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> * chore: translation workflow trigger (#9684) * Revert "chore: translation workflow trigger (#9684)" (#9686) This reverts commit cfacd85ac179ad00340d7ef7430be22f7d8d18f2. * Kate / WEBREL-51 / Test coverage: ProgressSliderStream in Trader package (#9464) * feat: add unit tests * refactor: incapsulated trade providers * Kate / Test coverage: ChartLoader + Loading in Trader package (#8398) * refactor: add integr and unit tests for loader * refactor: removed hardcoded test id * likhith/fix: :bug: display onfido error message (#9401) * fix: :bug: display onfido error message * fix: reverted change * test: :white_check_mark: added testcases * fix: test case names * fix: added testcases * Henry/fix: test coverage and ts migration for asset/trading/categories (#8483) * fix: test coverage and ts migration for asset/trading/categories * fix: codecov issues * fix: codecov issues * test: dynamic test component import * fix: code smell add error handling * fix: change from FC to componenttype * fix: circleCi * fix: circleCI * fix: circleCi * fix: failing test * fix: circleCI * Matin/WALL-1308/Adding Korean language (#9426) * chore: adding Korean language * chore: changed Korean short form to KO from KR * chore: fix translation issue in login history table * chore: update all flags to follow the latest design system * chore: Korean language on P2P * chore: update deriv-charts to v1.3.2 * chore: empty * translations: 📚 sync translations with crowdin (#9607) Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> * chore: empty --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> * Amina/fix: disable account when proof failed (#9555) * fix: disable account when proof failed * fix: disable account when proof failed * fix: flag * fix: import * fix: update with master * fix: duplicate_types (#9691) * likhith/fix: :bug: translation of IDV documents dropdown option (#9336) * fix: :bug: translation of IDV documents dropdown option * fix: :bug: translation of default config * fix: :bug: translation of default config * fix: :bug: removed unused-import * fix: :bug: refactored code * fix: :recycle: incorporated review comments * fix: :bug: added missing function * maryia/DTRA-350/feat: handle displayed positions locally in TogglePositionsMobile (#9610) * feat: handle displayed positions locally in mobile TogglePositions * test: added a test * chore: refactoring * test: fix tests after conflict resolution * FarhanNurzi/P2PS-1417/2FA order confirm modal is not showing up on mobile browsers (#9620) * fix: completed order modal is not showing in mobile * fix: add test case, fix error in chat component upon creating order * refactor: destructure order in handleResponse * Adrienne / Implemented new navigation flow for filtering payment methods in buy/sell page (#8544) * Create codeql.yml * Create codeql-test.yml * chore: removed codeql workflows * chore: removed dccache * chore: added escapeHtml function to login * feat: added new flow for filter modal * chore: removed old commits * fix: fixed ui issues regarding requirements * feat: changed reset flow * feat: changed flow for reset, added status for filter modal icon * chore: incorporated reviews * chore: applied code review changes * Amina/wall 575/maintenance notifications for site and cashier (#9064) * fix: notifications_in_cashier_and_accounts * fix: notification for maintenance * fix: notification_filter * fix: notification_filter * fix: filter notifications in mobile * fix: code_review_suggestions * chore: merge master * chore: resolve conflict * fix: showing notification in mobile * Shaheer/wall 1229 (#9240) * feat: :sparkles: adds financial assessment notification * refactor: :art: sorts the object block * feat: :sparkles: displays financial assessment notification on trigger from backend * chore: :ambulance: resolves merge conflict with master * test: :test_tube: adds test case for app-notification * test: :test_tube: adds test cases for notification * Kate / OPT-306 / Update Accumulator to Accumulators (#9577) * chore: change text * chore: apply suggestion * Kate / Add video for Vanillas description (#9622) * feat: add video for vanilla * refactor: add tests and change file structure * refactor: video component and test * refactor: change folders name and add more videos * refactor: apply suggestions * chore: rename data test id * chore: correct spelling * chore: remove optional data test id * refactor: add backup * fix: tests * likhith/chore: incorporated the API response to save the opt-out user data (#9618) * chore: incorporated the API response to save the opt-out user data * chore: incorporated the API response to save the opt-out user data * chore: incorporated the API response to save the opt-out user data * chore: incorporated the API response to save the opt-out user data * chore: incorporated review comments * chore: incorporated review comments * chore: incorporated review comments * fix: error displayed for MF account creation * Merge branch 'master' into likhith/KYC-362/track-idv-opt-out-during-account-creation * translations: 📚 sync translations with crowdin (#9702) Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> * Matin / Remove ESLint Ignore (#9707) * chore: fix Oneall social unlinking from Apple accounts * Revert "chore: fix Oneall social unlinking from Apple accounts" This reverts commit 84009b09da4eb9ffe2164ef62d3e98acfd707b17. * chore: remove eslint ignore * translations: 📚 sync translations with crowdin (#9709) Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> * fix: set dbot as external in platform config for authorize logout isssue (#9711) * feat: transaction details modal (#9032) * feat: transaction details modal * feat: complete test cases for TransactionDetails modal * chore: fix code smells * chore: fix code smells * chore: remove code smells * chore: redeploy * chore: move transaction details types to types folder * chore: show enrty and exit tick if available * fix: transaction scroll css issue fix * fix: update key with data for divider inside transaction details modal * fix: update buy price to have decimal value * fix: css issue on modal height and fixed decimal profit/loss * fix: fix style for modal getting cut * fix: modal css issue after build * fix: decrease the modal height for edge cutting issue * fix: hide download button on mobile * fix: gtm issue (#9551) * fix: registration flow in buy/sell tab (#9573) * fix: registration flow in buy/sell tab * fix: added unit test * Farzin/WALL-460/DepositCrypto module (#8867) * Merge branch 'master' into farzin/wall-252/replace_the_use_of_cashier_store_in_other_packages_with_shared_hooks * Merge branch 'farzin/wall-252/replace_the_use_of_cashier_store_in_other_packages_with_shared_hooks' into farzin/wall-434/separate_cashier_onboarding_to_a_new_route * fix(cashier): :memo: resolve conflict * feat(cashier): :fire: remove `AccountPromptDialogStore` * fix(cashier): :white_check_mark: fix failing tests * feat(cashier): :fire: remove `onMountCashierOnboarding` * fix(cashier): :white_check_mark: fix `CashierOnboardingP2PCard` * Merge branch 'master' into farzin/wall-434/separate_cashier_onboarding_to_a_new_route * Merge branch 'master' into farzin/wall-434/separate_cashier_onboarding_to_a_new_route * fix(cashier): :bug: fix dialog issue * fix(cashier): :memo: resolve PR comments * refactor(cashier): :recycle: `CashierOnboardingModule` clean-up * feat(cashier): :sparkles: add `useDepositCryptoAddress` hook * feat(cashier): :sparkles: add `DepositCryptoWalletAddress` * feat(cashier): :sparkles: add `DepositCryptoTryFiatOnRamp` * feat(cashier): :sparkles: add `DepositCryptoModule` * feat(cashier): :sparkles: add `PageContainer` * refactor(cashier): :truck: change folder structure * feat(cashier): :sparkles: add `PageContainer` * style(cashier): :lipstick: update the styles to match with the desing * fix(cashier): :memo: resolve PR comments * fix(cashier): :memo: resolve PR comments * fix(cashier): :white_check_mark: fix failing tests * feat(cashier): :recycle: move `CashierBreadcrumb` to `PageContainer` * feat(cashier): :sparkles: add `DepositCryptoCurrencyDetails` * feat(cashier): :sparkles: add `DepositCryptoWalletAddress` * refactor(cashier): :truck: change folder structure * style(cashier): :lipstick: update the styles to match with the design * feat(cashier): :sparkles: add `DepositCryptoDisclaimers` * feat(components): :sparkles: add `InlineMessage` * feat(cashier): :recycle: render `RecentTransaction` in `DepositCrypto` * ci: :green_heart: trigger build * refactor(cashier): ♻️ `CashierOnboardingModule` clean-up * refactor(cashier): ♻️ `CashierOnboardingModule` clean-up * fix(cashier): :bug: fix double loader issue while switching accounts * fix(cashier): :white_check_mark: fix failing test * fix: :wrench: fix `jest.config.js` issue * ci: :construction_worker: set jest `maxWorkers` to `8` * ci: :construction_worker: set jest `maxWorkers` to `2` * refactor(components): :lipstick: refactor `InlineMessage` component with the new design * refactor(components): :lipstick: refactor `InlineMessage` component with the new design * refactor(components): :truck: move `SideNote` to components package * feat(components): :sparkles: add `InlineMessage` component * feat(components): :sparkles: add `SideNote` component * feat(hooks): :sparkles: add `useInputDecimalFormatter` hook * feat(hooks): :sparkles: add `useInputATMFormatter` hook * feat(hooks): :sparkles: add `useCurrencyConfig` hook * feat(hooks): :sparkles: add `useDepositCryptoAddress` hook * fix: :wrench: fix `jest.config.js` * feat: :label: add `Prettify` utility type * fix(hooks): :white_check_mark: fix failing test * fix(hooks): :white_check_mark: fix failing test * feat(cashier): :sparkles: show transaction confirmations number * feat(cashier): :sparkles: add `useUnsafeCashierRouteHandler` hook * feat(cashier): :sparkles: use `useUnsafeCashierRouteHandler` hook in `AppContent` * fix(appstore): :truck: update deposit link in trader hub page * refactor(cashier): :recycle: refactor cashier onboarding side notes * feat(cashier): :sparkles: add `DepositCryptoResentTransactionSideNote` * fix(cashier): :recycle: replace `is_crypto` with `useCurrencyConfig` hook * style(cashier): :lipstick: update the styles * style(cashier): :lipstick: update the styles * style(cashier): :lipstick: update the styles * refactor(cashier): :truck: move components * Merge branch 'master' into farzin/deposit_crypto_module * feat(cashier): :sparkles: add `Confirmations` column to crypto transactions history * refactor(cashier): :recycle: improve `CashierBreadcrumb` * refactor(cashier): :recycle: improve `PageContainer` * refactor(cashier): :truck: move `SwitchToFiatAccountDialog` to components * refactor(cashier): :recycle: clean-up cashier onboarding components * feat(cashier): :sparkles: add `Confirmations` to recent transaction side note * fix(cashier): :white_check_mark: fix failing test * fix(cashier): :white_check_mark: fix failing test * Merge remote-tracking branch 'aum-deriv/aum/WALL-297/deposit-fiat-module' into farzin/deposit_crypto_module * refactor(cashier): :fire: remove `containers` constant * refactor(cashier): :fire: remove `ErrorDialogStore` * refactor(cashier): :fire: remove `DepositStore` * fix(cashier): :memo: resolve conflicts * fix(cashier): :memo: resolve conflicts * fix(cashier): :memo: resolve conflicts * fix(cashier): :memo: resolve conflicts * fix(cashier): :bug: fix reaise issues * refactor(cashier): :art: improvements on `CashierOnboardingModule` * refactor(cashier): :truck: move cashier `EmptyState` to components package * fix(cashier): :bug: fix raised issues * chore: :arrow_up: update `@deriv/api-types` to `1.0.111` * feat(api): :label: add types for `cashier_payments` private call * style(cashier): :lipstick: update deposit crypto page style to match the design * feat(hooks): :sparkles: add `useCurrentCurrencyConfig` hook * fix(cashier): :white_check_mark: fix failing tests * fix(cashier): :bug: fix raised issues * fix(cashier): :bug: fix raised issues * fix(cashier): :bug: fix raised issues * fix(cashier): :bug: fix raised issues * fix(cashier): :bug: fix raised issues * feat(hooks): :sparkles: add `useCryptoTransactions` hook * fix(cashier): :bug: fix raised issues * style(cashier): :lipstick: update `CryptoTransactionsSideNoteResentTransaction` style * style(cashier): :lipstick: update `DepositCryptoSideNoteUSDT` style * fix(cashier): :bug: fix raised issues * fix(cashier): :bug: fix raised issues * fix(cashier): :memo: resolve conflicts * fix(cashier): :memo: resolve conflicts * fix(cashier): :memo: resolve comments * fix(cashier): :memo: resolve comments * Merge branch 'master' into farzin/wall-852/show_pending_crypto_deposit_transaction_even_if_0_confirmation * fix(cashier): :memo: resolve PR comments * fix(cashier): :memo: resolve PR comments * fix(cashier): :memo: resolve PR comments * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * Merge branch 'master' into farzin/deposit_crypto_module * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues * fix(cashier): :memo: fix raised issues --------- Co-authored-by: Farzin Mirzaie * fix: fix quick add modal's height bug (#8574) * Farabi/bot 296/update responsive of tour in light mode (#9315) * fix: tour responsive on light mode * chore: updated PR * fix: highlighted target issue on tour * fix: added back data-testid * Maryia/Bot-303/feat: add crash/boom to markets list (#9098) * feat: add cryptocurrencies to markets list * feat: crash/boom, step indices * feat: take profit, stop loss disable when equal 0 to skip definition, add progress slider for crypta * refactor: currency definition, fix type of variable * fix: is_mobile * chore: remove cryptocurrency and step index * chore: remove cryptocurrency and step index(2) * fix: Hide Crash & Boom from quick strategy form * fix: DBot doesn't allow to run mutlipliers with take profit <=0 and stop loss > 0 * Kate / DTRA-166 / Implement Contract pages for Ends/ Stays contracts (#8998) * refactor: move trade type from un to supported * feat: ad contract type check func and add to contract details * feat: add chart markers settings for contract type * chore: add style for mobile * chore: remove gradient * chore: empty commit * chore: add gradient for contract details card for desktop * feat: add chart markers setings and update style * refactor: apply suggestions * chore: empty commit * feat: enable smart trader contract * refactor: remove rounding for barrier value * refactor: add swipble component for contract audit mobile and fix style * refactor: applied suggestions from review * fix: change trade type icons * chore: empty commit * fix: conflicts * Henry/dtra 282/rewrite contract type info component (#9352) * fix: initialize * fix: ts migrate and add test coverage to ContractType folder * fix: remove unused import * fix: TS Error due to name and value not being intrinsic attribute to span element * fix: add test cases * fix: code smells * fix: consistency issue * fix: code smell * fix: minor change * fix: rewrite contract-type-info to get rid of visual bug when switching between tabs * fix: remove unused import * fix: remove unused css * fix: refactor component * fix: small word change * fix: resolve comments * fix: resolve comments * fix: empty commit * fix: code smells * fix: circleCI * fix: resolve comments * fix: missing import * fix: remove scroll for contract-type-info * fix: resolve conflicts and merge master * fix: remove useeffect as per comment * fix: remove css styling * fix: circleCI * farabi/bot-228/fix-step-5-modal-alignment (#9377) * fix: removed for loop of loader in dashboard scss * fix: step 5 content * Niloofar Sadeghi / useP2PAdvertList custom hook (#9704) * feat: create a custom hook for handling p2p-advert-list endpoint * fix: review comments * fix: review comments * test: add test case for usepaginatedfetch custom hook * fix: circle/ci error --------- Co-authored-by: niloofar sadeghi * chore: test case for dbot-providers (#9583) * henry/test: add test coverage and ts migration for successdialog (#8432) * test: add test coverage and ts migration for successdialog * fix: code smell * fix: switch to userEvent from fireEvent * fix: make something reusuable variable * fix: remove unused file * test: :white_check_mark: add test case for Audio component (#9572) * test: :white_check_mark: add test case for Audio component * test: add test case in audio component to check src attribute * fix: fixed type in audio test file bot-web-ui * translations: 📚 sync translations with crowdin (#9730) Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> * chore: fixed orders failing test case (#9735) * translations: 📚 sync translations with crowdin (#9741) Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> * chore: update code owners (#9678) --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> Co-authored-by: prince-deriv <82309725+prince-deriv@users.noreply.github.com> Co-authored-by: kate-deriv <121025168+kate-deriv@users.noreply.github.com> Co-authored-by: Likhith Kolayari <98398322+likhith-deriv@users.noreply.github.com> Co-authored-by: henry-deriv <118344354+henry-deriv@users.noreply.github.com> Co-authored-by: Matin shafiei Co-authored-by: amina-deriv <84661147+amina-deriv@users.noreply.github.com> Co-authored-by: Maryia <103177211+maryia-deriv@users.noreply.github.com> Co-authored-by: Farhan Ahmad Nurzi <125247833+farhan-nurzi-deriv@users.noreply.github.com> Co-authored-by: adrienne-deriv <103016120+adrienne-deriv@users.noreply.github.com> Co-authored-by: Shaheer <122449658+shaheer-deriv@users.noreply.github.com> Co-authored-by: Shafin Al Karim <129021108+shafin-deriv@users.noreply.github.com> Co-authored-by: nada-deriv <122768621+nada-deriv@users.noreply.github.com> Co-authored-by: Farzin Mirzaie <72082844+farzin-deriv@users.noreply.github.com> Co-authored-by: Farzin Mirzaie Co-authored-by: Farabi <102643568+farabi-deriv@users.noreply.github.com> Co-authored-by: maryia-matskevich-deriv <103181650+maryia-matskevich-deriv@users.noreply.github.com> Co-authored-by: Niloofar Sadeghi <93518187+niloofar-deriv@users.noreply.github.com> Co-authored-by: niloofar sadeghi Co-authored-by: vinu-deriv <100689171+vinu-deriv@users.noreply.github.com> Co-authored-by: ameerul-deriv <103412909+ameerul-deriv@users.noreply.github.com> * Revert "Sync with master to get latest update (#9750)" This reverts commit 0dcb820af2806f51fc91ac27ecd2ead7062bda67. * Shafin/bot 531/chore toolbar widget test (#9883) * chore: test case for ToolbarWidgets * chore: remove act * chore: empty commit * chore: contract card loading tests (#9884) * Farabi/bot 533/contract result overlay test case (#9886) * fix: added test case for contract result overlay * fix: using mock_ws from utils/mock * Maryia/Bot-535/test: react-joyride-wrapper component (#9893) * test: react-joyride-wrapper * refactor: react-joyride-wrapper * Update packages/bot-web-ui/src/components/dashboard/__tests__/react-joyride-wrapper.spec.tsx * chore: empty commit * refactor: test for react-joyride-wrapper * test: search-icon (#9891) * Maryia/BOT-537/test: RunStrategy (#9892) * test: RunStrategy * refactor: test for run strategy * Farabi/bot 536/test case for icon button (#9888) * fix: added test case for icon-button.tsx * fix: removed test for popovercd * fix: removed icon-button and test case as its no longer used * Vinu/bot 519/bot notification messages test case (#9881) * test: add test case for bot-notification-messages component * fix: fixed any type in bot-notification-messages.spec * fix: added actions in bot-notification-messages spec file insted of changing store value directly * fix: empty commit to trigger build * fix: removed unused component (#9873) * chore: test case for BotPreview (#9951) * chore: test case for BotPreview * chore: change type for reference --------- Co-authored-by: Sandeep Rajput <90243468+sandeep-deriv@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: DerivFE <80095553+DerivFE@users.noreply.github.com> Co-authored-by: prince-deriv <82309725+prince-deriv@users.noreply.github.com> Co-authored-by: kate-deriv <121025168+kate-deriv@users.noreply.github.com> Co-authored-by: Likhith Kolayari <98398322+likhith-deriv@users.noreply.github.com> Co-authored-by: henry-deriv <118344354+henry-deriv@users.noreply.github.com> Co-authored-by: Matin shafiei Co-authored-by: amina-deriv <84661147+amina-deriv@users.noreply.github.com> Co-authored-by: Maryia <103177211+maryia-deriv@users.noreply.github.com> Co-authored-by: Farhan Ahmad Nurzi <125247833+farhan-nurzi-deriv@users.noreply.github.com> Co-authored-by: adrienne-deriv <103016120+adrienne-deriv@users.noreply.github.com> Co-authored-by: Shaheer <122449658+shaheer-deriv@users.noreply.github.com> Co-authored-by: Shafin Al Karim <129021108+shafin-deriv@users.noreply.github.com> Co-authored-by: nada-deriv <122768621+nada-deriv@users.noreply.github.com> Co-authored-by: Farzin Mirzaie <72082844+farzin-deriv@users.noreply.github.com> Co-authored-by: Farzin Mirzaie Co-authored-by: Farabi <102643568+farabi-deriv@users.noreply.github.com> Co-authored-by: maryia-matskevich-deriv <103181650+maryia-matskevich-deriv@users.noreply.github.com> Co-authored-by: Niloofar Sadeghi <93518187+niloofar-deriv@users.noreply.github.com> Co-authored-by: niloofar sadeghi Co-authored-by: ameerul-deriv <103412909+ameerul-deriv@users.noreply.github.com> Co-authored-by: rupato-deriv <97010868+rupato-deriv@users.noreply.github.com> Co-authored-by: Sandeep --- .../components/audio/__tests__/audio.spec.tsx | 1 - .../bot-notification-messages.spec.tsx | 73 +++++++++++++++++++ .../bot-notification-messages.tsx | 1 + .../chart/__tests__/toolbar-widgets.spec.tsx | 71 ++++++++++++++++++ .../__tests__/contract-card-loading.spec.tsx | 57 +++++++++++++++ .../contract-card-loading.tsx | 1 + .../contract-result-overlay.spec.tsx | 54 ++++++++++++++ .../__tests__/react-joyride-wrapper.spec.tsx | 47 ++++++++++++ .../bot-builder/toolbar/icon-button.tsx | 32 -------- .../toolbox/__tests__/search-icon.spec.tsx | 59 +++++++++++++++ .../toolbox/search-box/search-icon.tsx | 2 +- .../__tests__/dashboard-component.spec.tsx | 9 --- .../__tests__/run-strategy.spec.tsx | 23 ++++++ .../__tests__/bot-preview.spec.tsx | 32 ++++++++ .../load-bot-preview/bot-preview.tsx | 4 +- .../dashboard-component/run-strategy.tsx | 2 +- .../dashboard/dashboard-component/sidebar.tsx | 42 ----------- 17 files changed, 422 insertions(+), 88 deletions(-) create mode 100644 packages/bot-web-ui/src/components/bot-notification-messages/__tests__/bot-notification-messages.spec.tsx create mode 100644 packages/bot-web-ui/src/components/chart/__tests__/toolbar-widgets.spec.tsx create mode 100644 packages/bot-web-ui/src/components/contract-card-loading/__tests__/contract-card-loading.spec.tsx create mode 100644 packages/bot-web-ui/src/components/contract-result-overlay/contract-result-overlay.spec.tsx create mode 100644 packages/bot-web-ui/src/components/dashboard/__tests__/react-joyride-wrapper.spec.tsx delete mode 100644 packages/bot-web-ui/src/components/dashboard/bot-builder/toolbar/icon-button.tsx create mode 100644 packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/__tests__/search-icon.spec.tsx create mode 100644 packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/run-strategy.spec.tsx create mode 100644 packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/__tests__/bot-preview.spec.tsx delete mode 100644 packages/bot-web-ui/src/components/dashboard/dashboard-component/sidebar.tsx diff --git a/packages/bot-web-ui/src/components/audio/__tests__/audio.spec.tsx b/packages/bot-web-ui/src/components/audio/__tests__/audio.spec.tsx index 8384cc3f15c6..a1c73bacdee8 100644 --- a/packages/bot-web-ui/src/components/audio/__tests__/audio.spec.tsx +++ b/packages/bot-web-ui/src/components/audio/__tests__/audio.spec.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import exp from 'constants'; import { render, screen } from '@testing-library/react'; import Audio from '../audio'; diff --git a/packages/bot-web-ui/src/components/bot-notification-messages/__tests__/bot-notification-messages.spec.tsx b/packages/bot-web-ui/src/components/bot-notification-messages/__tests__/bot-notification-messages.spec.tsx new file mode 100644 index 000000000000..0341c0e713a0 --- /dev/null +++ b/packages/bot-web-ui/src/components/bot-notification-messages/__tests__/bot-notification-messages.spec.tsx @@ -0,0 +1,73 @@ +import React from 'react'; +import { mockStore, StoreProvider } from '@deriv/stores'; +import { render, screen } from '@testing-library/react'; +import { mock_ws } from 'Utils/mock'; +import RootStore from 'Stores/root-store'; +import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore'; +import BotNotificationMessages from '../bot-notification-messages'; + +jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn()); +jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => ({ + saveRecentWorkspace: jest.fn(), + unHighlightAllBlocks: jest.fn(), +})); +jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn()); +jest.mock('@deriv/bot-skeleton', () => ({ + ...jest.requireActual('@deriv/bot-skeleton'), + blocksCoordinate: jest.fn(), +})); + +describe('BotNotificationMessages', () => { + let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element, mock_DBot_store: RootStore | undefined; + beforeAll(() => { + const mock_store = mockStore({ + ui: { + notification_messages_ui: jest + .fn() + .mockReturnValue(

Mocked Notification Message

) as React.ElementType, + }, + }); + mock_DBot_store = mockDBotStore(mock_store, mock_ws); + + wrapper = ({ children }: { children: JSX.Element }) => ( + + + {children} + + + ); + }); + + it('should render BotNotificationMessages', () => { + const { container } = render(, { + wrapper, + }); + expect(container).toBeInTheDocument(); + expect(screen.getByTestId('dt_notifications_container')).toHaveClass('notifications-container'); + }); + + it('should apply notifications-container__dashboard class when active tab is 0 and is_info_panel_visible is true', () => { + mock_DBot_store!.dashboard.setInfoPanelVisibility(true); + + render(, { + wrapper, + }); + + expect(screen.getByTestId('dt_notifications_container')).toHaveClass( + 'notifications-container notifications-container__dashboard' + ); + }); + + it('should apply notifications-container--panel-open class when is_drawer_open is true and active tab has a value of 1 or 2', () => { + mock_DBot_store!.dashboard.setActiveTab(1); + mock_DBot_store!.run_panel.toggleDrawer(true); + + render(, { + wrapper, + }); + + expect(screen.getByTestId('dt_notifications_container')).toHaveClass( + 'notifications-container notifications-container--panel-open' + ); + }); +}); diff --git a/packages/bot-web-ui/src/components/bot-notification-messages/bot-notification-messages.tsx b/packages/bot-web-ui/src/components/bot-notification-messages/bot-notification-messages.tsx index 34bc22b1a3a6..5f915cea319a 100644 --- a/packages/bot-web-ui/src/components/bot-notification-messages/bot-notification-messages.tsx +++ b/packages/bot-web-ui/src/components/bot-notification-messages/bot-notification-messages.tsx @@ -20,6 +20,7 @@ const BotNotificationMessages = observer(() => { 'notifications-container__dashboard': active_tab === 0 && is_info_panel_visible, 'notifications-container--panel-open': [BOT_BUILDER, CHART].includes(active_tab) && is_drawer_open, })} + data-testid='dt_notifications_container' > diff --git a/packages/bot-web-ui/src/components/chart/__tests__/toolbar-widgets.spec.tsx b/packages/bot-web-ui/src/components/chart/__tests__/toolbar-widgets.spec.tsx new file mode 100644 index 000000000000..07a9b8c8eedc --- /dev/null +++ b/packages/bot-web-ui/src/components/chart/__tests__/toolbar-widgets.spec.tsx @@ -0,0 +1,71 @@ +import React from 'react'; +import { isDesktop, isMobile } from '@deriv/shared'; +import { mockStore, StoreProvider } from '@deriv/stores'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { render, screen } from '@testing-library/react'; +import { mock_ws } from 'Utils/mock'; +import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore'; +import ToolbarWidgets from '../toolbar-widgets'; + +jest.mock('@deriv/shared', () => ({ + ...jest.requireActual('@deriv/shared'), + isMobile: jest.fn(), + isDesktop: jest.fn(), +})); + +jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn()); +jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => ({ + saveRecentWorkspace: jest.fn(), + unHighlightAllBlocks: jest.fn(), +})); +jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn()); + +// // Mocking the imports from @deriv/deriv-charts +jest.mock('@deriv/deriv-charts', () => ({ + ...jest.requireActual('@deriv/deriv-charts'), + __esModule: true, + ChartMode: jest.fn(() =>
Mocked ChartMode
), + DrawTools: jest.fn(() =>
Mocked DrawTools
), + Share: jest.fn(() =>
Mocked Share
), + StudyLegend: jest.fn(() =>
Mocked StudyLegend
), + ToolbarWidget: jest.fn(({ children }) =>
{children}
), + Views: jest.fn(() =>
Mocked Views
), +})); + +describe('ToolbarWidgets', () => { + let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element; + + const mockUpdateChartType = jest.fn(); + const mockUpdateGranularity = jest.fn(); + + beforeAll(() => { + const mock_store = mockStore({}); + const mock_DBot_store = mockDBotStore(mock_store, mock_ws); + + wrapper = ({ children }: { children: JSX.Element }) => ( + + + {children} + + + ); + }); + + it('should render ToolbarWidgets in desktop', () => { + (isMobile as jest.Mock).mockReturnValueOnce(false); + (isDesktop as jest.Mock).mockReturnValueOnce(true); + render(, { + wrapper, + }); + expect(screen.getByText('Mocked StudyLegend')).toBeInTheDocument(); + }); + + it('should render ToolbarWidgets in mobile', () => { + (isMobile as jest.Mock).mockReturnValueOnce(true); + (isDesktop as jest.Mock).mockReturnValueOnce(false); + render(, { + wrapper, + }); + expect(screen.queryByText('Mocked StudyLegend')).not.toBeInTheDocument(); + }); +}); diff --git a/packages/bot-web-ui/src/components/contract-card-loading/__tests__/contract-card-loading.spec.tsx b/packages/bot-web-ui/src/components/contract-card-loading/__tests__/contract-card-loading.spec.tsx new file mode 100644 index 000000000000..fa7935458d2f --- /dev/null +++ b/packages/bot-web-ui/src/components/contract-card-loading/__tests__/contract-card-loading.spec.tsx @@ -0,0 +1,57 @@ +import React from 'react'; +import { mockStore, StoreProvider } from '@deriv/stores'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { render, screen } from '@testing-library/react'; +import { mock_ws } from 'Utils/mock'; +import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore'; +import ContractCardLoader from '../contract-card-loading'; + +jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn()); +jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => ({ + saveRecentWorkspace: jest.fn(), + unHighlightAllBlocks: jest.fn(), +})); +jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn()); + +describe('ContractCardLoader', () => { + let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element; + beforeAll(() => { + const mock_store = mockStore({}); + const mock_DBot_store = mockDBotStore(mock_store, mock_ws); + + wrapper = ({ children }: { children: JSX.Element }) => ( + + + {children} + + + ); + }); + + it('should render ContractCardLoader', () => { + render(, { + wrapper, + }); + expect(screen.getByTestId('contract-card-loader')).toBeInTheDocument(); + }); + + it('should render ContractCardLoader with default speed value', () => { + render(, { + wrapper, + }); + const svgElement = screen.getByTestId('contract-card-loader'); + // eslint-disable-next-line testing-library/no-node-access + const stopElement = svgElement.querySelector('animate'); // accessing the node directly to test the animation duration + expect(stopElement).toHaveAttribute('dur', '3s'); + }); + + it('should render ContractCardLoader with speed value passed as prop', () => { + render(, { + wrapper, + }); + const svgElement = screen.getByTestId('contract-card-loader'); + // eslint-disable-next-line testing-library/no-node-access + const stopElement = svgElement.querySelector('animate'); // accessing the node directly to test the animation duration + expect(stopElement).toHaveAttribute('dur', '5s'); + }); +}); diff --git a/packages/bot-web-ui/src/components/contract-card-loading/contract-card-loading.tsx b/packages/bot-web-ui/src/components/contract-card-loading/contract-card-loading.tsx index cc0ff4dcc85c..fe9d03e014e6 100644 --- a/packages/bot-web-ui/src/components/contract-card-loading/contract-card-loading.tsx +++ b/packages/bot-web-ui/src/components/contract-card-loading/contract-card-loading.tsx @@ -12,6 +12,7 @@ const ContractCardLoader = ({ speed = 3 }: TContractCardLoader) => ( speed={speed} backgroundColor={'var(--general-section-2)'} foregroundColor={'var(--general-hover)'} + data-testid='contract-card-loader' > diff --git a/packages/bot-web-ui/src/components/contract-result-overlay/contract-result-overlay.spec.tsx b/packages/bot-web-ui/src/components/contract-result-overlay/contract-result-overlay.spec.tsx new file mode 100644 index 000000000000..155ca9a8418b --- /dev/null +++ b/packages/bot-web-ui/src/components/contract-result-overlay/contract-result-overlay.spec.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { mockStore, StoreProvider } from '@deriv/stores'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { render, screen } from '@testing-library/react'; +import { mock_ws } from 'Utils/mock'; +import RootStore from 'Stores/index'; +import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore'; +import ContractResultOverlay from './contract-result-overlay'; + +jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn()); +jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => ({ + saveRecentWorkspace: jest.fn(), + unHighlightAllBlocks: jest.fn(), +})); +jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn()); + +describe('ContractResultOverlay', () => { + let wrapper: ({ children }: { children: JSX.Element }) => JSX.Element, mock_DBot_store: RootStore | undefined; + + beforeEach(() => { + jest.resetModules(); + const mock_store = mockStore({}); + mock_DBot_store = mockDBotStore(mock_store, mock_ws); + + wrapper = ({ children }: { children: JSX.Element }) => ( + + + {children} + + + ); + }); + + it('should render the ContractResultOverlay component', () => { + const { container } = render(, { + wrapper, + }); + expect(container).toBeInTheDocument(); + }); + + it('should show contract won', () => { + render(, { + wrapper, + }); + expect(screen.getByText('Won')).toBeInTheDocument(); + }); + + it('should show contract lost', () => { + render(, { + wrapper, + }); + expect(screen.getByText('Lost')).toBeInTheDocument(); + }); +}); diff --git a/packages/bot-web-ui/src/components/dashboard/__tests__/react-joyride-wrapper.spec.tsx b/packages/bot-web-ui/src/components/dashboard/__tests__/react-joyride-wrapper.spec.tsx new file mode 100644 index 000000000000..29e7ce344ece --- /dev/null +++ b/packages/bot-web-ui/src/components/dashboard/__tests__/react-joyride-wrapper.spec.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { mockStore, StoreProvider } from '@deriv/stores'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { render, screen } from '@testing-library/react'; +import { mock_ws } from 'Utils/mock'; +import { DBotStoreProvider, mockDBotStore } from '../../../stores/useDBotStore'; +import ReactJoyrideWrapper from '../react-joyride-wrapper'; + +jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn()); +jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => ({ + saveRecentWorkspace: jest.fn(), + unHighlightAllBlocks: jest.fn(), +})); +jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn()); +jest.mock('react-joyride', () => jest.fn(() =>
ReactJoyride
)); + +describe('ReactJoyrideWrapper', () => { + const mock_store = mockStore({}); + const mock_DBot_store = mockDBotStore(mock_store, mock_ws); + + const mocked_props = { + steps: [ + { + target: '.animation__wrapper', + content:
Content step 1
, + }, + { + target: '.animation__wrapper', + content:
Content step 2
, + }, + ], + styles: {}, + run: true, + }; + + it('should render ReactJoyrideWrapper', () => { + render( + + + + + + ); + + expect(screen.getByText('ReactJoyride')).toBeInTheDocument(); + }); +}); diff --git a/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbar/icon-button.tsx b/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbar/icon-button.tsx deleted file mode 100644 index 0800bcf6aaed..000000000000 --- a/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbar/icon-button.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import { Icon, Popover } from '@deriv/components'; -import { popover_zindex } from 'Constants/z-indexes'; - -type TIconButton = { - icon: string; - icon_id: string; - iconOnClick: () => void; - icon_color?: string; - popover_message: string; -}; - -const IconButton = ({ popover_message, icon, icon_id, icon_color, iconOnClick }: TIconButton) => { - return ( - - - - ); -}; - -export default IconButton; diff --git a/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/__tests__/search-icon.spec.tsx b/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/__tests__/search-icon.spec.tsx new file mode 100644 index 000000000000..2a6b9d586a37 --- /dev/null +++ b/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/__tests__/search-icon.spec.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import SearchIcon from '../search-box/search-icon'; + +jest.mock('@deriv/components', () => { + const original_module = jest.requireActual('@deriv/components'); + return { + ...original_module, + Icon: jest.fn(props => ( +
+ Icon +
+ )), + }; +}); + +const mocked_props = { + search: 'text', + is_search_loading: false, + onClick: jest.fn(), +}; + +describe('SearchIcon', () => { + it('should render the SearchIcon component', () => { + render(); + + const icon_element = screen.getByText('Icon'); + + expect(icon_element).toBeInTheDocument(); + }); + + it('should render the SearchIcon component with IcCloseCircle icon and has correct props when search value is not empty', () => { + render(); + + const icon_close_circle = screen.getByText('Icon'); + + expect(icon_close_circle).toBeInTheDocument(); + expect(icon_close_circle).toHaveAttribute('data-testid-color', 'secondary'); + expect(icon_close_circle).toHaveAttribute('data-testid-icon', 'IcCloseCircle'); + }); + + it('should render search icon when search is empty', () => { + render(); + + const search_icon = screen.getByText('Icon'); + + expect(search_icon).toBeInTheDocument(); + expect(search_icon).toHaveAttribute('data-testid-icon', 'IcSearch'); + }); + + it('should render loader when is_search_loading is true', () => { + render(); + + const loader = screen.getByTestId('loader'); + + expect(loader).toBeInTheDocument(); + expect(loader).toHaveClass('loader', { exact: true }); + }); +}); diff --git a/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/search-box/search-icon.tsx b/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/search-box/search-icon.tsx index 4083b76ce9fb..314af5040856 100644 --- a/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/search-box/search-icon.tsx +++ b/packages/bot-web-ui/src/components/dashboard/bot-builder/toolbox/search-box/search-icon.tsx @@ -9,7 +9,7 @@ type TSearchIcon = { const SearchIcon = ({ search, is_search_loading, onClick }: TSearchIcon) => { if (!search) return ; - if (is_search_loading) return
; + if (is_search_loading) return
; return ; }; diff --git a/packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/dashboard-component.spec.tsx b/packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/dashboard-component.spec.tsx index 9598e8cad2fa..8a4818ba48c3 100644 --- a/packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/dashboard-component.spec.tsx +++ b/packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/dashboard-component.spec.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { isMobile } from '@deriv/shared'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import Sidebar from '../sidebar'; import UserGuide from '../user-guide'; jest.mock('@deriv/components', () => { @@ -66,12 +65,4 @@ describe('', () => { expect(screen.getByTestId('btn-user-guide')).toBeInTheDocument(); expect(use_guide_button).toBeEnabled(); }); - - it('on user guide button click it should render the tutorials tab', () => { - render(); - const use_guide_button = screen.getByTestId('btn-user-guide'); - userEvent.click(use_guide_button); - render(); - expect(mocked_props.setActiveTab).toHaveBeenCalledWith(3); - }); }); diff --git a/packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/run-strategy.spec.tsx b/packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/run-strategy.spec.tsx new file mode 100644 index 000000000000..76405bb66b3a --- /dev/null +++ b/packages/bot-web-ui/src/components/dashboard/dashboard-component/__tests__/run-strategy.spec.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import RunStrategy from '../run-strategy'; + +jest.mock('../../../trade-animation/trade-animation', () => jest.fn(() =>
TradeAnimation
)); + +describe('RunStrategy', () => { + beforeEach(() => { + render(); + }); + + it('should render the RunStrategy component', () => { + const run_strategy = screen.getByTestId('dt_run_strategy'); + + expect(run_strategy).toBeInTheDocument(); + }); + + it('should render the TradeAnimation component inside of RunStrategy', () => { + const trade_animation = screen.getByText('TradeAnimation'); + + expect(trade_animation).toBeInTheDocument(); + }); +}); diff --git a/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/__tests__/bot-preview.spec.tsx b/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/__tests__/bot-preview.spec.tsx new file mode 100644 index 000000000000..e6206dfc0cb7 --- /dev/null +++ b/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/__tests__/bot-preview.spec.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { mockStore, StoreProvider } from '@deriv/stores'; +// eslint-disable-next-line import/no-extraneous-dependencies +import { render } from '@testing-library/react'; +import { mock_ws } from 'Utils/mock'; +import { DBotStoreProvider, mockDBotStore } from 'Stores/useDBotStore'; +import BotPreview from '../bot-preview'; + +jest.mock('@deriv/bot-skeleton/src/scratch/blockly', () => jest.fn()); +jest.mock('@deriv/bot-skeleton/src/scratch/dbot', () => ({ + saveRecentWorkspace: jest.fn(), + unHighlightAllBlocks: jest.fn(), +})); +jest.mock('@deriv/bot-skeleton/src/scratch/hooks/block_svg', () => jest.fn()); + +describe('BotPreview', () => { + it('should render BotPreview component with ref', () => { + const mock_store = mockStore({}); + const mock_DBot_store = mockDBotStore(mock_store, mock_ws); + const ref = React.createRef(); + + render( + + + + + + ); + + expect(ref.current).toBeInTheDocument(); + }); +}); diff --git a/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/bot-preview.tsx b/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/bot-preview.tsx index 1c39c2a400b0..8131c5d5d364 100644 --- a/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/bot-preview.tsx +++ b/packages/bot-web-ui/src/components/dashboard/dashboard-component/load-bot-preview/bot-preview.tsx @@ -1,8 +1,8 @@ -import React from 'react'; +import React, { RefObject } from 'react'; import WorkspaceControl from './workspace-control'; type TBotPreview = { - id_ref: HTMLElement | React.ReactNode | null; + id_ref: RefObject; }; const BotPreview = ({ id_ref }: TBotPreview) => { diff --git a/packages/bot-web-ui/src/components/dashboard/dashboard-component/run-strategy.tsx b/packages/bot-web-ui/src/components/dashboard/dashboard-component/run-strategy.tsx index bef7c154a4d6..57636875a838 100644 --- a/packages/bot-web-ui/src/components/dashboard/dashboard-component/run-strategy.tsx +++ b/packages/bot-web-ui/src/components/dashboard/dashboard-component/run-strategy.tsx @@ -2,7 +2,7 @@ import React from 'react'; import TradeAnimation from 'Components/trade-animation'; const RunStrategy = () => ( -
+
); diff --git a/packages/bot-web-ui/src/components/dashboard/dashboard-component/sidebar.tsx b/packages/bot-web-ui/src/components/dashboard/dashboard-component/sidebar.tsx deleted file mode 100644 index 18983c8264b5..000000000000 --- a/packages/bot-web-ui/src/components/dashboard/dashboard-component/sidebar.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; -import classNames from 'classnames'; -import { Icon } from '@deriv/components'; -import { SIDEBAR_INTRO } from './constants'; -import IntroCard from './intro-card'; - -type TSideBar = { - is_sidebar_open: boolean; - setSideBarState: (state: boolean) => void; -}; - -const Sidebar = ({ setSideBarState, is_sidebar_open }: TSideBar) => { - return ( -
-
- { - setSideBarState(false); - }} - /> -
- {SIDEBAR_INTRO.map(sidebar_item => { - const { label } = sidebar_item; - return ( - - ; - - ); - })} -
- ); -}; - -export default Sidebar;