diff --git a/.evergreen/functions.yml b/.evergreen/functions.yml index 9ee50e63a67..bf77d055ee8 100644 --- a/.evergreen/functions.yml +++ b/.evergreen/functions.yml @@ -228,7 +228,11 @@ functions: --stream \ --scope "${scope}" \ --include-dependencies - + # If scope is not provided, we're bootstrapping the whole monorepo and + # should follow the logic in bootstrap npm scripts + if [ -z "${scope}" ]; then + npm run compile --workspace=@mongodb-js/testing-library-compass + fi check: command: shell.exec params: diff --git a/THIRD-PARTY-NOTICES.md b/THIRD-PARTY-NOTICES.md index 1608cd1abfd..e4afdb12f6b 100644 --- a/THIRD-PARTY-NOTICES.md +++ b/THIRD-PARTY-NOTICES.md @@ -1,5 +1,5 @@ The following third-party software is used by and included in **Mongodb Compass**. -This document was automatically generated on Tue Sep 03 2024. +This document was automatically generated on Thu Sep 05 2024. ## List of dependencies @@ -464,7 +464,7 @@ This document was automatically generated on Tue Sep 03 2024. | **[modify-filename](#7153be07939379ccf0072006c519fba2bdf5ab79ca8bb59bc5273f87a7bacbf6)** | 1.1.0 | MIT | | **[moment](#94975b5423311209f3beed9c2c6bb6157f622312a3f8563d507b52e804bf6285)** | 2.29.4 | MIT | | **[mongodb-build-info](#f0a98c22ae0766702726f79e058ac6dc4e4bead8557b67b816f40bd13fb54170)** | 1.7.2 | Apache-2.0 | -| **[mongodb-client-encryption](#42ba122fc0db7791e33e6160aff7213f42c4a34a8e891e78cd07c606555c2bb9)** | 6.0.1 | Apache-2.0 | +| **[mongodb-client-encryption](#01c104ff07b0715f77217b6b7adfc9a0056f35ffd976182ffbf409f69b3a0df3)** | 6.1.0 | Apache-2.0 | | **[mongodb-cloud-info](#a784f3b401cf51746f49964e044db933529b3e3791e557702715730f5a3f1e46)** | 2.1.2 | Apache-2.0 | | **[mongodb-connection-string-url](#2e1146256a89ebd24e3398881e03807fe363d58444e6b7952ea50bd6108707bc)** | 3.0.1 | Apache-2.0 | | **[mongodb-log-writer](#c4945018f8490fc8e56e1414e262fcf1b802800e05cd15f2bd6b7a9d0b94af85)** | 1.4.2 | Apache-2.0 | @@ -27448,9 +27448,9 @@ License files: See the License for the specific language governing permissions and limitations under the License. - + -### [mongodb-client-encryption](https://www.npmjs.com/package/mongodb-client-encryption) (version 6.0.1) +### [mongodb-client-encryption](https://www.npmjs.com/package/mongodb-client-encryption) (version 6.1.0) License tags: Apache-2.0 diff --git a/configs/mocha-config-compass/register/resolve-from-source-register.js b/configs/mocha-config-compass/register/resolve-from-source-register.js index 28b152e7058..2816f39cfda 100644 --- a/configs/mocha-config-compass/register/resolve-from-source-register.js +++ b/configs/mocha-config-compass/register/resolve-from-source-register.js @@ -4,18 +4,27 @@ const path = require('path'); const Module = require('module'); const workspacesDirPath = path.resolve(__dirname, '..', '..', '..', 'packages'); -if (!fs.existsSync(workspacesDirPath)) { +const configsDirPath = path.resolve(__dirname, '..', '..', '..', 'configs'); + +if (!fs.existsSync(workspacesDirPath) || !fs.existsSync(configsDirPath)) { // Not running inside the Compass monorepo return; } -const workspaces = fs - .readdirSync(workspacesDirPath) - .filter((workspacesDir) => { - // Unexpected but seems to be a thing that happens? Ignore hidden files - return !workspacesDir.startsWith('.'); - }) - .map((workspaceName) => path.join(workspacesDirPath, workspaceName)); +const getPackagePathsFromDir = (dirPath) => { + return fs + .readdirSync(dirPath) + .filter((dir) => { + // Unexpected but seems to be a thing that happens? Ignore hidden files + return !dir.startsWith('.'); + }) + .map((name) => path.join(dirPath, name)); +}; + +const workspaces = [ + ...getPackagePathsFromDir(workspacesDirPath), + ...getPackagePathsFromDir(configsDirPath), +]; const sourcePaths = Object.fromEntries( workspaces diff --git a/configs/testing-library-compass/.depcheckrc b/configs/testing-library-compass/.depcheckrc new file mode 100644 index 00000000000..18b9386cedf --- /dev/null +++ b/configs/testing-library-compass/.depcheckrc @@ -0,0 +1,21 @@ +ignores: + - '@mongodb-js/prettier-config-compass' + - '@mongodb-js/tsconfig-compass' + - '@types/chai' + - '@types/sinon-chai' + - 'sinon' + # This package relies on some other compass packages to function, but adding a + # dependency will introduce a circular one in our dependency tree, as it's only + # used for testing and doesn't require compilation, we're escaping the + # recursiveness issue by just not including those in the package.json + - '@mongodb-js/compass-logging' + - '@mongodb-js/compass-telemetry' + - '@mongodb-js/connection-info' + - '@mongodb-js/compass-connections' + - '@mongodb-js/compass-components' + - '@mongodb-js/connection-storage' + - 'compass-preferences-model' + - 'hadron-app-registry' + - 'mongodb-data-service' +ignore-patterns: + - 'dist' diff --git a/configs/testing-library-compass/.eslintignore b/configs/testing-library-compass/.eslintignore new file mode 100644 index 00000000000..85a8a75e68c --- /dev/null +++ b/configs/testing-library-compass/.eslintignore @@ -0,0 +1,2 @@ +.nyc-output +dist diff --git a/configs/testing-library-compass/.eslintrc.js b/configs/testing-library-compass/.eslintrc.js new file mode 100644 index 00000000000..e4cf824b6ac --- /dev/null +++ b/configs/testing-library-compass/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + root: true, + extends: ['@mongodb-js/eslint-config-compass'], + parserOptions: { + tsconfigRootDir: __dirname, + project: ['./tsconfig-lint.json'], + }, +}; diff --git a/configs/testing-library-compass/.mocharc.js b/configs/testing-library-compass/.mocharc.js new file mode 100644 index 00000000000..7e473d17b76 --- /dev/null +++ b/configs/testing-library-compass/.mocharc.js @@ -0,0 +1 @@ +module.exports = require('@mongodb-js/mocha-config-compass'); diff --git a/configs/testing-library-compass/.prettierignore b/configs/testing-library-compass/.prettierignore new file mode 100644 index 00000000000..4d28df6603a --- /dev/null +++ b/configs/testing-library-compass/.prettierignore @@ -0,0 +1,3 @@ +.nyc_output +dist +coverage diff --git a/configs/testing-library-compass/.prettierrc.json b/configs/testing-library-compass/.prettierrc.json new file mode 100644 index 00000000000..18853d1532e --- /dev/null +++ b/configs/testing-library-compass/.prettierrc.json @@ -0,0 +1 @@ +"@mongodb-js/prettier-config-compass" diff --git a/configs/testing-library-compass/package.json b/configs/testing-library-compass/package.json new file mode 100644 index 00000000000..35a2dbe3a36 --- /dev/null +++ b/configs/testing-library-compass/package.json @@ -0,0 +1,71 @@ +{ + "name": "@mongodb-js/testing-library-compass", + "description": "Compass unit testing utils", + "author": { + "name": "MongoDB Inc", + "email": "compass@mongodb.com" + }, + "private": true, + "bugs": { + "url": "https://jira.mongodb.org/projects/COMPASS/issues", + "email": "compass@mongodb.com" + }, + "homepage": "https://github.com/mongodb-js/compass", + "version": "1.0.0", + "repository": { + "type": "git", + "url": "https://github.com/mongodb-js/compass.git" + }, + "files": [ + "dist" + ], + "license": "SSPL", + "main": "dist/index.js", + "compass:main": "src/index.tsx", + "exports": { + ".": "./dist/index.js" + }, + "compass:exports": { + ".": "./src/index.tsx" + }, + "types": "./dist/index.d.ts", + "scripts": { + "compile": "tsc -p tsconfig.json", + "typecheck": "tsc -p tsconfig-lint.json --noEmit", + "eslint": "eslint", + "prettier": "prettier", + "lint": "npm run eslint . && npm run prettier -- --check .", + "depcheck": "depcheck", + "check": "npm run typecheck && npm run lint && npm run depcheck", + "check-ci": "npm run check", + "test": "mocha", + "test-cov": "nyc --compact=false --produce-source-map=false -x \"**/*.spec.*\" --reporter=lcov --reporter=text --reporter=html npm run test", + "test-watch": "npm run test -- --watch", + "test-ci": "npm run test-cov", + "reformat": "npm run eslint . -- --fix && npm run prettier -- --write ." + }, + "devDependencies": { + "@mongodb-js/eslint-config-compass": "^1.1.6", + "@mongodb-js/mocha-config-compass": "^1.4.1", + "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/tsconfig-compass": "^1.0.4", + "@types/chai": "^4.2.21", + "@types/mocha": "^9.0.0", + "@types/sinon-chai": "^3.2.5", + "chai": "^4.3.6", + "depcheck": "^1.4.1", + "eslint": "^7.25.0", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "prettier": "^2.7.1", + "typescript": "^5.0.4" + }, + "dependencies": { + "@testing-library/react": "^12.1.5", + "@testing-library/user-event": "^13.5.0", + "mongodb-connection-string-url": "^3.0.1", + "react": "^17.0.2", + "react-redux": "^8.1.3", + "sinon": "^17.0.1" + } +} diff --git a/configs/testing-library-compass/src/index.spec.tsx b/configs/testing-library-compass/src/index.spec.tsx new file mode 100644 index 00000000000..908b0584176 --- /dev/null +++ b/configs/testing-library-compass/src/index.spec.tsx @@ -0,0 +1,11 @@ +describe('helper methods', function () { + describe('render', function () {}); + + describe('renderHook', function () {}); + + describe('renderWithActiveConnection', function () {}); + + describe('renderHookWithActiveConnection', function () {}); + + describe('renderHookWithActiveConnection', function () {}); +}); diff --git a/packages/compass-connections/src/test.tsx b/configs/testing-library-compass/src/index.tsx similarity index 96% rename from packages/compass-connections/src/test.tsx rename to configs/testing-library-compass/src/index.tsx index cd51215ba8b..030ff13a46a 100644 --- a/packages/compass-connections/src/test.tsx +++ b/configs/testing-library-compass/src/index.tsx @@ -1,6 +1,3 @@ -/** - * TODO: move this to mocha-config-compass package - */ import { EventEmitter } from 'events'; import { createNoopLogger, @@ -21,6 +18,7 @@ import { waitForElementToBeRemoved, act, within, + fireEvent as testingLibraryFireEvent, } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import type { @@ -43,12 +41,17 @@ import { CompassComponentsProvider } from '@mongodb-js/compass-components'; import { ConnectionInfoProvider, TEST_CONNECTION_INFO, -} from './connection-info-provider'; -import type { State } from './stores/connections-store-redux'; -import { createDefaultConnectionInfo } from './stores/connections-store-redux'; -import { getDataServiceForConnection } from './stores/connections-store-redux'; -import { useConnectionActions, useStore } from './stores/store-context'; -import CompassConnections, { ConnectFnProvider } from './index'; +} from '@mongodb-js/compass-connections/src/connection-info-provider'; +import type { State } from '@mongodb-js/compass-connections/src/stores/connections-store-redux'; +import { createDefaultConnectionInfo } from '@mongodb-js/compass-connections/src/stores/connections-store-redux'; +import { getDataServiceForConnection } from '@mongodb-js/compass-connections/src/stores/connections-store-redux'; +import { + useConnectionActions, + useStore, +} from '@mongodb-js/compass-connections/src/stores/store-context'; +import CompassConnections, { + ConnectFnProvider, +} from '@mongodb-js/compass-connections/src/index'; import type { HadronPluginComponent, HadronPlugin } from 'hadron-app-registry'; import AppRegistry, { AppRegistryProvider, @@ -669,6 +672,11 @@ async function activatePluginWithActiveConnection< return { plugin: result.current, ...rest }; } +/** + * @deprecated use userEvent instead + */ +const fireEvent = testingLibraryFireEvent; + export { // There is never a good reason not to have these wrapper providers when // rendering something in compass for testing. Using these render methods @@ -695,4 +703,5 @@ export { createDefaultConnectionInfo, userEvent, within, + fireEvent, }; diff --git a/configs/testing-library-compass/tsconfig-lint.json b/configs/testing-library-compass/tsconfig-lint.json new file mode 100644 index 00000000000..6bdef84f322 --- /dev/null +++ b/configs/testing-library-compass/tsconfig-lint.json @@ -0,0 +1,5 @@ +{ + "extends": "./tsconfig.json", + "include": ["**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/configs/testing-library-compass/tsconfig.json b/configs/testing-library-compass/tsconfig.json new file mode 100644 index 00000000000..053993e2d48 --- /dev/null +++ b/configs/testing-library-compass/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@mongodb-js/tsconfig-compass/tsconfig.react.json", + "compilerOptions": { + "outDir": "dist", + // Because of the recursive deps + "skipLibCheck": true + }, + "include": ["src/**/*"], + "exclude": ["./src/**/*.spec.*"] +} diff --git a/package-lock.json b/package-lock.json index e71bf974ac5..d0bd5a90b63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -428,6 +428,108 @@ "prettier": "^2.7.1" } }, + "configs/testing-library-compass": { + "name": "@mongodb-js/testing-library-compass", + "version": "1.0.0", + "license": "SSPL", + "dependencies": { + "@testing-library/react": "^12.1.5", + "@testing-library/user-event": "^13.5.0", + "mongodb-connection-string-url": "^3.0.1", + "react": "^17.0.2", + "react-redux": "^8.1.3", + "sinon": "^17.0.1" + }, + "devDependencies": { + "@mongodb-js/eslint-config-compass": "^1.1.6", + "@mongodb-js/mocha-config-compass": "^1.4.1", + "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/tsconfig-compass": "^1.0.4", + "@types/chai": "^4.2.21", + "@types/mocha": "^9.0.0", + "@types/sinon-chai": "^3.2.5", + "chai": "^4.3.6", + "depcheck": "^1.4.1", + "eslint": "^7.25.0", + "mocha": "^10.2.0", + "nyc": "^15.1.0", + "prettier": "^2.7.1", + "typescript": "^5.0.4" + } + }, + "configs/testing-library-compass/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "configs/testing-library-compass/node_modules/@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "configs/testing-library-compass/node_modules/@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "dependencies": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "configs/testing-library-compass/node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "configs/testing-library-compass/node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==" + }, + "configs/testing-library-compass/node_modules/nise": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, + "configs/testing-library-compass/node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==" + }, + "configs/testing-library-compass/node_modules/sinon": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, "configs/tsconfig-compass": { "name": "@mongodb-js/tsconfig-compass", "version": "1.0.4", @@ -9311,6 +9413,10 @@ "node": ">=0.10.0" } }, + "node_modules/@mongodb-js/testing-library-compass": { + "resolved": "configs/testing-library-compass", + "link": true + }, "node_modules/@mongodb-js/tsconfig-compass": { "resolved": "configs/tsconfig-compass", "link": true @@ -12774,8 +12880,7 @@ "node_modules/@sinonjs/text-encoding": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==" }, "node_modules/@smithy/abort-controller": { "version": "3.1.1", @@ -13634,7 +13739,6 @@ "version": "8.20.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", - "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -13653,7 +13757,6 @@ "version": "27.2.5", "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", - "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -13669,7 +13772,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, "dependencies": { "@types/istanbul-lib-report": "*" } @@ -13678,7 +13780,6 @@ "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, "dependencies": { "@types/yargs-parser": "*" } @@ -13687,7 +13788,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -13696,7 +13796,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, "engines": { "node": ">=10" }, @@ -13708,7 +13807,6 @@ "version": "5.1.3", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, "dependencies": { "deep-equal": "^2.0.5" } @@ -13717,7 +13815,6 @@ "version": "27.3.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", - "dev": true, "dependencies": { "@jest/types": "^27.2.5", "ansi-regex": "^5.0.1", @@ -13732,7 +13829,6 @@ "version": "12.1.5", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^8.0.0", @@ -13779,7 +13875,6 @@ "version": "13.5.0", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", - "dev": true, "dependencies": { "@babel/runtime": "^7.12.5" }, @@ -14158,14 +14253,12 @@ "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, "dependencies": { "@types/istanbul-lib-coverage": "*" } @@ -14326,7 +14419,6 @@ "version": "17.0.10", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.10.tgz", "integrity": "sha512-8oz3NAUId2z/zQdFI09IMhQPNgIbiP8Lslhv39DIDamr846/0spjZK0vnrMak0iB8EKb9QFTTIdg2Wj2zH5a3g==", - "dev": true, "dependencies": { "@types/react": "*" } @@ -14621,8 +14713,7 @@ "node_modules/@types/yargs-parser": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "node_modules/@types/yauzl": { "version": "2.9.2", @@ -20787,7 +20878,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true, "engines": { "node": ">=0.3.1" } @@ -44176,8 +44266,8 @@ "@mongodb-js/compass-telemetry": "^1.1.6", "@mongodb-js/compass-user-data": "^0.3.6", "@mongodb-js/compass-utils": "^0.6.11", - "@mongodb-js/devtools-connect": "^3.2.8", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-connect": "^3.2.10", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/oidc-plugin": "^1.1.1", "compass-preferences-model": "^2.28.2", "electron": "^30.4.0", @@ -44209,11 +44299,12 @@ } }, "packages/atlas-service/node_modules/@mongodb-js/devtools-connect": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.8.tgz", - "integrity": "sha512-GVYmehyE5e2Z3KdouQCnub1qhk4N6qimeG/2OJcnBAYHm4G6Tc/LrxTKe/asOmNk41kNa9tskyr6ilDHlq1uMw==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.10.tgz", + "integrity": "sha512-x+MhIwJzCKjc5NhGHbns5IGa6yBwj/Nm6uVh0TwmhdKGxBbIP4o0xa4YVRwRajxHHGrxhiKQRNRJsHD6IzVVOw==", + "license": "Apache-2.0", "dependencies": { - "@mongodb-js/devtools-proxy-support": "^0.3.7", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/oidc-http-server-pages": "1.1.3", "lodash.merge": "^4.6.2", "mongodb-connection-string-url": "^3.0.0", @@ -44232,9 +44323,10 @@ } }, "packages/atlas-service/node_modules/@mongodb-js/devtools-proxy-support": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.7.tgz", - "integrity": "sha512-afBjqQo0SXyE6X2U0MJSyX+XTeMZdZONDj9DdeR3DVBg/H6i9menv4Gex9vasxPHANxgs7Yn3gCukifLEBn+gA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", + "license": "Apache-2.0", "dependencies": { "@mongodb-js/socksv5": "^0.0.10", "agent-base": "^7.1.1", @@ -44258,6 +44350,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", "engines": { "node": ">= 12" } @@ -44266,6 +44359,7 @@ "version": "4.3.6", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -44291,6 +44385,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "license": "ISC", "engines": { "node": "20 || >=22" } @@ -44299,6 +44394,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -44435,7 +44531,7 @@ "@mongodb-js/compass-workspaces": "^0.22.0", "@mongodb-js/connection-info": "^0.7.0", "@mongodb-js/connection-storage": "^0.20.0", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/get-os-info": "^0.3.24", "@mongodb-js/mocha-config-compass": "^1.4.1", @@ -44443,6 +44539,7 @@ "@mongodb-js/my-queries-storage": "^0.15.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/sbom-tools": "^0.7.0", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@mongodb-js/webpack-config-compass": "^1.4.1", "@segment/analytics-node": "^1.1.4", @@ -44544,6 +44641,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -44622,6 +44720,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/mocha": "^9.0.0", @@ -44881,6 +44980,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", @@ -44959,6 +45059,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/dom": "^8.20.1", "@testing-library/react": "^12.1.5", @@ -45705,6 +45806,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/mocha": "^9.0.0", @@ -46028,6 +46130,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -46437,7 +46540,7 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.4.6", "@mongodb-js/compass-user-data": "^0.3.6", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "bson": "^6.7.0", "hadron-app-registry": "^9.2.5", "hadron-ipc": "^3.2.22", @@ -46461,9 +46564,10 @@ } }, "packages/compass-preferences-model/node_modules/@mongodb-js/devtools-proxy-support": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.6.tgz", - "integrity": "sha512-si41DJkT/SGhXm3C6BAdnts/5iKy1KJk/QnH0iWL+esMiiYkY929BIJ0v1sg6mm2cE9sX+nUb/a1jEByXWk8Dg==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", + "license": "Apache-2.0", "dependencies": { "@mongodb-js/socksv5": "^0.0.10", "agent-base": "^7.1.1", @@ -46670,6 +46774,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", @@ -47001,6 +47106,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "chai": "^4.2.0", "depcheck": "^1.4.1", @@ -47073,6 +47179,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -47448,6 +47555,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@mongodb-js/webpack-config-compass": "^1.4.1", "@testing-library/react": "^12.1.5", @@ -47782,6 +47890,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/chai-dom": "^0.0.10", @@ -47899,10 +48008,11 @@ } }, "packages/compass/node_modules/@mongodb-js/devtools-proxy-support": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.6.tgz", - "integrity": "sha512-si41DJkT/SGhXm3C6BAdnts/5iKy1KJk/QnH0iWL+esMiiYkY929BIJ0v1sg6mm2cE9sX+nUb/a1jEByXWk8Dg==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", "dev": true, + "license": "Apache-2.0", "dependencies": { "@mongodb-js/socksv5": "^0.0.10", "agent-base": "^7.1.1", @@ -48240,8 +48350,8 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.4.6", "@mongodb-js/compass-utils": "^0.6.11", - "@mongodb-js/devtools-connect": "^3.2.8", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-connect": "^3.2.10", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "bson": "^6.7.0", "lodash": "^4.17.21", "mongodb": "^6.8.0", @@ -48277,11 +48387,12 @@ } }, "packages/data-service/node_modules/@mongodb-js/devtools-connect": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.8.tgz", - "integrity": "sha512-GVYmehyE5e2Z3KdouQCnub1qhk4N6qimeG/2OJcnBAYHm4G6Tc/LrxTKe/asOmNk41kNa9tskyr6ilDHlq1uMw==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.10.tgz", + "integrity": "sha512-x+MhIwJzCKjc5NhGHbns5IGa6yBwj/Nm6uVh0TwmhdKGxBbIP4o0xa4YVRwRajxHHGrxhiKQRNRJsHD6IzVVOw==", + "license": "Apache-2.0", "dependencies": { - "@mongodb-js/devtools-proxy-support": "^0.3.7", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/oidc-http-server-pages": "1.1.3", "lodash.merge": "^4.6.2", "mongodb-connection-string-url": "^3.0.0", @@ -48324,9 +48435,10 @@ } }, "packages/data-service/node_modules/@mongodb-js/devtools-proxy-support": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.7.tgz", - "integrity": "sha512-afBjqQo0SXyE6X2U0MJSyX+XTeMZdZONDj9DdeR3DVBg/H6i9menv4Gex9vasxPHANxgs7Yn3gCukifLEBn+gA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", + "license": "Apache-2.0", "dependencies": { "@mongodb-js/socksv5": "^0.0.10", "agent-base": "^7.1.1", @@ -48350,6 +48462,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", "engines": { "node": ">= 12" } @@ -48358,6 +48471,7 @@ "version": "4.3.6", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", + "license": "MIT", "dependencies": { "ms": "2.1.2" }, @@ -48408,6 +48522,7 @@ "version": "11.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.0.tgz", "integrity": "sha512-Qv32eSV1RSCfhY3fpPE2GNZ8jgM9X7rdAfemLWqTUxwiyIC4jJ6Sy0fZ8H+oLWevO6i4/bizg7c8d8i6bxrzbA==", + "license": "ISC", "engines": { "node": "20 || >=22" } @@ -48416,6 +48531,7 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -48590,6 +48706,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -56496,8 +56613,8 @@ "@mongodb-js/compass-telemetry": "^1.1.6", "@mongodb-js/compass-user-data": "^0.3.6", "@mongodb-js/compass-utils": "^0.6.11", - "@mongodb-js/devtools-connect": "^3.2.8", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-connect": "^3.2.10", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/oidc-plugin": "^1.1.1", @@ -56527,11 +56644,11 @@ }, "dependencies": { "@mongodb-js/devtools-connect": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.8.tgz", - "integrity": "sha512-GVYmehyE5e2Z3KdouQCnub1qhk4N6qimeG/2OJcnBAYHm4G6Tc/LrxTKe/asOmNk41kNa9tskyr6ilDHlq1uMw==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.10.tgz", + "integrity": "sha512-x+MhIwJzCKjc5NhGHbns5IGa6yBwj/Nm6uVh0TwmhdKGxBbIP4o0xa4YVRwRajxHHGrxhiKQRNRJsHD6IzVVOw==", "requires": { - "@mongodb-js/devtools-proxy-support": "^0.3.7", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/oidc-http-server-pages": "1.1.3", "kerberos": "^2.1.0", "lodash.merge": "^4.6.2", @@ -56543,9 +56660,9 @@ } }, "@mongodb-js/devtools-proxy-support": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.7.tgz", - "integrity": "sha512-afBjqQo0SXyE6X2U0MJSyX+XTeMZdZONDj9DdeR3DVBg/H6i9menv4Gex9vasxPHANxgs7Yn3gCukifLEBn+gA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", "requires": { "@mongodb-js/socksv5": "^0.0.10", "agent-base": "^7.1.1", @@ -56644,6 +56761,7 @@ "@mongodb-js/my-queries-storage": "^0.15.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/shell-bson-parser": "^1.1.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -56722,6 +56840,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/mocha": "^9.0.0", @@ -56956,6 +57075,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", @@ -57019,6 +57139,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/dom": "^8.20.1", "@testing-library/react": "^12.1.5", @@ -57209,6 +57330,7 @@ "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/my-queries-storage": "^0.15.3", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -57455,6 +57577,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/mocha": "^9.0.0", @@ -57658,6 +57781,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -58092,6 +58216,7 @@ "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/my-queries-storage": "^0.15.3", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", @@ -58774,6 +58899,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@mongosh/browser-repl": "^2.3.0", "@mongosh/logging": "^2.3.0", @@ -58837,6 +58963,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", @@ -59179,6 +59306,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@mongodb-js/webpack-config-compass": "^1.4.1", "@testing-library/react": "^12.1.5", @@ -59450,6 +59578,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/chai-dom": "^0.0.10", @@ -60909,6 +61038,104 @@ "ip-address": "^9.0.5" } }, + "@mongodb-js/testing-library-compass": { + "version": "file:configs/testing-library-compass", + "requires": { + "@mongodb-js/eslint-config-compass": "^1.1.6", + "@mongodb-js/mocha-config-compass": "^1.4.1", + "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/tsconfig-compass": "^1.0.4", + "@testing-library/react": "^12.1.5", + "@testing-library/user-event": "^13.5.0", + "@types/chai": "^4.2.21", + "@types/mocha": "^9.0.0", + "@types/sinon-chai": "^3.2.5", + "chai": "^4.3.6", + "depcheck": "^1.4.1", + "eslint": "^7.25.0", + "mocha": "^10.2.0", + "mongodb-connection-string-url": "^3.0.1", + "nyc": "^15.1.0", + "prettier": "^2.7.1", + "react": "^17.0.2", + "react-redux": "^8.1.3", + "sinon": "^17.0.1", + "typescript": "^5.0.4" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "11.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.3.1.tgz", + "integrity": "sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==", + "requires": { + "@sinonjs/commons": "^3.0.1" + } + }, + "@sinonjs/samsam": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", + "requires": { + "@sinonjs/commons": "^2.0.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "requires": { + "type-detect": "4.0.8" + } + } + } + }, + "just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==" + }, + "nise": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.9.tgz", + "integrity": "sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==", + "requires": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" + } + }, + "path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==" + }, + "sinon": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz", + "integrity": "sha512-wmwE19Lie0MLT+ZYNpDymasPHUKTaZHUH/pKEubRXIzySv9Atnlw+BUMGCzWgV7b7wO+Hw6f1TEOr0IUnmU8/g==", + "requires": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.1.0", + "nise": "^5.1.5", + "supports-color": "^7.2.0" + } + } + } + }, "@mongodb-js/tsconfig-compass": { "version": "file:configs/tsconfig-compass", "requires": { @@ -64157,8 +64384,7 @@ "@sinonjs/text-encoding": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==" }, "@smithy/abort-controller": { "version": "3.1.1", @@ -64878,7 +65104,6 @@ "version": "8.20.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.20.1.tgz", "integrity": "sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==", - "dev": true, "requires": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", @@ -64894,7 +65119,6 @@ "version": "27.2.5", "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.2.5.tgz", "integrity": "sha512-nmuM4VuDtCZcY+eTpw+0nvstwReMsjPoj7ZR80/BbixulhLaiX+fbv8oeLW8WZlJMcsGQsTmMKT/iTZu1Uy/lQ==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", @@ -64907,7 +65131,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, "requires": { "@types/istanbul-lib-report": "*" } @@ -64916,7 +65139,6 @@ "version": "16.0.4", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, "requires": { "@types/yargs-parser": "*" } @@ -64924,20 +65146,17 @@ "ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" }, "ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==" }, "aria-query": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz", "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==", - "dev": true, "requires": { "deep-equal": "^2.0.5" } @@ -64946,7 +65165,6 @@ "version": "27.3.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.3.1.tgz", "integrity": "sha512-DR/c+pvFc52nLimLROYjnXPtolawm+uWDxr4FjuLDLUn+ktWnSN851KoHwHzzqq6rfCOjkzN8FLgDrSub6UDuA==", - "dev": true, "requires": { "@jest/types": "^27.2.5", "ansi-regex": "^5.0.1", @@ -64960,7 +65178,6 @@ "version": "12.1.5", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-12.1.5.tgz", "integrity": "sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==", - "dev": true, "requires": { "@babel/runtime": "^7.12.5", "@testing-library/dom": "^8.0.0", @@ -64984,7 +65201,6 @@ "version": "13.5.0", "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", - "dev": true, "requires": { "@babel/runtime": "^7.12.5" } @@ -65343,14 +65559,12 @@ "@types/istanbul-lib-coverage": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", - "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", - "dev": true + "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==" }, "@types/istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, "requires": { "@types/istanbul-lib-coverage": "*" } @@ -65511,7 +65725,6 @@ "version": "17.0.10", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.10.tgz", "integrity": "sha512-8oz3NAUId2z/zQdFI09IMhQPNgIbiP8Lslhv39DIDamr846/0spjZK0vnrMak0iB8EKb9QFTTIdg2Wj2zH5a3g==", - "dev": true, "requires": { "@types/react": "*" } @@ -65807,8 +66020,7 @@ "@types/yargs-parser": { "version": "21.0.0", "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==" }, "@types/yauzl": { "version": "2.9.2", @@ -69371,7 +69583,7 @@ "requires": { "@mongodb-js/compass-logging": "^1.4.6", "@mongodb-js/compass-user-data": "^0.3.6", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@testing-library/react": "^12.1.5", @@ -69393,9 +69605,9 @@ }, "dependencies": { "@mongodb-js/devtools-proxy-support": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.6.tgz", - "integrity": "sha512-si41DJkT/SGhXm3C6BAdnts/5iKy1KJk/QnH0iWL+esMiiYkY929BIJ0v1sg6mm2cE9sX+nUb/a1jEByXWk8Dg==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", "requires": { "@mongodb-js/socksv5": "^0.0.10", "agent-base": "^7.1.1", @@ -70962,8 +71174,7 @@ "diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", - "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", - "dev": true + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==" }, "diff-match-patch": { "version": "1.0.5", @@ -81079,7 +81290,7 @@ "@mongodb-js/compass-workspaces": "^0.22.0", "@mongodb-js/connection-info": "^0.7.0", "@mongodb-js/connection-storage": "^0.20.0", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/get-os-info": "^0.3.24", "@mongodb-js/mocha-config-compass": "^1.4.1", @@ -81087,6 +81298,7 @@ "@mongodb-js/my-queries-storage": "^0.15.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/sbom-tools": "^0.7.0", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@mongodb-js/webpack-config-compass": "^1.4.1", "@mongosh/node-runtime-worker-thread": "^2.3.0", @@ -81140,9 +81352,9 @@ }, "dependencies": { "@mongodb-js/devtools-proxy-support": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.6.tgz", - "integrity": "sha512-si41DJkT/SGhXm3C6BAdnts/5iKy1KJk/QnH0iWL+esMiiYkY929BIJ0v1sg6mm2cE9sX+nUb/a1jEByXWk8Dg==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", "dev": true, "requires": { "@mongodb-js/socksv5": "^0.0.10", @@ -81217,9 +81429,9 @@ "@mongodb-js/compass-logging": "^1.4.6", "@mongodb-js/compass-test-server": "^0.1.21", "@mongodb-js/compass-utils": "^0.6.11", - "@mongodb-js/devtools-connect": "^3.2.8", + "@mongodb-js/devtools-connect": "^3.2.10", "@mongodb-js/devtools-docker-test-envs": "^1.3.3", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/oidc-plugin": "^1.1.1", @@ -81249,11 +81461,11 @@ }, "dependencies": { "@mongodb-js/devtools-connect": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.8.tgz", - "integrity": "sha512-GVYmehyE5e2Z3KdouQCnub1qhk4N6qimeG/2OJcnBAYHm4G6Tc/LrxTKe/asOmNk41kNa9tskyr6ilDHlq1uMw==", + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-connect/-/devtools-connect-3.2.10.tgz", + "integrity": "sha512-x+MhIwJzCKjc5NhGHbns5IGa6yBwj/Nm6uVh0TwmhdKGxBbIP4o0xa4YVRwRajxHHGrxhiKQRNRJsHD6IzVVOw==", "requires": { - "@mongodb-js/devtools-proxy-support": "^0.3.7", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/oidc-http-server-pages": "1.1.3", "kerberos": "^2.1.0", "lodash.merge": "^4.6.2", @@ -81291,9 +81503,9 @@ } }, "@mongodb-js/devtools-proxy-support": { - "version": "0.3.7", - "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.7.tgz", - "integrity": "sha512-afBjqQo0SXyE6X2U0MJSyX+XTeMZdZONDj9DdeR3DVBg/H6i9menv4Gex9vasxPHANxgs7Yn3gCukifLEBn+gA==", + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@mongodb-js/devtools-proxy-support/-/devtools-proxy-support-0.3.9.tgz", + "integrity": "sha512-y6EpBQuOYMSbnc3y7lWG3ThFWC7iv6HHZn8+7tRsr9diSMwHRoxM/GNrz2yeldT7xstFdGL4zmmSK/3JcSz+8g==", "requires": { "@mongodb-js/socksv5": "^0.0.10", "agent-base": "^7.1.1", diff --git a/package.json b/package.json index b73b431be01..febeb24d28e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,9 @@ "license": "SSPL", "scripts": { "bootstrap": "npm install && lerna run bootstrap --stream", + "postbootstrap": "npm run compile --workspace=@mongodb-js/testing-library-compass", "bootstrap-ci": "npm ci && lerna run bootstrap", + "postbootstrap-ci": "npm run postbootstrap", "precheck": "npm run depcheck && npm run check-logids && npm run check-leafygreen-dependency-usage", "changed": "node ./scripts/changed.js", "check": "lerna run check --stream", diff --git a/packages/atlas-service/package.json b/packages/atlas-service/package.json index 8bd4a5712d2..9d7c21acc00 100644 --- a/packages/atlas-service/package.json +++ b/packages/atlas-service/package.json @@ -78,8 +78,8 @@ "@mongodb-js/compass-telemetry": "^1.1.6", "@mongodb-js/compass-user-data": "^0.3.6", "@mongodb-js/compass-utils": "^0.6.11", - "@mongodb-js/devtools-connect": "^3.2.8", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-connect": "^3.2.10", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/oidc-plugin": "^1.1.1", "hadron-app-registry": "^9.2.5", "compass-preferences-model": "^2.28.2", diff --git a/packages/compass-aggregations/package.json b/packages/compass-aggregations/package.json index 082b92528a6..110813cc89f 100644 --- a/packages/compass-aggregations/package.json +++ b/packages/compass-aggregations/package.json @@ -35,12 +35,13 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", + "@types/babel__generator": "^7.6.8", "@types/lodash": "^4.14.188", "@types/semver": "^7.3.9", - "@types/babel__generator": "^7.6.8", "chai": "^4.3.6", "depcheck": "^1.4.1", "electron-mocha": "^12.2.0", diff --git a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx index 04458b965ff..f62bd1b00e2 100644 --- a/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx +++ b/packages/compass-aggregations/src/components/pipeline-toolbar/pipeline-settings/index.tsx @@ -78,6 +78,7 @@ export const PipelineSettings: React.FunctionComponent< onClick={onExportToLanguage} data-testid="pipeline-toolbar-export-button" disabled={!isExportToLanguageEnabled} + title="Export to language" > Export to language diff --git a/packages/compass-aggregations/src/stores/create-view.spec.ts b/packages/compass-aggregations/src/stores/create-view.spec.ts index 35e5f562768..729d32b7d40 100644 --- a/packages/compass-aggregations/src/stores/create-view.spec.ts +++ b/packages/compass-aggregations/src/stores/create-view.spec.ts @@ -5,7 +5,7 @@ import Sinon from 'sinon'; import { activatePluginWithConnections, cleanup, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import { CreateViewPlugin } from '../index'; const TEST_CONNECTION = { diff --git a/packages/compass-aggregations/test/configure-store.ts b/packages/compass-aggregations/test/configure-store.ts index 9c2fe89b090..a610979a6b5 100644 --- a/packages/compass-aggregations/test/configure-store.ts +++ b/packages/compass-aggregations/test/configure-store.ts @@ -7,7 +7,7 @@ import { AtlasAuthService } from '@mongodb-js/atlas-service/provider'; import { activatePluginWithActiveConnection, renderPluginComponentWithActiveConnection, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import { CompassAggregationsHadronPlugin } from '../src/index'; import type { DataService } from '@mongodb-js/compass-connections/provider'; import React from 'react'; diff --git a/packages/compass-app-stores/package.json b/packages/compass-app-stores/package.json index a2d56670f43..d02b5324898 100644 --- a/packages/compass-app-stores/package.json +++ b/packages/compass-app-stores/package.json @@ -56,6 +56,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/mocha": "^9.0.0", diff --git a/packages/compass-app-stores/src/provider.spec.tsx b/packages/compass-app-stores/src/provider.spec.tsx index 65e21819ac9..a0226fb5a2d 100644 --- a/packages/compass-app-stores/src/provider.spec.tsx +++ b/packages/compass-app-stores/src/provider.spec.tsx @@ -11,7 +11,7 @@ import { screen, cleanup, waitFor, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; describe('NamespaceProvider', function () { const sandbox = Sinon.createSandbox(); diff --git a/packages/compass-app-stores/src/stores/instance-store.spec.ts b/packages/compass-app-stores/src/stores/instance-store.spec.ts index a30eabc1a39..051239f3d17 100644 --- a/packages/compass-app-stores/src/stores/instance-store.spec.ts +++ b/packages/compass-app-stores/src/stores/instance-store.spec.ts @@ -8,7 +8,7 @@ import { createDefaultConnectionInfo, activatePluginWithConnections, cleanup, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; const mockConnections = [ createDefaultConnectionInfo(), diff --git a/packages/compass-components/src/components/item-action-controls.tsx b/packages/compass-components/src/components/item-action-controls.tsx index b26c56a3961..95d6a06eba4 100644 --- a/packages/compass-components/src/components/item-action-controls.tsx +++ b/packages/compass-components/src/components/item-action-controls.tsx @@ -18,6 +18,7 @@ import type { ButtonProps } from '@leafygreen-ui/button'; import type { glyphs } from '@leafygreen-ui/icon'; import { spacing } from '@leafygreen-ui/tokens'; import { css, cx } from '@leafygreen-ui/emotion'; +import { WorkspaceContainer } from './workspace-container'; export type ItemAction = { action: Action; @@ -486,6 +487,13 @@ export function ItemActionControls({ return ; } +const hiddenOnNarrowStyles = css({ + [`@container ${WorkspaceContainer.toolbarContainerQueryName} (width < 900px)`]: + { + display: 'none', + }, +}); + export function DropdownMenuButton({ isVisible = true, actions, @@ -557,8 +565,9 @@ export function DropdownMenuButton({ onClick && onClick(evt); }} rightGlyph={} + title={buttonText} > - {buttonText} + {buttonText} {children} ); diff --git a/packages/compass-components/tsconfig.json b/packages/compass-components/tsconfig.json index 01520548b34..29bc42505ac 100644 --- a/packages/compass-components/tsconfig.json +++ b/packages/compass-components/tsconfig.json @@ -4,5 +4,5 @@ "outDir": "lib" }, "include": ["src/**/*"], - "exclude": ["./src/**/*.spec.*"] + "exclude": ["./src/**/*.spec.*", "./src/**/*.test.*"] } diff --git a/packages/compass-connection-import-export/package.json b/packages/compass-connection-import-export/package.json index 1b22569a890..776a9f35136 100644 --- a/packages/compass-connection-import-export/package.json +++ b/packages/compass-connection-import-export/package.json @@ -62,6 +62,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", diff --git a/packages/compass-connection-import-export/src/hooks/use-export-connections.spec.tsx b/packages/compass-connection-import-export/src/hooks/use-export-connections.spec.tsx index cfcff3677e6..7669af6f027 100644 --- a/packages/compass-connection-import-export/src/hooks/use-export-connections.spec.tsx +++ b/packages/compass-connection-import-export/src/hooks/use-export-connections.spec.tsx @@ -5,14 +5,14 @@ import type { ImportExportResult } from './common'; import os from 'os'; import path from 'path'; import { promises as fs } from 'fs'; -import type { RenderConnectionsOptions } from '@mongodb-js/compass-connections/test'; +import type { RenderConnectionsOptions } from '@mongodb-js/testing-library-compass'; import { renderHookWithConnections, act, cleanup, createDefaultConnectionInfo, waitFor, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; describe('useExportConnections', function () { let sandbox: sinon.SinonSandbox; diff --git a/packages/compass-connection-import-export/src/hooks/use-import-connections.spec.tsx b/packages/compass-connection-import-export/src/hooks/use-import-connections.spec.tsx index 6b47e31c8bd..4d7312fda89 100644 --- a/packages/compass-connection-import-export/src/hooks/use-import-connections.spec.tsx +++ b/packages/compass-connection-import-export/src/hooks/use-import-connections.spec.tsx @@ -6,12 +6,12 @@ import os from 'os'; import path from 'path'; import { promises as fs } from 'fs'; import { type ConnectionInfo } from '@mongodb-js/connection-storage/provider'; -import type { RenderConnectionsOptions } from '@mongodb-js/compass-connections/test'; +import type { RenderConnectionsOptions } from '@mongodb-js/testing-library-compass'; import { renderHookWithConnections, waitFor, act, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; const exampleFileContents = '{"a":"b"}'; diff --git a/packages/compass-connections/package.json b/packages/compass-connections/package.json index 688a45e201e..ea8b49e6e8f 100644 --- a/packages/compass-connections/package.json +++ b/packages/compass-connections/package.json @@ -28,8 +28,7 @@ "compass:main": "src/index.tsx", "compass:exports": { ".": "./src/index.tsx", - "./provider": "./src/provider.ts", - "./test": "./src/test.tsx" + "./provider": "./src/provider.ts" }, "types": "./dist/index.d.ts", "scripts": { @@ -76,6 +75,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/dom": "^8.20.1", "@testing-library/react": "^12.1.5", diff --git a/packages/compass-connections/src/components/legacy-connections.spec.tsx b/packages/compass-connections/src/components/legacy-connections.spec.tsx index ba498d552ca..55034c5a608 100644 --- a/packages/compass-connections/src/components/legacy-connections.spec.tsx +++ b/packages/compass-connections/src/components/legacy-connections.spec.tsx @@ -10,7 +10,7 @@ import { userEvent, waitFor, cleanup, -} from '../test'; +} from '@mongodb-js/testing-library-compass'; async function loadSavedConnectionAndConnect(connectionInfo: ConnectionInfo) { const savedConnectionButton = screen.getByTestId( diff --git a/packages/compass-connections/src/hooks/use-active-connections.spec.ts b/packages/compass-connections/src/hooks/use-active-connections.spec.ts index ecc1940717b..dc481354dea 100644 --- a/packages/compass-connections/src/hooks/use-active-connections.spec.ts +++ b/packages/compass-connections/src/hooks/use-active-connections.spec.ts @@ -1,5 +1,8 @@ import { useActiveConnections } from './use-active-connections'; -import { cleanup, renderHookWithConnections } from '../test'; +import { + cleanup, + renderHookWithConnections, +} from '@mongodb-js/testing-library-compass'; import { expect } from 'chai'; import type { ConnectionInfo } from '@mongodb-js/connection-storage/provider'; diff --git a/packages/compass-connections/src/hooks/use-connection-repository.spec.ts b/packages/compass-connections/src/hooks/use-connection-repository.spec.ts index b9f7fd47724..70315585a63 100644 --- a/packages/compass-connections/src/hooks/use-connection-repository.spec.ts +++ b/packages/compass-connections/src/hooks/use-connection-repository.spec.ts @@ -5,7 +5,7 @@ import { cleanup } from '@testing-library/react'; import { createDefaultConnectionInfo, renderHookWithConnections, -} from '../test'; +} from '@mongodb-js/testing-library-compass'; const favoriteMockConnections = [ { diff --git a/packages/compass-connections/src/hooks/use-connection-supports.spec.ts b/packages/compass-connections/src/hooks/use-connection-supports.spec.ts index 37e25288135..ad11e0270ee 100644 --- a/packages/compass-connections/src/hooks/use-connection-supports.spec.ts +++ b/packages/compass-connections/src/hooks/use-connection-supports.spec.ts @@ -1,7 +1,7 @@ import { useConnectionSupports } from './use-connection-supports'; import { type ConnectionInfo } from '@mongodb-js/connection-storage/provider'; import { expect } from 'chai'; -import { renderHookWithConnections } from '../test'; +import { renderHookWithConnections } from '@mongodb-js/testing-library-compass'; const mockConnections: ConnectionInfo[] = [ { diff --git a/packages/compass-connections/src/hooks/use-connections-with-status.spec.tsx b/packages/compass-connections/src/hooks/use-connections-with-status.spec.tsx index bbe3957841e..3f02183c3d0 100644 --- a/packages/compass-connections/src/hooks/use-connections-with-status.spec.tsx +++ b/packages/compass-connections/src/hooks/use-connections-with-status.spec.tsx @@ -2,7 +2,7 @@ import { useConnectionsWithStatus } from './use-connections-with-status'; import { type ConnectionInfo } from '@mongodb-js/connection-storage/provider'; import { expect } from 'chai'; import Sinon from 'sinon'; -import { renderHookWithConnections } from '../test'; +import { renderHookWithConnections } from '@mongodb-js/testing-library-compass'; const mockConnections: ConnectionInfo[] = [ { diff --git a/packages/compass-connections/src/hooks/use-tab-connection-theme.spec.ts b/packages/compass-connections/src/hooks/use-tab-connection-theme.spec.ts index 29d8d002046..b72ce52f8c5 100644 --- a/packages/compass-connections/src/hooks/use-tab-connection-theme.spec.ts +++ b/packages/compass-connections/src/hooks/use-tab-connection-theme.spec.ts @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { useTabConnectionTheme } from '../provider'; -import { renderHookWithConnections } from '../test'; +import { renderHookWithConnections } from '@mongodb-js/testing-library-compass'; const CONNECTION_INFO = { id: '1234', diff --git a/packages/compass-connections/src/stores/connections-store.spec.tsx b/packages/compass-connections/src/stores/connections-store.spec.tsx index 6151e39031e..adf34f4acab 100644 --- a/packages/compass-connections/src/stores/connections-store.spec.tsx +++ b/packages/compass-connections/src/stores/connections-store.spec.tsx @@ -8,7 +8,7 @@ import { screen, createDefaultConnectionInfo, wait, -} from '../test'; +} from '@mongodb-js/testing-library-compass'; const mockConnections = [ { diff --git a/packages/compass-connections/test.d.ts b/packages/compass-connections/test.d.ts deleted file mode 100644 index dc68cf65297..00000000000 --- a/packages/compass-connections/test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './dist/test.d'; diff --git a/packages/compass-connections/test.js b/packages/compass-connections/test.js deleted file mode 100644 index 2b7f7cb9dd8..00000000000 --- a/packages/compass-connections/test.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict'; -module.exports = require('./dist/test'); diff --git a/packages/compass-crud/src/components/crud-toolbar.spec.tsx b/packages/compass-crud/src/components/crud-toolbar.spec.tsx index 6827f08c688..295ef0999b2 100644 --- a/packages/compass-crud/src/components/crud-toolbar.spec.tsx +++ b/packages/compass-crud/src/components/crud-toolbar.spec.tsx @@ -151,24 +151,47 @@ describe('CrudToolbar Component', function () { expect(screen.getByTestId('docs-toolbar-prev-page-btn')).to.be.visible; }); - it('should have the next page button disabled when on the first page without more than a page of documents', function () { - const getPageSpy = sinon.spy(); - renderCrudToolbar({ - getPage: getPageSpy, - count: 5, - page: 0, - start: 1, - end: 5, + context('respecting the docsPerPage setting', () => { + it('should have the next page button disabled when on the first page without more than a page of documents', function () { + const getPageSpy = sinon.spy(); + renderCrudToolbar({ + getPage: getPageSpy, + docsPerPage: 50, + count: 50, + page: 0, + start: 1, + end: 50, + }); + expect(getPageSpy.called).to.be.false; + fireEvent.click(screen.getByTestId('docs-toolbar-next-page-btn')); + + expect( + screen.getByTestId('docs-toolbar-next-page-btn') + ).to.have.attribute('aria-disabled', 'true'); + + expect(getPageSpy.calledOnce).to.be.false; }); - expect(getPageSpy.called).to.be.false; - fireEvent.click(screen.getByTestId('docs-toolbar-next-page-btn')); - expect(screen.getByTestId('docs-toolbar-next-page-btn')).to.have.attribute( - 'aria-disabled', - 'true' - ); + it('should have the next page button disabled when on the first page with more than a page of documents', function () { + const getPageSpy = sinon.spy(); + renderCrudToolbar({ + getPage: getPageSpy, + docsPerPage: 25, + count: 50, + page: 0, + start: 1, + end: 25, + }); + expect(getPageSpy.called).to.be.false; + fireEvent.click(screen.getByTestId('docs-toolbar-next-page-btn')); - expect(getPageSpy.calledOnce).to.be.false; + expect( + screen.getByTestId('docs-toolbar-next-page-btn') + ).to.have.attribute('aria-disabled', 'false'); + + expect(getPageSpy.calledOnce).to.be.true; + expect(getPageSpy.firstCall.args[0]).to.equal(1); + }); }); it('should call to get the next page when the prev button is hit on a non-first page', function () { diff --git a/packages/compass-crud/src/components/crud-toolbar.tsx b/packages/compass-crud/src/components/crud-toolbar.tsx index 3c307d0c1da..47355683ece 100644 --- a/packages/compass-crud/src/components/crud-toolbar.tsx +++ b/packages/compass-crud/src/components/crud-toolbar.tsx @@ -173,8 +173,10 @@ const CrudToolbar: React.FunctionComponent = ({ const nextButtonDisabled = useMemo( // If we don't know the count, we can't know if there are more pages. () => - count === undefined || count === null ? false : 20 * (page + 1) >= count, - [count, page] + count === undefined || count === null + ? false + : docsPerPage * (page + 1) >= count, + [count, page, docsPerPage] ); const enableExplainPlan = usePreference('enableExplainPlan'); diff --git a/packages/compass-crud/src/components/delete-data-menu.tsx b/packages/compass-crud/src/components/delete-data-menu.tsx index f318f05927d..848fed3bcf0 100644 --- a/packages/compass-crud/src/components/delete-data-menu.tsx +++ b/packages/compass-crud/src/components/delete-data-menu.tsx @@ -31,6 +31,7 @@ const DeleteMenuButton: React.FunctionComponent = ({ onClick={onClick} leftGlyph={} data-testid="crud-bulk-delete" + title="Delete" > Delete diff --git a/packages/compass-crud/src/components/update-data-menu.tsx b/packages/compass-crud/src/components/update-data-menu.tsx index a5d9ffd063e..007e7e7924e 100644 --- a/packages/compass-crud/src/components/update-data-menu.tsx +++ b/packages/compass-crud/src/components/update-data-menu.tsx @@ -31,6 +31,7 @@ const UpdateMenuButton: React.FunctionComponent = ({ onClick={onClick} leftGlyph={} data-testid="crud-update" + title="Update" > Update diff --git a/packages/compass-editor/src/codemirror/query-autocompleter-with-history.test.ts b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.test.ts index c85205ec492..292780c1c42 100644 --- a/packages/compass-editor/src/codemirror/query-autocompleter-with-history.test.ts +++ b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.test.ts @@ -2,7 +2,13 @@ import { expect } from 'chai'; import { createQueryWithHistoryAutocompleter } from './query-autocompleter-with-history'; import { setupCodemirrorCompleter } from '../../test/completer'; import type { SavedQuery } from '../../dist/codemirror/query-history-autocompleter'; -import { createQuery } from './query-history-autocompleter'; +import type { Completion } from '@codemirror/autocomplete'; + +function getQueryHistoryAutocompletions(completions: Readonly) { + return completions.filter( + ({ type }) => type === 'favorite' || type === 'query-history' + ); +} describe('query history autocompleter', function () { const { getCompletions, cleanup } = setupCodemirrorCompleter( @@ -46,7 +52,7 @@ describe('query history autocompleter', function () { type: 'recent', lastExecuted: new Date('2023-06-04T18:00:00Z'), queryProperties: { - filter: { isActive: true }, + filter: { isActive: true, score: { $exists: false } }, project: { userId: 1, isActive: 1 }, collation: { locale: 'simple' }, sort: { userId: 1 }, @@ -71,32 +77,105 @@ describe('query history autocompleter', function () { const mockOnApply: (query: SavedQuery['queryProperties']) => any = () => {}; - it('returns all saved queries as completions on click', async function () { + it('returns all saved queries as completions with default {}', async function () { expect( - await getCompletions('{}', savedQueries, undefined, mockOnApply, 'light') + await getCompletions('{}', { + savedQueries, + options: undefined, + queryProperty: '', + onApply: mockOnApply, + theme: 'light', + }) ).to.have.lengthOf(5); }); - it('returns combined completions when user starts typing', async function () { + it('returns all saved queries as completions with empty entry', async function () { expect( - await getCompletions('foo', savedQueries, undefined, mockOnApply, 'light') - ).to.have.lengthOf(50); + await getCompletions('', { + savedQueries, + options: undefined, + queryProperty: '', + onApply: mockOnApply, + theme: 'light', + }) + ).to.have.lengthOf(5); + }); + + it('returns combined completions that match the prefix of the field', async function () { + const completions = await getCompletions('scor', { + savedQueries, + options: undefined, + queryProperty: 'filter', + onApply: mockOnApply, + theme: 'light', + }); + const queryHistoryCompletions = getQueryHistoryAutocompletions(completions); + + expect(queryHistoryCompletions).to.have.lengthOf(2); + expect(completions).to.have.length.greaterThan( + queryHistoryCompletions.length + ); + }); + + it('returns completions that match with multiple fields', async function () { + const completions = getQueryHistoryAutocompletions( + await getCompletions('{ price: 1, category: 1', { + savedQueries, + options: undefined, + queryProperty: 'project', + onApply: mockOnApply, + theme: 'light', + }) + ); + expect(completions).to.have.lengthOf(1); + expect(completions[0].label).to.equal(`{ + productId: 1, + category: 1, + price: 1 +}`); }); - it('completes "any text" when inside a string', async function () { - const prettifiedSavedQueries = savedQueries.map((query) => - createQuery(query) + it('does not return fields that match in other query properties', async function () { + const completions = getQueryHistoryAutocompletions( + await getCompletions('local', { + savedQueries, + options: undefined, + queryProperty: 'project', + onApply: mockOnApply, + theme: 'light', + }) ); + + const queryHistoryCompletions = getQueryHistoryAutocompletions(completions); + expect(queryHistoryCompletions).to.have.lengthOf(0); + }); + + it('completes regular query autocompletion items', async function () { + // 'foo' matches > 45 methods and fields in the query autocompletion. + const completions = ( + await getCompletions('foo', { + savedQueries, + options: undefined, + queryProperty: '', + onApply: mockOnApply, + theme: 'light', + }) + ).filter(({ type }) => type !== 'favorite' && type !== 'query-history'); + + expect(completions).to.have.length.greaterThan(40); + }); + + it('completes fields inside a string', async function () { expect( ( - await getCompletions( - '{ bar: 1, buz: 2, foo: "b', + await getCompletions('{ bar: 1, buz: 2, foo: "b', { savedQueries, - undefined, - mockOnApply, - 'light' - ) + options: undefined, + queryProperty: '', + onApply: mockOnApply, + theme: 'light', + }) ).map((completion) => completion.label) - ).to.deep.eq(['bar', '1', 'buz', '2', 'foo', ...prettifiedSavedQueries]); + ).to.deep.eq(['bar', '1', 'buz', '2', 'foo']); }); }); diff --git a/packages/compass-editor/src/codemirror/query-autocompleter-with-history.ts b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.ts index 49a0bda23ed..e4b6b07bf1a 100644 --- a/packages/compass-editor/src/codemirror/query-autocompleter-with-history.ts +++ b/packages/compass-editor/src/codemirror/query-autocompleter-with-history.ts @@ -13,17 +13,25 @@ import type { CompletionOptions } from '../autocompleter'; import { css } from '@mongodb-js/compass-components'; import type { CodemirrorThemeType } from '../editor'; -export const createQueryWithHistoryAutocompleter = ( - recentQueries: SavedQuery[], - options: Pick = {}, - onApply: (query: SavedQuery['queryProperties']) => void, - theme: CodemirrorThemeType -): CompletionSource => { - const queryHistoryAutocompleter = createQueryHistoryAutocompleter( - recentQueries, +export const createQueryWithHistoryAutocompleter = ({ + savedQueries, + options = {}, + queryProperty, + onApply, + theme, +}: { + savedQueries: SavedQuery[]; + options?: Pick; + queryProperty: string; + onApply: (query: SavedQuery['queryProperties']) => void; + theme: CodemirrorThemeType; +}): CompletionSource => { + const queryHistoryAutocompleter = createQueryHistoryAutocompleter({ + savedQueries, onApply, - theme - ); + queryProperty, + theme, + }); const originalQueryAutocompleter = createQueryAutocompleter(options); const historySection: CompletionSection = { diff --git a/packages/compass-editor/src/codemirror/query-history-autocompleter.test.ts b/packages/compass-editor/src/codemirror/query-history-autocompleter.test.ts index 13cc25a80d5..39adf8142c7 100644 --- a/packages/compass-editor/src/codemirror/query-history-autocompleter.test.ts +++ b/packages/compass-editor/src/codemirror/query-history-autocompleter.test.ts @@ -1,5 +1,9 @@ import { expect } from 'chai'; -import { scaleBetween } from './query-history-autocompleter'; +import { + createQueryDisplayLabel, + createQueryLabel, + scaleBetween, +} from './query-history-autocompleter'; describe('scaleBetween', function () { // args: unscaledNum, newScaleMin, newScaleMax, originalScaleMin, originalScaleMax @@ -23,3 +27,107 @@ describe('scaleBetween', function () { expect(result).to.equal(25); }); }); + +describe('createQueryLabel', function () { + it('should return an empty string if the property does not exist', () => { + const result = createQueryLabel( + { + type: 'favorite', + lastExecuted: new Date('2023-06-03T16:00:00Z'), + queryProperties: { + filter: { name: 'pineapple' }, + project: {}, + sort: undefined, + limit: undefined, + }, + }, + 'collation' + ); + expect(result).to.equal(''); + }); + + it('should return the string representation of the property value if it exists', () => { + const result = createQueryLabel( + { + type: 'favorite', + lastExecuted: new Date('2023-06-03T16:00:00Z'), + queryProperties: { + filter: { name: 'pineapple' }, + project: {}, + sort: undefined, + limit: undefined, + }, + }, + 'filter' + ); + expect(result).to.equal("{\n name: 'pineapple'\n}"); + }); + + it('should return an empty string if the property value is undefined', () => { + const result = createQueryLabel( + { + type: 'favorite', + lastExecuted: new Date('2023-06-03T16:00:00Z'), + queryProperties: { + filter: { name: 'pineapple' }, + project: {}, + sort: undefined, + limit: undefined, + }, + }, + 'exampleProperty' + ); + expect(result).to.equal(''); + }); +}); + +describe('createQueryDisplayLabel', function () { + it('should return an empty string if queryProperties is empty', () => { + const result = createQueryDisplayLabel({ + type: 'recent', + lastExecuted: new Date('2023-06-03T16:00:00Z'), + queryProperties: {}, + }); + expect(result).to.equal(''); + }); + + it('should return a formatted label for multiple properties', () => { + const result = createQueryDisplayLabel({ + type: 'favorite', + lastExecuted: new Date('2023-06-03T16:00:00Z'), + queryProperties: { + filter: { name: 'pineapple' }, + project: { _id: 0 }, + sort: { score: -1 }, + hint: { indexName: 'score_1' }, + limit: 20, + maxTimeMS: 1000, + }, + }); + expect(result).to.equal(`{ + name: 'pineapple' +}, project: { + _id: 0 +}, sort: { + score: -1 +}, hint: { + indexName: 'score_1' +}, limit: 20, maxTimeMS: 1000`); + }); + + it('should handle empty or undefined property values', () => { + const result = createQueryDisplayLabel({ + type: 'favorite', + lastExecuted: new Date('2023-06-03T16:00:00Z'), + queryProperties: { + filter: { name: 'pineapple' }, + project: {}, + sort: undefined, + limit: undefined, + }, + }); + expect(result).to.equal(`{ + name: 'pineapple' +}, project: {}, sort: undefined, limit: undefined`); + }); +}); diff --git a/packages/compass-editor/src/codemirror/query-history-autocompleter.ts b/packages/compass-editor/src/codemirror/query-history-autocompleter.ts index b9c78e80e20..c617d9251c5 100644 --- a/packages/compass-editor/src/codemirror/query-history-autocompleter.ts +++ b/packages/compass-editor/src/codemirror/query-history-autocompleter.ts @@ -21,11 +21,96 @@ export type SavedQuery = { }; }; -export const createQueryHistoryAutocompleter = ( - savedQueries: SavedQuery[], - onApply: (query: SavedQuery['queryProperties']) => void, - theme: CodemirrorThemeType -): CompletionSource => { +function simplifyQueryStringForAutocomplete(queryString: string): string { + return queryString.replace(/[\s'"\n\t{}},]/g, '').toLowerCase(); +} + +/** + * Codemirror runs a fuzzy search on the completion item labels. + * Oftentimes the fuzzy search will match on too many query history items. + * We limit the possible results to be improve accuracy. + * We give suggestions of queries that either match at least one field, + * or that contain the prefix the user is typing. + */ +function getMatchingQueryHistoryItemsForInput({ + savedQueries, + queryProperty, + input: _input, +}: { + savedQueries: SavedQuery[]; + queryProperty: string; + input: string; +}) { + const input = simplifyQueryStringForAutocomplete(_input); + + if (input.length === 0) { + // Everything matches when empty search. + return savedQueries; + } + + return savedQueries.filter((query) => { + const queryValue = query.queryProperties[queryProperty]; + + // Only some query properties are objects. For instance limit can be an array. + if (typeof queryValue !== 'object') { + const queryValueString = toJSString(queryValue) || ''; + if (!queryValueString) { + return false; + } + + const queryValueSimplified = + simplifyQueryStringForAutocomplete(queryValueString); + return queryValueSimplified.startsWith(input); + } + + // We subtract parts of the string until there's nothing left. + // We know it's a possible match if the all of the input is found in the query. + let inputToMatch = input; + + // We check each top level field as they can be in any order. + for (const [key, value] of Object.entries(queryValue).slice( + 0, + 30 /* Some queries can have a ton of fields, we slice to avoid long loops on each character typed. */ + )) { + const fieldString = toJSString({ [key]: value }) || ''; + const fieldStringSimplified = + simplifyQueryStringForAutocomplete(fieldString); + + if (input === fieldStringSimplified) { + // Don't show an option if the user has typed the whole field. + return false; + } + + if (fieldStringSimplified.startsWith(input)) { + // When the user is typing their first field, we can return early. + return true; + } + + const inputIndex = inputToMatch.indexOf(fieldStringSimplified); + if (inputIndex !== -1) { + inputToMatch = inputToMatch.replace(fieldStringSimplified, ''); + } + } + + if (inputToMatch.length === 0) { + return true; + } + + return false; + }); +} + +export const createQueryHistoryAutocompleter = ({ + savedQueries, + onApply, + queryProperty, + theme, +}: { + savedQueries: SavedQuery[]; + onApply: (query: SavedQuery['queryProperties']) => void; + queryProperty: string; + theme: CodemirrorThemeType; +}): CompletionSource => { return function queryCompletions(context: CompletionContext) { if (savedQueries.length === 0) { return null; @@ -35,8 +120,18 @@ export const createQueryHistoryAutocompleter = ( savedQueries[savedQueries.length - 1].lastExecuted.getTime(); const minTime = savedQueries[0].lastExecuted.getTime(); - const options = savedQueries.map((query) => ({ - label: createQuery(query), + const contextValue = context.state.sliceDoc(0, context.pos); + const matchedQueries = getMatchingQueryHistoryItemsForInput({ + savedQueries, + queryProperty, + input: contextValue, + }); + + const options = matchedQueries.map((query) => ({ + // Use a display label to show the query property + // field names before their respective parts. + displayLabel: createQueryDisplayLabel(query), + label: createQueryLabel(query, queryProperty), type: query.type === 'recent' ? 'query-history' : 'favorite', detail: formatDate(query.lastExecuted.getTime()), info: () => createInfo(query, theme).dom, @@ -74,14 +169,30 @@ const queryCodeStyles = css({ whiteSpace: 'pre-wrap', }); -export function createQuery(query: SavedQuery): string { - let res = ''; - Object.entries(query.queryProperties).forEach(([key, value]) => { - const formattedQuery = toJSString(value); - const noFilterKey = key === 'filter' ? '' : `${key}: `; - res += formattedQuery ? `, ${noFilterKey}${formattedQuery}` : ''; - }); - return res.slice(2, res.length); +export function createQueryLabel( + query: SavedQuery, + propertyName: string +): string { + if (!query.queryProperties[propertyName]) { + return ''; + } + + // The autocompletion uses a fuzzy search on the label, we only want to + // auto complete property that is being edited, not all of them. + return toJSString(query.queryProperties[propertyName]) || ''; +} + +export function createQueryDisplayLabel(query: SavedQuery): string { + return Object.entries(query.queryProperties) + .map(([key, value]) => { + const formattedQuery = toJSString(value, 1); + if (!formattedQuery) return ''; + // Hide the `filter` key in the display label as it's the default field. + const fieldKey = key === 'filter' ? '' : `${key}: `; + return `${fieldKey}${formattedQuery}`; + }) + .filter(Boolean) + .reduce((acc, curr) => (acc ? `${acc}, ${curr}` : curr), ''); } const javascriptExpressionLanguageParser = diff --git a/packages/compass-editor/src/editor.tsx b/packages/compass-editor/src/editor.tsx index 5d70deb773f..8c166a9c638 100644 --- a/packages/compass-editor/src/editor.tsx +++ b/packages/compass-editor/src/editor.tsx @@ -32,6 +32,7 @@ import { foldEffect, } from '@codemirror/language'; import { + cursorDocEnd, defaultKeymap, history, historyKeymap, @@ -433,7 +434,7 @@ function getStylesForTheme(theme: CodemirrorThemeType) { marginTop: 0, paddingTop: 0, fontSize: '12px', - maxHeight: '70vh', + maxHeight: `${spacing[1600] * 5}px`, }, '& .cm-tooltip .completion-info p': { margin: 0, @@ -698,6 +699,7 @@ export type EditorRef = { prettify: () => boolean; applySnippet: (template: string) => boolean; focus: () => boolean; + cursorDocEnd: () => boolean; startCompletion: () => boolean; readonly editorContents: string | null; readonly editor: EditorView | null; @@ -808,6 +810,12 @@ const BaseEditor = React.forwardRef(function BaseEditor( editorViewRef.current.focus(); return true; }, + cursorDocEnd() { + if (!editorViewRef.current) { + return false; + } + return cursorDocEnd(editorViewRef.current); + }, startCompletion() { if (!editorViewRef.current) { return false; @@ -1455,6 +1463,9 @@ const MultilineEditor = React.forwardRef( applySnippet(template: string) { return editorRef.current?.applySnippet(template) ?? false; }, + cursorDocEnd() { + return editorRef.current?.cursorDocEnd() ?? false; + }, startCompletion() { return editorRef.current?.startCompletion() ?? false; }, diff --git a/packages/compass-field-store/package.json b/packages/compass-field-store/package.json index 914dd2fa58a..2783bf45a58 100644 --- a/packages/compass-field-store/package.json +++ b/packages/compass-field-store/package.json @@ -52,6 +52,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/mocha": "^9.0.0", diff --git a/packages/compass-field-store/src/index.spec.ts b/packages/compass-field-store/src/index.spec.ts index a407cc958df..0eb8ebaa813 100644 --- a/packages/compass-field-store/src/index.spec.ts +++ b/packages/compass-field-store/src/index.spec.ts @@ -6,7 +6,7 @@ import { renderPluginHookWithActiveConnection, cleanup, waitFor, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; describe('useAutocompleteFields', function () { afterEach(cleanup); diff --git a/packages/compass-field-store/src/stores/store.spec.ts b/packages/compass-field-store/src/stores/store.spec.ts index 5d15a5aa637..c5b0159234d 100644 --- a/packages/compass-field-store/src/stores/store.spec.ts +++ b/packages/compass-field-store/src/stores/store.spec.ts @@ -6,7 +6,7 @@ import type { Schema } from 'mongodb-schema'; import { activatePluginWithConnections, cleanup, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import FieldStorePlugin from '..'; import { documentsUpdated, schemaUpdated } from '../modules'; diff --git a/packages/compass-generative-ai/src/components/ai-experience-entry.tsx b/packages/compass-generative-ai/src/components/ai-experience-entry.tsx index e4877a64dd0..5333eab0b46 100644 --- a/packages/compass-generative-ai/src/components/ai-experience-entry.tsx +++ b/packages/compass-generative-ai/src/components/ai-experience-entry.tsx @@ -105,6 +105,7 @@ function AIExperienceEntry({ onClick={onClick} data-testid={dataTestId} type="button" + title={`Generate ${type}`} > Generate {type} diff --git a/packages/compass-import-export/package.json b/packages/compass-import-export/package.json index cd042153d03..ba7212952d9 100644 --- a/packages/compass-import-export/package.json +++ b/packages/compass-import-export/package.json @@ -82,6 +82,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", diff --git a/packages/compass-import-export/src/modules/export.spec.ts b/packages/compass-import-export/src/modules/export.spec.ts index 2d5450bf082..e2e48f3824b 100644 --- a/packages/compass-import-export/src/modules/export.spec.ts +++ b/packages/compass-import-export/src/modules/export.spec.ts @@ -20,7 +20,7 @@ import { mochaTestServer } from '@mongodb-js/compass-test-server'; import { activatePluginWithConnections, cleanup, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import { ExportPlugin } from '../index'; import type { ExportStore } from '../stores/export-store'; import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider'; diff --git a/packages/compass-import-export/src/modules/import.spec.ts b/packages/compass-import-export/src/modules/import.spec.ts index bd40d7abebd..1bd9b39cf89 100644 --- a/packages/compass-import-export/src/modules/import.spec.ts +++ b/packages/compass-import-export/src/modules/import.spec.ts @@ -3,7 +3,7 @@ import path from 'path'; import { onStarted, openImport, selectImportFileName } from './import'; import type { ImportStore } from '../stores/import-store'; import { ImportPlugin } from '../index'; -import { activatePluginWithConnections } from '@mongodb-js/compass-connections/test'; +import { activatePluginWithConnections } from '@mongodb-js/testing-library-compass'; function activatePlugin( dataService = { diff --git a/packages/compass-import-export/src/stores/export-store.spec.tsx b/packages/compass-import-export/src/stores/export-store.spec.tsx index ced0050f48c..bf73d8a8d44 100644 --- a/packages/compass-import-export/src/stores/export-store.spec.tsx +++ b/packages/compass-import-export/src/stores/export-store.spec.tsx @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { activatePluginWithConnections, cleanup, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import { ExportPlugin } from '..'; import type { ExportStore } from './export-store'; diff --git a/packages/compass-import-export/src/stores/import-store.spec.tsx b/packages/compass-import-export/src/stores/import-store.spec.tsx index 3d05a4bc538..7a8850d8cf4 100644 --- a/packages/compass-import-export/src/stores/import-store.spec.tsx +++ b/packages/compass-import-export/src/stores/import-store.spec.tsx @@ -3,7 +3,7 @@ import { expect } from 'chai'; import { activatePluginWithConnections, cleanup, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import type { ImportStore } from './import-store'; import { ImportPlugin } from '..'; diff --git a/packages/compass-indexes/src/components/indexes/indexes.spec.tsx b/packages/compass-indexes/src/components/indexes/indexes.spec.tsx index df3e3a3da05..3fea526c22d 100644 --- a/packages/compass-indexes/src/components/indexes/indexes.spec.tsx +++ b/packages/compass-indexes/src/components/indexes/indexes.spec.tsx @@ -32,8 +32,11 @@ const DEFAULT_PROPS: Partial = { }, } as any; -const renderIndexes = (props: Partial = {}) => { - const store = setupStore(); +const renderIndexes = ( + props: Partial = {}, + dataProvider: Partial = {} +) => { + const store = setupStore(undefined, dataProvider); const allProps: Partial = { ...DEFAULT_PROPS, @@ -78,12 +81,14 @@ describe('Indexes Component', function () { }); it('renders indexes toolbar when there is a search indexes error', async function () { - const store = renderIndexes(); - // the component will load the search indexes the moment we switch to them - store.getState()!.dataService!.getSearchIndexes = function () { - return Promise.reject(new Error('This is an error.')); + const getSearchIndexesStub = sinon + .stub() + .rejects(new Error('This is an error.')); + const dataProvider = { + getSearchIndexes: getSearchIndexesStub, }; + renderIndexes({}, dataProvider); const toolbar = screen.getByTestId('indexes-toolbar'); expect(toolbar).to.exist; @@ -267,11 +272,11 @@ describe('Indexes Component', function () { context('search indexes', function () { it('renders the search indexes table if the current view changes to search indexes', async function () { - const store = renderIndexes(); - - store.getState()!.dataService!.getSearchIndexes = function () { - return Promise.resolve(searchIndexes); + const getSearchIndexesStub = sinon.stub().resolves(searchIndexes); + const dataProvider = { + getSearchIndexes: getSearchIndexesStub, }; + renderIndexes({}, dataProvider); // switch to the Search Indexes tab const toolbar = screen.getByTestId('indexes-toolbar'); @@ -284,18 +289,17 @@ describe('Indexes Component', function () { }); it('refreshes the search indexes if the search indexes view is active', async function () { - const store = renderIndexes(); - - const spy = sinon.spy( - store.getState()?.dataService as IndexesDataService, - 'getSearchIndexes' - ); + const getSearchIndexesStub = sinon.stub().resolves(searchIndexes); + const dataProvider = { + getSearchIndexes: getSearchIndexesStub, + }; + renderIndexes({}, dataProvider); // switch to the Search Indexes tab const toolbar = screen.getByTestId('indexes-toolbar'); fireEvent.click(within(toolbar).getByText('Search Indexes')); - expect(spy.callCount).to.equal(1); + expect(getSearchIndexesStub.callCount).to.equal(1); // click the refresh button const refreshButton = within(toolbar).getByText('Refresh'); @@ -304,7 +308,7 @@ describe('Indexes Component', function () { ); fireEvent.click(refreshButton); - expect(spy.callCount).to.equal(2); + expect(getSearchIndexesStub.callCount).to.equal(2); }); it('switches to the search indexes table when a search index is created', async function () { diff --git a/packages/compass-indexes/src/components/search-index-template-dropdown/index.spec.tsx b/packages/compass-indexes/src/components/search-index-template-dropdown/index.spec.tsx index 05e1ac3ea05..13d2894bf0a 100644 --- a/packages/compass-indexes/src/components/search-index-template-dropdown/index.spec.tsx +++ b/packages/compass-indexes/src/components/search-index-template-dropdown/index.spec.tsx @@ -9,41 +9,68 @@ import userEvent from '@testing-library/user-event'; import React from 'react'; +const knnVectorText = 'KNN Vector field mapping'; + function templateNamed(name: string) { return ATLAS_SEARCH_TEMPLATES.find((t) => t.name === name); } describe('Search Index Template Dropdown', function () { - let onTemplateSpy: SinonSpy; - - beforeEach(function () { - onTemplateSpy = sinon.spy(); - - render( - - ); - }); - afterEach(cleanup); - it('notifies upwards with onTemplate when a new template is choosen', async function () { - const dropDown = screen - .getByText('Dynamic field mappings') - .closest('button')!; + describe('when rendered', function () { + let onTemplateSpy: SinonSpy; + + beforeEach(function () { + onTemplateSpy = sinon.spy(); + + render( + + ); + }); - userEvent.click(dropDown); + it('notifies upwards with onTemplate when a new template is chosen', async function () { + const dropDown = screen + .getByText('Dynamic field mappings') + .closest('button')!; + + userEvent.click(dropDown); + + const staticFieldMappingOption = await screen.findByText( + 'Static field mappings' + ); + userEvent.click(staticFieldMappingOption); + + expect(onTemplateSpy).to.have.been.calledWith( + templateNamed('Static field mappings') + ); + }); + + it('does not shows the knn vector search template', function () { + userEvent.click(screen.getByRole('button', { name: 'Template' })); + expect(screen.queryByRole('option', { name: knnVectorText })).to.not + .exist; + }); + }); - const staticFieldMappingOption = await screen.findByText( - 'Static field mappings' - ); - userEvent.click(staticFieldMappingOption); + describe('when rendered with vector search disabled', function () { + beforeEach(function () { + render( + {}} + /> + ); + }); - expect(onTemplateSpy).to.have.been.calledWith( - templateNamed('Static field mappings') - ); + it('shows the knn vector search template', function () { + userEvent.click(screen.getByRole('button', { name: 'Template' })); + expect(screen.getByRole('option', { name: knnVectorText })).to.be.visible; + }); }); }); diff --git a/packages/compass-indexes/src/components/search-index-template-dropdown/index.tsx b/packages/compass-indexes/src/components/search-index-template-dropdown/index.tsx index fbdbe0931d3..0343399b4f4 100644 --- a/packages/compass-indexes/src/components/search-index-template-dropdown/index.tsx +++ b/packages/compass-indexes/src/components/search-index-template-dropdown/index.tsx @@ -14,18 +14,18 @@ import { const containerStyles = css({ display: 'flex', flexDirection: 'column', - gap: spacing[1], + gap: spacing[100], }); const dropdownLabelStyles = css({ display: 'flex', - gap: spacing[1], + gap: spacing[100], alignItems: 'center', }); type SearchIndexTemplateDropdownProps = { tooltip: string; - isVectorSearchSupported?: boolean; + isVectorSearchSupported: boolean; onTemplate: (template: SearchTemplate) => void; }; diff --git a/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.spec.tsx b/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.spec.tsx index 00662e75741..dec5f39f765 100644 --- a/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.spec.tsx +++ b/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.spec.tsx @@ -164,7 +164,8 @@ describe('Base Search Index Modal', function () { }); }); - it('resets the template on type switch', async function () { + // TODO(COMPASS-7557): super flaky even on mac + it.skip('resets the template on type switch', async function () { userEvent.click( screen.getByTestId('search-index-type-vectorSearch-button'), undefined, diff --git a/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx b/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx index 6d95b91d965..76e4b1417b4 100644 --- a/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx +++ b/packages/compass-indexes/src/components/search-indexes-modals/base-search-index-modal.tsx @@ -119,7 +119,7 @@ type BaseSearchIndexModalProps = { initialIndexType?: string; isModalOpen: boolean; isBusy: boolean; - isVectorSearchSupported?: boolean; + isVectorSearchSupported: boolean; error: string | undefined; onSubmit: (index: { name: string; diff --git a/packages/compass-indexes/src/components/search-indexes-modals/update-search-index-modal.spec.tsx b/packages/compass-indexes/src/components/search-indexes-modals/update-search-index-modal.spec.tsx new file mode 100644 index 00000000000..5734cddb132 --- /dev/null +++ b/packages/compass-indexes/src/components/search-indexes-modals/update-search-index-modal.spec.tsx @@ -0,0 +1,56 @@ +import React from 'react'; +import { expect } from 'chai'; +import { render, screen, cleanup } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { UpdateSearchIndexModal } from './update-search-index-modal'; + +const knnVectorText = 'KNN Vector field mapping'; + +function renderUpdateSearchIndexModal( + props?: Partial> +) { + return render( + {}} + onCloseModal={() => {}} + error={'Invalid index definition.'} + {...props} + /> + ); +} + +describe('Base Search Index Modal', function () { + afterEach(cleanup); + + describe('when rendered', function () { + beforeEach(function () { + renderUpdateSearchIndexModal(); + }); + + it('does not show the KNN vector field mapping template', function () { + userEvent.click(screen.getByRole('button', { name: 'Template' })); + expect(screen.queryByRole('option', { name: knnVectorText })).to.not + .exist; + }); + }); + + describe('when rendered and isVectorSearchSupported is false', function () { + beforeEach(function () { + renderUpdateSearchIndexModal({ + isVectorSearchSupported: false, + }); + }); + + it('shows the KNN vector field mapping template', function () { + userEvent.click(screen.getByRole('button', { name: 'Template' })); + expect(screen.getByRole('option', { name: knnVectorText })).to.be.visible; + }); + }); +}); diff --git a/packages/compass-indexes/src/components/search-indexes-modals/update-search-index-modal.tsx b/packages/compass-indexes/src/components/search-indexes-modals/update-search-index-modal.tsx index a28f671264c..362fdc340ad 100644 --- a/packages/compass-indexes/src/components/search-indexes-modals/update-search-index-modal.tsx +++ b/packages/compass-indexes/src/components/search-indexes-modals/update-search-index-modal.tsx @@ -4,6 +4,7 @@ import { connect } from 'react-redux'; import type { RootState } from '../../modules'; import type { Document } from 'mongodb'; import { BaseSearchIndexModal } from './base-search-index-modal'; +import { isAtlasVectorSearchSupportedForServerVersion } from '../../utils/vector-search-indexes'; type UpdateSearchIndexModalProps = { namespace: string; @@ -12,6 +13,7 @@ type UpdateSearchIndexModalProps = { indexType?: string; isModalOpen: boolean; isBusy: boolean; + isVectorSearchSupported: boolean; error: string | undefined; onUpdateIndex: (index: { name: string; @@ -30,6 +32,7 @@ export const UpdateSearchIndexModal: React.FunctionComponent< indexType, isModalOpen, isBusy, + isVectorSearchSupported, error, onUpdateIndex, onCloseModal, @@ -37,6 +40,7 @@ export const UpdateSearchIndexModal: React.FunctionComponent< return ( { const index = indexes.find((x) => x.name === indexName); return { + isVectorSearchSupported: + isAtlasVectorSearchSupportedForServerVersion(serverVersion), namespace, isModalOpen, isBusy, diff --git a/packages/compass-indexes/src/modules/data-service.spec.ts b/packages/compass-indexes/src/modules/data-service.spec.ts deleted file mode 100644 index dc2b443b461..00000000000 --- a/packages/compass-indexes/src/modules/data-service.spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { expect } from 'chai'; -import type { DataService } from 'mongodb-data-service'; - -import reducer, { - dataServiceConnected, - ActionTypes as DataServiceActions, -} from './data-service'; - -const mockDataService = new (class { - indexes() {} -})() as any as DataService; - -describe('data service module', function () { - describe('#dataServiceConnected', function () { - it('returns the connected action', function () { - expect(dataServiceConnected(mockDataService)).to.deep.equal({ - type: DataServiceActions.DataServiceConnected, - dataService: mockDataService, - }); - }); - }); - - describe('#reducer', function () { - context('when the action is not data service connected', function () { - it('returns the default state', function () { - expect(reducer(undefined, { type: 'test' } as any)).to.deep.equal(null); - }); - }); - - context('when the action is data service connected', function () { - it('returns the new state', function () { - expect( - reducer(undefined, dataServiceConnected(mockDataService)) - ).to.deep.equal(mockDataService); - }); - }); - }); -}); diff --git a/packages/compass-indexes/src/modules/data-service.ts b/packages/compass-indexes/src/modules/data-service.ts deleted file mode 100644 index 8b347ebdd01..00000000000 --- a/packages/compass-indexes/src/modules/data-service.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { IndexesDataService } from '../stores/store'; - -export enum ActionTypes { - DataServiceConnected = 'indexes/data-service/DATA_SERVICE_CONNECTED', -} - -type DataServiceConnectedAction = { - type: ActionTypes.DataServiceConnected; - dataService: IndexesDataService; -}; - -type State = IndexesDataService | null; - -const INITIAL_STATE: State = null; - -export default function reducer( - state = INITIAL_STATE, - action: DataServiceConnectedAction -) { - if (action.type === ActionTypes.DataServiceConnected) { - return action.dataService; - } - return state; -} - -export const dataServiceConnected = (dataService: IndexesDataService) => ({ - type: ActionTypes.DataServiceConnected, - dataService, -}); diff --git a/packages/compass-indexes/src/modules/index.ts b/packages/compass-indexes/src/modules/index.ts index 9a3b4e549bb..941cba995ce 100644 --- a/packages/compass-indexes/src/modules/index.ts +++ b/packages/compass-indexes/src/modules/index.ts @@ -1,7 +1,6 @@ import { combineReducers } from 'redux'; import type { Action, AnyAction } from 'redux'; import type AppRegistry from 'hadron-app-registry'; -import dataService from './data-service'; import isWritable from './is-writable'; import indexView from './index-view'; import isReadonlyView from './is-readonly-view'; @@ -11,16 +10,17 @@ import searchIndexes from './search-indexes'; import serverVersion from './server-version'; import namespace from './namespace'; import type { ThunkAction, ThunkDispatch } from 'redux-thunk'; +import type { DataService } from 'mongodb-data-service'; import type { Logger } from '@mongodb-js/compass-logging'; import type { TrackFunction } from '@mongodb-js/compass-telemetry'; import type { ConnectionInfoAccess } from '@mongodb-js/compass-connections/provider'; +import type { IndexesDataServiceProps } from '../stores/store'; const reducer = combineReducers({ isWritable, isReadonlyView, indexView, description, - dataService, serverVersion, namespace, regularIndexes, @@ -35,6 +35,7 @@ export type IndexesExtraArgs = { localAppRegistry: AppRegistry; logger: Logger; track: TrackFunction; + dataService: Pick; connectionInfoAccess: ConnectionInfoAccess; }; export type IndexesThunkDispatch = ThunkDispatch< diff --git a/packages/compass-indexes/src/modules/regular-indexes.spec.ts b/packages/compass-indexes/src/modules/regular-indexes.spec.ts index 9e775c25790..a34bfdfb901 100644 --- a/packages/compass-indexes/src/modules/regular-indexes.spec.ts +++ b/packages/compass-indexes/src/modules/regular-indexes.spec.ts @@ -69,23 +69,6 @@ describe('regular-indexes module', function () { expect(indexesSpy.callCount).to.equal(0); }); - it('when dataService is not connected, sets refreshing to false', async function () { - const store = setupStore({}, { - isConnected() { - return false; - }, - } as any); - store.dispatch({ - type: ActionTypes.IndexesAdded, - indexes: defaultSortedIndexes, - }); - await store.dispatch(fetchIndexes()); - - const state = store.getState().regularIndexes; - expect(state.indexes).to.deep.equal(defaultSortedIndexes); - expect(state.isRefreshing).to.equal(false); - }); - it('sets indexes to empty array when there is an error', async function () { const error = new Error('failed to connect to server'); const store = setupStore({}, { diff --git a/packages/compass-indexes/src/modules/regular-indexes.ts b/packages/compass-indexes/src/modules/regular-indexes.ts index 9bd38fffb76..b451bca2182 100644 --- a/packages/compass-indexes/src/modules/regular-indexes.ts +++ b/packages/compass-indexes/src/modules/regular-indexes.ts @@ -209,10 +209,9 @@ export const fetchIndexes = (): IndexesThunkAction< Promise, RegularIndexesActions > => { - return async (dispatch, getState, { logger: { debug } }) => { + return async (dispatch, getState, { dataService }) => { const { isReadonlyView, - dataService, namespace, regularIndexes: { inProgressIndexes }, } = getState(); @@ -222,12 +221,6 @@ export const fetchIndexes = (): IndexesThunkAction< return; } - if (!dataService || !dataService.isConnected()) { - dispatch(setIsRefreshing(false)); - debug('warning: trying to load indexes but dataService is disconnected'); - return; - } - try { dispatch(setError(null)); const indexes = await dataService.indexes(namespace); @@ -304,8 +297,8 @@ export const showCreateModal = (): IndexesThunkAction => { export const hideIndex = ( indexName: string ): IndexesThunkAction> => { - return async (dispatch, getState) => { - const { dataService, namespace } = getState(); + return async (dispatch, getState, { dataService }) => { + const { namespace } = getState(); const confirmed = await showConfirmation({ title: `Hiding \`${indexName}\``, description: hideModalDescription(indexName), @@ -338,8 +331,8 @@ export const hideIndex = ( export const unhideIndex = ( indexName: string ): IndexesThunkAction> => { - return async (dispatch, getState) => { - const { namespace, dataService } = getState(); + return async (dispatch, getState, { dataService }) => { + const { namespace } = getState(); const confirmed = await showConfirmation({ title: `Unhiding \`${indexName}\``, description: unhideModalDescription(indexName), diff --git a/packages/compass-indexes/src/modules/search-indexes.spec.ts b/packages/compass-indexes/src/modules/search-indexes.spec.ts index 55aee3dd1eb..8cf08908d54 100644 --- a/packages/compass-indexes/src/modules/search-indexes.spec.ts +++ b/packages/compass-indexes/src/modules/search-indexes.spec.ts @@ -23,12 +23,21 @@ import { writeStateChanged } from './is-writable'; describe('search-indexes module', function () { let store: ReturnType; let dataProvider: Partial; - let getSearchIndexesStub: any; + let createSearchIndexStub: sinon.SinonStub; + let updateSearchIndexStub: sinon.SinonStub; + let getSearchIndexesStub: sinon.SinonStub; + let dropSearchIndexStub: sinon.SinonStub; beforeEach(function () { + createSearchIndexStub = sinon.stub().resolves('foo'); + updateSearchIndexStub = sinon.stub().resolves(); + getSearchIndexesStub = sinon.stub().resolves(searchIndexes); + dropSearchIndexStub = sinon.stub().resolves(); dataProvider = { - createSearchIndex: sinon.spy(), - updateSearchIndex: sinon.spy(), + createSearchIndex: createSearchIndexStub, + updateSearchIndex: updateSearchIndexStub, + getSearchIndexes: getSearchIndexesStub, + dropSearchIndex: dropSearchIndexStub, }; store = setupStore( @@ -38,13 +47,6 @@ describe('search-indexes module', function () { }, dataProvider ); - - getSearchIndexesStub = sinon - .stub( - store.getState().dataService as IndexesDataService, - 'getSearchIndexes' - ) - .resolves(searchIndexes); }); it('has not available search indexes state by default', function () { @@ -79,12 +81,6 @@ describe('search-indexes module', function () { expect(store.getState().searchIndexes.status).to.equal('NOT_READY'); }); - it('does nothing if there is no dataService', function () { - store.getState().dataService = null; - store.dispatch(fetchSearchIndexes); - // would throw if it tried to use it - }); - it('fetches the indexes', async function () { expect(getSearchIndexesStub.callCount).to.equal(0); expect(store.getState().searchIndexes.status).to.equal('NOT_READY'); @@ -105,17 +101,11 @@ describe('search-indexes module', function () { expect(store.getState().searchIndexes.status).to.equal('READY'); // replace the stub - getSearchIndexesStub.restore(); - getSearchIndexesStub = sinon - .stub( - store.getState().dataService as IndexesDataService, - 'getSearchIndexes' - ) - .callsFake(() => { - return new Promise(() => { - // never resolves - }); + getSearchIndexesStub.callsFake(() => { + return new Promise(() => { + // never resolves }); + }); // not awaiting because REFRESHING happens during the action void store.dispatch(fetchSearchIndexes()); @@ -150,13 +140,7 @@ describe('search-indexes module', function () { it('sets the status to ERROR if loading the indexes fails', async function () { // replace the stub - getSearchIndexesStub.restore(); - getSearchIndexesStub = sinon - .stub( - store.getState().dataService as IndexesDataService, - 'getSearchIndexes' - ) - .rejects(new Error('this is an error')); + getSearchIndexesStub.rejects(new Error('this is an error')); await store.dispatch(fetchSearchIndexes()); @@ -257,29 +241,25 @@ describe('search-indexes module', function () { }); context('drop search index', function () { - let dropSearchIndexStub: sinon.SinonStub; let showConfirmationStub: sinon.SinonStub; beforeEach(function () { - dropSearchIndexStub = sinon.stub( - store.getState().dataService as IndexesDataService, - 'dropSearchIndex' - ); showConfirmationStub = sinon.stub(searchIndexesSlice, 'showConfirmation'); }); afterEach(function () { showConfirmationStub.restore(); - dropSearchIndexStub.restore(); }); it('does not drop index when user does not confirm', async function () { - showConfirmationStub.resolves(false); + dropSearchIndexStub.resolves(false); await store.dispatch(dropSearchIndex('index_name')); expect(dropSearchIndexStub.callCount).to.equal(0); }); it('drops index successfully', async function () { showConfirmationStub.resolves(true); + dropSearchIndexStub.resolves(true); + dropSearchIndexStub.resolves(true); await store.dispatch(dropSearchIndex('index_name')); expect(dropSearchIndexStub.firstCall.args).to.deep.equal([ diff --git a/packages/compass-indexes/src/modules/search-indexes.ts b/packages/compass-indexes/src/modules/search-indexes.ts index 7ded17fe313..d10f670760d 100644 --- a/packages/compass-indexes/src/modules/search-indexes.ts +++ b/packages/compass-indexes/src/modules/search-indexes.ts @@ -387,8 +387,12 @@ export const createIndex = ({ type?: string; definition: Document; }): IndexesThunkAction> => { - return async function (dispatch, getState, { track, connectionInfoAccess }) { - const { namespace, dataService } = getState(); + return async function ( + dispatch, + getState, + { track, connectionInfoAccess, dataService } + ) { + const { namespace } = getState(); dispatch({ type: ActionTypes.CreateSearchIndexStarted }); @@ -449,10 +453,13 @@ export const updateIndex = ({ type?: string; definition: Document; }): IndexesThunkAction> => { - return async function (dispatch, getState, { track, connectionInfoAccess }) { + return async function ( + dispatch, + getState, + { track, connectionInfoAccess, dataService } + ) { const { namespace, - dataService, searchIndexes: { indexes }, } = getState(); @@ -501,11 +508,10 @@ const setError = (error: string | undefined): SetErrorAction => ({ const fetchIndexes = ( newStatus: SearchIndexesStatus ): IndexesThunkAction> => { - return async (dispatch, getState, { logger: { debug } }) => { + return async (dispatch, getState, { dataService }) => { const { isReadonlyView, isWritable, - dataService, namespace, searchIndexes: { status }, } = getState(); @@ -514,11 +520,6 @@ const fetchIndexes = ( return; } - if (!dataService || !dataService.isConnected()) { - debug('warning: trying to load indexes but dataService is disconnected'); - return; - } - // If we are currently doing fetching indexes, we will // wait for that if (NOT_FETCHABLE_STATUSES.includes(status)) { @@ -571,11 +572,12 @@ export const showConfirmation = showConfirmationModal; export const dropSearchIndex = ( name: string ): IndexesThunkAction> => { - return async function (dispatch, getState, { track, connectionInfoAccess }) { - const { namespace, dataService } = getState(); - if (!dataService) { - return; - } + return async function ( + dispatch, + getState, + { track, connectionInfoAccess, dataService } + ) { + const { namespace } = getState(); const isConfirmed = await showConfirmation({ title: `Are you sure you want to drop "${name}" from Cluster?`, diff --git a/packages/compass-indexes/src/stores/store.spec.ts b/packages/compass-indexes/src/stores/store.spec.ts index f7d374b3acb..4ca21c6d4a7 100644 --- a/packages/compass-indexes/src/stores/store.spec.ts +++ b/packages/compass-indexes/src/stores/store.spec.ts @@ -67,10 +67,6 @@ describe('IndexesStore [Store]', function () { expect(store.getState().isReadonlyView).to.equal(true); }); - it('sets the data service', function () { - expect(store.getState().dataService).to.not.equal(null); - }); - context('when instance state changes', function () { before(function () { expect(store.getState().isWritable).to.equal(true); diff --git a/packages/compass-indexes/src/stores/store.ts b/packages/compass-indexes/src/stores/store.ts index 9dae37bf903..a699015623e 100644 --- a/packages/compass-indexes/src/stores/store.ts +++ b/packages/compass-indexes/src/stores/store.ts @@ -64,20 +64,21 @@ export type IndexesStore = Store & { export function activateIndexesPlugin( options: IndexesPluginOptions, { - dataService, connectionInfoAccess, instance, localAppRegistry, globalAppRegistry, logger, track, + dataService, }: IndexesPluginServices, { on, cleanup }: ActivateHelpers ) { const store: IndexesStore = createStore( reducer, { - dataService, + isWritable: instance.isWritable, + description: instance.description, namespace: options.namespace, serverVersion: options.serverVersion, isReadonlyView: options.isReadonly, @@ -96,6 +97,7 @@ export function activateIndexesPlugin( logger, track, connectionInfoAccess, + dataService, }) ) ); @@ -138,10 +140,6 @@ export function activateIndexesPlugin( void store.dispatch(refreshSearchIndexes()); }); - // set the initial values - store.dispatch(writeStateChanged(instance.isWritable)); - store.dispatch(getDescription(instance.description)); - // these can change later on(instance, 'change:isWritable', () => { store.dispatch(writeStateChanged(instance.isWritable)); diff --git a/packages/compass-preferences-model/package.json b/packages/compass-preferences-model/package.json index d43cfa2e0a7..9ffa054264f 100644 --- a/packages/compass-preferences-model/package.json +++ b/packages/compass-preferences-model/package.json @@ -51,7 +51,7 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.4.6", "@mongodb-js/compass-user-data": "^0.3.6", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "bson": "^6.7.0", "hadron-app-registry": "^9.2.5", "hadron-ipc": "^3.2.22", diff --git a/packages/compass-query-bar/src/components/option-editor.tsx b/packages/compass-query-bar/src/components/option-editor.tsx index 18ac82d93ec..db74d34b930 100644 --- a/packages/compass-query-bar/src/components/option-editor.tsx +++ b/packages/compass-query-bar/src/components/option-editor.tsx @@ -10,7 +10,11 @@ import { rafraf, useDarkMode, } from '@mongodb-js/compass-components'; -import type { Command, EditorRef } from '@mongodb-js/compass-editor'; +import type { + Command, + EditorRef, + SavedQuery, +} from '@mongodb-js/compass-editor'; import { CodemirrorInlineEditor as InlineEditor, createQueryAutocompleter, @@ -23,8 +27,9 @@ import type { RootState } from '../stores/query-bar-store'; import { useAutocompleteFields } from '@mongodb-js/compass-field-store'; import { applyFromHistory } from '../stores/query-bar-reducer'; import { getQueryAttributes } from '../utils'; -import type { BaseQuery } from '../constants/query-properties'; -import type { SavedQuery } from '@mongodb-js/compass-editor'; +import type { BaseQuery, QueryFormFields } from '../constants/query-properties'; +import { mapQueryToFormFields } from '../utils/query'; +import { DEFAULT_FIELD_VALUES } from '../constants/query-bar-store'; const editorContainerStyles = css({ position: 'relative', @@ -155,11 +160,13 @@ export const OptionEditor: React.FunctionComponent = ({ }, []); const schemaFields = useAutocompleteFields(namespace); + const maxTimeMSPreference = usePreference('maxTimeMS'); const completer = useMemo(() => { return isQueryHistoryAutocompleteEnabled - ? createQueryWithHistoryAutocompleter( - savedQueries + ? createQueryWithHistoryAutocompleter({ + queryProperty: optionName, + savedQueries: savedQueries .filter((query) => { const isOptionNameInQuery = optionName === 'filter' || optionName in query.queryProperties; @@ -174,24 +181,44 @@ export const OptionEditor: React.FunctionComponent = ({ .sort( (a, b) => a.lastExecuted.getTime() - b.lastExecuted.getTime() ), - { + options: { fields: schemaFields, serverVersion, }, - onApplyQuery, - darkMode ? 'dark' : 'light' - ) + onApply: (query: SavedQuery['queryProperties']) => { + onApplyQuery(query); + if (!query[optionName]) { + return; + } + const formFields = mapQueryToFormFields( + { maxTimeMS: maxTimeMSPreference }, + { + ...DEFAULT_FIELD_VALUES, + ...query, + } + ); + const optionFormField = + formFields[optionName as keyof QueryFormFields]; + if (optionFormField?.string) { + // When we did apply something we want to move the cursor to the end of the input. + editorRef.current?.cursorDocEnd(); + } + }, + theme: darkMode ? 'dark' : 'light', + }) : createQueryAutocompleter({ fields: schemaFields, serverVersion, }); }, [ + maxTimeMSPreference, savedQueries, schemaFields, serverVersion, onApplyQuery, isQueryHistoryAutocompleteEnabled, darkMode, + optionName, ]); const onFocus = () => { diff --git a/packages/compass-query-bar/src/components/query-history/index.spec.tsx b/packages/compass-query-bar/src/components/query-history/index.spec.tsx index 8bfb774cd2e..908cfc7af54 100644 --- a/packages/compass-query-bar/src/components/query-history/index.spec.tsx +++ b/packages/compass-query-bar/src/components/query-history/index.spec.tsx @@ -9,7 +9,7 @@ import { import userEvent from '@testing-library/user-event'; import { Provider } from '../../stores/context'; import Sinon from 'sinon'; -import fs from 'fs'; +import { promises as fs } from 'fs'; import os from 'os'; import path from 'path'; import QueryHistory from '.'; @@ -92,12 +92,12 @@ const renderQueryHistory = (basepath: string) => { describe('query-history', function () { let tmpDir: string; - before(function () { - tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'compass-query-history')); + before(async function () { + tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'compass-query-history')); }); - after(function () { - fs.rmdirSync(tmpDir, { recursive: true }); + after(async function () { + await fs.rm(tmpDir, { recursive: true }); }); context('zero state', function () { diff --git a/packages/compass-saved-aggregations-queries/package.json b/packages/compass-saved-aggregations-queries/package.json index bc21d80205c..b844badf217 100644 --- a/packages/compass-saved-aggregations-queries/package.json +++ b/packages/compass-saved-aggregations-queries/package.json @@ -71,6 +71,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/react-hooks": "^7.0.2", diff --git a/packages/compass-saved-aggregations-queries/src/index.spec.tsx b/packages/compass-saved-aggregations-queries/src/index.spec.tsx index adb05c3ebec..55fedf2d210 100644 --- a/packages/compass-saved-aggregations-queries/src/index.spec.tsx +++ b/packages/compass-saved-aggregations-queries/src/index.spec.tsx @@ -15,14 +15,14 @@ import { } from '@mongodb-js/compass-app-stores/provider'; import { type WorkspacesService } from '@mongodb-js/compass-workspaces/provider'; import { getConnectionTitle } from '@mongodb-js/connection-info'; -import type { RenderWithConnectionsResult } from '@mongodb-js/compass-connections/test'; +import type { RenderWithConnectionsResult } from '@mongodb-js/testing-library-compass'; import { renderWithConnections, screen, cleanup, within, waitFor, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; let id = 0; function getConnection() { diff --git a/packages/compass-shell/package.json b/packages/compass-shell/package.json index 12f6fc2f15d..4f931ca3ff5 100644 --- a/packages/compass-shell/package.json +++ b/packages/compass-shell/package.json @@ -71,6 +71,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "chai": "^4.2.0", "depcheck": "^1.4.1", diff --git a/packages/compass-shell/src/plugin.spec.tsx b/packages/compass-shell/src/plugin.spec.tsx index 7d9d4b6a652..9179731d68e 100644 --- a/packages/compass-shell/src/plugin.spec.tsx +++ b/packages/compass-shell/src/plugin.spec.tsx @@ -6,7 +6,7 @@ import { renderWithActiveConnection, screen, waitFor, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; describe('CompassShellPlugin', function () { afterEach(() => { diff --git a/packages/compass-sidebar/package.json b/packages/compass-sidebar/package.json index 5c52833c4cf..7842c647a11 100644 --- a/packages/compass-sidebar/package.json +++ b/packages/compass-sidebar/package.json @@ -74,6 +74,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", diff --git a/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx b/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx index ba8312262ef..a794e2c6846 100644 --- a/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx +++ b/packages/compass-sidebar/src/components/multiple-connections/sidebar.spec.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { expect } from 'chai'; import sinon from 'sinon'; -import type { RenderWithConnectionsHookResult } from '@mongodb-js/compass-connections/test'; +import type { RenderWithConnectionsHookResult } from '@mongodb-js/testing-library-compass'; import { renderPluginComponentWithConnections, screen, @@ -9,7 +9,7 @@ import { waitFor, within, userEvent, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import MultipleConnectionSidebar from './sidebar'; import type { WorkspaceTab } from '@mongodb-js/compass-workspaces'; import { WorkspacesProvider } from '@mongodb-js/compass-workspaces'; diff --git a/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts b/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts index 8a374186702..dae61d4cf34 100644 --- a/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts +++ b/packages/compass-sidebar/src/components/use-filtered-connections.spec.ts @@ -6,7 +6,7 @@ import { useFilteredConnections } from './use-filtered-connections'; import _ from 'lodash'; import Sinon from 'sinon'; import { expect } from 'chai'; -import { renderHook, waitFor } from '@mongodb-js/compass-connections/test'; +import { renderHook, waitFor } from '@mongodb-js/testing-library-compass'; const connectedConnection1 = { id: 'connected_connection_1', diff --git a/packages/compass-web/package.json b/packages/compass-web/package.json index 4165b554424..cbdc5149ec9 100644 --- a/packages/compass-web/package.json +++ b/packages/compass-web/package.json @@ -87,6 +87,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@mongodb-js/webpack-config-compass": "^1.4.1", "@testing-library/react": "^12.1.5", diff --git a/packages/compass-web/src/entrypoint.spec.tsx b/packages/compass-web/src/entrypoint.spec.tsx index d14396b0218..80a65e4380c 100644 --- a/packages/compass-web/src/entrypoint.spec.tsx +++ b/packages/compass-web/src/entrypoint.spec.tsx @@ -6,7 +6,7 @@ import { expect } from 'chai'; import { CompassWeb } from './entrypoint'; import Sinon from 'sinon'; import { ConnectFnProvider } from '@mongodb-js/compass-connections'; -import { MockDataService as TestHelpersMockDataService } from '@mongodb-js/compass-connections/test'; +import { MockDataService as TestHelpersMockDataService } from '@mongodb-js/testing-library-compass'; function mockDb(name: string) { return { _id: name, name }; diff --git a/packages/compass-workspaces/package.json b/packages/compass-workspaces/package.json index fe300c97f43..4e6840a7cf6 100644 --- a/packages/compass-workspaces/package.json +++ b/packages/compass-workspaces/package.json @@ -55,8 +55,8 @@ "@mongodb-js/compass-components": "^1.29.3", "@mongodb-js/compass-connections": "^1.41.0", "@mongodb-js/compass-logging": "^1.4.6", - "compass-preferences-model": "^2.28.2", "bson": "^6.7.0", + "compass-preferences-model": "^2.28.2", "hadron-app-registry": "^9.2.5", "lodash": "^4.17.21", "mongodb-collection-model": "^5.23.2", @@ -71,6 +71,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@types/chai": "^4.2.21", "@types/chai-dom": "^0.0.10", diff --git a/packages/compass-workspaces/src/components/workspace-tab-state-provider.spec.tsx b/packages/compass-workspaces/src/components/workspace-tab-state-provider.spec.tsx index 8b265638968..d1b5cdb4f8e 100644 --- a/packages/compass-workspaces/src/components/workspace-tab-state-provider.spec.tsx +++ b/packages/compass-workspaces/src/components/workspace-tab-state-provider.spec.tsx @@ -1,7 +1,7 @@ import { renderHook, cleanup as cleanupHooks, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import { useTabState, tabStateStore, diff --git a/packages/compass-workspaces/src/index.spec.tsx b/packages/compass-workspaces/src/index.spec.tsx index 770c1541843..81dc02e4e02 100644 --- a/packages/compass-workspaces/src/index.spec.tsx +++ b/packages/compass-workspaces/src/index.spec.tsx @@ -10,7 +10,7 @@ import { screen, waitFor, userEvent, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import { TestMongoDBInstanceManager } from '@mongodb-js/compass-app-stores/provider'; function mockWorkspace(name: string) { diff --git a/packages/compass-workspaces/src/stores/workspaces.spec.ts b/packages/compass-workspaces/src/stores/workspaces.spec.ts index 57e6060ad8c..6a7dabb42d6 100644 --- a/packages/compass-workspaces/src/stores/workspaces.spec.ts +++ b/packages/compass-workspaces/src/stores/workspaces.spec.ts @@ -8,7 +8,7 @@ import { TestMongoDBInstanceManager } from '@mongodb-js/compass-app-stores/provi import type { ConnectionInfo } from '../../../connection-info/dist'; import type { WorkspaceTab } from '../../dist'; import { setTabDestroyHandler } from '../components/workspace-close-handler'; -import { activatePluginWithConnections } from '@mongodb-js/compass-connections/test'; +import { activatePluginWithConnections } from '@mongodb-js/testing-library-compass'; type WorkspacesStore = ReturnType['store']; diff --git a/packages/compass/package.json b/packages/compass/package.json index 2d4fa512244..1deef76e9ef 100644 --- a/packages/compass/package.json +++ b/packages/compass/package.json @@ -196,8 +196,8 @@ "@mongodb-js/compass-app-stores": "^7.27.0", "@mongodb-js/compass-collection": "^4.40.0", "@mongodb-js/compass-components": "^1.29.3", - "@mongodb-js/compass-connections": "^1.41.0", "@mongodb-js/compass-connection-import-export": "^0.37.0", + "@mongodb-js/compass-connections": "^1.41.0", "@mongodb-js/compass-crud": "^13.41.0", "@mongodb-js/compass-databases-collections": "^1.40.0", "@mongodb-js/compass-explain-plan": "^6.41.0", @@ -209,7 +209,6 @@ "@mongodb-js/compass-indexes": "^5.40.0", "@mongodb-js/compass-intercom": "^0.12.2", "@mongodb-js/compass-logging": "^1.4.6", - "@mongodb-js/compass-telemetry": "^1.1.6", "@mongodb-js/compass-query-bar": "^8.42.0", "@mongodb-js/compass-saved-aggregations-queries": "^1.41.0", "@mongodb-js/compass-schema": "^6.42.0", @@ -218,12 +217,13 @@ "@mongodb-js/compass-settings": "^0.40.2", "@mongodb-js/compass-shell": "^3.40.0", "@mongodb-js/compass-sidebar": "^5.41.0", + "@mongodb-js/compass-telemetry": "^1.1.6", "@mongodb-js/compass-utils": "^0.6.11", "@mongodb-js/compass-welcome": "^0.39.0", "@mongodb-js/compass-workspaces": "^0.22.0", "@mongodb-js/connection-info": "^0.7.0", "@mongodb-js/connection-storage": "^0.20.0", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/get-os-info": "^0.3.24", "@mongodb-js/mocha-config-compass": "^1.4.1", @@ -231,6 +231,7 @@ "@mongodb-js/my-queries-storage": "^0.15.3", "@mongodb-js/prettier-config-compass": "^1.0.2", "@mongodb-js/sbom-tools": "^0.7.0", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@mongodb-js/webpack-config-compass": "^1.4.1", "@segment/analytics-node": "^1.1.4", diff --git a/packages/compass/src/app/components/home.spec.tsx b/packages/compass/src/app/components/home.spec.tsx index 036ec3b55c6..f9c4edeaa05 100644 --- a/packages/compass/src/app/components/home.spec.tsx +++ b/packages/compass/src/app/components/home.spec.tsx @@ -12,7 +12,7 @@ import { screen, waitFor, within, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import type { AllPreferences } from 'compass-preferences-model/provider'; import type { ConnectionInfo } from '@mongodb-js/compass-connections/provider'; diff --git a/packages/data-service/package.json b/packages/data-service/package.json index 2b81f61d573..1d40c5a3a54 100644 --- a/packages/data-service/package.json +++ b/packages/data-service/package.json @@ -53,8 +53,8 @@ "dependencies": { "@mongodb-js/compass-logging": "^1.4.6", "@mongodb-js/compass-utils": "^0.6.11", - "@mongodb-js/devtools-connect": "^3.2.8", - "@mongodb-js/devtools-proxy-support": "^0.3.6", + "@mongodb-js/devtools-connect": "^3.2.10", + "@mongodb-js/devtools-proxy-support": "^0.3.9", "bson": "^6.7.0", "lodash": "^4.17.21", "mongodb": "^6.8.0", diff --git a/packages/databases-collections/package.json b/packages/databases-collections/package.json index 7260e4e1ce8..d77a6748505 100644 --- a/packages/databases-collections/package.json +++ b/packages/databases-collections/package.json @@ -45,6 +45,7 @@ "@mongodb-js/eslint-config-compass": "^1.1.6", "@mongodb-js/mocha-config-compass": "^1.4.1", "@mongodb-js/prettier-config-compass": "^1.0.2", + "@mongodb-js/testing-library-compass": "^1.0.0", "@mongodb-js/tsconfig-compass": "^1.0.4", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^13.5.0", diff --git a/packages/databases-collections/src/stores/create-namespace.spec.tsx b/packages/databases-collections/src/stores/create-namespace.spec.tsx index 12915fae656..6bb58becb05 100644 --- a/packages/databases-collections/src/stores/create-namespace.spec.tsx +++ b/packages/databases-collections/src/stores/create-namespace.spec.tsx @@ -16,7 +16,7 @@ import { userEvent, createDefaultConnectionInfo, waitFor, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; const mockConnections = [ { ...createDefaultConnectionInfo(), id: '1' }, diff --git a/packages/databases-collections/src/stores/drop-namespace.spec.tsx b/packages/databases-collections/src/stores/drop-namespace.spec.tsx index d8a9207f403..0de7e4daa3d 100644 --- a/packages/databases-collections/src/stores/drop-namespace.spec.tsx +++ b/packages/databases-collections/src/stores/drop-namespace.spec.tsx @@ -11,7 +11,7 @@ import { waitFor, userEvent, createDefaultConnectionInfo, -} from '@mongodb-js/compass-connections/test'; +} from '@mongodb-js/testing-library-compass'; import type { DataService } from '@mongodb-js/compass-connections/provider'; const mockConnectionInfo = createDefaultConnectionInfo(); diff --git a/scripts/create-workspace.js b/scripts/create-workspace.js index ccb279c1255..76ab249782a 100644 --- a/scripts/create-workspace.js +++ b/scripts/create-workspace.js @@ -290,8 +290,7 @@ async function createWorkspace({ prettier: '*', sinon: '*', ...(isReact && { - '@testing-library/react': '*', - '@testing-library/user-event': '*', + '@mongodb-js/testing-library-compass': '*', '@types/chai-dom': '*', '@types/react': '*', '@types/react-dom': '*',