From a5b178094bb41b7023b5f6a73e696fa993b886ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 20:56:59 +0900 Subject: [PATCH 01/18] Bump react-toggle from 4.1.1 to 4.1.2 (#15900) Bumps [react-toggle](https://github.com/aaronshaf/react-toggle) from 4.1.1 to 4.1.2. - [Release notes](https://github.com/aaronshaf/react-toggle/releases) - [Changelog](https://github.com/aaronshaf/react-toggle/blob/master/CHANGELOG.md) - [Commits](https://github.com/aaronshaf/react-toggle/commits) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index d4453db8511..5ef449f6af5 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "react-sparklines": "^1.7.0", "react-swipeable-views": "^0.13.9", "react-textarea-autosize": "^8.3.2", - "react-toggle": "^4.1.1", + "react-toggle": "^4.1.2", "redis": "^3.0.2", "redux": "^4.0.5", "redux-immutable": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 7adcc4ab0f2..d9a3e3e30f6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8988,10 +8988,10 @@ react-textarea-autosize@^8.3.2: use-composed-ref "^1.0.0" use-latest "^1.0.0" -react-toggle@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/react-toggle/-/react-toggle-4.1.1.tgz#2317f67bf918ea3508a96b09dd383efd9da572af" - integrity sha512-+wXlMcSpg8SmnIXauMaZiKpR+r2wp2gMUteroejp2UTSqGTVvZLN+m9EhMzFARBKEw7KpQOwzCyfzeHeAndQGw== +react-toggle@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/react-toggle/-/react-toggle-4.1.2.tgz#b00500832f925ad524356d909821821ae39f6c52" + integrity sha512-4Ohw31TuYQdhWfA6qlKafeXx3IOH7t4ZHhmRdwsm1fQREwOBGxJT+I22sgHqR/w8JRdk+AeMCJXPImEFSrNXow== dependencies: classnames "^2.2.5" From 211e5164c41ec57e3b42fd44943d2931e6e710ac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 21:02:24 +0900 Subject: [PATCH 02/18] Bump @babel/core from 7.13.8 to 7.13.10 (#15902) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.13.8 to 7.13.10. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.13.10/packages/babel-core) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 48 ++++++++++++++++++++++++------------------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 5ef449f6af5..b4ab384690c 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ }, "private": true, "dependencies": { - "@babel/core": "^7.13.8", + "@babel/core": "^7.13.10", "@babel/plugin-proposal-class-properties": "^7.8.3", "@babel/plugin-proposal-decorators": "^7.13.5", "@babel/plugin-transform-react-inline-elements": "^7.12.13", diff --git a/yarn.lock b/yarn.lock index d9a3e3e30f6..9a3651c53c2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -21,17 +21,17 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.8.tgz#5b783b9808f15cef71547f1b691f34f8ff6003a6" integrity sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog== -"@babel/core@^7.1.0", "@babel/core@^7.13.8", "@babel/core@^7.7.2", "@babel/core@^7.7.5": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.8.tgz#c191d9c5871788a591d69ea1dc03e5843a3680fb" - integrity sha512-oYapIySGw1zGhEFRd6lzWNLWFX2s5dA/jm+Pw/+59ZdXtjyIuwlXbrId22Md0rgZVop+aVoqow2riXhBLNyuQg== +"@babel/core@^7.1.0", "@babel/core@^7.13.10", "@babel/core@^7.7.2", "@babel/core@^7.7.5": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.10.tgz#07de050bbd8193fcd8a3c27918c0890613a94559" + integrity sha512-bfIYcT0BdKeAZrovpMqX2Mx5NrgAckGbwT982AkdS5GNfn3KMGiprlBAtmBcFZRUmpaufS6WZFP8trvx8ptFDw== dependencies: "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.13.0" - "@babel/helper-compilation-targets" "^7.13.8" + "@babel/generator" "^7.13.9" + "@babel/helper-compilation-targets" "^7.13.10" "@babel/helper-module-transforms" "^7.13.0" - "@babel/helpers" "^7.13.0" - "@babel/parser" "^7.13.4" + "@babel/helpers" "^7.13.10" + "@babel/parser" "^7.13.10" "@babel/template" "^7.12.13" "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.0" @@ -43,10 +43,10 @@ semver "^6.3.0" source-map "^0.5.0" -"@babel/generator@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.0.tgz#bd00d4394ca22f220390c56a0b5b85568ec1ec0c" - integrity sha512-zBZfgvBB/ywjx0Rgc2+BwoH/3H+lDtlgD4hBOpEv5LxRnYsm/753iRuLepqnYlynpjC3AdQxtxsoeHJoEEwOAw== +"@babel/generator@^7.13.0", "@babel/generator@^7.13.9": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" + integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== dependencies: "@babel/types" "^7.13.0" jsesc "^2.5.1" @@ -82,10 +82,10 @@ "@babel/helper-annotate-as-pure" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.8": - version "7.13.8" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.8.tgz#02bdb22783439afb11b2f009814bdd88384bd468" - integrity sha512-pBljUGC1y3xKLn1nrx2eAhurLMA8OqBtBP/JwG4U8skN7kf8/aqwwxpV1N6T0e7r6+7uNitIa/fUxPFagSXp3A== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.10", "@babel/helper-compilation-targets@^7.13.8": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.10.tgz#1310a1678cb8427c07a753750da4f8ce442bdd0c" + integrity sha512-/Xju7Qg1GQO4mHZ/Kcs6Au7gfafgZnwm+a7sy/ow/tV1sHeraRUHbjdat8/UvDor4Tez+siGKDk6zIKtCPKVJA== dependencies: "@babel/compat-data" "^7.13.8" "@babel/helper-validator-option" "^7.12.17" @@ -274,10 +274,10 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.0" -"@babel/helpers@^7.13.0": - version "7.13.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.0.tgz#7647ae57377b4f0408bf4f8a7af01c42e41badc0" - integrity sha512-aan1MeFPxFacZeSz6Ld7YZo5aPuqnKlD7+HZY75xQsueczFccP9A7V05+oe0XpLwHK3oLorPe9eaAUljL7WEaQ== +"@babel/helpers@^7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.10.tgz#fd8e2ba7488533cdeac45cc158e9ebca5e3c7df8" + integrity sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ== dependencies: "@babel/template" "^7.12.13" "@babel/traverse" "^7.13.0" @@ -292,10 +292,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.0", "@babel/parser@^7.13.4", "@babel/parser@^7.7.0": - version "7.13.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.4.tgz#340211b0da94a351a6f10e63671fa727333d13ab" - integrity sha512-uvoOulWHhI+0+1f9L4BoozY7U5cIkZ9PgJqvb041d6vypgUmtVPG4vmGm4pSggjl8BELzvHyUeJSUyEMY6b+qA== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.13", "@babel/parser@^7.13.0", "@babel/parser@^7.13.10", "@babel/parser@^7.7.0": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.10.tgz#8f8f9bf7b3afa3eabd061f7a5bcdf4fec3c48409" + integrity sha512-0s7Mlrw9uTWkYua7xWr99Wpk2bnGa0ANleKfksYAES8LpWH4gW1OUr42vqKNf0us5UQNfru2wPqMqRITzq/SIQ== "@babel/plugin-proposal-async-generator-functions@^7.13.8": version "7.13.8" From 9cd6a076b79c4d259b8cfbde00a75984217da0a7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 21:03:02 +0900 Subject: [PATCH 03/18] Bump css-loader from 5.1.1 to 5.1.2 (#15905) Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 5.1.1 to 5.1.2. - [Release notes](https://github.com/webpack-contrib/css-loader/releases) - [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/css-loader/compare/v5.1.1...v5.1.2) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 25 +++++++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index b4ab384690c..7d145022754 100644 --- a/package.json +++ b/package.json @@ -86,7 +86,7 @@ "color-blend": "^3.0.1", "compression-webpack-plugin": "^6.1.1", "cross-env": "^7.0.3", - "css-loader": "^5.1.1", + "css-loader": "^5.1.2", "cssnano": "^4.1.10", "detect-passive-events": "^2.0.3", "dotenv": "^8.2.0", diff --git a/yarn.lock b/yarn.lock index 9a3651c53c2..5b08287b997 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3055,6 +3055,11 @@ colorette@^1.2.1: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -3368,16 +3373,16 @@ css-list-helpers@^1.0.1: dependencies: tcomb "^2.5.0" -css-loader@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.1.tgz#9362d444a0f7c08c148a109596715c904e252879" - integrity sha512-5FfhpjwtuRgxqmusDidowqmLlcb+1HgnEDMsi2JhiUrZUcoc+cqw+mUtMIF/+OfeMYaaFCLYp1TaIt9H6I/fKA== +css-loader@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.2.tgz#b93dba498ec948b543b49d4fab5017205d4f5c3e" + integrity sha512-T7vTXHSx0KrVEg/xjcl7G01RcVXpcw4OELwDPvkr7izQNny85A84dK3dqrczuEfBcu7Yg7mdTjJLSTibRUoRZg== dependencies: camelcase "^6.2.0" cssesc "^3.0.0" icss-utils "^5.1.0" loader-utils "^2.0.0" - postcss "^8.2.6" + postcss "^8.2.8" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" @@ -8474,12 +8479,12 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.32: source-map "^0.6.1" supports-color "^6.1.0" -postcss@^8.2.6: - version "8.2.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.6.tgz#5d69a974543b45f87e464bc4c3e392a97d6be9fe" - integrity sha512-xpB8qYxgPuly166AGlpRjUdEYtmOWx2iCwGmrv4vqZL9YPVviDVPZPRXxnXr6xPZOdxQ9lp3ZBFCRgWJ7LE3Sg== +postcss@^8.2.8: + version "8.2.8" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" + integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== dependencies: - colorette "^1.2.1" + colorette "^1.2.2" nanoid "^3.1.20" source-map "^0.6.1" From 89ff042292a0c5c434105561ea2b51ea6c1597d8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 21:03:19 +0900 Subject: [PATCH 04/18] Bump eslint from 7.21.0 to 7.22.0 (#15906) Bumps [eslint](https://github.com/eslint/eslint) from 7.21.0 to 7.22.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/master/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v7.21.0...v7.22.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 24 ++++++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 7d145022754..52ff2959dcf 100644 --- a/package.json +++ b/package.json @@ -176,7 +176,7 @@ "@testing-library/react": "^11.2.5", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.3", - "eslint": "^7.21.0", + "eslint": "^7.22.0", "eslint-plugin-import": "~2.22.1", "eslint-plugin-jsx-a11y": "~6.4.1", "eslint-plugin-promise": "~4.3.1", diff --git a/yarn.lock b/yarn.lock index 5b08287b997..4572da4bdfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4336,10 +4336,10 @@ eslint@^2.7.0: text-table "~0.2.0" user-home "^2.0.0" -eslint@^7.21.0: - version "7.21.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.21.0.tgz#4ecd5b8c5b44f5dedc9b8a110b01bbfeb15d1c83" - integrity sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg== +eslint@^7.22.0: + version "7.22.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.22.0.tgz#07ecc61052fec63661a2cab6bd507127c07adc6f" + integrity sha512-3VawOtjSJUQiiqac8MQc+w457iGLfuNGLFn8JmF051tTKbh5/x/0vlcEj8OgDCaw7Ysa2Jn8paGshV7x2abKXg== dependencies: "@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^0.4.0" @@ -4358,7 +4358,7 @@ eslint@^7.21.0: file-entry-cache "^6.0.1" functional-red-black-tree "^1.0.1" glob-parent "^5.0.0" - globals "^12.1.0" + globals "^13.6.0" ignore "^4.0.6" import-fresh "^3.0.0" imurmurhash "^0.1.4" @@ -4366,7 +4366,7 @@ eslint@^7.21.0: js-yaml "^3.13.1" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" - lodash "^4.17.20" + lodash "^4.17.21" minimatch "^3.0.4" natural-compare "^1.4.0" optionator "^0.9.1" @@ -5112,6 +5112,13 @@ globals@^12.1.0: dependencies: type-fest "^0.8.1" +globals@^13.6.0: + version "13.6.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.6.0.tgz#d77138e53738567bb96a3916ff6f6b487af20ef7" + integrity sha512-YFKCX0SiPg7l5oKYCJ2zZGxcXprVXHcSnVuvzrT3oSENQonVLqM5pf9fN5dLGZGyCjhw8TN8Btwe/jKnZ0pjvQ== + dependencies: + type-fest "^0.20.2" + globals@^9.2.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -10771,6 +10778,11 @@ type-fest@^0.11.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" From aa97433e00352afcd7c0af7e972bdadff9640a09 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 21:03:46 +0900 Subject: [PATCH 05/18] Bump @babel/preset-env from 7.13.9 to 7.13.10 (#15901) Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.13.9 to 7.13.10. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.13.10/packages/babel-preset-env) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 52ff2959dcf..42aae917188 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@babel/plugin-proposal-decorators": "^7.13.5", "@babel/plugin-transform-react-inline-elements": "^7.12.13", "@babel/plugin-transform-runtime": "^7.13.9", - "@babel/preset-env": "^7.13.9", + "@babel/preset-env": "^7.13.10", "@babel/preset-react": "^7.12.13", "@babel/runtime": "^7.13.9", "@clusterws/cws": "^3.0.0", diff --git a/yarn.lock b/yarn.lock index 4572da4bdfb..2344b8e49ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -828,13 +828,13 @@ "@babel/helper-create-regexp-features-plugin" "^7.12.13" "@babel/helper-plugin-utils" "^7.12.13" -"@babel/preset-env@^7.13.9": - version "7.13.9" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.9.tgz#3ee5f233316b10d066d7f379c6d1e13a96853654" - integrity sha512-mcsHUlh2rIhViqMG823JpscLMesRt3QbMsv1+jhopXEb3W2wXvQ9QoiOlZI9ZbR3XqPtaFpZwEZKYqGJnGMZTQ== +"@babel/preset-env@^7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.13.10.tgz#b5cde31d5fe77ab2a6ab3d453b59041a1b3a5252" + integrity sha512-nOsTScuoRghRtUsRr/c69d042ysfPHcu+KOB4A9aAO9eJYqrkat+LF8G1yp1HD18QiwixT2CisZTr/0b3YZPXQ== dependencies: "@babel/compat-data" "^7.13.8" - "@babel/helper-compilation-targets" "^7.13.8" + "@babel/helper-compilation-targets" "^7.13.10" "@babel/helper-plugin-utils" "^7.13.0" "@babel/helper-validator-option" "^7.12.17" "@babel/plugin-proposal-async-generator-functions" "^7.13.8" From 8066f7baf0282213d4bbcc660b9b8c9d4fab53b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 21:04:03 +0900 Subject: [PATCH 06/18] Bump @babel/runtime from 7.13.9 to 7.13.10 (#15904) Bumps [@babel/runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-runtime) from 7.13.9 to 7.13.10. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.13.10/packages/babel-runtime) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 42aae917188..ad9d1e4355c 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "@babel/plugin-transform-runtime": "^7.13.9", "@babel/preset-env": "^7.13.10", "@babel/preset-react": "^7.12.13", - "@babel/runtime": "^7.13.9", + "@babel/runtime": "^7.13.10", "@clusterws/cws": "^3.0.0", "@gamestdio/websocket": "^0.3.2", "@github/webauthn-json": "^0.5.7", diff --git a/yarn.lock b/yarn.lock index 2344b8e49ba..94d55ee1fb4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -939,10 +939,10 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.9", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.13.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.9.tgz#97dbe2116e2630c489f22e0656decd60aaa1fcee" - integrity sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA== +"@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" + integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== dependencies: regenerator-runtime "^0.13.4" From 506010abc53087f23c518c7576e878a18d9abdd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Mar 2021 21:19:16 +0900 Subject: [PATCH 07/18] Bump bundler-audit from 0.7.0.1 to 0.8.0 (#15877) Bumps [bundler-audit](https://github.com/postmodern/bundler-audit) from 0.7.0.1 to 0.8.0. - [Release notes](https://github.com/postmodern/bundler-audit/releases) - [Changelog](https://github.com/rubysec/bundler-audit/blob/master/ChangeLog.md) - [Commits](https://github.com/postmodern/bundler-audit/compare/v0.7.0.1...v0.8.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 2bdf6118ea4..7a5b119b843 100644 --- a/Gemfile +++ b/Gemfile @@ -141,7 +141,7 @@ group :development do gem 'rubocop', '~> 1.11', require: false gem 'rubocop-rails', '~> 2.9', require: false gem 'brakeman', '~> 4.10', require: false - gem 'bundler-audit', '~> 0.7', require: false + gem 'bundler-audit', '~> 0.8', require: false gem 'capistrano', '~> 3.16' gem 'capistrano-rails', '~> 1.6' diff --git a/Gemfile.lock b/Gemfile.lock index 7b3d1131960..ec63daf5f67 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -115,9 +115,9 @@ GEM bullet (6.1.4) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) - bundler-audit (0.7.0.1) + bundler-audit (0.8.0) bundler (>= 1.2.0, < 3) - thor (>= 0.18, < 2) + thor (~> 1.0) byebug (11.1.3) capistrano (3.16.0) airbrussh (>= 1.0.0) @@ -705,7 +705,7 @@ DEPENDENCIES brakeman (~> 4.10) browser bullet (~> 6.1) - bundler-audit (~> 0.7) + bundler-audit (~> 0.8) capistrano (~> 3.16) capistrano-rails (~> 1.6) capistrano-rbenv (~> 2.2) From 0c9ce7b451258b9628fadd92b2b7d92e9f297a29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Mar 2021 07:52:23 +0900 Subject: [PATCH 08/18] Bump @babel/plugin-transform-runtime from 7.13.9 to 7.13.10 (#15903) Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-runtime) from 7.13.9 to 7.13.10. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.13.10/packages/babel-plugin-transform-runtime) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ad9d1e4355c..fd766cc8c1d 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@babel/plugin-proposal-class-properties": "^7.8.3", "@babel/plugin-proposal-decorators": "^7.13.5", "@babel/plugin-transform-react-inline-elements": "^7.12.13", - "@babel/plugin-transform-runtime": "^7.13.9", + "@babel/plugin-transform-runtime": "^7.13.10", "@babel/preset-env": "^7.13.10", "@babel/preset-react": "^7.12.13", "@babel/runtime": "^7.13.10", diff --git a/yarn.lock b/yarn.lock index 94d55ee1fb4..3cc2c7f83ea 100644 --- a/yarn.lock +++ b/yarn.lock @@ -765,10 +765,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" -"@babel/plugin-transform-runtime@^7.13.9": - version "7.13.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.9.tgz#744d3103338a0d6c90dee0497558150b490cee07" - integrity sha512-XCxkY/wBI6M6Jj2mlWxkmqbKPweRanszWbF3Tyut+hKh+PHcuIH/rSr/7lmmE7C3WW+HSIm2GT+d5jwmheuB0g== +"@babel/plugin-transform-runtime@^7.13.10": + version "7.13.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.13.10.tgz#a1e40d22e2bf570c591c9c7e5ab42d6bf1e419e1" + integrity sha512-Y5k8ipgfvz5d/76tx7JYbKQTcgFSU6VgJ3kKQv4zGTKr+a9T/KBvfRvGtSFgKDQGt/DBykQixV0vNWKIdzWErA== dependencies: "@babel/helper-module-imports" "^7.12.13" "@babel/helper-plugin-utils" "^7.13.0" From 9cb6bc56faab374c1c740c7093d5271d37201aed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Mar 2021 07:55:43 +0900 Subject: [PATCH 09/18] Bump rspec-rails from 4.1.0 to 5.0.0 (#15876) Bumps [rspec-rails](https://github.com/rspec/rspec-rails) from 4.1.0 to 5.0.0. - [Release notes](https://github.com/rspec/rspec-rails/releases) - [Changelog](https://github.com/rspec/rspec-rails/blob/main/Changelog.md) - [Commits](https://github.com/rspec/rspec-rails/compare/v4.1.0...v5.0.0) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 7a5b119b843..5117962391d 100644 --- a/Gemfile +++ b/Gemfile @@ -109,7 +109,7 @@ group :development, :test do gem 'i18n-tasks', '~> 0.9', require: false gem 'pry-byebug', '~> 3.9' gem 'pry-rails', '~> 0.3' - gem 'rspec-rails', '~> 4.1' + gem 'rspec-rails', '~> 5.0' end group :production, :test do diff --git a/Gemfile.lock b/Gemfile.lock index ec63daf5f67..d2037b3bce2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -530,10 +530,10 @@ GEM rspec-mocks (3.10.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.10.0) - rspec-rails (4.1.0) - actionpack (>= 4.2) - activesupport (>= 4.2) - railties (>= 4.2) + rspec-rails (5.0.0) + actionpack (>= 5.2) + activesupport (>= 5.2) + railties (>= 5.2) rspec-core (~> 3.10) rspec-expectations (~> 3.10) rspec-mocks (~> 3.10) @@ -792,7 +792,7 @@ DEPENDENCIES redis-namespace (~> 1.8) redis-rails (~> 5.0) rqrcode (~> 1.2) - rspec-rails (~> 4.1) + rspec-rails (~> 5.0) rspec-sidekiq (~> 3.1) rspec_junit_formatter (~> 0.4) rubocop (~> 1.11) From 43eff898a0b0f31aaf042d9d387aaece2627a01d Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 17 Mar 2021 10:09:55 +0100 Subject: [PATCH 10/18] Prepare Mastodon for Rails 6 (#15911) * Fix misuse of foreign_type * Fix use of removed "add_template_helper" * Use response.media_type instead of response.content_type in tests * Fix CSV export controller test on Rails 6 Rails 6 sets a "filename*" field in the Content-Disposition header to explicitly encode the filename as UTF-8. This changes checks the first part of the Content-Disposition header so it matches in both Rails 5 and Rails 6. * Fix emoji formatting with Rails 6 * Make emoji output more idiomatic and robust * Switch from redis-rails gem to built-in Rails redis cache storage --- Gemfile | 1 - Gemfile.lock | 17 ----------------- app/lib/formatter.rb | 4 ++-- app/mailers/notification_mailer.rb | 2 +- app/mailers/user_mailer.rb | 2 +- app/models/notification.rb | 12 ++++++------ config/environments/development.rb | 2 +- config/environments/production.rb | 2 +- config/initializers/sidekiq.rb | 2 +- lib/mastodon/redis_config.rb | 2 ++ spec/controllers/accounts_controller_spec.rb | 8 ++++---- .../activitypub/collections_controller_spec.rb | 8 ++++---- ...ollowers_synchronizations_controller_spec.rb | 2 +- .../activitypub/outboxes_controller_spec.rb | 12 ++++++------ .../activitypub/replies_controller_spec.rb | 4 ++-- .../concerns/export_controller_concern_spec.rb | 4 ++-- .../well_known/host_meta_controller_spec.rb | 2 +- .../keybase_proof_config_controller_spec.rb | 2 +- .../well_known/nodeinfo_controller_spec.rb | 4 ++-- .../well_known/webfinger_controller_spec.rb | 2 +- spec/requests/catch_all_route_request_spec.rb | 4 ++-- spec/requests/host_meta_request_spec.rb | 2 +- spec/requests/webfinger_request_spec.rb | 6 +++--- 23 files changed, 45 insertions(+), 61 deletions(-) diff --git a/Gemfile b/Gemfile index 5117962391d..c3f50ec30c4 100644 --- a/Gemfile +++ b/Gemfile @@ -153,7 +153,6 @@ end group :production do gem 'lograge', '~> 0.11' - gem 'redis-rails', '~> 5.0' end gem 'concurrent-ruby', require: false diff --git a/Gemfile.lock b/Gemfile.lock index d2037b3bce2..106c13554ca 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -491,24 +491,8 @@ GEM rdf-normalize (0.4.0) rdf (~> 3.1) redis (4.2.5) - redis-actionpack (5.2.0) - actionpack (>= 5, < 7) - redis-rack (>= 2.1.0, < 3) - redis-store (>= 1.1.0, < 2) - redis-activesupport (5.2.0) - activesupport (>= 3, < 7) - redis-store (>= 1.3, < 2) redis-namespace (1.8.1) redis (>= 3.0.4) - redis-rack (2.1.3) - rack (>= 2.0.8, < 3) - redis-store (>= 1.2, < 2) - redis-rails (5.0.2) - redis-actionpack (>= 5.0, < 6) - redis-activesupport (>= 5.0, < 6) - redis-store (>= 1.2, < 2) - redis-store (1.9.0) - redis (>= 4, < 5) regexp_parser (2.1.1) request_store (1.5.0) rack (>= 1.4) @@ -790,7 +774,6 @@ DEPENDENCIES rdf-normalize (~> 0.4) redis (~> 4.2) redis-namespace (~> 1.8) - redis-rails (~> 5.0) rqrcode (~> 1.2) rspec-rails (~> 5.0) rspec-sidekiq (~> 3.1) diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 7252234d6a9..6fb5d541997 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -158,9 +158,9 @@ class Formatter original_url, static_url = emoji replacement = begin if animate - "\":#{encode(shortcode)}:\"" + image_tag(original_url, draggable: false, class: 'emojione', alt: ":#{shortcode}:", title: ":#{shortcode}:") else - "\":#{encode(shortcode)}:\"" + image_tag(original_url, draggable: false, class: 'emojione custom-emoji', alt: ":#{shortcode}:", title: ":#{shortcode}:", data: { original: original_url, static: static_url }) end end before_html = shortname_start_index.positive? ? html[0..shortname_start_index - 1] : '' diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 54db892ccc6..9e683b6a161 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -4,7 +4,7 @@ class NotificationMailer < ApplicationMailer helper :accounts helper :statuses - add_template_helper RoutingHelper + helper RoutingHelper def mention(recipient, notification) @me = recipient diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 95996ba3ff9..68d1c4507e8 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -8,7 +8,7 @@ class UserMailer < Devise::Mailer helper :instance helper :statuses - add_template_helper RoutingHelper + helper RoutingHelper def confirmation_instructions(user, token, **) @resource = user diff --git a/app/models/notification.rb b/app/models/notification.rb index 98a6a618f5f..3bf9dd483e6 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -49,12 +49,12 @@ class Notification < ApplicationRecord belongs_to :from_account, class_name: 'Account', optional: true belongs_to :activity, polymorphic: true, optional: true - belongs_to :mention, foreign_type: 'Mention', foreign_key: 'activity_id', optional: true - belongs_to :status, foreign_type: 'Status', foreign_key: 'activity_id', optional: true - belongs_to :follow, foreign_type: 'Follow', foreign_key: 'activity_id', optional: true - belongs_to :follow_request, foreign_type: 'FollowRequest', foreign_key: 'activity_id', optional: true - belongs_to :favourite, foreign_type: 'Favourite', foreign_key: 'activity_id', optional: true - belongs_to :poll, foreign_type: 'Poll', foreign_key: 'activity_id', optional: true + belongs_to :mention, foreign_key: 'activity_id', optional: true + belongs_to :status, foreign_key: 'activity_id', optional: true + belongs_to :follow, foreign_key: 'activity_id', optional: true + belongs_to :follow_request, foreign_key: 'activity_id', optional: true + belongs_to :favourite, foreign_key: 'activity_id', optional: true + belongs_to :poll, foreign_key: 'activity_id', optional: true validates :type, inclusion: { in: TYPES } diff --git a/config/environments/development.rb b/config/environments/development.rb index 0791b82ab6e..d76361c6027 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -17,7 +17,7 @@ Rails.application.configure do if Rails.root.join('tmp/caching-dev.txt').exist? config.action_controller.perform_caching = true - config.cache_store = :redis_store, ENV['REDIS_URL'], REDIS_CACHE_PARAMS + config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS config.public_file_server.headers = { 'Cache-Control' => "public, max-age=#{2.days.to_i}", diff --git a/config/environments/production.rb b/config/environments/production.rb index aaad2449f23..81a67902ead 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -52,7 +52,7 @@ Rails.application.configure do config.log_tags = [:request_id] # Use a different cache store in production. - config.cache_store = :redis_store, ENV['CACHE_REDIS_URL'], REDIS_CACHE_PARAMS + config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 9d348ddd08e..fc85a391376 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true namespace = ENV.fetch('REDIS_NAMESPACE') { nil } -redis_params = { url: ENV['REDIS_URL'] } +redis_params = { url: ENV['REDIS_URL'], driver: :hiredis } if namespace redis_params[:namespace] = namespace diff --git a/lib/mastodon/redis_config.rb b/lib/mastodon/redis_config.rb index c3c8ff8005d..3f2a8f7c264 100644 --- a/lib/mastodon/redis_config.rb +++ b/lib/mastodon/redis_config.rb @@ -27,6 +27,8 @@ namespace = ENV.fetch('REDIS_NAMESPACE', nil) cache_namespace = namespace ? namespace + '_cache' : 'cache' REDIS_CACHE_PARAMS = { + driver: :hiredis, + url: ENV['REDIS_URL'], expires_in: 10.minutes, namespace: cache_namespace, }.freeze diff --git a/spec/controllers/accounts_controller_spec.rb b/spec/controllers/accounts_controller_spec.rb index f7d0b1af54e..ac426b01e63 100644 --- a/spec/controllers/accounts_controller_spec.rb +++ b/spec/controllers/accounts_controller_spec.rb @@ -370,7 +370,7 @@ RSpec.describe AccountsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it_behaves_like 'cachable response' @@ -402,7 +402,7 @@ RSpec.describe AccountsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns public Cache-Control header' do @@ -428,7 +428,7 @@ RSpec.describe AccountsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it_behaves_like 'cachable response' @@ -446,7 +446,7 @@ RSpec.describe AccountsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns private Cache-Control header' do diff --git a/spec/controllers/activitypub/collections_controller_spec.rb b/spec/controllers/activitypub/collections_controller_spec.rb index ac661e5e1d9..d584136ff56 100644 --- a/spec/controllers/activitypub/collections_controller_spec.rb +++ b/spec/controllers/activitypub/collections_controller_spec.rb @@ -43,7 +43,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it_behaves_like 'cachable response' @@ -88,7 +88,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it_behaves_like 'cachable response' @@ -116,7 +116,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns private Cache-Control header' do @@ -141,7 +141,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns private Cache-Control header' do diff --git a/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb b/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb index 88f4554c2d6..d373f56bdb0 100644 --- a/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb +++ b/spec/controllers/activitypub/followers_synchronizations_controller_spec.rb @@ -40,7 +40,7 @@ RSpec.describe ActivityPub::FollowersSynchronizationsController, type: :controll end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns orderedItems with followers from example.com' do diff --git a/spec/controllers/activitypub/outboxes_controller_spec.rb b/spec/controllers/activitypub/outboxes_controller_spec.rb index 84e3a895602..d23f2c17cbc 100644 --- a/spec/controllers/activitypub/outboxes_controller_spec.rb +++ b/spec/controllers/activitypub/outboxes_controller_spec.rb @@ -46,7 +46,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns totalItems' do @@ -85,7 +85,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns orderedItems with public or unlisted statuses' do @@ -133,7 +133,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns orderedItems with public or unlisted statuses' do @@ -159,7 +159,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns orderedItems with private statuses' do @@ -185,7 +185,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns empty orderedItems' do @@ -210,7 +210,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it 'returns empty orderedItems' do diff --git a/spec/controllers/activitypub/replies_controller_spec.rb b/spec/controllers/activitypub/replies_controller_spec.rb index 25025975283..bf82fd0207b 100644 --- a/spec/controllers/activitypub/replies_controller_spec.rb +++ b/spec/controllers/activitypub/replies_controller_spec.rb @@ -73,7 +73,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it_behaves_like 'cachable response' @@ -120,7 +120,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do end it 'returns application/activity+json' do - expect(response.content_type).to eq 'application/activity+json' + expect(response.media_type).to eq 'application/activity+json' end it_behaves_like 'cachable response' diff --git a/spec/controllers/concerns/export_controller_concern_spec.rb b/spec/controllers/concerns/export_controller_concern_spec.rb index fce129bee22..1a5e46f8efd 100644 --- a/spec/controllers/concerns/export_controller_concern_spec.rb +++ b/spec/controllers/concerns/export_controller_concern_spec.rb @@ -22,8 +22,8 @@ describe ApplicationController, type: :controller do get :index, format: :csv expect(response).to have_http_status(200) - expect(response.content_type).to eq 'text/csv' - expect(response.headers['Content-Disposition']).to eq 'attachment; filename="anonymous.csv"' + expect(response.media_type).to eq 'text/csv' + expect(response.headers['Content-Disposition']).to start_with 'attachment; filename="anonymous.csv"' expect(response.body).to eq user.account.username end diff --git a/spec/controllers/well_known/host_meta_controller_spec.rb b/spec/controllers/well_known/host_meta_controller_spec.rb index 643ba9cd328..c02aa0d596d 100644 --- a/spec/controllers/well_known/host_meta_controller_spec.rb +++ b/spec/controllers/well_known/host_meta_controller_spec.rb @@ -8,7 +8,7 @@ describe WellKnown::HostMetaController, type: :controller do get :show, format: :xml expect(response).to have_http_status(200) - expect(response.content_type).to eq 'application/xrd+xml' + expect(response.media_type).to eq 'application/xrd+xml' expect(response.body).to eq < diff --git a/spec/controllers/well_known/keybase_proof_config_controller_spec.rb b/spec/controllers/well_known/keybase_proof_config_controller_spec.rb index 9067e676deb..00f251c3c67 100644 --- a/spec/controllers/well_known/keybase_proof_config_controller_spec.rb +++ b/spec/controllers/well_known/keybase_proof_config_controller_spec.rb @@ -8,7 +8,7 @@ describe WellKnown::KeybaseProofConfigController, type: :controller do get :show expect(response).to have_http_status(200) - expect(response.content_type).to eq 'application/json' + expect(response.media_type).to eq 'application/json' expect { JSON.parse(response.body) }.not_to raise_exception end end diff --git a/spec/controllers/well_known/nodeinfo_controller_spec.rb b/spec/controllers/well_known/nodeinfo_controller_spec.rb index 12e1fa4159c..694bb0fb9fe 100644 --- a/spec/controllers/well_known/nodeinfo_controller_spec.rb +++ b/spec/controllers/well_known/nodeinfo_controller_spec.rb @@ -8,7 +8,7 @@ describe WellKnown::NodeInfoController, type: :controller do get :index expect(response).to have_http_status(200) - expect(response.content_type).to eq 'application/json' + expect(response.media_type).to eq 'application/json' json = body_as_json @@ -23,7 +23,7 @@ describe WellKnown::NodeInfoController, type: :controller do get :show expect(response).to have_http_status(200) - expect(response.content_type).to eq 'application/json' + expect(response.media_type).to eq 'application/json' json = body_as_json diff --git a/spec/controllers/well_known/webfinger_controller_spec.rb b/spec/controllers/well_known/webfinger_controller_spec.rb index cf7005b0e79..1075456f336 100644 --- a/spec/controllers/well_known/webfinger_controller_spec.rb +++ b/spec/controllers/well_known/webfinger_controller_spec.rb @@ -25,7 +25,7 @@ describe WellKnown::WebfingerController, type: :controller do end it 'returns application/jrd+json' do - expect(response.content_type).to eq 'application/jrd+json' + expect(response.media_type).to eq 'application/jrd+json' end it 'returns links for the account' do diff --git a/spec/requests/catch_all_route_request_spec.rb b/spec/requests/catch_all_route_request_spec.rb index 22ce1cf59f6..f965f552219 100644 --- a/spec/requests/catch_all_route_request_spec.rb +++ b/spec/requests/catch_all_route_request_spec.rb @@ -6,7 +6,7 @@ describe "The catch all route" do get "/test" expect(response.status).to eq 404 - expect(response.content_type).to eq "text/html" + expect(response.media_type).to eq "text/html" end end @@ -15,7 +15,7 @@ describe "The catch all route" do get "/test.test" expect(response.status).to eq 404 - expect(response.content_type).to eq "text/html" + expect(response.media_type).to eq "text/html" end end end diff --git a/spec/requests/host_meta_request_spec.rb b/spec/requests/host_meta_request_spec.rb index beb33a859e5..0ca64146137 100644 --- a/spec/requests/host_meta_request_spec.rb +++ b/spec/requests/host_meta_request_spec.rb @@ -6,7 +6,7 @@ describe "The host_meta route" do get host_meta_url expect(response).to have_http_status(200) - expect(response.content_type).to eq "application/xrd+xml" + expect(response.media_type).to eq "application/xrd+xml" end end end diff --git a/spec/requests/webfinger_request_spec.rb b/spec/requests/webfinger_request_spec.rb index 48823714e20..209fda72aad 100644 --- a/spec/requests/webfinger_request_spec.rb +++ b/spec/requests/webfinger_request_spec.rb @@ -8,7 +8,7 @@ describe 'The webfinger route' do get webfinger_url(resource: alice.to_webfinger_s) expect(response).to have_http_status(200) - expect(response.content_type).to eq 'application/jrd+json' + expect(response.media_type).to eq 'application/jrd+json' end end @@ -17,7 +17,7 @@ describe 'The webfinger route' do get webfinger_url(resource: alice.to_webfinger_s, format: :json) expect(response).to have_http_status(200) - expect(response.content_type).to eq 'application/jrd+json' + expect(response.media_type).to eq 'application/jrd+json' end it 'returns a json response for json accept header' do @@ -25,7 +25,7 @@ describe 'The webfinger route' do get webfinger_url(resource: alice.to_webfinger_s), headers: headers expect(response).to have_http_status(200) - expect(response.content_type).to eq 'application/jrd+json' + expect(response.media_type).to eq 'application/jrd+json' end end end From 5027abecd1e5e511064de75fb5248139e1c8fe23 Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 18 Mar 2021 00:41:32 +0100 Subject: [PATCH 11/18] Fix cache_collection crashing when given an empty collection (#15921) * Fix cache_collection crashing when given an empty collection * Add tests --- app/controllers/concerns/cache_concern.rb | 4 +- app/lib/entity_cache.rb | 4 +- .../concerns/cache_concern_spec.rb | 40 +++++++++++++++++++ spec/lib/entity_cache_spec.rb | 19 +++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 spec/controllers/concerns/cache_concern_spec.rb create mode 100644 spec/lib/entity_cache_spec.rb diff --git a/app/controllers/concerns/cache_concern.rb b/app/controllers/concerns/cache_concern.rb index 3fb4b962a3a..05e431b19ac 100644 --- a/app/controllers/concerns/cache_concern.rb +++ b/app/controllers/concerns/cache_concern.rb @@ -31,7 +31,9 @@ module CacheConcern def cache_collection(raw, klass) return raw unless klass.respond_to?(:with_includes) - raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation) + raw = raw.cache_ids.to_a if raw.is_a?(ActiveRecord::Relation) + return [] if raw.empty? + cached_keys_with_value = Rails.cache.read_multi(*raw).transform_keys(&:id) uncached_ids = raw.map(&:id) - cached_keys_with_value.keys diff --git a/app/lib/entity_cache.rb b/app/lib/entity_cache.rb index 5d51e858529..80b0046eeaf 100644 --- a/app/lib/entity_cache.rb +++ b/app/lib/entity_cache.rb @@ -16,7 +16,9 @@ class EntityCache end def emoji(shortcodes, domain) - shortcodes = Array(shortcodes) + shortcodes = Array(shortcodes) + return [] if shortcodes.empty? + cached = Rails.cache.read_multi(*shortcodes.map { |shortcode| to_key(:emoji, shortcode, domain) }) uncached_ids = [] diff --git a/spec/controllers/concerns/cache_concern_spec.rb b/spec/controllers/concerns/cache_concern_spec.rb new file mode 100644 index 00000000000..a34d7d72676 --- /dev/null +++ b/spec/controllers/concerns/cache_concern_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe CacheConcern, type: :controller do + controller(ApplicationController) do + include CacheConcern + + def empty_array + render plain: cache_collection([], Status).size + end + + def empty_relation + render plain: cache_collection(Status.none, Status).size + end + end + + before do + routes.draw do + get 'empty_array' => 'anonymous#empty_array' + post 'empty_relation' => 'anonymous#empty_relation' + end + end + + describe '#cache_collection' do + context 'given an empty array' do + it 'returns an empty array' do + get :empty_array + expect(response.body).to eq '0' + end + end + + context 'given an empty relation' do + it 'returns an empty array' do + get :empty_relation + expect(response.body).to eq '0' + end + end + end +end diff --git a/spec/lib/entity_cache_spec.rb b/spec/lib/entity_cache_spec.rb new file mode 100644 index 00000000000..43494bd92aa --- /dev/null +++ b/spec/lib/entity_cache_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +RSpec.describe EntityCache do + let(:local_account) { Fabricate(:account, domain: nil, username: 'alice') } + let(:remote_account) { Fabricate(:account, domain: 'remote.test', username: 'bob', url: 'https://remote.test/') } + + describe '#emoji' do + subject { EntityCache.instance.emoji(shortcodes, domain) } + + context 'called with an empty list of shortcodes' do + let(:shortcodes) { [] } + let(:domain) { 'example.org' } + + it 'returns an empty array' do + is_expected.to eq [] + end + end + end +end From a4dcaef53b97c58fd153de6f151b6fada40f3442 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 02:42:43 +0100 Subject: [PATCH 12/18] Prepare Mastodon for zeitwerk autoloader (#15917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prepare Mastodon for zeitwerk autoloader (Rails 6) Add inflections and rename/move a few classes. In particular, app/lib/exceptions.rb and app/lib/sanitize_config.rb were manually loaded while still in autoload paths. * Add inflection for Url → URL --- app/lib/formatter.rb | 1 - app/validators/url_validator.rb | 2 +- config/application.rb | 3 ++- config/initializers/inflections.rb | 4 ++++ db/migrate/20160223165723_add_url_to_statuses.rb | 2 +- db/migrate/20160223165855_add_url_to_accounts.rb | 2 +- .../20160322193748_add_avatar_remote_url_to_accounts.rb | 2 +- .../20170318214217_add_header_remote_url_to_accounts.rb | 2 +- db/migrate/20171130000000_add_embed_url_to_preview_cards.rb | 2 +- .../20180304013859_add_featured_collection_url_to_accounts.rb | 2 +- db/migrate/20200529214050_add_devices_url_to_accounts.rb | 2 +- {app/lib => lib}/exceptions.rb | 0 {app/lib => lib/sanitize_ext}/sanitize_config.rb | 0 spec/lib/sanitize_config_spec.rb | 1 - spec/validators/url_validator_spec.rb | 2 +- 15 files changed, 15 insertions(+), 12 deletions(-) rename {app/lib => lib}/exceptions.rb (100%) rename {app/lib => lib/sanitize_ext}/sanitize_config.rb (100%) diff --git a/app/lib/formatter.rb b/app/lib/formatter.rb index 6fb5d541997..2611bcbae01 100644 --- a/app/lib/formatter.rb +++ b/app/lib/formatter.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'singleton' -require_relative './sanitize_config' class Formatter include Singleton diff --git a/app/validators/url_validator.rb b/app/validators/url_validator.rb index d95a03fbf86..f50abbe246e 100644 --- a/app/validators/url_validator.rb +++ b/app/validators/url_validator.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class UrlValidator < ActiveModel::EachValidator +class URLValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) record.errors.add(attribute, I18n.t('applications.invalid_url')) unless compliant?(value) end diff --git a/config/application.rb b/config/application.rb index 116eaf29d40..0960247b3a7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -6,8 +6,9 @@ require 'rails/all' # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -require_relative '../app/lib/exceptions' +require_relative '../lib/exceptions' require_relative '../lib/enumerable' +require_relative '../lib/sanitize_ext/sanitize_config' require_relative '../lib/redis/namespace_extensions' require_relative '../lib/paperclip/url_generator_extensions' require_relative '../lib/paperclip/attachment_extensions' diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index ebb7541ebab..9bc9a54b2d5 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -20,6 +20,10 @@ ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.acronym 'JsonLd' inflect.acronym 'NodeInfo' inflect.acronym 'Ed25519' + inflect.acronym 'TOC' + inflect.acronym 'RSS' + inflect.acronym 'REST' + inflect.acronym 'URL' inflect.singular 'data', 'data' end diff --git a/db/migrate/20160223165723_add_url_to_statuses.rb b/db/migrate/20160223165723_add_url_to_statuses.rb index 80f4b3289e5..fee7f9c59fa 100644 --- a/db/migrate/20160223165723_add_url_to_statuses.rb +++ b/db/migrate/20160223165723_add_url_to_statuses.rb @@ -1,4 +1,4 @@ -class AddUrlToStatuses < ActiveRecord::Migration[4.2] +class AddURLToStatuses < ActiveRecord::Migration[4.2] def change add_column :statuses, :url, :string, null: true, default: nil end diff --git a/db/migrate/20160223165855_add_url_to_accounts.rb b/db/migrate/20160223165855_add_url_to_accounts.rb index c81b1c64fc7..a4db8814afc 100644 --- a/db/migrate/20160223165855_add_url_to_accounts.rb +++ b/db/migrate/20160223165855_add_url_to_accounts.rb @@ -1,4 +1,4 @@ -class AddUrlToAccounts < ActiveRecord::Migration[4.2] +class AddURLToAccounts < ActiveRecord::Migration[4.2] def change add_column :accounts, :url, :string, null: true, default: nil end diff --git a/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb b/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb index f9c213d9b47..0792863a373 100644 --- a/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb +++ b/db/migrate/20160322193748_add_avatar_remote_url_to_accounts.rb @@ -1,4 +1,4 @@ -class AddAvatarRemoteUrlToAccounts < ActiveRecord::Migration[4.2] +class AddAvatarRemoteURLToAccounts < ActiveRecord::Migration[4.2] def change add_column :accounts, :avatar_remote_url, :string, null: true, default: nil end diff --git a/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb b/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb index 0ba38d3e001..20c96598809 100644 --- a/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb +++ b/db/migrate/20170318214217_add_header_remote_url_to_accounts.rb @@ -1,4 +1,4 @@ -class AddHeaderRemoteUrlToAccounts < ActiveRecord::Migration[5.0] +class AddHeaderRemoteURLToAccounts < ActiveRecord::Migration[5.0] def change add_column :accounts, :header_remote_url, :string, null: false, default: '' end diff --git a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb index d19c0091bcd..8fcabef9fd5 100644 --- a/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb +++ b/db/migrate/20171130000000_add_embed_url_to_preview_cards.rb @@ -1,6 +1,6 @@ require Rails.root.join('lib', 'mastodon', 'migration_helpers') -class AddEmbedUrlToPreviewCards < ActiveRecord::Migration[5.1] +class AddEmbedURLToPreviewCards < ActiveRecord::Migration[5.1] include Mastodon::MigrationHelpers disable_ddl_transaction! diff --git a/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb index e0b8ed5cc19..1964b512166 100644 --- a/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb +++ b/db/migrate/20180304013859_add_featured_collection_url_to_accounts.rb @@ -1,4 +1,4 @@ -class AddFeaturedCollectionUrlToAccounts < ActiveRecord::Migration[5.1] +class AddFeaturedCollectionURLToAccounts < ActiveRecord::Migration[5.1] def change add_column :accounts, :featured_collection_url, :string end diff --git a/db/migrate/20200529214050_add_devices_url_to_accounts.rb b/db/migrate/20200529214050_add_devices_url_to_accounts.rb index 564877e5dcb..1323f8df7e7 100644 --- a/db/migrate/20200529214050_add_devices_url_to_accounts.rb +++ b/db/migrate/20200529214050_add_devices_url_to_accounts.rb @@ -1,4 +1,4 @@ -class AddDevicesUrlToAccounts < ActiveRecord::Migration[5.2] +class AddDevicesURLToAccounts < ActiveRecord::Migration[5.2] def change add_column :accounts, :devices_url, :string end diff --git a/app/lib/exceptions.rb b/lib/exceptions.rb similarity index 100% rename from app/lib/exceptions.rb rename to lib/exceptions.rb diff --git a/app/lib/sanitize_config.rb b/lib/sanitize_ext/sanitize_config.rb similarity index 100% rename from app/lib/sanitize_config.rb rename to lib/sanitize_ext/sanitize_config.rb diff --git a/spec/lib/sanitize_config_spec.rb b/spec/lib/sanitize_config_spec.rb index d66302e6449..747d81158da 100644 --- a/spec/lib/sanitize_config_spec.rb +++ b/spec/lib/sanitize_config_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require 'rails_helper' -require Rails.root.join('app', 'lib', 'sanitize_config.rb') describe Sanitize::Config do describe '::MASTODON_STRICT' do diff --git a/spec/validators/url_validator_spec.rb b/spec/validators/url_validator_spec.rb index e8d0e649469..a44878a44f8 100644 --- a/spec/validators/url_validator_spec.rb +++ b/spec/validators/url_validator_spec.rb @@ -2,7 +2,7 @@ require 'rails_helper' -RSpec.describe UrlValidator, type: :validator do +RSpec.describe URLValidator, type: :validator do describe '#validate_each' do before do allow(validator).to receive(:compliant?).with(value) { compliant } From 9aaaa96d2ff5e27f065375a2544e86afa31a4e13 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 02:43:13 +0100 Subject: [PATCH 13/18] Use more robust hook for loading timestamp_id function into database (#15919) --- config/application.rb | 1 + ...70920024819_status_ids_to_timestamp_ids.rb | 4 +- .../database_tasks_extensions.rb | 20 +++++++ lib/tasks/db.rake | 56 ------------------- 4 files changed, 23 insertions(+), 58 deletions(-) create mode 100644 lib/active_record/database_tasks_extensions.rb diff --git a/config/application.rb b/config/application.rb index 0960247b3a7..3267fa71be5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -28,6 +28,7 @@ require_relative '../lib/webpacker/manifest_extensions' require_relative '../lib/webpacker/helper_extensions' require_relative '../lib/action_dispatch/cookie_jar_extensions' require_relative '../lib/rails/engine_extensions' +require_relative '../lib/active_record/database_tasks_extensions' Dotenv::Railtie.load diff --git a/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb b/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb index c10aa2c4f76..8679f8ece87 100644 --- a/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb +++ b/db/migrate/20170920024819_status_ids_to_timestamp_ids.rb @@ -1,7 +1,7 @@ class StatusIdsToTimestampIds < ActiveRecord::Migration[5.1] def up # Prepare the function we will use to generate IDs. - Rake::Task['db:define_timestamp_id'].execute + Mastodon::Snowflake.define_timestamp_id # Set up the statuses.id column to use our timestamp-based IDs. ActiveRecord::Base.connection.execute(<<~SQL) @@ -11,7 +11,7 @@ class StatusIdsToTimestampIds < ActiveRecord::Migration[5.1] SQL # Make sure we have a sequence to use. - Rake::Task['db:ensure_id_sequences_exist'].execute + Mastodon::Snowflake.ensure_id_sequences_exist end def down diff --git a/lib/active_record/database_tasks_extensions.rb b/lib/active_record/database_tasks_extensions.rb new file mode 100644 index 00000000000..e274f476dff --- /dev/null +++ b/lib/active_record/database_tasks_extensions.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require_relative '../mastodon/snowflake' + +module ActiveRecord + module Tasks + module DatabaseTasks + original_load_schema = instance_method(:load_schema) + + define_method(:load_schema) do |db_config, *args| + ActiveRecord::Base.establish_connection(db_config) + Mastodon::Snowflake.define_timestamp_id + + original_load_schema.bind(self).call(db_config, *args) + + Mastodon::Snowflake.ensure_id_sequences_exist + end + end + end +end diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index f6c9c7eecfc..552a02b3f11 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -1,36 +1,5 @@ # frozen_string_literal: true -require_relative '../mastodon/snowflake' - -def each_schema_load_environment - # If we're in development, also run this for the test environment. - # This is a somewhat hacky way to do this, so here's why: - # 1. We have to define this before we load the schema, or we won't - # have a timestamp_id function when we get to it in the schema. - # 2. db:setup calls db:schema:load_if_ruby, which calls - # db:schema:load, which we define above as having a prerequisite - # of this task. - # 3. db:schema:load ends up running - # ActiveRecord::Tasks::DatabaseTasks.load_schema_current, which - # calls a private method `each_current_configuration`, which - # explicitly also does the loading for the `test` environment - # if the current environment is `development`, so we end up - # needing to do the same, and we can't even use the same method - # to do it. - - if Rails.env.development? - test_conf = ActiveRecord::Base.configurations['test'] - - if test_conf['database']&.present? - ActiveRecord::Base.establish_connection(:test) - yield - ActiveRecord::Base.establish_connection(Rails.env.to_sym) - end - end - - yield -end - namespace :db do namespace :migrate do desc 'Setup the db or migrate depending on state of db' @@ -61,29 +30,4 @@ namespace :db do end Rake::Task['db:migrate'].enhance(['db:post_migration_hook']) - - # Before we load the schema, define the timestamp_id function. - # Idiomatically, we might do this in a migration, but then it - # wouldn't end up in schema.rb, so we'd need to figure out a way to - # get it in before doing db:setup as well. This is simpler, and - # ensures it's always in place. - Rake::Task['db:schema:load'].enhance ['db:define_timestamp_id'] - - # After we load the schema, make sure we have sequences for each - # table using timestamp IDs. - Rake::Task['db:schema:load'].enhance do - Rake::Task['db:ensure_id_sequences_exist'].invoke - end - - task :define_timestamp_id do - each_schema_load_environment do - Mastodon::Snowflake.define_timestamp_id - end - end - - task :ensure_id_sequences_exist do - each_schema_load_environment do - Mastodon::Snowflake.ensure_id_sequences_exist - end - end end From 55ac2b9c6085def9e692fa69b849239c1249d9fd Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 02:44:57 +0100 Subject: [PATCH 14/18] Add option to opt out of unread notification markers (#15842) Fixes #15133 --- .../notifications/components/column_settings.js | 10 ++++++++++ .../mastodon/features/notifications/index.js | 4 ++-- app/javascript/mastodon/reducers/settings.js | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js index 8339a367ebc..0c24c3294a8 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.js +++ b/app/javascript/mastodon/features/notifications/components/column_settings.js @@ -55,6 +55,16 @@ export default class ColumnSettings extends React.PureComponent { +
+ + + + +
+ +
+
+
diff --git a/app/javascript/mastodon/features/notifications/index.js b/app/javascript/mastodon/features/notifications/index.js index 108470c9a71..cf8fd71277f 100644 --- a/app/javascript/mastodon/features/notifications/index.js +++ b/app/javascript/mastodon/features/notifications/index.js @@ -60,8 +60,8 @@ const mapStateToProps = state => ({ isUnread: state.getIn(['notifications', 'unread']) > 0 || state.getIn(['notifications', 'pendingItems']).size > 0, hasMore: state.getIn(['notifications', 'hasMore']), numPending: state.getIn(['notifications', 'pendingItems'], ImmutableList()).size, - lastReadId: state.getIn(['notifications', 'readMarkerId']), - canMarkAsRead: state.getIn(['notifications', 'readMarkerId']) !== '0' && getNotifications(state).some(item => item !== null && compareId(item.get('id'), state.getIn(['notifications', 'readMarkerId'])) > 0), + lastReadId: state.getIn(['settings', 'notifications', 'showUnread']) ? state.getIn(['notifications', 'readMarkerId']) : '0', + canMarkAsRead: state.getIn(['settings', 'notifications', 'showUnread']) && state.getIn(['notifications', 'readMarkerId']) !== '0' && getNotifications(state).some(item => item !== null && compareId(item.get('id'), state.getIn(['notifications', 'readMarkerId'])) > 0), needsNotificationPermission: state.getIn(['settings', 'notifications', 'alerts']).includes(true) && state.getIn(['notifications', 'browserSupport']) && state.getIn(['notifications', 'browserPermission']) === 'default' && !state.getIn(['settings', 'notifications', 'dismissPermissionBanner']), }); diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js index 357ab352aee..2a89919e1f0 100644 --- a/app/javascript/mastodon/reducers/settings.js +++ b/app/javascript/mastodon/reducers/settings.js @@ -45,6 +45,7 @@ const initialState = ImmutableMap({ }), dismissPermissionBanner: false, + showUnread: true, shows: ImmutableMap({ follow: true, From b3582298341e32528929c6f3292e36a6fa261ba5 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 02:45:34 +0100 Subject: [PATCH 15/18] Further preparation for Rails 6 (#15916) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Use ActiveRecord::Result#to_ary instead of deprecated to_hash They do the same thing, and to_hash has been removed from Rails 6.1 * Explicitly name polymorphic indexes to workaround a bug in Rails 6.1 cf. https://github.com/rails/rails/issues/41693 * Fix incorrect usage of “foreign_key” in migration script * Use `ActiveModel::Errors#delete` instead of deprecated clear method * Fix link headers tests on Rails 6.1 Rails 6.1 adds values to the Link header by default, thus it is not a LinkHeader object anymore. Fix the test to parse the Link header instead of assuming it is a LinkHeader. --- app/controllers/admin/domain_blocks_controller.rb | 2 +- db/migrate/20161006213403_rails_settings_migration.rb | 8 ++++---- db/migrate/20171119172437_create_admin_action_logs.rb | 2 +- db/migrate/20180528141303_fix_accounts_unique_index.rb | 2 +- .../20181024224956_migrate_account_conversations.rb | 4 ++-- .../20181207011115_downcase_custom_emoji_domains.rb | 2 +- .../20190726175042_add_case_insensitive_index_to_tags.rb | 2 +- lib/mastodon/migration_helpers.rb | 6 +++--- spec/requests/link_headers_spec.rb | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index ba927b04ada..b140c454c17 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -22,7 +22,7 @@ module Admin if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block) @domain_block.save flash.now[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe # rubocop:disable Rails/OutputSafety - @domain_block.errors[:domain].clear + @domain_block.errors.delete(:domain) render :new else if existing_domain_block.present? diff --git a/db/migrate/20161006213403_rails_settings_migration.rb b/db/migrate/20161006213403_rails_settings_migration.rb index 42875d7cbda..9d565cb5c6f 100644 --- a/db/migrate/20161006213403_rails_settings_migration.rb +++ b/db/migrate/20161006213403_rails_settings_migration.rb @@ -7,12 +7,12 @@ end class RailsSettingsMigration < MIGRATION_BASE_CLASS def self.up create_table :settings do |t| - t.string :var, :null => false + t.string :var, null: false t.text :value - t.references :target, :null => false, :polymorphic => true - t.timestamps :null => true + t.references :target, null: false, polymorphic: true, index: { name: 'index_settings_on_target_type_and_target_id' } + t.timestamps null: true end - add_index :settings, [ :target_type, :target_id, :var ], :unique => true + add_index :settings, [ :target_type, :target_id, :var ], unique: true end def self.down diff --git a/db/migrate/20171119172437_create_admin_action_logs.rb b/db/migrate/20171119172437_create_admin_action_logs.rb index 0c2b6c623d1..b690735d265 100644 --- a/db/migrate/20171119172437_create_admin_action_logs.rb +++ b/db/migrate/20171119172437_create_admin_action_logs.rb @@ -3,7 +3,7 @@ class CreateAdminActionLogs < ActiveRecord::Migration[5.1] create_table :admin_action_logs do |t| t.belongs_to :account, foreign_key: { on_delete: :cascade } t.string :action, null: false, default: '' - t.references :target, polymorphic: true + t.references :target, polymorphic: true, index: { name: 'index_admin_action_logs_on_target_type_and_target_id' } t.text :recorded_changes, null: false, default: '' t.timestamps diff --git a/db/migrate/20180528141303_fix_accounts_unique_index.rb b/db/migrate/20180528141303_fix_accounts_unique_index.rb index 5d7b3c463b0..02813f363c7 100644 --- a/db/migrate/20180528141303_fix_accounts_unique_index.rb +++ b/db/migrate/20180528141303_fix_accounts_unique_index.rb @@ -37,7 +37,7 @@ class FixAccountsUniqueIndex < ActiveRecord::Migration[5.2] end end - duplicates = Account.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM accounts GROUP BY lower(username), lower(domain) HAVING count(*) > 1').to_hash + duplicates = Account.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM accounts GROUP BY lower(username), lower(domain) HAVING count(*) > 1').to_ary duplicates.each do |row| deduplicate_account!(row['ids'].split(',')) diff --git a/db/migrate/20181024224956_migrate_account_conversations.rb b/db/migrate/20181024224956_migrate_account_conversations.rb index 12e0a70fac9..9e6497d81ff 100644 --- a/db/migrate/20181024224956_migrate_account_conversations.rb +++ b/db/migrate/20181024224956_migrate_account_conversations.rb @@ -17,8 +17,8 @@ class MigrateAccountConversations < ActiveRecord::Migration[5.2] belongs_to :account, optional: true belongs_to :activity, polymorphic: true, optional: true - belongs_to :status, foreign_type: 'Status', foreign_key: 'activity_id', optional: true - belongs_to :mention, foreign_type: 'Mention', foreign_key: 'activity_id', optional: true + belongs_to :status, foreign_key: 'activity_id', optional: true + belongs_to :mention, foreign_key: 'activity_id', optional: true def target_status mention&.status diff --git a/db/migrate/20181207011115_downcase_custom_emoji_domains.rb b/db/migrate/20181207011115_downcase_custom_emoji_domains.rb index 65f1fc8d938..e27e0249d9d 100644 --- a/db/migrate/20181207011115_downcase_custom_emoji_domains.rb +++ b/db/migrate/20181207011115_downcase_custom_emoji_domains.rb @@ -2,7 +2,7 @@ class DowncaseCustomEmojiDomains < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up - duplicates = CustomEmoji.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM custom_emojis GROUP BY shortcode, lower(domain) HAVING count(*) > 1').to_hash + duplicates = CustomEmoji.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM custom_emojis GROUP BY shortcode, lower(domain) HAVING count(*) > 1').to_ary duplicates.each do |row| CustomEmoji.where(id: row['ids'].split(',')[0...-1]).destroy_all diff --git a/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb b/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb index 057fc86baa8..eb03d7ca7d2 100644 --- a/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb +++ b/db/migrate/20190726175042_add_case_insensitive_index_to_tags.rb @@ -2,7 +2,7 @@ class AddCaseInsensitiveIndexToTags < ActiveRecord::Migration[5.2] disable_ddl_transaction! def up - Tag.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM tags GROUP BY lower(name) HAVING count(*) > 1').to_hash.each do |row| + Tag.connection.select_all('SELECT string_agg(id::text, \',\') AS ids FROM tags GROUP BY lower(name) HAVING count(*) > 1').to_ary.each do |row| canonical_tag_id = row['ids'].split(',').first redundant_tag_ids = row['ids'].split(',')[1..-1] diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb index bf2314ecb1e..fcaa9259e3b 100644 --- a/lib/mastodon/migration_helpers.rb +++ b/lib/mastodon/migration_helpers.rb @@ -319,7 +319,7 @@ module Mastodon count_arel = table.project(Arel.star.count.as('count')) count_arel = yield table, count_arel if block_given? - total = exec_query(count_arel.to_sql).to_hash.first['count'].to_i + total = exec_query(count_arel.to_sql).to_ary.first['count'].to_i return if total == 0 end @@ -335,7 +335,7 @@ module Mastodon start_arel = table.project(table[:id]).order(table[:id].asc).take(1) start_arel = yield table, start_arel if block_given? - first_row = exec_query(start_arel.to_sql).to_hash.first + first_row = exec_query(start_arel.to_sql).to_ary.first # In case there are no rows but we didn't catch it in the estimated size: return unless first_row start_id = first_row['id'].to_i @@ -356,7 +356,7 @@ module Mastodon .skip(batch_size) stop_arel = yield table, stop_arel if block_given? - stop_row = exec_query(stop_arel.to_sql).to_hash.first + stop_row = exec_query(stop_arel.to_sql).to_ary.first update_arel = Arel::UpdateManager.new .table(table) diff --git a/spec/requests/link_headers_spec.rb b/spec/requests/link_headers_spec.rb index 712ee262b80..c32e0f79a93 100644 --- a/spec/requests/link_headers_spec.rb +++ b/spec/requests/link_headers_spec.rb @@ -25,7 +25,7 @@ describe 'Link headers' do end def link_header_with_type(type) - response.headers['Link'].links.find do |link| + LinkHeader.parse(response.headers['Link'].to_s).links.find do |link| link.attr_pairs.any? { |pair| pair == ['type', type] } end end From 82caed594c3ad2cafe0c83b814879f30942fe57b Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 11:07:56 +0100 Subject: [PATCH 16/18] Change deduplication order of tootctl maintenance fix-duplicates (#15923) Hopefully fixes #15922 Also update support up to latest database schema version --- lib/mastodon/maintenance_cli.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/mastodon/maintenance_cli.rb b/lib/mastodon/maintenance_cli.rb index 029d42a05a6..9f1eaf263a8 100644 --- a/lib/mastodon/maintenance_cli.rb +++ b/lib/mastodon/maintenance_cli.rb @@ -14,7 +14,7 @@ module Mastodon end MIN_SUPPORTED_VERSION = 2019_10_01_213028 - MAX_SUPPORTED_VERSION = 2020_12_18_054746 + MAX_SUPPORTED_VERSION = 2021_03_08_133107 # Stubs to enjoy ActiveRecord queries while not depending on a particular # version of the code/database @@ -142,7 +142,6 @@ module Mastodon @prompt.warn 'Please make sure to stop Mastodon and have a backup.' exit(1) unless @prompt.yes?('Continue?') - deduplicate_accounts! deduplicate_users! deduplicate_account_domain_blocks! deduplicate_account_identity_proofs! @@ -157,6 +156,7 @@ module Mastodon deduplicate_media_attachments! deduplicate_preview_cards! deduplicate_statuses! + deduplicate_accounts! deduplicate_tags! deduplicate_webauthn_credentials! From c31c95ffe4fbf80981a0ee03484d72ee6d75d2ee Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 13:14:40 +0100 Subject: [PATCH 17/18] Remove MySQL-specific code from Mastodon::MigrationHelpers (#15924) Mastodon::MigrationHelpers has been forked from Gitlab a long time ago, but Mastodon has never supported using a MySQL database. Removing MySQL support from Mastodon::MigrationHelpers makes it a little easier to maintain. In particular, it removes code that would need updating with Rails 6. --- lib/mastodon/migration_helpers.rb | 84 ++++++------------------------- 1 file changed, 14 insertions(+), 70 deletions(-) diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb index fcaa9259e3b..147642a1cc3 100644 --- a/lib/mastodon/migration_helpers.rb +++ b/lib/mastodon/migration_helpers.rb @@ -41,42 +41,18 @@ module Mastodon module MigrationHelpers - # Stub for Database.postgresql? from GitLab - def self.postgresql? - ActiveRecord::Base.configurations[Rails.env]['adapter'].casecmp('postgresql').zero? - end - - # Stub for Database.mysql? from GitLab - def self.mysql? - ActiveRecord::Base.configurations[Rails.env]['adapter'].casecmp('mysql2').zero? - end - # Model that can be used for querying permissions of a SQL user. class Grant < ActiveRecord::Base - self.table_name = - if Mastodon::MigrationHelpers.postgresql? - 'information_schema.role_table_grants' - else - 'mysql.user' - end + self.table_name = 'information_schema.role_table_grants' def self.scope_to_current_user - if Mastodon::MigrationHelpers.postgresql? - where('grantee = user') - else - where("CONCAT(User, '@', Host) = current_user()") - end + where('grantee = user') end # Returns true if the current user can create and execute triggers on the # given table. def self.create_and_execute_trigger?(table) - priv = - if Mastodon::MigrationHelpers.postgresql? - where(privilege_type: 'TRIGGER', table_name: table) - else - where(Trigger_priv: 'Y') - end + priv = where(privilege_type: 'TRIGGER', table_name: table) priv.scope_to_current_user.any? end @@ -141,10 +117,8 @@ module Mastodon 'in the body of your migration class' end - if MigrationHelpers.postgresql? - options = options.merge({ algorithm: :concurrently }) - disable_statement_timeout - end + options = options.merge({ algorithm: :concurrently }) + disable_statement_timeout add_index(table_name, column_name, options) end @@ -199,8 +173,6 @@ module Mastodon # Only available on Postgresql >= 9.2 def supports_drop_index_concurrently? - return false unless MigrationHelpers.postgresql? - version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i version >= 90200 @@ -226,13 +198,7 @@ module Mastodon # While MySQL does allow disabling of foreign keys it has no equivalent # of PostgreSQL's "VALIDATE CONSTRAINT". As a result we'll just fall # back to the normal foreign key procedure. - if MigrationHelpers.mysql? - return add_foreign_key(source, target, - column: column, - on_delete: on_delete) - else - on_delete = 'SET NULL' if on_delete == :nullify - end + on_delete = 'SET NULL' if on_delete == :nullify disable_statement_timeout @@ -270,7 +236,7 @@ module Mastodon # the database. Disable the session's statement timeout to ensure # migrations don't get killed prematurely. (PostgreSQL only) def disable_statement_timeout - execute('SET statement_timeout TO 0') if MigrationHelpers.postgresql? + execute('SET statement_timeout TO 0') end # Updates the value of a column in batches. @@ -487,11 +453,7 @@ module Mastodon # If we were in the middle of update_column_in_batches, we should remove # the old column and start over, as we have no idea where we were. if column_for(table, new) - if MigrationHelpers.postgresql? - remove_rename_triggers_for_postgresql(table, trigger_name) - else - remove_rename_triggers_for_mysql(trigger_name) - end + remove_rename_triggers_for_postgresql(table, trigger_name) remove_column(table, new) end @@ -521,13 +483,8 @@ module Mastodon quoted_old = quote_column_name(old) quoted_new = quote_column_name(new) - if MigrationHelpers.postgresql? - install_rename_triggers_for_postgresql(trigger_name, quoted_table, - quoted_old, quoted_new) - else - install_rename_triggers_for_mysql(trigger_name, quoted_table, - quoted_old, quoted_new) - end + install_rename_triggers_for_postgresql(trigger_name, quoted_table, + quoted_old, quoted_new) update_column_in_batches(table, new, Arel::Table.new(table)[old]) @@ -685,11 +642,7 @@ module Mastodon check_trigger_permissions!(table) - if MigrationHelpers.postgresql? - remove_rename_triggers_for_postgresql(table, trigger_name) - else - remove_rename_triggers_for_mysql(trigger_name) - end + remove_rename_triggers_for_postgresql(table, trigger_name) remove_column(table, old) end @@ -844,18 +797,9 @@ module Mastodon quoted_pattern = Arel::Nodes::Quoted.new(pattern.to_s) quoted_replacement = Arel::Nodes::Quoted.new(replacement.to_s) - if MigrationHelpers.mysql? - locate = Arel::Nodes::NamedFunction - .new('locate', [quoted_pattern, column]) - insert_in_place = Arel::Nodes::NamedFunction - .new('insert', [column, locate, pattern.size, quoted_replacement]) - - Arel::Nodes::SqlLiteral.new(insert_in_place.to_sql) - else - replace = Arel::Nodes::NamedFunction - .new("regexp_replace", [column, quoted_pattern, quoted_replacement]) - Arel::Nodes::SqlLiteral.new(replace.to_sql) - end + replace = Arel::Nodes::NamedFunction + .new("regexp_replace", [column, quoted_pattern, quoted_replacement]) + Arel::Nodes::SqlLiteral.new(replace.to_sql) end def remove_foreign_key_without_error(*args) From 741d0952b174740e70a09fe6db6862624dfe1e44 Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 19 Mar 2021 13:14:57 +0100 Subject: [PATCH 18/18] Improve account counters handling (#15913) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Improve account counters handling * Use ActiveRecord::Base::sanitize_sql to pass values instead of interpolating them Keep using string interpolation for `key` as it is safe and using “ActiveRecord::Base::sanitize_sql_hash_for_assignment” would require stitching bits of SQL in a way that is not more easily checked for safety. * Add migration hook to catch PostgreSQL versions earlier than 9.5 --- app/models/account_stat.rb | 42 ------------- app/models/concerns/account_counters.rb | 60 ++++++++++++++++++- lib/tasks/db.rake | 8 ++- spec/models/account_stat_spec.rb | 57 ------------------ spec/models/concerns/account_counters_spec.rb | 60 +++++++++++++++++++ 5 files changed, 125 insertions(+), 102 deletions(-) delete mode 100644 spec/models/account_stat_spec.rb create mode 100644 spec/models/concerns/account_counters_spec.rb diff --git a/app/models/account_stat.rb b/app/models/account_stat.rb index e70b54d79b9..a826a9af3ba 100644 --- a/app/models/account_stat.rb +++ b/app/models/account_stat.rb @@ -18,46 +18,4 @@ class AccountStat < ApplicationRecord belongs_to :account, inverse_of: :account_stat update_index('accounts#account', :account) - - def increment_count!(key) - update(attributes_for_increment(key)) - rescue ActiveRecord::StaleObjectError, ActiveRecord::RecordNotUnique - begin - reload_with_id - rescue ActiveRecord::RecordNotFound - return - end - - retry - end - - def decrement_count!(key) - update(attributes_for_decrement(key)) - rescue ActiveRecord::StaleObjectError, ActiveRecord::RecordNotUnique - begin - reload_with_id - rescue ActiveRecord::RecordNotFound - return - end - - retry - end - - private - - def attributes_for_increment(key) - attrs = { key => public_send(key) + 1 } - attrs[:last_status_at] = Time.now.utc if key == :statuses_count - attrs - end - - def attributes_for_decrement(key) - attrs = { key => [public_send(key) - 1, 0].max } - attrs - end - - def reload_with_id - self.id = self.class.find_by!(account: account).id if new_record? - reload - end end diff --git a/app/models/concerns/account_counters.rb b/app/models/concerns/account_counters.rb index 6e25e1905e4..fd3f161ad53 100644 --- a/app/models/concerns/account_counters.rb +++ b/app/models/concerns/account_counters.rb @@ -3,6 +3,8 @@ module AccountCounters extend ActiveSupport::Concern + ALLOWED_COUNTER_KEYS = %i(statuses_count following_count followers_count).freeze + included do has_one :account_stat, inverse_of: :account after_save :save_account_stat @@ -14,11 +16,65 @@ module AccountCounters :following_count=, :followers_count, :followers_count=, - :increment_count!, - :decrement_count!, :last_status_at, to: :account_stat + # @param [Symbol] key + def increment_count!(key) + update_count!(key, 1) + end + + # @param [Symbol] key + def decrement_count!(key) + update_count!(key, -1) + end + + # @param [Symbol] key + # @param [Integer] value + def update_count!(key, value) + raise ArgumentError, "Invalid key #{key}" unless ALLOWED_COUNTER_KEYS.include?(key) + raise ArgumentError, 'Do not call update_count! on dirty objects' if association(:account_stat).loaded? && account_stat&.changed? && account_stat.changed_attribute_names_to_save == %w(id) + + value = value.to_i + default_value = value.positive? ? value : 0 + + # We do an upsert using manually written SQL, as Rails' upsert method does + # not seem to support writing expressions in the UPDATE clause, but only + # re-insert the provided values instead. + # Even ARel seem to be missing proper handling of upserts. + sql = if value.positive? && key == :statuses_count + <<-SQL.squish + INSERT INTO account_stats(account_id, #{key}, created_at, updated_at, last_status_at) + VALUES (:account_id, :default_value, now(), now(), now()) + ON CONFLICT (account_id) DO UPDATE + SET #{key} = account_stats.#{key} + :value, + last_status_at = now(), + lock_version = account_stats.lock_version + 1, + updated_at = now() + RETURNING id; + SQL + else + <<-SQL.squish + INSERT INTO account_stats(account_id, #{key}, created_at, updated_at) + VALUES (:account_id, :default_value, now(), now()) + ON CONFLICT (account_id) DO UPDATE + SET #{key} = account_stats.#{key} + :value, + lock_version = account_stats.lock_version + 1, + updated_at = now() + RETURNING id; + SQL + end + + sql = AccountStat.sanitize_sql([sql, account_id: id, default_value: default_value, value: value]) + account_stat_id = AccountStat.connection.exec_query(sql)[0]['id'] + + # Reload account_stat if it was loaded, taking into account newly-created unsaved records + if association(:account_stat).loaded? + account_stat.id = account_stat_id if account_stat.new_record? + account_stat.reload + end + end + def account_stat super || build_account_stat end diff --git a/lib/tasks/db.rake b/lib/tasks/db.rake index 552a02b3f11..7e6c1c8fc59 100644 --- a/lib/tasks/db.rake +++ b/lib/tasks/db.rake @@ -19,7 +19,7 @@ namespace :db do task :post_migration_hook do at_exit do - unless %w(C POSIX).include?(ActiveRecord::Base.connection.execute('SELECT datcollate FROM pg_database WHERE datname = current_database();').first['datcollate']) + unless %w(C POSIX).include?(ActiveRecord::Base.connection.select_one('SELECT datcollate FROM pg_database WHERE datname = current_database();')['datcollate']) warn <<~WARNING Your database collation is susceptible to index corruption. (This warning does not indicate that index corruption has occured and can be ignored) @@ -29,5 +29,11 @@ namespace :db do end end + task :pre_migration_check do + version = ActiveRecord::Base.connection.select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i + abort 'ERROR: This version of Mastodon requires PostgreSQL 9.5 or newer. Please update PostgreSQL before updating Mastodon.' if version < 90_500 + end + + Rake::Task['db:migrate'].enhance(['db:pre_migration_check']) Rake::Task['db:migrate'].enhance(['db:post_migration_hook']) end diff --git a/spec/models/account_stat_spec.rb b/spec/models/account_stat_spec.rb deleted file mode 100644 index 8adc0d1d638..00000000000 --- a/spec/models/account_stat_spec.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'rails_helper' - -RSpec.describe AccountStat, type: :model do - describe '#increment_count!' do - it 'increments the count' do - account_stat = AccountStat.create(account: Fabricate(:account)) - expect(account_stat.followers_count).to eq 0 - account_stat.increment_count!(:followers_count) - expect(account_stat.followers_count).to eq 1 - end - - it 'increments the count in multi-threaded an environment' do - account_stat = AccountStat.create(account: Fabricate(:account), statuses_count: 0) - increment_by = 15 - wait_for_start = true - - threads = Array.new(increment_by) do - Thread.new do - true while wait_for_start - AccountStat.find(account_stat.id).increment_count!(:statuses_count) - end - end - - wait_for_start = false - threads.each(&:join) - - expect(account_stat.reload.statuses_count).to eq increment_by - end - end - - describe '#decrement_count!' do - it 'decrements the count' do - account_stat = AccountStat.create(account: Fabricate(:account), followers_count: 15) - expect(account_stat.followers_count).to eq 15 - account_stat.decrement_count!(:followers_count) - expect(account_stat.followers_count).to eq 14 - end - - it 'decrements the count in multi-threaded an environment' do - account_stat = AccountStat.create(account: Fabricate(:account), statuses_count: 15) - decrement_by = 10 - wait_for_start = true - - threads = Array.new(decrement_by) do - Thread.new do - true while wait_for_start - AccountStat.find(account_stat.id).decrement_count!(:statuses_count) - end - end - - wait_for_start = false - threads.each(&:join) - - expect(account_stat.reload.statuses_count).to eq 5 - end - end -end diff --git a/spec/models/concerns/account_counters_spec.rb b/spec/models/concerns/account_counters_spec.rb new file mode 100644 index 00000000000..4350496e79e --- /dev/null +++ b/spec/models/concerns/account_counters_spec.rb @@ -0,0 +1,60 @@ +require 'rails_helper' + +describe AccountCounters do + let!(:account) { Fabricate(:account) } + + describe '#increment_count!' do + it 'increments the count' do + expect(account.followers_count).to eq 0 + account.increment_count!(:followers_count) + expect(account.followers_count).to eq 1 + end + + it 'increments the count in multi-threaded an environment' do + increment_by = 15 + wait_for_start = true + + threads = Array.new(increment_by) do + Thread.new do + true while wait_for_start + account.increment_count!(:statuses_count) + end + end + + wait_for_start = false + threads.each(&:join) + + expect(account.statuses_count).to eq increment_by + end + end + + describe '#decrement_count!' do + it 'decrements the count' do + account.followers_count = 15 + account.save! + expect(account.followers_count).to eq 15 + account.decrement_count!(:followers_count) + expect(account.followers_count).to eq 14 + end + + it 'decrements the count in multi-threaded an environment' do + decrement_by = 10 + wait_for_start = true + + account.statuses_count = 15 + account.save! + + threads = Array.new(decrement_by) do + Thread.new do + true while wait_for_start + account.decrement_count!(:statuses_count) + end + end + + wait_for_start = false + threads.each(&:join) + + expect(account.statuses_count).to eq 5 + end + end +end