diff --git a/.gitignore b/.gitignore index 6fdbfa9d..bd4f4a99 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,6 @@ env.json # baca-cli build scripts/cli/build/ scripts/cli/temp/ + +# maestro +e2e-debug-output diff --git a/.maestro/auth/login-with-validation.yaml b/.maestro/auth/login-with-validation.yaml index 61c29969..2ff10e86 100644 --- a/.maestro/auth/login-with-validation.yaml +++ b/.maestro/auth/login-with-validation.yaml @@ -1,12 +1,55 @@ -appId: host.exp.Exponent +appId: ${APP_ID} +tags: + - auth --- -- launchApp +# Check if the login screen is visible +- assertVisible: + id: 'sign_in:title' +- assertVisible: + id: 'sign_in:sub_title' +- assertVisible: + id: 'sign_in:email_input:label' + +# Check if empty email input is invalid - tapOn: - text: 'BACA (qa)' -- assertVisible: 'Welcome back' -- assertVisible: 'Remember me' + id: 'sign_in:submit_button' +- assertVisible: + id: 'sign_in:email_input:error_message' +- assertVisible: + id: 'sign_in:password_input:error_message' + +# Check if invalid email input and empty password is invalid - tapOn: - text: 'Remember me' -- assertVisible: 'Log in' -- tapOn: 'Log in' -- assertVisible: 'Home' + id: 'sign_in:email_input:input' +- inputText: 'invalid-email' +- hideKeyboard +- tapOn: + id: 'sign_in:submit_button' +- assertVisible: + id: 'sign_in:email_input:error_message' +- assertVisible: + id: 'sign_in:password_input:error_message' + +# Check if valid email input and empty password is invalid +- tapOn: + id: 'sign_in:email_input:input' +- eraseText +- inputText: 'email@test.com' +- hideKeyboard +- tapOn: + id: 'sign_in:submit_button' +- assertVisible: + id: 'sign_in:password_input:error_message' + +# Check if valid email input and password is valid +- tapOn: + id: 'sign_in:password_input:input' +- eraseText +- inputText: 'password' +- hideKeyboard +- tapOn: + id: 'sign_in:submit_button' + +# Check if login is successful +- assertVisible: + id: 'home_screen:title' diff --git a/.maestro/auth/logout-when-needed.yaml b/.maestro/auth/logout-when-needed.yaml new file mode 100644 index 00000000..4a03b5eb --- /dev/null +++ b/.maestro/auth/logout-when-needed.yaml @@ -0,0 +1,11 @@ +appId: ${APP_ID} +tags: + - auth +--- +- stopApp +- openLink: exp://127.0.0.1:8081/--/sign-in +- runFlow: + when: + visible: + id: 'home_screen:title' + file: ../utils/logout.yaml diff --git a/.maestro/categories/categories.yaml b/.maestro/categories/categories.yaml deleted file mode 100644 index 2a33bee2..00000000 --- a/.maestro/categories/categories.yaml +++ /dev/null @@ -1,7 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: ' Categories' -- tapOn: ' Categories' -- assertVisible: 'Categories screen' -- assertVisible: ' Example' -- tapOn: ' Example' diff --git a/.maestro/config.yaml b/.maestro/config.yaml index 6bcb08d5..1ff0c6c2 100644 --- a/.maestro/config.yaml +++ b/.maestro/config.yaml @@ -1,30 +1,25 @@ flows: - - auth/* - - home/* - - categories/* - - example/* - - settings/* - - profile/* + - 'auth/*' + - 'home/*' + - 'settings/*' + - 'profile/*' -excludeTags: - - utils +includeTags: + - 'auth' + - 'home' + - 'settings' + - 'profile' executionOrder: - continueOnFailure: true + continueOnFailure: false flowsOrder: - - login-with-validation - - details - - full-screen-form - - blog - - categories - - application-info - - colors - - components - - typography - - homestack - - data-backend - - test-form - - notifications-helpers - - user-session - - settings - - profile + - 'logout-when-needed' + - 'login-with-validation' + - 'details' + - 'full-screen-form' + - 'settings' + # https://github.com/mobile-dev-inc/maestro/issues/1484 + # Wait for it to be resolved and then remove blog from the list + # blog is not implemented, it's just a placeholder, to make tests run + - 'blog' + - 'profile' diff --git a/.maestro/example/application-info.yaml b/.maestro/example/application-info.yaml deleted file mode 100644 index af2f6cac..00000000 --- a/.maestro/example/application-info.yaml +++ /dev/null @@ -1,12 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to ApplicationInfo' -- tapOn: 'Go to ApplicationInfo' -- assertVisible: 'Go back' -- tapOn: 'Go back' -- assertVisible: "Don't leave" -- tapOn: "Don't leave" -- assertVisible: 'Go back' -- tapOn: 'Go back' -- assertVisible: 'Discard' -- tapOn: 'Discard' diff --git a/.maestro/example/colors.yaml b/.maestro/example/colors.yaml deleted file mode 100644 index 3fa1451f..00000000 --- a/.maestro/example/colors.yaml +++ /dev/null @@ -1,6 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to Colors' -- tapOn: 'Go to Colors' -- assertVisible: 'Examples' -- tapOn: 'Examples' diff --git a/.maestro/example/components.yaml b/.maestro/example/components.yaml deleted file mode 100644 index ef7481c9..00000000 --- a/.maestro/example/components.yaml +++ /dev/null @@ -1,62 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to Components' -- tapOn: - text: 'Go to Components' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Test notification' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Button primary' - waitToSettleTimeoutMs: 25 -- tapOn: - text: ' Button with icons ' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Button primary destructive' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Button secondary color' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Button secondary gray' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Button secondary destructive' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Button tertiary color' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Button tertiary gray' - waitToSettleTimeoutMs: 25 -- scrollUntilVisible: - element: - text: ' Log in with Apple' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- tapOn: 'Button tertiary destructive' -- tapOn: 'Button link color' -- tapOn: 'Button link gray' -- tapOn: 'Button link destructive' -- tapOn: 'Log in with Google' -- tapOn: ' Log in with Facebook' -- tapOn: ' Log in with Apple' -- assertVisible: 'Remember me' -- tapOn: 'Remember me' -- scrollUntilVisible: - element: - text: 'Disk loader' - direction: DOWN - timeout: 12500 - speed: 72 - visibilityPercentage: 50 -- tapOn: - text: '41-50' - waitToSettleTimeoutMs: 25 -- tapOn: - text: 'Examples' - waitToSettleTimeoutMs: 25 diff --git a/.maestro/example/data-backend.yaml b/.maestro/example/data-backend.yaml deleted file mode 100644 index f3bf2aa6..00000000 --- a/.maestro/example/data-backend.yaml +++ /dev/null @@ -1,6 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to screen with data from BE' -- tapOn: 'Go to screen with data from BE' -- assertVisible: 'Examples' -- tapOn: 'Examples' diff --git a/.maestro/example/homestack.yaml b/.maestro/example/homestack.yaml deleted file mode 100644 index 54e2ea26..00000000 --- a/.maestro/example/homestack.yaml +++ /dev/null @@ -1,12 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to HomeStackDetails' -- tapOn: 'Go to HomeStackDetails' -- assertVisible: 'Open BottomSheetModal' -- tapOn: 'Open BottomSheetModal' -- tapOn: - point: 50%,50% -- assertVisible: 'Home' -- tapOn: 'Home' -- assertVisible: ' Example' -- tapOn: ' Example' diff --git a/.maestro/example/notifications-helpers.yaml b/.maestro/example/notifications-helpers.yaml deleted file mode 100644 index 95628b1e..00000000 --- a/.maestro/example/notifications-helpers.yaml +++ /dev/null @@ -1,40 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to push notifications helpers' -- tapOn: 'Go to push notifications helpers' -- assertVisible: 'Copy push token' -- tapOn: 'Copy push token' -- assertVisible: 'OK' -- tapOn: 'OK' -- assertVisible: 'Check notifications permission status' -- tapOn: 'Check notifications permission status' -- scrollUntilVisible: - element: - text: 'Last push notification data' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- scrollUntilVisible: - element: - text: 'Scheduled notifications' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- assertVisible: 'Schedule new push notification - 10 seconds' -- tapOn: 'Schedule new push notification - 10 seconds' -- assertVisible: 'Get list of scheduled notifications' -- tapOn: 'Get list of scheduled notifications' -- assertVisible: 'PUSH TITLE' -- tapOn: 'Ok' -- scrollUntilVisible: - element: - text: 'Get list of scheduled notifications' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- tapOn: 'Get list of scheduled notifications' -- assertVisible: 'Examples' -- tapOn: 'Examples' diff --git a/.maestro/example/test-form.yaml b/.maestro/example/test-form.yaml deleted file mode 100644 index f54f0c06..00000000 --- a/.maestro/example/test-form.yaml +++ /dev/null @@ -1,66 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to test form' -- tapOn: 'Go to test form' -- assertVisible: 'Contact data' -- assertVisible: 'Name* Name' -- tapOn: 'Name* Name' -- inputText: 'RandomName' -- assertVisible: 'Surname* Surname' -- tapOn: 'Surname* Surname' -- inputText: 'RandomSurname' -- assertVisible: 'E-mail* E-mail' -- tapOn: 'E-mail* E-mail' -- inputRandomEmail -- assertVisible: 'Phone number* Phone number' -- tapOn: 'Phone number* Phone number' -- inputText: '600-000-000' -- assertVisible: 'Postal code* Postal code' -- tapOn: 'Postal code* Postal code' -- inputText: '00-000' -- assertVisible: 'City* City' -- tapOn: 'City* City' -- inputRandomText -- assertVisible: 'Age* 18-30 31-40 41-50 51-60 61-70 71-80 81-90 91-100' -- tapOn: '18-30' -- scrollUntilVisible: - element: - text: 'Interests* IT Cooking Sport Games Dancing' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- assertVisible: 'Sex* Male Female' -- tapOn: 'Male' -- assertVisible: 'Education* Education ' -- tapOn: 'Education* Education ' -- assertVisible: 'Bottom sheet handle' -# - tapOn: 'Postsecondary' -- assertVisible: 'Shoe size* Shoe size ' -- tapOn: 'Shoe size* Shoe size ' -- assertVisible: 'Bottom sheet handle' -# - tapOn: '40' -- scrollUntilVisible: - element: - text: 'Additional comment' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- assertVisible: 'what kind of music do you listen ?* Metal Heavy Metal Rock Pop Rap' -- tapOn: 'Rock' -- tapOn: 'Pop' -- tapOn: 'Rap' -- assertVisible: 'Interests* IT Cooking Sport Games Dancing' -- tapOn: 'IT' -- tapOn: 'Sport' -- scrollUntilVisible: - element: - text: 'Submit' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- tapOn: 'Submit' -- assertVisible: 'Examples' -- tapOn: 'Examples' diff --git a/.maestro/example/typography.yaml b/.maestro/example/typography.yaml deleted file mode 100644 index 59a5f26b..00000000 --- a/.maestro/example/typography.yaml +++ /dev/null @@ -1,24 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to Typography' -- tapOn: 'Go to Typography' -- assertVisible: '1' -- tapOn: '1' -- tapOn: '0' -- scrollUntilVisible: - element: - text: 'Display - MdBold' - direction: DOWN - timeout: 15000 - speed: 90 - visibilityPercentage: 100 - centerElement: true -- scrollUntilVisible: - element: - text: 'Text - XsRegular' - direction: DOWN - timeout: 15000 - speed: 90 - visibilityPercentage: 100 -- assertVisible: 'Examples' -- tapOn: 'Examples' diff --git a/.maestro/example/user-session.yaml b/.maestro/example/user-session.yaml deleted file mode 100644 index e7a49be4..00000000 --- a/.maestro/example/user-session.yaml +++ /dev/null @@ -1,18 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Go to user session' -- tapOn: 'Go to user session' -- assertVisible: 'Refetch user' -- tapOn: 'Refetch user' -- scrollUntilVisible: - element: - text: 'Try to get new token if needed' - direction: DOWN - timeout: 12500 - speed: 60 - visibilityPercentage: 100 -- tapOn: 'Try to get new token if needed' -- assertVisible: 'Examples' -- tapOn: 'Examples' -- assertVisible: ' Settings' -- tapOn: ' Settings' diff --git a/.maestro/home/blog.yaml b/.maestro/home/blog.yaml deleted file mode 100644 index 75f20b2b..00000000 --- a/.maestro/home/blog.yaml +++ /dev/null @@ -1,6 +0,0 @@ -appId: host.exp.Exponent ---- -- assertVisible: 'Open blog' -- tapOn: 'Open blog' -- assertVisible: '' -- tapOn: '' diff --git a/.maestro/home/details.yaml b/.maestro/home/details.yaml index 5dfd7a62..34eccd35 100644 --- a/.maestro/home/details.yaml +++ b/.maestro/home/details.yaml @@ -1,8 +1,14 @@ -appId: host.exp.Exponent +appId: ${APP_ID} +tags: + - home --- -- assertVisible: 'Details' -- tapOn: 'Details' -- assertVisible: 'Open BottomSheetModal' +- assertVisible: + id: 'home_screen:details' +- tapOn: + id: 'home_screen:details' +- extendedWaitUntil: + visible: 'Open BottomSheetModal' + timeout: 10000 - tapOn: 'Open BottomSheetModal' - tapOn: point: 50%,50% diff --git a/.maestro/home/full-screen-form.yaml b/.maestro/home/full-screen-form.yaml index 736a97a6..d0f4d517 100644 --- a/.maestro/home/full-screen-form.yaml +++ b/.maestro/home/full-screen-form.yaml @@ -1,8 +1,14 @@ -appId: host.exp.Exponent +appId: ${APP_ID} +tags: + - home --- -- assertVisible: 'Open full screen form' -- tapOn: 'Open full screen form' -- assertVisible: 'Contact data' +- assertVisible: + id: 'home_screen:full_screen_form' +- tapOn: + id: 'home_screen:full_screen_form' +- extendedWaitUntil: + visible: 'Contact data' + timeout: 10000 - assertVisible: 'Name* Name' - tapOn: 'Name* Name' - inputText: 'RandomName' @@ -37,11 +43,13 @@ appId: host.exp.Exponent - assertVisible: 'Education* Education ' - tapOn: 'Education* Education ' - assertVisible: 'Bottom sheet handle' -# - tapOn: 'Postsecondary' +- tapOn: + point: 6%,91% - assertVisible: 'Shoe size* Shoe size ' - tapOn: 'Shoe size* Shoe size ' - assertVisible: 'Bottom sheet handle' -# - tapOn: '40' +- tapOn: + point: 6%,91% - scrollUntilVisible: element: text: 'Additional comment' @@ -53,6 +61,13 @@ appId: host.exp.Exponent - tapOn: 'Rock' - tapOn: 'Pop' - tapOn: 'Rap' +- scrollUntilVisible: + element: + text: 'Submit' + direction: DOWN + timeout: 15000 + speed: 40 + visibilityPercentage: 100 - assertVisible: 'Interests* IT Cooking Sport Games Dancing' - tapOn: 'IT' - tapOn: 'Sport' diff --git a/.maestro/profile/profile.yaml b/.maestro/profile/profile.yaml index d08a373d..1ee76879 100644 --- a/.maestro/profile/profile.yaml +++ b/.maestro/profile/profile.yaml @@ -1,37 +1,36 @@ -appId: host.exp.Exponent +appId: ${APP_ID} +tags: + - profile --- -- assertVisible: 'Upload' -- tapOn: 'Upload' -- assertVisible: 'Photos' - tapOn: - index: 1 -- assertVisible: 'Choose' -- tapOn: 'Choose' -- assertVisible: 'First name' -- assertVisible: 'Last name' -- assertVisible: 'Cancel' -- tapOn: 'Cancel' -- assertVisible: 'Home' -- assertVisible: ' Profile' -- tapOn: ' Profile' -- assertVisible: 'Save' -- tapOn: 'Save' -- scrollUntilVisible: - element: - text: ' Remove account' - direction: DOWN - timeout: 15000 - speed: 40 - visibilityPercentage: 100 -- tapOn: 'Old password Enter current password ' -- inputRandomText -- assertVisible: 'Automatic Strong Password cover view text ' -- assertVisible: 'Change' -- tapOn: 'Change' -- assertVisible: ' Remove account' -- tapOn: ' Remove account' -- assertVisible: 'Bottom sheet handle' -- tapOn: - point: 50%,50% -- assertVisible: ' Home' -- tapOn: ' Home' + id: 'bottom_tab_button:profile' +# TODO: Properly implement the profile flow + +# CHANING USER DATA FLOW +# Change first name +# Change last name +# Save data +# Reload app +# Check if the changes are saved + +# CHANGING PASSWORD FLOW +# Input old password +# Input new password + +# Input wrong new password +# TODO: Finish the password flow +# - tapOn: +# id: 'passwordInput:input' +# - inputText: 'invalidpassword' +# - assertVisible: +# id: 'change_password:min_8_chars:success' +# - assertVisible: +# id: 'change_password:min_1_special_char:error' +# - tapOn: +# id: 'passwordInput:input' +# - inputText: 'invalidpassword!' +# - hideKeyboard +# - assertVisible: +# id: 'change_password:min_8_chars:success' +# - assertVisible: +# id: 'change_password:min_1_special_char:success' diff --git a/.maestro/settings/settings.yaml b/.maestro/settings/settings.yaml index c27d7b62..2d5544c5 100644 --- a/.maestro/settings/settings.yaml +++ b/.maestro/settings/settings.yaml @@ -1,19 +1,14 @@ -appId: host.exp.Exponent +appId: ${APP_ID} +tags: + - settings --- +- tapOn: + id: 'bottom_tab_button:settings' + +# TODO: Check if after changing the theme it really changes - assertVisible: 'light' - tapOn: 'light' - assertVisible: 'dark' - tapOn: 'dark' - assertVisible: 'system' - tapOn: 'system' -- assertVisible: 'Sign out!' -- tapOn: 'Sign out!' -- assertVisible: 'Welcome back' -- assertVisible: 'Remember me' -- tapOn: - text: 'Remember me' -- assertVisible: 'Log in' -- tapOn: 'Log in' -- assertVisible: 'Home' -- assertVisible: ' Profile' -- tapOn: ' Profile' diff --git a/.maestro/utils/hide-keyboard-android.yaml b/.maestro/utils/hide-keyboard-android.yaml deleted file mode 100644 index b92bc02d..00000000 --- a/.maestro/utils/hide-keyboard-android.yaml +++ /dev/null @@ -1,5 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- hideKeyboard diff --git a/.maestro/utils/hide-keyboard-ios.yaml b/.maestro/utils/hide-keyboard-ios.yaml deleted file mode 100644 index 0a0ff6fa..00000000 --- a/.maestro/utils/hide-keyboard-ios.yaml +++ /dev/null @@ -1,6 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- tapOn: - id: 'Return' # Keyboard Return diff --git a/.maestro/utils/hide-keyboard.yaml b/.maestro/utils/hide-keyboard.yaml deleted file mode 100644 index ca332310..00000000 --- a/.maestro/utils/hide-keyboard.yaml +++ /dev/null @@ -1,12 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- runFlow: - when: - platform: iOS - file: ./hide-keyboard-ios.yaml -- runFlow: - when: - platform: Android - file: ./hide-keyboard-android.yaml diff --git a/.maestro/utils/login.yaml b/.maestro/utils/login.yaml deleted file mode 100644 index aca9f74e..00000000 --- a/.maestro/utils/login.yaml +++ /dev/null @@ -1,22 +0,0 @@ -appId: ${APP_ID} -env: - Name: 'User' - EMAIL: 'user@test.com' - PASSWORD: 'password' -tags: - - util ---- -- tapOn: - id: 'name' -- inputText: ${Name} -- tapOn: - id: 'email-input' -- inputText: ${EMAIL} -- runFlow: ../utils/hide-keyboard.yaml -- tapOn: - id: 'password-input' -- inputText: ${PASSWORD} -- runFlow: ../utils/hide-keyboard.yaml -- tapOn: - id: 'login-button' -- assertVisible: 'Typography' diff --git a/.maestro/utils/logout.yaml b/.maestro/utils/logout.yaml new file mode 100644 index 00000000..c65e6558 --- /dev/null +++ b/.maestro/utils/logout.yaml @@ -0,0 +1,15 @@ +appId: ${APP_ID} +tags: + - util +--- +- tapOn: + id: 'bottom_tab_button:settings' + +- extendedWaitUntil: + visible: + id: 'settings:logout' + timeout: 1000 +- tapOn: + id: 'settings:logout' +- assertVisible: + id: 'sign_in:title' diff --git a/.maestro/utils/onboarding-and-login.yaml b/.maestro/utils/onboarding-and-login.yaml deleted file mode 100644 index 502f2de9..00000000 --- a/.maestro/utils/onboarding-and-login.yaml +++ /dev/null @@ -1,12 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- runFlow: - when: - visible: 'Obytes Starter' - file: onboarding.yaml -- runFlow: - when: - visible: Sign In - file: login.yaml diff --git a/.maestro/utils/onboarding.yaml b/.maestro/utils/onboarding.yaml deleted file mode 100644 index bb1b8937..00000000 --- a/.maestro/utils/onboarding.yaml +++ /dev/null @@ -1,8 +0,0 @@ -appId: ${APP_ID} -tags: - - util ---- -- assertVisible: 'Obytes Starter' -- assertVisible: "Let's Get Started " -- tapOn: "Let's Get Started " -- assertVisible: 'Sign In' diff --git a/App.tsx b/App.tsx index 2a69b483..654800eb 100644 --- a/App.tsx +++ b/App.tsx @@ -9,14 +9,17 @@ import 'core-js/stable/atob' // Rest imports import '@baca/i18n' +import { isMock } from '@baca/constants' import { enableAndroidBackgroundNotificationListener, startMockedServer } from '@baca/services' import * as Device from 'expo-device' import 'expo-router/entry' -const ENABLE_MOCKED_SERVER = false +const ENABLE_MOCKED_SERVER = isMock if (ENABLE_MOCKED_SERVER) { startMockedServer() + console.error = () => {} + console.warn = () => {} } // TODO: Uncomment reactotron setup when using diff --git a/docs/docs/data-management/MOCKING.md b/docs/docs/data-management/MOCKING.md index bbddf2a2..5f4b539d 100644 --- a/docs/docs/data-management/MOCKING.md +++ b/docs/docs/data-management/MOCKING.md @@ -22,12 +22,22 @@ Mocks are automatically generated with orval script - you can check [docs here]( ## Enabling mocks +You have two types of enabling mocks in the app + +1. Start server and set mock on start + +``` +IS_MOCK=true yarn start +``` + +2. Enable mock manually + Go to `App.tsx` and change `ENABLE_MOCKED_SERVER` variable from false to true ```tsx title="/App.tsx" // FIXME: moking not working on mobile app - follow this discussion https://github.com/mswjs/msw/issues/2026 // error-line -const ENABLE_MOCKED_SERVER = false +const ENABLE_MOCKED_SERVER = isMock // success-line const ENABLE_MOCKED_SERVER = true diff --git a/docs/docs/testing/TESTING_E2E.md b/docs/docs/testing/TESTING_E2E.md new file mode 100644 index 00000000..f52e82ac --- /dev/null +++ b/docs/docs/testing/TESTING_E2E.md @@ -0,0 +1,34 @@ +--- +id: jotai +slug: /jotai +title: E2E tests - maestro +sidebar_position: 4 +tags: + - E2E + - E2E tests + - Testing + - Maestro +description: E2E tests with maestro +--- + +# E2E tests with maestro + +## Installing Maestro + +To install Maestro, run the following : + +``` +# it's a simple npm script that runs the following command: curl -Ls 'https://get.maestro.mobile.dev' | bash +yarn install-maestro +``` + +## Tutorial + + + +1. Maestro works on normal apps that are already built on a device. This means we can skip the slow native builds by using Expo Go with `yarn start:e2e`. + +Problem: + +- Maestro tests are not running on clean app, that means if you were logged before we should logout user, fortunatelly we have solved making maestro e2e test: `logout-when-needed.yaml` +- Maestro tests for baca are build for expo go, that means we have to start server and build app before running tests. If you will not do that tests will not pass, because server is starting for ~1min and tests are runing instantly (the best option whould be to wait with tests, but for some reason maestro wait don't work properly) diff --git a/docs/docs/testing/_category_.json b/docs/docs/testing/_category_.json new file mode 100644 index 00000000..7f6ab004 --- /dev/null +++ b/docs/docs/testing/_category_.json @@ -0,0 +1,10 @@ +{ + "label": "Testing", + "position": 7, + "collapsible": true, + "collapsed": false, + "link": { + "type": "generated-index", + "description": "Testing using unit tests or E2E tests" + } +} diff --git a/orval.config.ts b/orval.config.ts index 20b0f691..00321516 100644 --- a/orval.config.ts +++ b/orval.config.ts @@ -10,7 +10,6 @@ export default defineConfig({ client: 'react-query', // solution for not working mocked data on mobile - it removes automatically added "*" to address url at the beginning mock: { - baseUrl: '', type: 'msw', }, clean: true, diff --git a/package.json b/package.json index 1a90351b..96d11bd0 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "deploy:staging:android": "yarn prepare:staging && eas build --platform android --profile staging --auto-submit --non-interactive", "deploy:staging:ios": "yarn prepare:staging && eas build --platform ios --profile staging --auto-submit --non-interactive", "deploy:staging": "yarn prepare:staging && eas build --platform all --profile staging --auto-submit --non-interactive", - "e2e-testing": "maestro test .maestro/ -e APP_ID=host.exp.Exponent", "eas-build-pre-install": "base64 --help && echo $ANDROID_FIREBASE_CONFIG | base64 --decode > google-services.json && cat google-services.json && echo $IOS_FIREBASE_CONFIG | base64 --decode > GoogleService-Info.plist && cat GoogleService-Info.plist", "g": "yarn baca g", "generate:env:production": "scripts/generate_dotenv.sh production", @@ -58,6 +57,7 @@ "generate:query": "yarn orval --config ./orval.config.ts", "ios:dev-client": "IS_DEV=1 npx expo run:ios", "ios": "expo run:ios", + "install-maestro": "curl -Ls 'https://get.maestro.mobile.dev' | bash", "lint:fix": "eslint src --fix", "lint": "eslint src && yarn tsc", "postinstall": "patch-package && yarn build:baca-cli", @@ -72,9 +72,11 @@ "start:production": "yarn generate:env:production && IS_DEV=1 IS_EXPO_GO=1 expo start -c -g", "start:staging": "yarn generate:env:staging && IS_DEV=1 IS_EXPO_GO=1 expo start -c -g", "start": "yarn generate:env:qa && cross-env IS_DEV=1 IS_EXPO_GO=1 expo start -c -g", + "start:e2e": "yarn generate:env:qa && cross-env IS_MOCK=1 IS_DEV=1 IS_EXPO_GO=1 npx expo start -c -g --no-dev --minify", "test:debug": "jest -o --watch --coverage=false", "test:final": "jest", "test": "jest --watch --coverage=false --changedSince=origin/main", + "test:e2e": "maestro test .maestro/ -e APP_ID=host.exp.Exponent --debug-output=./e2e-debug-output", "typecheck": "eslint .eslintrc.js --fix", "update:expo_go": "yarn prepare:qa && cross-env IS_DEV=1 eas update --auto", "update:production:android": "yarn prepare:production && eas update --branch production --platform android && yarn generate:last:publish production", @@ -142,7 +144,6 @@ "i18next": "^23.7.20", "jotai": "^2.8.1", "jwt-decode": "^4.0.0", - "maestro": "^2.1.1", "moti": "^0.25.3", "react": "18.2.0", "react-dom": "18.2.0", @@ -198,8 +199,8 @@ "jest": "^29.6.1", "jest-expo": "~51.0.3", "lint-staged": "^13.2.3", - "msw": "^2.3.0", - "orval": "^6.29.1", + "msw": "^2.3.5", + "orval": "^7.0.1", "patch-package": "^7.0.1", "prettier": "^2.8.8", "pretty-quick": "^4.0.0", diff --git a/patches/@mswjs+interceptors+0.29.1.patch b/patches/@mswjs+interceptors+0.29.1.patch new file mode 100644 index 00000000..540bd91a --- /dev/null +++ b/patches/@mswjs+interceptors+0.29.1.patch @@ -0,0 +1,18 @@ +diff --git a/node_modules/@mswjs/interceptors/lib/browser/chunk-PSX5J3RF.js b/node_modules/@mswjs/interceptors/lib/browser/chunk-PSX5J3RF.js +index 37e2a0f..48d16d6 100644 +--- a/node_modules/@mswjs/interceptors/lib/browser/chunk-PSX5J3RF.js ++++ b/node_modules/@mswjs/interceptors/lib/browser/chunk-PSX5J3RF.js +@@ -457,6 +457,13 @@ var XMLHttpRequestController = class { + readNextResponseBodyChunk(); + }; + readNextResponseBodyChunk(); ++ } else if (response._bodyInit) { ++ this.logger.info('mocked response has _bodyInit, faking streaming...') ++ ++ const bodyInit = response._bodyInit ++ const encoder = new TextEncoder() ++ this.responseBuffer = encoder.encode(bodyInit) ++ finalizeResponse() + } else { + finalizeResponse(); + } diff --git a/src/api/query/articles/articles.msw.ts b/src/api/query/articles/articles.msw.ts index 2e23759b..1485e297 100644 --- a/src/api/query/articles/articles.msw.ts +++ b/src/api/query/articles/articles.msw.ts @@ -12,13 +12,12 @@ import { HttpResponse, delay, http } from 'msw' import type { ArticleEntity } from '../../types' export const getArticlesControllerCreateResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): ArticleEntity => ({ author: { email: faker.word.sample(), firstName: faker.word.sample(), lastName: faker.word.sample(), - ...overrideResponse, }, authorId: faker.helpers.arrayElement([ faker.helpers.arrayElement([faker.word.sample(), null]), @@ -38,15 +37,12 @@ export const getArticlesControllerCreateResponseMock = ( ...overrideResponse, }) -export const getArticlesControllerFindAllResponseMock = ( - overrideResponse: any = {} -): ArticleEntity[] => +export const getArticlesControllerFindAllResponseMock = (): ArticleEntity[] => Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ author: { email: faker.word.sample(), firstName: faker.word.sample(), lastName: faker.word.sample(), - ...overrideResponse, }, authorId: faker.helpers.arrayElement([ faker.helpers.arrayElement([faker.word.sample(), null]), @@ -63,18 +59,14 @@ export const getArticlesControllerFindAllResponseMock = ( published: faker.datatype.boolean(), title: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, })) -export const getArticlesControllerFindDraftsResponseMock = ( - overrideResponse: any = {} -): ArticleEntity[] => +export const getArticlesControllerFindDraftsResponseMock = (): ArticleEntity[] => Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ author: { email: faker.word.sample(), firstName: faker.word.sample(), lastName: faker.word.sample(), - ...overrideResponse, }, authorId: faker.helpers.arrayElement([ faker.helpers.arrayElement([faker.word.sample(), null]), @@ -91,17 +83,15 @@ export const getArticlesControllerFindDraftsResponseMock = ( published: faker.datatype.boolean(), title: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, })) export const getArticlesControllerFindOneResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): ArticleEntity => ({ author: { email: faker.word.sample(), firstName: faker.word.sample(), lastName: faker.word.sample(), - ...overrideResponse, }, authorId: faker.helpers.arrayElement([ faker.helpers.arrayElement([faker.word.sample(), null]), @@ -122,13 +112,12 @@ export const getArticlesControllerFindOneResponseMock = ( }) export const getArticlesControllerUpdateResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): ArticleEntity => ({ author: { email: faker.word.sample(), firstName: faker.word.sample(), lastName: faker.word.sample(), - ...overrideResponse, }, authorId: faker.helpers.arrayElement([ faker.helpers.arrayElement([faker.word.sample(), null]), @@ -148,100 +137,132 @@ export const getArticlesControllerUpdateResponseMock = ( ...overrideResponse, }) -export const getArticlesControllerCreateMockHandler = (overrideResponse?: ArticleEntity) => { - return http.post('/api/v1/articles', async () => { +export const getArticlesControllerCreateMockHandler = ( + overrideResponse?: + | ArticleEntity + | (( + info: Parameters[1]>[0] + ) => Promise | ArticleEntity) +) => { + return http.post('*/api/v1/articles', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getArticlesControllerCreateResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getArticlesControllerCreateResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getArticlesControllerFindAllMockHandler = (overrideResponse?: ArticleEntity[]) => { - return http.get('/api/v1/articles', async () => { +export const getArticlesControllerFindAllMockHandler = ( + overrideResponse?: + | ArticleEntity[] + | (( + info: Parameters[1]>[0] + ) => Promise | ArticleEntity[]) +) => { + return http.get('*/api/v1/articles', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getArticlesControllerFindAllResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getArticlesControllerFindAllResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 200, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getArticlesControllerFindDraftsMockHandler = (overrideResponse?: ArticleEntity[]) => { - return http.get('/api/v1/articles/drafts', async () => { +export const getArticlesControllerFindDraftsMockHandler = ( + overrideResponse?: + | ArticleEntity[] + | (( + info: Parameters[1]>[0] + ) => Promise | ArticleEntity[]) +) => { + return http.get('*/api/v1/articles/drafts', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getArticlesControllerFindDraftsResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getArticlesControllerFindDraftsResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 200, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getArticlesControllerFindOneMockHandler = (overrideResponse?: ArticleEntity) => { - return http.get('/api/v1/articles/:id', async () => { +export const getArticlesControllerFindOneMockHandler = ( + overrideResponse?: + | ArticleEntity + | (( + info: Parameters[1]>[0] + ) => Promise | ArticleEntity) +) => { + return http.get('*/api/v1/articles/:id', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getArticlesControllerFindOneResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getArticlesControllerFindOneResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 200, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getArticlesControllerUpdateMockHandler = (overrideResponse?: ArticleEntity) => { - return http.patch('/api/v1/articles/:id', async () => { +export const getArticlesControllerUpdateMockHandler = ( + overrideResponse?: + | ArticleEntity + | (( + info: Parameters[1]>[0] + ) => Promise | ArticleEntity) +) => { + return http.patch('*/api/v1/articles/:id', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getArticlesControllerUpdateResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getArticlesControllerUpdateResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getArticlesControllerRemoveMockHandler = () => { - return http.delete('/api/v1/articles/:id', async () => { +export const getArticlesControllerRemoveMockHandler = ( + overrideResponse?: + | void + | ((info: Parameters[1]>[0]) => Promise | void) +) => { + return http.delete('*/api/v1/articles/:id', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 204 }) }) } export const getArticlesMock = () => [ diff --git a/src/api/query/articles/articles.ts b/src/api/query/articles/articles.ts index f905a8f1..cdae0924 100644 --- a/src/api/query/articles/articles.ts +++ b/src/api/query/articles/articles.ts @@ -12,6 +12,7 @@ import type { QueryFunction, QueryKey, UseMutationOptions, + UseMutationResult, UseQueryOptions, UseQueryResult, } from '@tanstack/react-query' @@ -102,7 +103,12 @@ export const useArticlesControllerCreate = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getArticlesControllerCreateMutationOptions(options) return useMutation(mutationOptions) @@ -159,7 +165,8 @@ export type ArticlesControllerFindAllQueryError = ErrorType /** * @summary Find All Articles */ -export const useArticlesControllerFindAll = < + +export function useArticlesControllerFindAll< TData = Awaited>, TError = ErrorType >( @@ -168,7 +175,7 @@ export const useArticlesControllerFindAll = < query?: UseQueryOptions>, TError, TData> request?: SecondParameter } -): UseQueryResult & { queryKey: QueryKey } => { +): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getArticlesControllerFindAllQueryOptions(params, options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } @@ -232,7 +239,8 @@ export type ArticlesControllerFindDraftsQueryError = ErrorType>, TError = ErrorType >( @@ -241,7 +249,7 @@ export const useArticlesControllerFindDrafts = < query?: UseQueryOptions>, TError, TData> request?: SecondParameter } -): UseQueryResult & { queryKey: QueryKey } => { +): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getArticlesControllerFindDraftsQueryOptions(params, options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } @@ -303,7 +311,8 @@ export type ArticlesControllerFindOneQueryError = ErrorType /** * @summary Find Article by ID */ -export const useArticlesControllerFindOne = < + +export function useArticlesControllerFindOne< TData = Awaited>, TError = ErrorType >( @@ -312,7 +321,7 @@ export const useArticlesControllerFindOne = < query?: UseQueryOptions>, TError, TData> request?: SecondParameter } -): UseQueryResult & { queryKey: QueryKey } => { +): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getArticlesControllerFindOneQueryOptions(id, options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } @@ -395,7 +404,12 @@ export const useArticlesControllerUpdate = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { id: number; data: BodyType }, + TContext +> => { const mutationOptions = getArticlesControllerUpdateMutationOptions(options) return useMutation(mutationOptions) @@ -462,7 +476,12 @@ export const useArticlesControllerRemove = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { id: number }, + TContext +> => { const mutationOptions = getArticlesControllerRemoveMutationOptions(options) return useMutation(mutationOptions) diff --git a/src/api/query/auth-social/auth-social.msw.ts b/src/api/query/auth-social/auth-social.msw.ts index d8a465ab..1bed2c69 100644 --- a/src/api/query/auth-social/auth-social.msw.ts +++ b/src/api/query/auth-social/auth-social.msw.ts @@ -12,7 +12,7 @@ import { HttpResponse, delay, http } from 'msw' import type { AuthEntity } from '../../types' export const getAuthGoogleControllerLoginResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): AuthEntity => ({ accessToken: faker.word.sample(), refreshToken: faker.word.sample(), @@ -26,7 +26,6 @@ export const getAuthGoogleControllerLoginResponseMock = ( termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -39,24 +38,18 @@ export const getAuthGoogleControllerLoginResponseMock = ( locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, ...overrideResponse, }) export const getAuthFacebookControllerLoginResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): AuthEntity => ({ accessToken: faker.word.sample(), refreshToken: faker.word.sample(), @@ -70,7 +63,6 @@ export const getAuthFacebookControllerLoginResponseMock = ( termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -83,24 +75,18 @@ export const getAuthFacebookControllerLoginResponseMock = ( locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, ...overrideResponse, }) export const getAuthAppleControllerLoginResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): AuthEntity => ({ accessToken: faker.word.sample(), refreshToken: faker.word.sample(), @@ -114,7 +100,6 @@ export const getAuthAppleControllerLoginResponseMock = ( termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -127,69 +112,75 @@ export const getAuthAppleControllerLoginResponseMock = ( locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, ...overrideResponse, }) -export const getAuthGoogleControllerLoginMockHandler = (overrideResponse?: AuthEntity) => { - return http.post('/api/v1/auth/google/login', async () => { +export const getAuthGoogleControllerLoginMockHandler = ( + overrideResponse?: + | AuthEntity + | ((info: Parameters[1]>[0]) => Promise | AuthEntity) +) => { + return http.post('*/api/v1/auth/google/login', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getAuthGoogleControllerLoginResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getAuthGoogleControllerLoginResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getAuthFacebookControllerLoginMockHandler = (overrideResponse?: AuthEntity) => { - return http.post('/api/v1/auth/facebook/login', async () => { +export const getAuthFacebookControllerLoginMockHandler = ( + overrideResponse?: + | AuthEntity + | ((info: Parameters[1]>[0]) => Promise | AuthEntity) +) => { + return http.post('*/api/v1/auth/facebook/login', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getAuthFacebookControllerLoginResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getAuthFacebookControllerLoginResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getAuthAppleControllerLoginMockHandler = (overrideResponse?: AuthEntity) => { - return http.post('/api/v1/auth/apple/login', async () => { +export const getAuthAppleControllerLoginMockHandler = ( + overrideResponse?: + | AuthEntity + | ((info: Parameters[1]>[0]) => Promise | AuthEntity) +) => { + return http.post('*/api/v1/auth/apple/login', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getAuthAppleControllerLoginResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getAuthAppleControllerLoginResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } diff --git a/src/api/query/auth-social/auth-social.ts b/src/api/query/auth-social/auth-social.ts index ad3ce63b..8b81010f 100644 --- a/src/api/query/auth-social/auth-social.ts +++ b/src/api/query/auth-social/auth-social.ts @@ -7,7 +7,7 @@ * OpenAPI spec version: 1.0 */ import { useMutation } from '@tanstack/react-query' -import type { MutationFunction, UseMutationOptions } from '@tanstack/react-query' +import type { MutationFunction, UseMutationOptions, UseMutationResult } from '@tanstack/react-query' import { customInstance } from '../../axios/custom-instance' import type { ErrorType, BodyType } from '../../axios/custom-instance' @@ -92,7 +92,12 @@ export const useAuthGoogleControllerLogin = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthGoogleControllerLoginMutationOptions(options) return useMutation(mutationOptions) @@ -167,7 +172,12 @@ export const useAuthFacebookControllerLogin = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthFacebookControllerLoginMutationOptions(options) return useMutation(mutationOptions) @@ -242,7 +252,12 @@ export const useAuthAppleControllerLogin = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthAppleControllerLoginMutationOptions(options) return useMutation(mutationOptions) diff --git a/src/api/query/auth/auth.msw.ts b/src/api/query/auth/auth.msw.ts index 1df12bae..c4a0d116 100644 --- a/src/api/query/auth/auth.msw.ts +++ b/src/api/query/auth/auth.msw.ts @@ -11,7 +11,9 @@ import { HttpResponse, delay, http } from 'msw' import type { AuthEntity, RefreshEntity, UserEntity } from '../../types' -export const getAuthControllerLoginResponseMock = (overrideResponse: any = {}): AuthEntity => ({ +export const getAuthControllerLoginResponseMock = ( + overrideResponse: Partial = {} +): AuthEntity => ({ accessToken: faker.word.sample(), refreshToken: faker.word.sample(), tokenExpires: faker.number.int({ min: undefined, max: undefined }), @@ -24,7 +26,6 @@ export const getAuthControllerLoginResponseMock = (overrideResponse: any = {}): termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -37,23 +38,19 @@ export const getAuthControllerLoginResponseMock = (overrideResponse: any = {}): locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, ...overrideResponse, }) -export const getAuthControllerRegisterResponseMock = (overrideResponse: any = {}): UserEntity => ({ +export const getAuthControllerRegisterResponseMock = ( + overrideResponse: Partial = {} +): UserEntity => ({ consent: faker.helpers.arrayElement([ { createdAt: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -62,7 +59,6 @@ export const getAuthControllerRegisterResponseMock = (overrideResponse: any = {} termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -75,21 +71,18 @@ export const getAuthControllerRegisterResponseMock = (overrideResponse: any = {} locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, ...overrideResponse, }) -export const getAuthControllerMeResponseMock = (overrideResponse: any = {}): UserEntity => ({ +export const getAuthControllerMeResponseMock = ( + overrideResponse: Partial = {} +): UserEntity => ({ consent: faker.helpers.arrayElement([ { createdAt: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -98,7 +91,6 @@ export const getAuthControllerMeResponseMock = (overrideResponse: any = {}): Use termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -111,22 +103,17 @@ export const getAuthControllerMeResponseMock = (overrideResponse: any = {}): Use locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, ...overrideResponse, }) export const getAuthControllerRefreshResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): RefreshEntity => ({ accessToken: faker.word.sample(), refreshToken: faker.word.sample(), @@ -134,183 +121,229 @@ export const getAuthControllerRefreshResponseMock = ( ...overrideResponse, }) -export const getAuthControllerLoginMockHandler = (overrideResponse?: AuthEntity) => { - return http.post('/api/v1/auth/email/login', async () => { +export const getAuthControllerLoginMockHandler = ( + overrideResponse?: + | AuthEntity + | ((info: Parameters[1]>[0]) => Promise | AuthEntity) +) => { + return http.post('*/api/v1/auth/email/login', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getAuthControllerLoginResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getAuthControllerLoginResponseMock() + ), + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getAuthControllerRegisterMockHandler = (overrideResponse?: UserEntity) => { - return http.post('/api/v1/auth/email/register', async () => { +export const getAuthControllerRegisterMockHandler = ( + overrideResponse?: + | UserEntity + | ((info: Parameters[1]>[0]) => Promise | UserEntity) +) => { + return http.post('*/api/v1/auth/email/register', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getAuthControllerRegisterResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getAuthControllerRegisterResponseMock() + ), + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getAuthControllerConfirmEmailMockHandler = () => { - return http.post('/api/v1/auth/email/confirm', async () => { +export const getAuthControllerConfirmEmailMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/email/confirm', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerResendVerificationEmailMockHandler = () => { - return http.post('/api/v1/auth/email/resend', async () => { +export const getAuthControllerResendVerificationEmailMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/email/resend', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerForgotPasswordMockHandler = () => { - return http.post('/api/v1/auth/forgot/password', async () => { +export const getAuthControllerForgotPasswordMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/forgot/password', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerResetPasswordMockHandler = () => { - return http.post('/api/v1/auth/reset/password', async () => { +export const getAuthControllerResetPasswordMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/reset/password', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerEmailChangeMockHandler = () => { - return http.post('/api/v1/auth/email/change', async () => { +export const getAuthControllerEmailChangeMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/email/change', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerConfirmEmailChangeMockHandler = () => { - return http.post('/api/v1/auth/email/change-confirm', async () => { +export const getAuthControllerConfirmEmailChangeMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/email/change-confirm', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerMeMockHandler = (overrideResponse?: UserEntity) => { - return http.get('/api/v1/auth/me', async () => { +export const getAuthControllerMeMockHandler = ( + overrideResponse?: + | UserEntity + | ((info: Parameters[1]>[0]) => Promise | UserEntity) +) => { + return http.get('*/api/v1/auth/me', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getAuthControllerMeResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getAuthControllerMeResponseMock() + ), + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getAuthControllerUpdateMockHandler = () => { - return http.patch('/api/v1/auth/me', async () => { +export const getAuthControllerUpdateMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.patch('*/api/v1/auth/me', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerDeleteMockHandler = () => { - return http.delete('/api/v1/auth/me', async () => { +export const getAuthControllerDeleteMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.delete('*/api/v1/auth/me', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerRefreshMockHandler = (overrideResponse?: RefreshEntity) => { - return http.post('/api/v1/auth/refresh', async () => { +export const getAuthControllerRefreshMockHandler = ( + overrideResponse?: + | RefreshEntity + | (( + info: Parameters[1]>[0] + ) => Promise | RefreshEntity) +) => { + return http.post('*/api/v1/auth/refresh', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getAuthControllerRefreshResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getAuthControllerRefreshResponseMock() + ), + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getAuthControllerLogoutMockHandler = () => { - return http.post('/api/v1/auth/logout', async () => { +export const getAuthControllerLogoutMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/logout', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getAuthControllerLogoutAllMockHandler = () => { - return http.post('/api/v1/auth/logout/all', async () => { +export const getAuthControllerLogoutAllMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.post('*/api/v1/auth/logout/all', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } export const getAuthMock = () => [ diff --git a/src/api/query/auth/auth.ts b/src/api/query/auth/auth.ts index cb0b353a..ed28a70e 100644 --- a/src/api/query/auth/auth.ts +++ b/src/api/query/auth/auth.ts @@ -12,6 +12,7 @@ import type { QueryFunction, QueryKey, UseMutationOptions, + UseMutationResult, UseQueryOptions, UseQueryResult, } from '@tanstack/react-query' @@ -128,7 +129,12 @@ export const useAuthControllerLogin = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerLoginMutationOptions(options) return useMutation(mutationOptions) @@ -205,7 +211,12 @@ export const useAuthControllerRegister = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerRegisterMutationOptions(options) return useMutation(mutationOptions) @@ -282,7 +293,12 @@ export const useAuthControllerConfirmEmail = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerConfirmEmailMutationOptions(options) return useMutation(mutationOptions) @@ -364,7 +380,12 @@ export const useAuthControllerResendVerificationEmail = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerResendVerificationEmailMutationOptions(options) return useMutation(mutationOptions) @@ -445,7 +466,12 @@ export const useAuthControllerForgotPassword = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerForgotPasswordMutationOptions(options) return useMutation(mutationOptions) @@ -526,7 +552,12 @@ export const useAuthControllerResetPassword = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerResetPasswordMutationOptions(options) return useMutation(mutationOptions) @@ -607,7 +638,12 @@ export const useAuthControllerEmailChange = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerEmailChangeMutationOptions(options) return useMutation(mutationOptions) @@ -684,7 +720,12 @@ export const useAuthControllerConfirmEmailChange = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerConfirmEmailChangeMutationOptions(options) return useMutation(mutationOptions) @@ -731,13 +772,14 @@ export type AuthControllerMeQueryError = ErrorType>, TError = ErrorType >(options?: { query?: UseQueryOptions>, TError, TData> request?: SecondParameter -}): UseQueryResult & { queryKey: QueryKey } => { +}): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getAuthControllerMeQueryOptions(options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } @@ -819,7 +861,12 @@ export const useAuthControllerUpdate = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getAuthControllerUpdateMutationOptions(options) return useMutation(mutationOptions) @@ -883,7 +930,7 @@ export const useAuthControllerDelete = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult>, TError, void, TContext> => { const mutationOptions = getAuthControllerDeleteMutationOptions(options) return useMutation(mutationOptions) @@ -947,7 +994,12 @@ export const useAuthControllerRefresh = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + void, + TContext +> => { const mutationOptions = getAuthControllerRefreshMutationOptions(options) return useMutation(mutationOptions) @@ -1011,7 +1063,7 @@ export const useAuthControllerLogout = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult>, TError, void, TContext> => { const mutationOptions = getAuthControllerLogoutMutationOptions(options) return useMutation(mutationOptions) @@ -1075,7 +1127,12 @@ export const useAuthControllerLogoutAll = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + void, + TContext +> => { const mutationOptions = getAuthControllerLogoutAllMutationOptions(options) return useMutation(mutationOptions) diff --git a/src/api/query/files/files.msw.ts b/src/api/query/files/files.msw.ts index cc5c50b2..d5797d52 100644 --- a/src/api/query/files/files.msw.ts +++ b/src/api/query/files/files.msw.ts @@ -12,7 +12,7 @@ import { HttpResponse, delay, http } from 'msw' import type { FileEntity } from '../../types' export const getFilesControllerUploadFileResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): FileEntity => ({ category: faker.helpers.arrayElement([faker.word.sample(), null]), createdAt: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -25,44 +25,52 @@ export const getFilesControllerUploadFileResponseMock = ( ...overrideResponse, }) -export const getFilesControllerUploadFileMockHandler = (overrideResponse?: FileEntity) => { - return http.post('/api/v1/files/upload', async () => { +export const getFilesControllerUploadFileMockHandler = ( + overrideResponse?: + | FileEntity + | ((info: Parameters[1]>[0]) => Promise | FileEntity) +) => { + return http.post('*/api/v1/files/upload', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getFilesControllerUploadFileResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getFilesControllerUploadFileResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getFilesControllerDownloadMockHandler = () => { - return http.get('/api/v1/files/:fileName', async () => { +export const getFilesControllerDownloadMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.get('*/api/v1/files/:fileName', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } -export const getFilesControllerDeleteFileMockHandler = () => { - return http.delete('/api/v1/files/:fileName', async () => { +export const getFilesControllerDeleteFileMockHandler = ( + overrideResponse?: + | unknown + | ((info: Parameters[1]>[0]) => Promise | unknown) +) => { + return http.delete('*/api/v1/files/:fileName', async (info) => { await delay(1000) - return new HttpResponse(null, { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - }) + if (typeof overrideResponse === 'function') { + await overrideResponse(info) + } + return new HttpResponse(null, { status: 200 }) }) } export const getFilesMock = () => [ diff --git a/src/api/query/files/files.ts b/src/api/query/files/files.ts index 0808d73c..994405c8 100644 --- a/src/api/query/files/files.ts +++ b/src/api/query/files/files.ts @@ -12,6 +12,7 @@ import type { QueryFunction, QueryKey, UseMutationOptions, + UseMutationResult, UseQueryOptions, UseQueryResult, } from '@tanstack/react-query' @@ -100,7 +101,12 @@ export const useFilesControllerUploadFile = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getFilesControllerUploadFileMutationOptions(options) return useMutation(mutationOptions) @@ -157,7 +163,8 @@ export type FilesControllerDownloadQueryError = ErrorType /** * @summary Download File */ -export const useFilesControllerDownload = < + +export function useFilesControllerDownload< TData = Awaited>, TError = ErrorType >( @@ -166,7 +173,7 @@ export const useFilesControllerDownload = < query?: UseQueryOptions>, TError, TData> request?: SecondParameter } -): UseQueryResult & { queryKey: QueryKey } => { +): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getFilesControllerDownloadQueryOptions(fileName, options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } @@ -238,7 +245,12 @@ export const useFilesControllerDeleteFile = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { fileName: string }, + TContext +> => { const mutationOptions = getFilesControllerDeleteFileMutationOptions(options) return useMutation(mutationOptions) diff --git a/src/api/query/health/health.msw.ts b/src/api/query/health/health.msw.ts index 529a0188..9c733f36 100644 --- a/src/api/query/health/health.msw.ts +++ b/src/api/query/health/health.msw.ts @@ -11,35 +11,43 @@ import { HttpResponse, delay, http } from 'msw' import type { HealthEntity } from '../../types' -export const getHealthControllerCheckResponseMock = (overrideResponse: any = {}): HealthEntity => ({ +export const getHealthControllerCheckResponseMock = ( + overrideResponse: Partial = {} +): HealthEntity => ({ details: { - cache: { status: faker.word.sample(), ...overrideResponse }, - db: { status: faker.word.sample(), ...overrideResponse }, - domain: { status: faker.word.sample(), ...overrideResponse }, - ...overrideResponse, + cache: { status: faker.word.sample() }, + db: { status: faker.word.sample() }, + domain: { status: faker.word.sample() }, }, error: {}, info: { - cache: { status: faker.word.sample(), ...overrideResponse }, - db: { status: faker.word.sample(), ...overrideResponse }, - domain: { status: faker.word.sample(), ...overrideResponse }, - ...overrideResponse, + cache: { status: faker.word.sample() }, + db: { status: faker.word.sample() }, + domain: { status: faker.word.sample() }, }, status: faker.word.sample(), ...overrideResponse, }) -export const getHealthControllerCheckMockHandler = (overrideResponse?: HealthEntity) => { - return http.get('/api/v1/health', async () => { +export const getHealthControllerCheckMockHandler = ( + overrideResponse?: + | HealthEntity + | (( + info: Parameters[1]>[0] + ) => Promise | HealthEntity) +) => { + return http.get('*/api/v1/health', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getHealthControllerCheckResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getHealthControllerCheckResponseMock() + ), + { status: 200, headers: { 'Content-Type': 'application/json' } } ) }) } diff --git a/src/api/query/health/health.ts b/src/api/query/health/health.ts index 1ee684fe..89e5529e 100644 --- a/src/api/query/health/health.ts +++ b/src/api/query/health/health.ts @@ -64,13 +64,14 @@ export type HealthControllerCheckQueryError = ErrorType /** * @summary Check Health */ -export const useHealthControllerCheck = < + +export function useHealthControllerCheck< TData = Awaited>, TError = ErrorType >(options?: { query?: UseQueryOptions>, TError, TData> request?: SecondParameter -}): UseQueryResult & { queryKey: QueryKey } => { +}): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getHealthControllerCheckQueryOptions(options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } diff --git a/src/api/query/system/system.msw.ts b/src/api/query/system/system.msw.ts index ccddfb95..e80fe451 100644 --- a/src/api/query/system/system.msw.ts +++ b/src/api/query/system/system.msw.ts @@ -12,7 +12,7 @@ import { HttpResponse, delay, http } from 'msw' import type { AppVersionStatusEntity } from '../../types' export const getSystemControllerCheckForAppUpdateResponseMock = ( - overrideResponse: any = {} + overrideResponse: Partial = {} ): AppVersionStatusEntity => ({ appId: faker.word.sample(), currentVersionReleaseDate: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -23,20 +23,24 @@ export const getSystemControllerCheckForAppUpdateResponseMock = ( }) export const getSystemControllerCheckForAppUpdateMockHandler = ( - overrideResponse?: AppVersionStatusEntity + overrideResponse?: + | AppVersionStatusEntity + | (( + info: Parameters[1]>[0] + ) => Promise | AppVersionStatusEntity) ) => { - return http.post('*/api/v1/system/app-updates/check', async () => { + return http.post('*/api/v1/system/app-updates/check', async (info) => { await delay(1000) + return new HttpResponse( JSON.stringify( - overrideResponse ? overrideResponse : getSystemControllerCheckForAppUpdateResponseMock() + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getSystemControllerCheckForAppUpdateResponseMock() ), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } diff --git a/src/api/query/system/system.ts b/src/api/query/system/system.ts index 76c5752d..360ee339 100644 --- a/src/api/query/system/system.ts +++ b/src/api/query/system/system.ts @@ -7,7 +7,7 @@ * OpenAPI spec version: 1.0 */ import { useMutation } from '@tanstack/react-query' -import type { MutationFunction, UseMutationOptions } from '@tanstack/react-query' +import type { MutationFunction, UseMutationOptions, UseMutationResult } from '@tanstack/react-query' import { customInstance } from '../../axios/custom-instance' import type { ErrorType, BodyType } from '../../axios/custom-instance' @@ -86,7 +86,12 @@ export const useSystemControllerCheckForAppUpdate = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getSystemControllerCheckForAppUpdateMutationOptions(options) return useMutation(mutationOptions) diff --git a/src/api/query/users/users.msw.ts b/src/api/query/users/users.msw.ts index 6e86e5ac..6a408915 100644 --- a/src/api/query/users/users.msw.ts +++ b/src/api/query/users/users.msw.ts @@ -11,7 +11,9 @@ import { HttpResponse, delay, http } from 'msw' import type { UserEntity } from '../../types' -export const getUsersControllerCreateResponseMock = (overrideResponse: any = {}): UserEntity => ({ +export const getUsersControllerCreateResponseMock = ( + overrideResponse: Partial = {} +): UserEntity => ({ consent: faker.helpers.arrayElement([ { createdAt: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -20,7 +22,6 @@ export const getUsersControllerCreateResponseMock = (overrideResponse: any = {}) termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -33,21 +34,16 @@ export const getUsersControllerCreateResponseMock = (overrideResponse: any = {}) locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, ...overrideResponse, }) -export const getUsersControllerFindAllResponseMock = (overrideResponse: any = {}): UserEntity[] => +export const getUsersControllerFindAllResponseMock = (): UserEntity[] => Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, (_, i) => i + 1).map(() => ({ consent: faker.helpers.arrayElement([ { @@ -57,7 +53,6 @@ export const getUsersControllerFindAllResponseMock = (overrideResponse: any = {} termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -70,21 +65,17 @@ export const getUsersControllerFindAllResponseMock = (overrideResponse: any = {} locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, })) -export const getUsersControllerFindOneResponseMock = (overrideResponse: any = {}): UserEntity => ({ +export const getUsersControllerFindOneResponseMock = ( + overrideResponse: Partial = {} +): UserEntity => ({ consent: faker.helpers.arrayElement([ { createdAt: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -93,7 +84,6 @@ export const getUsersControllerFindOneResponseMock = (overrideResponse: any = {} termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -106,21 +96,18 @@ export const getUsersControllerFindOneResponseMock = (overrideResponse: any = {} locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, ...overrideResponse, }) -export const getUsersControllerUpdateResponseMock = (overrideResponse: any = {}): UserEntity => ({ +export const getUsersControllerUpdateResponseMock = ( + overrideResponse: Partial = {} +): UserEntity => ({ consent: faker.helpers.arrayElement([ { createdAt: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -129,7 +116,6 @@ export const getUsersControllerUpdateResponseMock = (overrideResponse: any = {}) termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -142,21 +128,18 @@ export const getUsersControllerUpdateResponseMock = (overrideResponse: any = {}) locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, ...overrideResponse, }) -export const getUsersControllerRemoveResponseMock = (overrideResponse: any = {}): UserEntity => ({ +export const getUsersControllerRemoveResponseMock = ( + overrideResponse: Partial = {} +): UserEntity => ({ consent: faker.helpers.arrayElement([ { createdAt: `${faker.date.past().toISOString().split('.')[0]}Z`, @@ -165,7 +148,6 @@ export const getUsersControllerRemoveResponseMock = (overrideResponse: any = {}) termsAccepted: faker.datatype.boolean(), termsVersion: faker.word.sample(), updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, - ...overrideResponse, }, undefined, ]), @@ -178,91 +160,118 @@ export const getUsersControllerRemoveResponseMock = (overrideResponse: any = {}) locale: faker.word.sample(), provider: faker.word.sample(), role: { - id: faker.number.int({ min: undefined, max: undefined }), + id: faker.helpers.arrayElement([1, 2] as const), name: faker.helpers.arrayElement(['ADMIN', 'USER'] as const), - ...overrideResponse, }, socialId: faker.word.sample(), - status: { - id: faker.number.int({ min: undefined, max: undefined }), - name: faker.word.sample(), - ...overrideResponse, - }, + status: { id: faker.number.int({ min: undefined, max: undefined }), name: faker.word.sample() }, updatedAt: `${faker.date.past().toISOString().split('.')[0]}Z`, ...overrideResponse, }) -export const getUsersControllerCreateMockHandler = (overrideResponse?: UserEntity) => { - return http.post('/api/v1/users', async () => { +export const getUsersControllerCreateMockHandler = ( + overrideResponse?: + | UserEntity + | ((info: Parameters[1]>[0]) => Promise | UserEntity) +) => { + return http.post('*/api/v1/users', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getUsersControllerCreateResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getUsersControllerCreateResponseMock() + ), + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getUsersControllerFindAllMockHandler = (overrideResponse?: UserEntity[]) => { - return http.get('/api/v1/users', async () => { +export const getUsersControllerFindAllMockHandler = ( + overrideResponse?: + | UserEntity[] + | (( + info: Parameters[1]>[0] + ) => Promise | UserEntity[]) +) => { + return http.get('*/api/v1/users', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getUsersControllerFindAllResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getUsersControllerFindAllResponseMock() + ), + { status: 200, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getUsersControllerFindOneMockHandler = (overrideResponse?: UserEntity) => { - return http.get('/api/v1/users/:id', async () => { +export const getUsersControllerFindOneMockHandler = ( + overrideResponse?: + | UserEntity + | ((info: Parameters[1]>[0]) => Promise | UserEntity) +) => { + return http.get('*/api/v1/users/:id', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getUsersControllerFindOneResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getUsersControllerFindOneResponseMock() + ), + { status: 200, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getUsersControllerUpdateMockHandler = (overrideResponse?: UserEntity) => { - return http.patch('/api/v1/users/:id', async () => { +export const getUsersControllerUpdateMockHandler = ( + overrideResponse?: + | UserEntity + | ((info: Parameters[1]>[0]) => Promise | UserEntity) +) => { + return http.patch('*/api/v1/users/:id', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getUsersControllerUpdateResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getUsersControllerUpdateResponseMock() + ), + { status: 201, headers: { 'Content-Type': 'application/json' } } ) }) } -export const getUsersControllerRemoveMockHandler = (overrideResponse?: UserEntity) => { - return http.delete('/api/v1/users/:id', async () => { +export const getUsersControllerRemoveMockHandler = ( + overrideResponse?: + | UserEntity + | ((info: Parameters[1]>[0]) => Promise | UserEntity) +) => { + return http.delete('*/api/v1/users/:id', async (info) => { await delay(1000) + return new HttpResponse( - JSON.stringify(overrideResponse ? overrideResponse : getUsersControllerRemoveResponseMock()), - { - status: 200, - headers: { - 'Content-Type': 'application/json', - }, - } + JSON.stringify( + overrideResponse !== undefined + ? typeof overrideResponse === 'function' + ? await overrideResponse(info) + : overrideResponse + : getUsersControllerRemoveResponseMock() + ), + { status: 200, headers: { 'Content-Type': 'application/json' } } ) }) } diff --git a/src/api/query/users/users.ts b/src/api/query/users/users.ts index 952dc8e7..d9890d17 100644 --- a/src/api/query/users/users.ts +++ b/src/api/query/users/users.ts @@ -12,6 +12,7 @@ import type { QueryFunction, QueryKey, UseMutationOptions, + UseMutationResult, UseQueryOptions, UseQueryResult, } from '@tanstack/react-query' @@ -107,7 +108,12 @@ export const useUsersControllerCreate = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { data: BodyType }, + TContext +> => { const mutationOptions = getUsersControllerCreateMutationOptions(options) return useMutation(mutationOptions) @@ -165,7 +171,8 @@ export type UsersControllerFindAllQueryError = ErrorType< /** * @summary Find All Users */ -export const useUsersControllerFindAll = < + +export function useUsersControllerFindAll< TData = Awaited>, TError = ErrorType >( @@ -174,7 +181,7 @@ export const useUsersControllerFindAll = < query?: UseQueryOptions>, TError, TData> request?: SecondParameter } -): UseQueryResult & { queryKey: QueryKey } => { +): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getUsersControllerFindAllQueryOptions(params, options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } @@ -234,7 +241,8 @@ export type UsersControllerFindOneQueryError = ErrorType< /** * @summary Find User by ID */ -export const useUsersControllerFindOne = < + +export function useUsersControllerFindOne< TData = Awaited>, TError = ErrorType >( @@ -243,7 +251,7 @@ export const useUsersControllerFindOne = < query?: UseQueryOptions>, TError, TData> request?: SecondParameter } -): UseQueryResult & { queryKey: QueryKey } => { +): UseQueryResult & { queryKey: QueryKey } { const queryOptions = getUsersControllerFindOneQueryOptions(id, options) const query = useQuery(queryOptions) as UseQueryResult & { queryKey: QueryKey } @@ -326,7 +334,12 @@ export const useUsersControllerUpdate = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { id: string; data: BodyType }, + TContext +> => { const mutationOptions = getUsersControllerUpdateMutationOptions(options) return useMutation(mutationOptions) @@ -395,7 +408,12 @@ export const useUsersControllerRemove = < TContext > request?: SecondParameter -}) => { +}): UseMutationResult< + Awaited>, + TError, + { id: string }, + TContext +> => { const mutationOptions = getUsersControllerRemoveMutationOptions(options) return useMutation(mutationOptions) diff --git a/src/api/types/articleEntity.ts b/src/api/types/articleEntity.ts index 13c4eabd..1368844e 100644 --- a/src/api/types/articleEntity.ts +++ b/src/api/types/articleEntity.ts @@ -10,10 +10,12 @@ import type { AuthorPublicDto } from './authorPublicDto' export interface ArticleEntity { author: AuthorPublicDto + /** @nullable */ authorId?: string | null body: string createdAt: string deletedAt: string + /** @nullable */ description?: string | null id: number published: boolean diff --git a/src/api/types/fileEntity.ts b/src/api/types/fileEntity.ts index 39be0464..fe411a26 100644 --- a/src/api/types/fileEntity.ts +++ b/src/api/types/fileEntity.ts @@ -8,7 +8,10 @@ */ export interface FileEntity { - /** Category of the file */ + /** + * Category of the file + * @nullable + */ category: string | null /** Creation date of the file */ createdAt: string diff --git a/src/api/types/healthEntityError.ts b/src/api/types/healthEntityError.ts index 821b8468..872f0387 100644 --- a/src/api/types/healthEntityError.ts +++ b/src/api/types/healthEntityError.ts @@ -10,4 +10,4 @@ /** * Details of any errors encountered during the health check */ -export type HealthEntityError = { [key: string]: any } +export type HealthEntityError = { [key: string]: unknown } diff --git a/src/components/molecules/Field/CheckboxGroup.tsx b/src/components/molecules/Field/CheckboxGroup.tsx index c74a2b0c..68e99f01 100644 --- a/src/components/molecules/Field/CheckboxGroup.tsx +++ b/src/components/molecules/Field/CheckboxGroup.tsx @@ -1,11 +1,5 @@ -import { - Box, - CheckboxButton, - FormErrorMessage, - FormLabel, - Spacer, -} from '@baca/design-system/components' -import { Fragment, useMemo } from 'react' +import { Box, CheckboxButton, FormErrorMessage, FormLabel } from '@baca/design-system/components' +import { useMemo } from 'react' import { FieldCheckboxGroupProps } from './types' @@ -36,24 +30,21 @@ export const CheckboxGroup = ({ } return ( - - - - + ) }) }, [items, selectedItems, props, onSelectItem]) return ( - + {renderCheckboxes} diff --git a/src/components/molecules/Field/Input.tsx b/src/components/molecules/Field/Input.tsx index 648199ed..22d3f9cd 100644 --- a/src/components/molecules/Field/Input.tsx +++ b/src/components/molecules/Field/Input.tsx @@ -5,7 +5,7 @@ import { Box, } from '@baca/design-system/components' import { forwardRef, useCallback, useImperativeHandle, useRef, useMemo } from 'react' -import { NativeSyntheticEvent, Pressable, TextInput, TextInputFocusEventData } from 'react-native' +import { NativeSyntheticEvent, TextInput, TextInputFocusEventData } from 'react-native' import type { FieldInputProps } from './types' @@ -47,6 +47,7 @@ export const Input = forwardRef, FieldInputProps>( labelStyle, onBlur, onFocus, + testID, ...props }, ref @@ -88,16 +89,19 @@ export const Input = forwardRef, FieldInputProps>( ) return ( - - - - - - + + + + ) } diff --git a/src/components/molecules/Field/RadioGroup.tsx b/src/components/molecules/Field/RadioGroup.tsx index 1ea51de0..5c6615c3 100644 --- a/src/components/molecules/Field/RadioGroup.tsx +++ b/src/components/molecules/Field/RadioGroup.tsx @@ -27,7 +27,6 @@ export const RadioGroup = ({ isError={isError} isSelected={item.value === selectedItem} onChange={() => onSelectItem(item.value)} - pb={2} label={item.label} size={size} /> @@ -37,7 +36,7 @@ export const RadioGroup = ({ ) return ( - + {renderRadioButtons} diff --git a/src/components/molecules/Field/Select.tsx b/src/components/molecules/Field/Select.tsx index d8aee5df..efa35149 100644 --- a/src/components/molecules/Field/Select.tsx +++ b/src/components/molecules/Field/Select.tsx @@ -7,7 +7,6 @@ import { } from '@baca/design-system/components' import { useMemo } from '@baca/hooks' import React from 'react' -import { Pressable } from 'react-native' import type { FieldSelectProps } from './types' @@ -55,12 +54,15 @@ export const Select = ({ ) return ( - - - - - - + + + + ) } diff --git a/src/constants/env.ts b/src/constants/env.ts index 6ff33041..8fa82c6c 100644 --- a/src/constants/env.ts +++ b/src/constants/env.ts @@ -5,4 +5,5 @@ export const ENV = { EAS_PROJECT_ID: Constants.expoConfig?.extra?.eas?.projectId, ENVIRONMENT_NAME: Constants?.expoConfig?.extra?.ENVIRONMENT_NAME, WEB_CLIENT_ID: Constants.expoConfig?.extra?.WEB_CLIENT_ID, + IS_MOCK: Constants.expoConfig?.extra?.IS_MOCK, } diff --git a/src/constants/environments.ts b/src/constants/environments.ts index 12d2ad22..97784438 100644 --- a/src/constants/environments.ts +++ b/src/constants/environments.ts @@ -1,8 +1,11 @@ import Constants, { AppOwnership } from 'expo-constants' import { Platform } from 'react-native' +import { ENV } from './env' + export const isExpoGo = Constants.appOwnership === AppOwnership.Expo export const isDevelopment = __DEV__ || process.env.NODE_ENV === 'development' export const isProduction = !isDevelopment || process.env.NODE_ENV === 'production' +export const isMock = !!ENV.IS_MOCK export const isWeb = Platform.OS === 'web' diff --git a/src/design-system/components/Button/__snapshots__/Button.test.tsx.snap b/src/design-system/components/Button/__snapshots__/Button.test.tsx.snap index c319f343..d4b1b378 100644 --- a/src/design-system/components/Button/__snapshots__/Button.test.tsx.snap +++ b/src/design-system/components/Button/__snapshots__/Button.test.tsx.snap @@ -78,7 +78,6 @@ exports[`Button renders correctly 1`] = ` "textTransform": "none", } } - testID="baseText" textAlign="center" > Button diff --git a/src/design-system/components/FormErrorMessage.tsx b/src/design-system/components/FormErrorMessage.tsx index 4574a81f..e420f7ff 100644 --- a/src/design-system/components/FormErrorMessage.tsx +++ b/src/design-system/components/FormErrorMessage.tsx @@ -1,18 +1,20 @@ import { useTheme } from '@baca/hooks' import React from 'react' -import { StyleSheet, Text } from 'react-native' +import { Text } from 'react-native' -export const FormErrorMessage = ({ errorMessage }: { errorMessage?: string }) => { +export const FormErrorMessage = ({ + errorMessage, + testId, +}: { + errorMessage?: string + testId?: string +}) => { const { colors } = useTheme() return ( errorMessage && ( - {errorMessage} + + {errorMessage} + ) ) } - -const styles = StyleSheet.create({ - text: { - marginTop: 8, - }, -}) diff --git a/src/design-system/components/FormLabel.tsx b/src/design-system/components/FormLabel.tsx index b64d750c..598acf2a 100644 --- a/src/design-system/components/FormLabel.tsx +++ b/src/design-system/components/FormLabel.tsx @@ -1,11 +1,18 @@ import { useTheme } from '@baca/hooks' import React from 'react' -import { StyleSheet, View } from 'react-native' +import { StyleSheet } from 'react-native' import { Text } from './Text' +import { Touchable } from './Touchables' import { FormLabelProps } from './types' -export const FormLabel = ({ label, isRequired, labelStyle }: FormLabelProps) => { +export const FormLabel = ({ + label, + isRequired, + labelStyle, + testID, + onLabelPress, +}: FormLabelProps) => { const { colors } = useTheme() const stylesForRequired = @@ -16,19 +23,21 @@ export const FormLabel = ({ label, isRequired, labelStyle }: FormLabelProps) => ) ) + if (!label) { + return null + } + return ( - - {label && ( - - {label} - {isRequired && ( - - * - - )} - - )} - + + + {label} + {isRequired && ( + + * + + )} + + ) } @@ -36,9 +45,6 @@ const styles = StyleSheet.create({ wrapper: { display: 'flex', flexDirection: 'row', - }, - wrapperWithLabel: { marginBottom: 8, - marginTop: 4, }, }) diff --git a/src/design-system/components/Text/Text.tsx b/src/design-system/components/Text/Text.tsx index c7168fb6..d3fcea7c 100644 --- a/src/design-system/components/Text/Text.tsx +++ b/src/design-system/components/Text/Text.tsx @@ -204,15 +204,7 @@ const RawText = memo( ] ) - return ( - - ) + return } ) ) diff --git a/src/design-system/components/types.ts b/src/design-system/components/types.ts index 0edaae90..db5301b7 100644 --- a/src/design-system/components/types.ts +++ b/src/design-system/components/types.ts @@ -184,6 +184,8 @@ export type FormLabelProps = { label?: string isRequired?: boolean labelStyle?: TextStyle + testID?: string + onLabelPress?: () => void } // ----------------------- diff --git a/src/hooks/forms/useSignInForm.ts b/src/hooks/forms/useSignInForm.ts index bd421206..3f15857c 100644 --- a/src/hooks/forms/useSignInForm.ts +++ b/src/hooks/forms/useSignInForm.ts @@ -1,5 +1,6 @@ import { useAuthControllerLogin } from '@baca/api/query/auth/auth' import { AuthEmailLoginDto } from '@baca/api/types' +import { isProduction } from '@baca/constants' import { assignPushToken, setToken } from '@baca/services' import { isSignedInAtom } from '@baca/store/auth' import { handleFormError, hapticImpact } from '@baca/utils' @@ -15,12 +16,18 @@ type UseSignInFormProps = { setIsSignInButtonsDisabled?: Dispatch> } -const defaultValues: SignInFormValues = { - // TODO: Reset this values when building production app - email: 'mateusz.rostkowski+baca@binarapps.com', - password: 'Test1234,', - confirm: false, -} +const defaultValues: SignInFormValues = isProduction + ? { + email: '', + password: '', + confirm: false, + } + : { + // TODO: Reset this values when building production app + email: 'mateusz.rostkowski+baca@binarapps.com', + password: 'Test1234,', + confirm: false, + } export const useSignInForm = ({ setIsSignInButtonsDisabled }: UseSignInFormProps) => { const setIsSignedIn = useSetAtom(isSignedInAtom) diff --git a/src/hooks/usePasswordValidation.tsx b/src/hooks/usePasswordValidation.tsx index cf8a638f..d25e88fb 100644 --- a/src/hooks/usePasswordValidation.tsx +++ b/src/hooks/usePasswordValidation.tsx @@ -38,8 +38,12 @@ export const usePasswordValidation = () => { ? 'utility.error.500' : 'utility.success.500' + const testID = `change_password:${suggestion}:${ + !showValidationState ? 'disabled' : isError ? 'error' : 'success' + }` + return ( - + diff --git a/src/navigation/tabNavigator/components/BottomBar.tsx b/src/navigation/tabNavigator/components/BottomBar.tsx index f1e5063c..87365710 100644 --- a/src/navigation/tabNavigator/components/BottomBar.tsx +++ b/src/navigation/tabNavigator/components/BottomBar.tsx @@ -27,7 +27,13 @@ export function BottomBar({ visible }: { visible: boolean }) { > {bottomTabs.map((tab, i) => ( - + {({ focused, pressed, hovered }) => ( void params?: Record style?: ViewStyle + testID?: string }) { const focused = useIsTabSelected(id) if (onPress) { return ( - + {(props) => children?.({ ...props, focused })} ) @@ -34,14 +36,16 @@ export function TabBarItemWrapper({ if (name.startsWith('/') || name.startsWith('.')) { return ( - + {(props) => children?.({ ...props, focused })} ) } return ( - {(props) => children?.({ ...props, focused })} + + {(props) => children?.({ ...props, focused })} + ) } diff --git a/src/screens/HomeScreen.tsx b/src/screens/HomeScreen.tsx index 7859b39e..9498fe0f 100644 --- a/src/screens/HomeScreen.tsx +++ b/src/screens/HomeScreen.tsx @@ -26,16 +26,18 @@ export const HomeScreen = () => { return (
- {t('hello')} + + {t('hello')} + {t('thanks')} {t('app_information')} - - -
diff --git a/src/screens/SettingsScreen.tsx b/src/screens/SettingsScreen.tsx index 5d32748d..bf9e2066 100644 --- a/src/screens/SettingsScreen.tsx +++ b/src/screens/SettingsScreen.tsx @@ -79,7 +79,7 @@ export const SettingsScreen = (): JSX.Element => { - + {t('settings_screen.sign_out')} diff --git a/src/screens/auth/SignInScreen.tsx b/src/screens/auth/SignInScreen.tsx index 1db1ece0..c81bcb5c 100644 --- a/src/screens/auth/SignInScreen.tsx +++ b/src/screens/auth/SignInScreen.tsx @@ -48,9 +48,16 @@ export const SignInScreen = (): JSX.Element => { - {t('sign_in_screen.welcome_back')} + + {t('sign_in_screen.welcome_back')} + - + {t('sign_in_screen.welcome_back_enter_details')} @@ -71,7 +78,7 @@ export const SignInScreen = (): JSX.Element => { message: t('form.validation.invalid_email_format'), }, }} - testID="emailInput" + testID="sign_in:email_input" /> { rules={{ required: t('form.validation.required'), }} - testID="passwordInput" + testID="sign_in:password_input" type="password" /> @@ -93,9 +100,12 @@ export const SignInScreen = (): JSX.Element => { {...{ control, errors }} label={t('form.checkbox.remember_me')} name="confirm" - testID="confirmCheckbox" + testID="sign_in:confirm_checkbox" /> - + {t('sign_in_screen.forgot_password')} @@ -104,7 +114,7 @@ export const SignInScreen = (): JSX.Element => { loading={isSubmitting} my={4} onPress={submit} - testID="signInButton" + testID="sign_in:submit_button" w="full" > {t('sign_in_screen.sign_in')} @@ -117,7 +127,7 @@ export const SignInScreen = (): JSX.Element => { {t('sign_in_screen.do_not_have_an_account')} - + {t('sign_in_screen.sign_up')}
diff --git a/yarn.lock b/yarn.lock index a82b7334..d99a65d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -930,6 +930,14 @@ dependencies: statuses "^2.0.1" +"@bundled-es-modules/tough-cookie@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz#fa9cd3cedfeecd6783e8b0d378b4a99e52bde5d3" + integrity sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw== + dependencies: + "@types/tough-cookie" "^4.0.5" + tough-cookie "^4.1.4" + "@egjs/hammerjs@^2.0.17": version "2.0.17" resolved "https://registry.yarnpkg.com/@egjs/hammerjs/-/hammerjs-2.0.17.tgz#5dc02af75a6a06e4c2db0202cae38c9263895124" @@ -2100,11 +2108,6 @@ hey-listen "^1.0.8" tslib "^2.3.1" -"@mswjs/cookies@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@mswjs/cookies/-/cookies-1.1.0.tgz#1528eb43630caf83a1d75d5332b30e75e9bb1b5b" - integrity sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw== - "@mswjs/interceptors@^0.29.0": version "0.29.1" resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.29.1.tgz#e77fc58b5188569041d0440b25c9e9ebb1ccd60a" @@ -2163,24 +2166,24 @@ resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda" integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== -"@orval/angular@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/angular/-/angular-6.29.1.tgz#1f576453974613fb113d3f12dd0a4ee4696bbcfa" - integrity sha512-nxoDP/m5B+Y5hilxbVHDuCb7LP9WPW250iVuxUHiQLCYFfrQiMJVizIHGZoBS1tx911qbHqFHB7XKHFsGqY1Zw== +"@orval/angular@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/angular/-/angular-7.0.1.tgz#db2ec97098c60602c395dd5f3cddc1460b433a25" + integrity sha512-a1gEjxXEPZM/riysHYzBPPB/rU9YlW+n/E0X1x25gPfkrmns0NfrKl5N8O6Vxawq7uK2nDTxvXEakEylrzEl3g== dependencies: - "@orval/core" "6.29.1" + "@orval/core" "7.0.1" -"@orval/axios@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/axios/-/axios-6.29.1.tgz#4e783861754b8743db9387ccbed1ce1b548d3675" - integrity sha512-qNRfPqSUiuA7m5aUMCBI1+ANJTjHl65ivpLTstfKExf1rvFqZ7gJpGBOGTcxaZdzwBbkN7Zm2CsGBpsWYxDmDg== +"@orval/axios@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/axios/-/axios-7.0.1.tgz#cadb32af9d8b6612fb983ec5461fd27a23c83da4" + integrity sha512-KBlUAgm9ERg+oVuF2UuBCg8htDehEeIo62kgpE3XnKXOHo3QN8p0bxAL26POdf40vP7S42pzBT3f1Q75fbqgug== dependencies: - "@orval/core" "6.29.1" + "@orval/core" "7.0.1" -"@orval/core@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/core/-/core-6.29.1.tgz#6c869ca30cf57988548bdf266d892dc533c0efe6" - integrity sha512-InWH4heF+2KT2e8Qxoa+w8bourNl/MIr2+camJnGbbX6RzsWmfvGCtfW2kiaYMPc4RnGwTg7Qvfqeung2Dj4GQ== +"@orval/core@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/core/-/core-7.0.1.tgz#649f63801283b51723b093e82bf35358f974c134" + integrity sha512-AcRSPTqCYdXqX/rznYk9SJ9CcxtrPR90N+0ILquXB3rxREAzp1uztH0oymoEtfu0izN4O5c52HQaTJh5sx1b2g== dependencies: "@apidevtools/swagger-parser" "^10.1.0" "@ibm-cloud/openapi-ruleset" "^1.14.2" @@ -2203,46 +2206,55 @@ openapi3-ts "4.2.2" swagger2openapi "^7.0.8" -"@orval/hono@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/hono/-/hono-6.29.1.tgz#2ffe1c5660f85433fb6e58f343feeaf916b026c1" - integrity sha512-nA4TpWRtGBzDok+BZl6yA4PZbmrXfaasuV0AfM9vmqlpEWn+X/x3ASzOrMBK2OkXc7oDfOToaaiq7CLIfEP8+g== +"@orval/fetch@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/fetch/-/fetch-7.0.1.tgz#7f5e5a1d03180b919aee501615ff7ae09d924d6e" + integrity sha512-GgVhbvPUYyvZd3bwFSwtx9g+Ojxv1+c+yuWC6OkKVsGb/o2+gbRRsGFL3TYfMgXPYTfgT+U0MkvLeax0TdL+oQ== + dependencies: + "@orval/core" "7.0.1" + +"@orval/hono@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/hono/-/hono-7.0.1.tgz#417e8992689608464f7ac3a00cafda1e46304aff" + integrity sha512-1y846isycK7pbcV85wtAVnOs4b0UO58+7b7dyTznWlvekin7qhL4jwESNRsi4Fy59k0woksQthrJhrz4KtJKXA== dependencies: - "@orval/core" "6.29.1" - "@orval/zod" "6.29.1" + "@orval/core" "7.0.1" + "@orval/zod" "7.0.1" lodash.uniq "^4.5.0" -"@orval/mock@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/mock/-/mock-6.29.1.tgz#6e967337f771f740f1c213e5a230f53f34beb410" - integrity sha512-l8UEtE1EOX40EHcl4qtu2IeQSRExqc63ekX84BqSWUZx0XicqZRzR348dqd3BB5qaPXKal6Y4ChX3qDeiuDJOw== +"@orval/mock@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/mock/-/mock-7.0.1.tgz#bebf2af7351549e72ad7f389577688ac758725c9" + integrity sha512-yDVh3MjvSr/jPUT5vUcke7bGPLMSlILdT2LmQF/HRWSZYxPgKDkqNAR3ovbFJ2M5ckoBhBoNh3t2Jjcrs4QCzg== dependencies: - "@orval/core" "6.29.1" + "@orval/core" "7.0.1" lodash.get "^4.4.2" lodash.omit "^4.5.0" openapi3-ts "^4.2.2" -"@orval/query@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/query/-/query-6.29.1.tgz#857f9cd626ed2193f9138c33a8c59c2e8fac3ba1" - integrity sha512-voJ3WO0AzQmfFxH0iQc2HsKVlzq7cy4Qik8sLT85upehpmJa/UlFjXr23FaW8SKkIG4kS2t80imCmpMfEezTbw== +"@orval/query@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/query/-/query-7.0.1.tgz#71aa065f6430f25e26498e4ec6ef1a159027abe4" + integrity sha512-rk8HZrPtWM4JJB8GPVS4fY3N1o7eIgTSaG237f5DGaeebI11qt6aUfrxMHm6Ybfs13dhCl4ApvVX7494FKdXHA== dependencies: - "@orval/core" "6.29.1" + "@orval/core" "7.0.1" + "@orval/fetch" "7.0.1" lodash.omitby "^4.6.0" -"@orval/swr@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/swr/-/swr-6.29.1.tgz#878c4e4bc41533f13d448d708f3ae3a5267a7048" - integrity sha512-/B7czuGVtWZ9GYeq2E7C8JuoOfd4wm94Qtu0E1gNTSFWgD0rLx3ZSEvR4cmt46t3tUbOw17Ra0k8lJg8T1MPAQ== +"@orval/swr@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/swr/-/swr-7.0.1.tgz#70e1d3fd75dff4962528deb266d251dee320694a" + integrity sha512-Op6VdhvWXdKHjJCm+M1CPr/Iaj0R3Kt9dM7xiUm0NMI/Q1VQFBFj20MTKWcfie4iFvjLO+AJOfjn0y+BUMaboA== dependencies: - "@orval/core" "6.29.1" + "@orval/core" "7.0.1" + "@orval/fetch" "7.0.1" -"@orval/zod@6.29.1": - version "6.29.1" - resolved "https://registry.yarnpkg.com/@orval/zod/-/zod-6.29.1.tgz#7348c518906cd11d49ef0b6d72fc3c628da89c7c" - integrity sha512-CPrcB7HnBoEtFKLvHSHB2vB3f1NlvI/eKd3P0wE7DsCn+c7YBXpRoOPxHpxIER+Y2kFUBh3DqKDLlRtYgg4JHA== +"@orval/zod@7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@orval/zod/-/zod-7.0.1.tgz#965b59e39ae98389fe88fa245bc62d266553a882" + integrity sha512-jxrWCLKPffEWR0OY/lDnzrq4rGGdzSvu/apdL4Qr0j/qeYddrUurt/bdDtcS+l8ZPcTz7ppnp4KMhv1gG4549A== dependencies: - "@orval/core" "6.29.1" + "@orval/core" "7.0.1" lodash.uniq "^4.5.0" "@pkgjs/parseargs@^0.11.0": @@ -3449,7 +3461,7 @@ resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.5.tgz#f61ab46d5352fd73c863a1ea4e1cef3b0b51ae63" integrity sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A== -"@types/tough-cookie@*": +"@types/tough-cookie@*", "@types/tough-cookie@^4.0.5": version "4.0.5" resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== @@ -4289,22 +4301,6 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-sdk@^2.724.0: - version "2.1651.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1651.0.tgz#1b3cd731dbbfd08072793c5d3e480953b689c0eb" - integrity sha512-MZjQvvOPkKcx1N428ejUjqSfhm4TAIcgPIgpniiDMw1LjB1yA8JBZvrWer6J6MACAXQ99v0uKE4BSvtYn+AT3g== - dependencies: - buffer "4.9.2" - events "1.1.1" - ieee754 "1.1.13" - jmespath "0.16.0" - querystring "0.2.0" - sax "1.2.1" - url "0.10.3" - util "^0.12.4" - uuid "8.0.0" - xml2js "0.6.2" - axios@^1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.2.tgz#b625db8a7051fbea61c35a3cbb3a1daa7b9c7621" @@ -4498,7 +4494,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.0.2, base64-js@^1.2.3, base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: +base64-js@^1.2.3, base64-js@^1.3.0, base64-js@^1.3.1, base64-js@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -4660,15 +4656,6 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer@4.9.2: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - buffer@^5.4.3, buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -4833,7 +4820,7 @@ charenc@0.0.2, charenc@~0.0.1: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: +"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3, chokidar@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -6376,11 +6363,6 @@ eventemitter3@^5.0.1: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== -events@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" - integrity sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw== - events@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -7769,12 +7751,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@1.1.13: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== - -ieee754@^1.1.13, ieee754@^1.1.4: +ieee754@^1.1.13: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -8252,16 +8229,16 @@ is-wsl@^2.0.0, is-wsl@^2.1.1, is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -8771,11 +8748,6 @@ jimp-compact@0.16.1: resolved "https://registry.yarnpkg.com/jimp-compact/-/jimp-compact-0.16.1.tgz#9582aea06548a2c1e04dd148d7c3ab92075aefa3" integrity sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww== -jmespath@0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" - integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== - joi@^17.2.1: version "17.13.1" resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.1.tgz#9c7b53dc3b44dd9ae200255cc3b398874918a6ca" @@ -9339,14 +9311,6 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -maestro@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/maestro/-/maestro-2.1.1.tgz#f09d9fce4914995aec3a584d4924d8e83c7070a4" - integrity sha512-orHkatrYOwBntNOPc7wInZ6uskLM5StaEJN8knqOapcpLHlL/zWZquh8tAWmFPwVzYdMC0CQUVTgncnu1xG/yQ== - dependencies: - aws-sdk "^2.724.0" - minimist "^1.2.5" - make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -9760,7 +9724,7 @@ minimatch@^9.0.4: dependencies: brace-expansion "^2.0.1" -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: +minimist@^1.2.0, minimist@^1.2.6: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -9865,15 +9829,15 @@ ms@2.1.3, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -msw@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/msw/-/msw-2.3.0.tgz#7d48ab8472a435878f4ee94dfa0efcd2b3c2264b" - integrity sha512-cDr1q/QTMzaWhY8n9lpGhceY209k29UZtdTgJ3P8Bzne3TSMchX2EM/ldvn4ATLOktpCefCU2gcEgzHc31GTPw== +msw@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/msw/-/msw-2.3.5.tgz#424ad91b20a548d6b77fc26aca0c789e5cbc4764" + integrity sha512-+GUI4gX5YC5Bv33epBrD+BGdmDvBg2XGruiWnI3GbIbRmMMBeZ5gs3mJ51OWSGHgJKztZ8AtZeYMMNMVrje2/Q== dependencies: "@bundled-es-modules/cookie" "^2.0.0" "@bundled-es-modules/statuses" "^1.0.1" + "@bundled-es-modules/tough-cookie" "^0.1.6" "@inquirer/confirm" "^3.0.0" - "@mswjs/cookies" "^1.1.0" "@mswjs/interceptors" "^0.29.0" "@open-draft/until" "^2.1.0" "@types/cookie" "^0.6.0" @@ -10363,24 +10327,25 @@ ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" -orval@^6.29.1: - version "6.29.1" - resolved "https://registry.yarnpkg.com/orval/-/orval-6.29.1.tgz#e0651d9072f4a4a5bc9de597d4278c8a67206415" - integrity sha512-hYGuPNucbHZeQgSpcoujuR6GzRKbHhl59zFMt6bxZd6XkeEONhGAqOLETAFQ9og/arOlPOMvchy6COCnrEKlRQ== +orval@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/orval/-/orval-7.0.1.tgz#12e8b4913d8c52a42850b5562a7883e989fa9de2" + integrity sha512-IEdllXbTD34u00NU4jj2jgaroQgpafNnaGP647gaF3NJ5SgxH2sGgxJUQslpoCwR3Dp0pLkj/IZbbxGMPOCMVQ== dependencies: "@apidevtools/swagger-parser" "^10.1.0" - "@orval/angular" "6.29.1" - "@orval/axios" "6.29.1" - "@orval/core" "6.29.1" - "@orval/hono" "6.29.1" - "@orval/mock" "6.29.1" - "@orval/query" "6.29.1" - "@orval/swr" "6.29.1" - "@orval/zod" "6.29.1" + "@orval/angular" "7.0.1" + "@orval/axios" "7.0.1" + "@orval/core" "7.0.1" + "@orval/fetch" "7.0.1" + "@orval/hono" "7.0.1" + "@orval/mock" "7.0.1" + "@orval/query" "7.0.1" + "@orval/swr" "7.0.1" + "@orval/zod" "7.0.1" ajv "^8.12.0" cac "^6.7.14" chalk "^4.1.2" - chokidar "^3.5.3" + chokidar "^3.6.0" enquirer "^2.4.1" execa "^5.1.1" find-up "5.0.0" @@ -11153,11 +11118,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== - punycode@^2.1.0, punycode@^2.1.1: version "2.3.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" @@ -11190,11 +11150,6 @@ query-string@^7.1.3: split-on-first "^1.0.0" strict-uri-encode "^2.0.0" -querystring@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== - querystring@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" @@ -11899,11 +11854,6 @@ sass@^1.77.2: immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" -sax@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" - integrity sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA== - sax@>=0.6.0: version "1.3.0" resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" @@ -12934,7 +12884,7 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@^4.1.2: +tough-cookie@^4.1.2, tough-cookie@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== @@ -13290,14 +13240,6 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -url@0.10.3: - version "0.10.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" - integrity sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ== - dependencies: - punycode "1.3.2" - querystring "0.2.0" - use-debounce@^9.0.4: version "9.0.4" resolved "https://registry.yarnpkg.com/use-debounce/-/use-debounce-9.0.4.tgz#51d25d856fbdfeb537553972ce3943b897f1ac85" @@ -13318,7 +13260,7 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -util@^0.12.3, util@^0.12.4, util@^0.12.5: +util@^0.12.3, util@^0.12.5: version "0.12.5" resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== @@ -13344,11 +13286,6 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -uuid@8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" - integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== - uuid@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" @@ -13795,14 +13732,6 @@ xml2js@0.6.0: sax ">=0.6.0" xmlbuilder "~11.0.0" -xml2js@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" - integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - xmlbuilder@^14.0.0: version "14.0.0" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-14.0.0.tgz#876b5aec4f05ffd5feb97b0a871c855d16fbeb8c"