diff --git a/.circleci/config.yml b/.circleci/config.yml index ca6ffe4b4..ce3846fe3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -70,6 +70,15 @@ jobs: - run: name: test command: yarn test:app + test-shared: + <<: *defaults + steps: + - checkout + - restore_cache: + key: dependency-cache-{{ checksum "package.json" }} + - run: + name: test + command: yarn test:shared test-server: <<: *defaults steps: @@ -81,7 +90,7 @@ jobs: command: ./node_modules/.bin/sequelize db:migrate --url $DATABASE_URL_TEST - run: name: test - command: yarn test:server + command: yarn test:server --forceExit bundle-size: <<: *defaults steps: @@ -140,6 +149,9 @@ workflows: - test-server: requires: - build + - test-shared: + requires: + - build - test-app: requires: - build @@ -149,6 +161,7 @@ workflows: - bundle-size: requires: - test-app + - test-shared - test-server build-docker: diff --git a/.jestconfig.json b/.jestconfig.json new file mode 100644 index 000000000..b99860db3 --- /dev/null +++ b/.jestconfig.json @@ -0,0 +1,82 @@ +{ + "projects": [ + { + "displayName": "server", + "verbose": false, + "roots": [ + "/server" + ], + "moduleNameMapper": { + "^@server/(.*)$": "/server/$1", + "^@shared/(.*)$": "/shared/$1" + }, + "setupFiles": [ + "/__mocks__/console.js", + "/server/test/setup.ts" + ], + "testEnvironment": "node", + "runner": "@getoutline/jest-runner-serial" + }, + { + "displayName": "app", + "verbose": false, + "roots": [ + "/app" + ], + "moduleNameMapper": { + "^~/(.*)$": "/app/$1", + "^@shared/(.*)$": "/shared/$1", + "^.*[.](gif|ttf|eot|svg)$": "/__test__/fileMock.js", + "^uuid$": "/node_modules/uuid/dist/index.js" + }, + "modulePaths": [ + "/app" + ], + "setupFiles": [ + "/__mocks__/window.js" + ], + "setupFilesAfterEnv": [ + "/app/test/setup.ts" + ], + "testEnvironment": "jsdom", + "testEnvironmentOptions": { + "url": "http://localhost" + } + }, + { + "displayName": "shared-node", + "verbose": false, + "roots": [ + "/shared" + ], + "moduleNameMapper": { + "^@server/(.*)$": "/server/$1", + "^@shared/(.*)$": "/shared/$1" + }, + "setupFiles": [ + "/__mocks__/console.js" + ], + "testEnvironment": "node" + }, + { + "displayName": "shared-jsdom", + "verbose": false, + "roots": [ + "/shared" + ], + "moduleNameMapper": { + "^~/(.*)$": "/app/$1", + "^@shared/(.*)$": "/shared/$1", + "^.*[.](gif|ttf|eot|svg)$": "/__test__/fileMock.js", + "^uuid$": "/node_modules/uuid/dist/index.js" + }, + "setupFiles": [ + "/__mocks__/window.js" + ], + "testEnvironment": "jsdom", + "testEnvironmentOptions": { + "url": "http://localhost" + } + } + ] +} \ No newline at end of file diff --git a/__mocks__/bull.js b/__mocks__/bull.js deleted file mode 100644 index 02c0a40b4..000000000 --- a/__mocks__/bull.js +++ /dev/null @@ -1,17 +0,0 @@ -export default class Queue { - name; - - constructor(name) { - this.name = name; - } - - process = (fn) => { - console.log(`Registered function ${this.name}`); - this.processFn = fn; - }; - - add = (data) => { - console.log(`Running ${this.name}`); - return this.processFn({ data }); - }; -} diff --git a/__mocks__/console.js b/__mocks__/console.js index b0a2ab99a..307dd1e59 100644 --- a/__mocks__/console.js +++ b/__mocks__/console.js @@ -1,2 +1 @@ -// Mock for node-uuid global.console.warn = () => {}; diff --git a/app/.jestconfig.json b/app/.jestconfig.json deleted file mode 100644 index 782c085e7..000000000 --- a/app/.jestconfig.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "verbose": false, - "rootDir": "..", - "roots": [ - "/app", - "/shared" - ], - "moduleNameMapper": { - "^~/(.*)$": "/app/$1", - "^@shared/(.*)$": "/shared/$1", - "^.*[.](gif|ttf|eot|svg)$": "/__test__/fileMock.js", - "^uuid$": "/node_modules/uuid/dist/index.js" - }, - "moduleDirectories": [ - "node_modules" - ], - "modulePaths": [ - "/app" - ], - "setupFiles": [ - "/__mocks__/window.js" - ], - "setupFilesAfterEnv": [ - "./app/test/setup.ts" - ], - "testEnvironment": "jsdom", - "testEnvironmentOptions": { - "url": "http://localhost" - } -} \ No newline at end of file diff --git a/package.json b/package.json index 3e91bc467..f83760986 100644 --- a/package.json +++ b/package.json @@ -24,10 +24,10 @@ "db:rollback": "sequelize db:migrate:undo", "db:reset": "sequelize db:drop && sequelize db:create && sequelize db:migrate", "upgrade": "git fetch && git pull && yarn install && yarn heroku-postbuild", - "test": "yarn test:app && yarn test:server", - "test:app": "jest --config=app/.jestconfig.json --runInBand --forceExit", - "test:server": "jest --config=server/.jestconfig.json --runInBand --forceExit", - "test:watch": "jest --config=server/.jestconfig.json --runInBand --forceExit --watchAll" + "test": "jest --config=.jestconfig.json --forceExit", + "test:app": "jest --config=.jestconfig.json --selectProjects app", + "test:shared": "jest --config=.jestconfig.json --selectProjects shared-node shared-jsdom", + "test:server": "jest --config=.jestconfig.json --selectProjects server" }, "funding": { "type": "GitHub Sponsors ❤", @@ -219,6 +219,7 @@ "devDependencies": { "@babel/cli": "^7.10.5", "@babel/preset-typescript": "^7.16.0", + "@getoutline/jest-runner-serial": "^2.0.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", "@relative-ci/agent": "^3.0.0", "@types/body-scroll-lock": "^3.1.0", diff --git a/server/.jestconfig.json b/server/.jestconfig.json deleted file mode 100644 index 627ccd53e..000000000 --- a/server/.jestconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "verbose": false, - "rootDir": "..", - "roots": [ - "/server", - "/shared" - ], - "moduleNameMapper": { - "^@server/(.*)$": "/server/$1", - "^@shared/(.*)$": "/shared/$1" - }, - "setupFiles": [ - "/__mocks__/console.js", - "./server/test/setup.ts" - ], - "testEnvironment": "node" -} \ No newline at end of file diff --git a/server/__mocks__/bull.ts b/server/__mocks__/bull.ts index 7c5c939d3..0ad21460d 100644 --- a/server/__mocks__/bull.ts +++ b/server/__mocks__/bull.ts @@ -19,9 +19,7 @@ export default class Queue { const job = this.createJob(data); if (!this.handler) { - throw Error( - "Mocking version requires handler to be set before first add()" - ); + return; } this.handler(job, this.done); diff --git a/server/test/setup.ts b/server/test/setup.ts index 56ab30596..3aeec48a2 100644 --- a/server/test/setup.ts +++ b/server/test/setup.ts @@ -22,6 +22,9 @@ jest.mock("bull"); // This is needed for the relative manual mock to be picked up jest.mock("../queues"); +// Avoid "Yjs was already imported" errors in the test environment +jest.mock("yjs"); + // We never want to make real S3 requests in test environment jest.mock("aws-sdk", () => { const mS3 = { diff --git a/shared/utils/domains.test.ts b/shared/utils/domains.test.ts index 3746e7b0c..64f04543e 100644 --- a/shared/utils/domains.test.ts +++ b/shared/utils/domains.test.ts @@ -1,4 +1,4 @@ -import env from "@shared/env"; +import env from "../env"; import { parseDomain, getCookieDomain, slugifyDomain } from "./domains"; // test suite is based on subset of parse-domain module we want to support diff --git a/yarn.lock b/yarn.lock index 4fc92e33a..f44c086f3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1285,6 +1285,11 @@ dependencies: tslib "^2.1.0" +"@getoutline/jest-runner-serial@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@getoutline/jest-runner-serial/-/jest-runner-serial-2.0.0.tgz#a5b7eba7e5ce198b6fef8f27a79060af6cc2ded0" + integrity sha512-sV0a/FbPuT5sf4iotQm7/GY6KtseXvlmNLEOmtXkZ9hZ0NjFzro62G8C4J/e71NJWudhQsKgrxa6Zq8G7F3mnw== + "@getoutline/y-prosemirror@^1.0.18": version "1.0.18" resolved "https://registry.yarnpkg.com/@getoutline/y-prosemirror/-/y-prosemirror-1.0.18.tgz#17245c0362d30adb85131c86fb9a59358884b234" @@ -6066,14 +6071,7 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== -define-properties@^1.1.2, define-properties@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" - integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== - dependencies: - object-keys "^1.0.12" - -define-properties@^1.1.4: +define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== @@ -6682,33 +6680,7 @@ error-stack-parser@^2.0.6: dependencies: stackframe "^1.1.1" -es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.18.0, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2, es-abstract@^1.19.0, es-abstract@^1.19.1: - version "1.19.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3" - integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w== - dependencies: - call-bind "^1.0.2" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - get-intrinsic "^1.1.1" - get-symbol-description "^1.0.0" - has "^1.0.3" - has-symbols "^1.0.2" - internal-slot "^1.0.3" - is-callable "^1.2.4" - is-negative-zero "^2.0.1" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.1" - is-string "^1.0.7" - is-weakref "^1.0.1" - object-inspect "^1.11.0" - object-keys "^1.1.1" - object.assign "^4.1.2" - string.prototype.trimend "^1.0.4" - string.prototype.trimstart "^1.0.4" - unbox-primitive "^1.0.1" - -es-abstract@^1.19.5, es-abstract@^1.20.0: +es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.18.0, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2, es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.5, es-abstract@^1.20.0: version "1.20.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== @@ -7690,17 +7662,7 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -function.prototype.name@^1.1.2, function.prototype.name@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.4.tgz#e4ea839b9d3672ae99d0efd9f38d9191c5eaac83" - integrity sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - functions-have-names "^1.2.2" - -function.prototype.name@^1.1.5: +function.prototype.name@^1.1.2, function.prototype.name@^1.1.3, function.prototype.name@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== @@ -7993,11 +7955,6 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" -has-bigints@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" - integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA== - has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -8859,11 +8816,6 @@ is-negated-glob@^1.0.0: resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" integrity sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI= -is-negative-zero@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" - integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== - is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -8958,11 +8910,6 @@ is-relative@^1.0.0: dependencies: is-unc-path "^1.0.0" -is-shared-array-buffer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6" - integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA== - is-shared-array-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" @@ -9027,13 +8974,6 @@ is-valid-glob@^1.0.0: resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= -is-weakref@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2" - integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ== - dependencies: - call-bind "^1.0.0" - is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -11138,7 +11078,7 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.11.0, object-inspect@^1.12.0, object-inspect@^1.7.0, object-inspect@^1.9.0: +object-inspect@^1.12.0, object-inspect@^1.7.0, object-inspect@^1.9.0: version "1.12.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0" integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g== @@ -11151,7 +11091,7 @@ object-is@^1.0.2, object-is@^1.1.2: call-bind "^1.0.2" define-properties "^1.1.3" -object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== @@ -13953,14 +13893,6 @@ string.prototype.trim@^1.2.1: define-properties "^1.1.3" es-abstract "^1.18.0-next.2" -string.prototype.trimend@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz#e75ae90c2942c63504686c18b287b4a0b1a45f80" - integrity sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - string.prototype.trimend@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" @@ -13970,14 +13902,6 @@ string.prototype.trimend@^1.0.5: define-properties "^1.1.4" es-abstract "^1.19.5" -string.prototype.trimstart@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed" - integrity sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - string.prototype.trimstart@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" @@ -14695,16 +14619,6 @@ umzug@^2.3.0: dependencies: bluebird "^3.7.2" -unbox-primitive@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.1.tgz#085e215625ec3162574dc8859abee78a59b14471" - integrity sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw== - dependencies: - function-bind "^1.1.1" - has-bigints "^1.0.1" - has-symbols "^1.0.2" - which-boxed-primitive "^1.0.2" - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"