From afc8550b63434232bb06b196132f2a180516061b Mon Sep 17 00:00:00 2001 From: Michael Stanclift Date: Mon, 11 Dec 2023 01:49:10 -0600 Subject: [PATCH 01/40] Change preview card deletes to be done using batch method (#28183) --- app/lib/vacuum/preview_cards_vacuum.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/lib/vacuum/preview_cards_vacuum.rb b/app/lib/vacuum/preview_cards_vacuum.rb index 14fdeda1ca9f62..9e34c87c30c386 100644 --- a/app/lib/vacuum/preview_cards_vacuum.rb +++ b/app/lib/vacuum/preview_cards_vacuum.rb @@ -14,9 +14,8 @@ def perform private def vacuum_cached_images! - preview_cards_past_retention_period.find_each do |preview_card| - preview_card.image.destroy - preview_card.save + preview_cards_past_retention_period.find_in_batches do |preview_card| + AttachmentBatch.new(PreviewCard, preview_card).clear end end From bd88883b6e6c7c614eac3c97fc40783ea7b8c91b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 07:52:53 +0000 Subject: [PATCH 02/40] Update eslint (non-major) (#28313) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 128 +++++++++++++++++++++++++++--------------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/yarn.lock b/yarn.lock index 45f58eaadc4562..4e1d0bd8c2c3ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1726,9 +1726,9 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^2.1.3": - version: 2.1.3 - resolution: "@eslint/eslintrc@npm:2.1.3" +"@eslint/eslintrc@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/eslintrc@npm:2.1.4" dependencies: ajv: "npm:^6.12.4" debug: "npm:^4.3.2" @@ -1739,14 +1739,14 @@ __metadata: js-yaml: "npm:^4.1.0" minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: f4103f4346126292eb15581c5a1d12bef03410fd3719dedbdb92e1f7031d46a5a2d60de8566790445d5d4b70b75ba050876799a11f5fff8265a91ee3fa77dab0 + checksum: 32f67052b81768ae876c84569ffd562491ec5a5091b0c1e1ca1e0f3c24fb42f804952fdd0a137873bc64303ba368a71ba079a6f691cee25beee9722d94cc8573 languageName: node linkType: hard -"@eslint/js@npm:8.54.0": - version: 8.54.0 - resolution: "@eslint/js@npm:8.54.0" - checksum: d61fb4a0be6af2d8cb290121c329697664a75d6255a29926d5454fb02aeb02b87112f67fdf218d10abac42f90c570ac366126751baefc5405d0e017ed0c946c5 +"@eslint/js@npm:8.55.0": + version: 8.55.0 + resolution: "@eslint/js@npm:8.55.0" + checksum: 88ab9fc57a651becd2b32ec40a3958db27fae133b1ae77bebd733aa5bbd00a92f325bb02f20ad680d31c731fa49b22f060a4777dd52eb3e27da013d940bd978d languageName: node linkType: hard @@ -3682,14 +3682,14 @@ __metadata: linkType: hard "@typescript-eslint/eslint-plugin@npm:^6.0.0": - version: 6.11.0 - resolution: "@typescript-eslint/eslint-plugin@npm:6.11.0" + version: 6.13.2 + resolution: "@typescript-eslint/eslint-plugin@npm:6.13.2" dependencies: "@eslint-community/regexpp": "npm:^4.5.1" - "@typescript-eslint/scope-manager": "npm:6.11.0" - "@typescript-eslint/type-utils": "npm:6.11.0" - "@typescript-eslint/utils": "npm:6.11.0" - "@typescript-eslint/visitor-keys": "npm:6.11.0" + "@typescript-eslint/scope-manager": "npm:6.13.2" + "@typescript-eslint/type-utils": "npm:6.13.2" + "@typescript-eslint/utils": "npm:6.13.2" + "@typescript-eslint/visitor-keys": "npm:6.13.2" debug: "npm:^4.3.4" graphemer: "npm:^1.4.0" ignore: "npm:^5.2.4" @@ -3702,44 +3702,44 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 6645aa09b9d51c5e3ea781eaf74da75b94f83f3e2d7b3dd988d5ce7eb82dd87e3509471cf2ee8c6b2428d907df5f1b02f29dbd04f54c2653f9566c8c4ce98009 + checksum: 531a4406d872738d165c6a66cb26e976523c94053b022a8210dc9fd10e91b79b705bc0fcc77145e9744e4108b53bdba55e02a10dc17757b22be92aff57849384 languageName: node linkType: hard "@typescript-eslint/parser@npm:^6.0.0": - version: 6.11.0 - resolution: "@typescript-eslint/parser@npm:6.11.0" + version: 6.13.2 + resolution: "@typescript-eslint/parser@npm:6.13.2" dependencies: - "@typescript-eslint/scope-manager": "npm:6.11.0" - "@typescript-eslint/types": "npm:6.11.0" - "@typescript-eslint/typescript-estree": "npm:6.11.0" - "@typescript-eslint/visitor-keys": "npm:6.11.0" + "@typescript-eslint/scope-manager": "npm:6.13.2" + "@typescript-eslint/types": "npm:6.13.2" + "@typescript-eslint/typescript-estree": "npm:6.13.2" + "@typescript-eslint/visitor-keys": "npm:6.13.2" debug: "npm:^4.3.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: e7caeb20069102e21f468fc0dbe7ff6fb6b1efa9e72f4c9f39d4a865ed0633f39130b593ef9ae8f394ca1d70563e15410faf30a482a97809951eaac6ed3a67da + checksum: 2c62b8cd8a37eb2ea59cd00e559f51a9f57af746e2040e872af3c58ddd3f4071ad7b7009789bdeb0e0d4ee0343bfe96ee77288020f3ae22d08e1674203f5e156 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/scope-manager@npm:6.11.0" +"@typescript-eslint/scope-manager@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/scope-manager@npm:6.13.2" dependencies: - "@typescript-eslint/types": "npm:6.11.0" - "@typescript-eslint/visitor-keys": "npm:6.11.0" - checksum: d8999e2d1a4cbde8a79df5e3ec416f0e3db9532d39f2f4bb5a0ebdf954ae75c183d3277579ba05268fe2c88e88ef87f0fa12f02bb8d95d9e67d92e411241f3a3 + "@typescript-eslint/types": "npm:6.13.2" + "@typescript-eslint/visitor-keys": "npm:6.13.2" + checksum: 9b159e5bb10dfb5953e71488200b4126378fc7e987ce7d90946aea9ec40cd66c7ada92399657c5d9794189b764ca6f4eb38a8dcb9e4c5aa50ab6000a39636b9c languageName: node linkType: hard -"@typescript-eslint/type-utils@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/type-utils@npm:6.11.0" +"@typescript-eslint/type-utils@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/type-utils@npm:6.13.2" dependencies: - "@typescript-eslint/typescript-estree": "npm:6.11.0" - "@typescript-eslint/utils": "npm:6.11.0" + "@typescript-eslint/typescript-estree": "npm:6.13.2" + "@typescript-eslint/utils": "npm:6.13.2" debug: "npm:^4.3.4" ts-api-utils: "npm:^1.0.1" peerDependencies: @@ -3747,23 +3747,23 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: ff68f2e052b8d688f1dc1a0050746704c8e0ab6263b47f1f52da73a7d251678e4950af23a95e1cd8e3fcea2457e6e5294ddbe01d29dafa2fdfb5b11ed9452a3f + checksum: 1ca97c78abdf479aea0c54e869fda2ae2f69de1974cc063062ce7b5b16c7fdf497ea15c50a29dd5941ea1b6b77e8f1213a5c272a747e334ac69ede083f327468 languageName: node linkType: hard -"@typescript-eslint/types@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/types@npm:6.11.0" - checksum: 23182813db39a5e9b9bcc1e85306c953f7b8b22d3885e41fcac0bd725c170fbcb70f4ce55633678cc5921dcf062fa0e55635eb39480c118a4411a00354820223 +"@typescript-eslint/types@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/types@npm:6.13.2" + checksum: 029918ca5b1442bb4bc435773504ce32191e2c3e2fde8d4176bb6513f03e3dfa2aa9724b2d22b1640656d666b97f7a7ebfeaf67b881d5e07250828fa83e3ebe8 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/typescript-estree@npm:6.11.0" +"@typescript-eslint/typescript-estree@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/typescript-estree@npm:6.13.2" dependencies: - "@typescript-eslint/types": "npm:6.11.0" - "@typescript-eslint/visitor-keys": "npm:6.11.0" + "@typescript-eslint/types": "npm:6.13.2" + "@typescript-eslint/visitor-keys": "npm:6.13.2" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" @@ -3772,34 +3772,34 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 3e183e554e1bc74f065da3015f7137eb40c262f989c547701b1e3f4f20134e574e56b749288cd00d77b9d1ddb705546613c2457661ffc63b6060ffa97ba3aac8 + checksum: 1c4c59dce0c51fdfee34d9f418e64fe28e3ec1a97661efc8a3d2780bdff36aff38de9090d356a968f394fa6d4e9c058936ce9cd260d4c44a52761ecd74915bce languageName: node linkType: hard -"@typescript-eslint/utils@npm:6.11.0, @typescript-eslint/utils@npm:^6.5.0": - version: 6.11.0 - resolution: "@typescript-eslint/utils@npm:6.11.0" +"@typescript-eslint/utils@npm:6.13.2, @typescript-eslint/utils@npm:^6.5.0": + version: 6.13.2 + resolution: "@typescript-eslint/utils@npm:6.13.2" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" "@types/json-schema": "npm:^7.0.12" "@types/semver": "npm:^7.5.0" - "@typescript-eslint/scope-manager": "npm:6.11.0" - "@typescript-eslint/types": "npm:6.11.0" - "@typescript-eslint/typescript-estree": "npm:6.11.0" + "@typescript-eslint/scope-manager": "npm:6.13.2" + "@typescript-eslint/types": "npm:6.13.2" + "@typescript-eslint/typescript-estree": "npm:6.13.2" semver: "npm:^7.5.4" peerDependencies: eslint: ^7.0.0 || ^8.0.0 - checksum: c91eb4578607959acc2b43ddc791571682e45601a19b25d5d120786ed4af607656f83c5c1fa71972e549ddfb5542acf2f7d443ae93b32ee28192c22c106b8883 + checksum: 84969be91e7949868eaaa289288c9d71927f0e427b572501b0991d8d62b40a4234f7287c35b35d276ccbb53e9ea5457b8250fcf4941e60e6b9ba4065fbfba416 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:6.11.0": - version: 6.11.0 - resolution: "@typescript-eslint/visitor-keys@npm:6.11.0" +"@typescript-eslint/visitor-keys@npm:6.13.2": + version: 6.13.2 + resolution: "@typescript-eslint/visitor-keys@npm:6.13.2" dependencies: - "@typescript-eslint/types": "npm:6.11.0" + "@typescript-eslint/types": "npm:6.13.2" eslint-visitor-keys: "npm:^3.4.1" - checksum: 5f48329422b7f286196661d39e93e9defd7c5cf80e6c84c8d03459853f5d9f86a5e91c5e80ea572dcdb907ebbe503bbcc77aeb8b468c294b2aa7b3ccfc81cb88 + checksum: c173bc1fcc42c3075a5ee094e7f3bf0279d98315c25ff49e20d02d79022b1d0402accfa113b070afb4d52a6f6d180594b67baa8b6a784eabdf82b54dd1ff454c languageName: node linkType: hard @@ -7313,13 +7313,13 @@ __metadata: linkType: hard "eslint-config-prettier@npm:^9.0.0": - version: 9.0.0 - resolution: "eslint-config-prettier@npm:9.0.0" + version: 9.1.0 + resolution: "eslint-config-prettier@npm:9.1.0" peerDependencies: eslint: ">=7.0.0" bin: eslint-config-prettier: bin/cli.js - checksum: bc1f661915845c631824178942e5d02f858fe6d0ea796f0050d63e0f681927b92696e81139dd04714c08c3e7de580fd079c66162e40070155ba79eaee78ab5d0 + checksum: 6d332694b36bc9ac6fdb18d3ca2f6ac42afa2ad61f0493e89226950a7091e38981b66bac2b47ba39d15b73fff2cd32c78b850a9cf9eed9ca9a96bfb2f3a2f10d languageName: node linkType: hard @@ -7555,13 +7555,13 @@ __metadata: linkType: hard "eslint@npm:^8.41.0": - version: 8.54.0 - resolution: "eslint@npm:8.54.0" + version: 8.55.0 + resolution: "eslint@npm:8.55.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.2.0" "@eslint-community/regexpp": "npm:^4.6.1" - "@eslint/eslintrc": "npm:^2.1.3" - "@eslint/js": "npm:8.54.0" + "@eslint/eslintrc": "npm:^2.1.4" + "@eslint/js": "npm:8.55.0" "@humanwhocodes/config-array": "npm:^0.11.13" "@humanwhocodes/module-importer": "npm:^1.0.1" "@nodelib/fs.walk": "npm:^1.2.8" @@ -7598,7 +7598,7 @@ __metadata: text-table: "npm:^0.2.0" bin: eslint: bin/eslint.js - checksum: 4f205f832bdbd0218cde374b067791f4f76d7abe8de86b2dc849c273899051126d912ebf71531ee49b8eeaa22cad77febdc8f2876698dc2a76e84a8cb976af22 + checksum: d28c0b60f19bb7d355cb8393e77b018c8f548dba3f820b799c89bb2e0c436ee26084e700c5e57e1e97e7972ec93065277849141b82e7b0c0d02c2dc1e553a2a1 languageName: node linkType: hard From d0e7999a904d6d5eb290f2378ce36809bfecb502 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 07:53:13 +0000 Subject: [PATCH 03/40] Update dependency typescript to v5.3.3 (#28312) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 4e1d0bd8c2c3ce..34e22f0521db0a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16495,22 +16495,22 @@ __metadata: linkType: hard "typescript@npm:5, typescript@npm:^5.0.4": - version: 5.3.2 - resolution: "typescript@npm:5.3.2" + version: 5.3.3 + resolution: "typescript@npm:5.3.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: d7dbe1fbe19039e36a65468ea64b5d338c976550394ba576b7af9c68ed40c0bc5d12ecce390e4b94b287a09a71bd3229f19c2d5680611f35b7c53a3898791159 + checksum: e33cef99d82573624fc0f854a2980322714986bc35b9cb4d1ce736ed182aeab78e2cb32b385efa493b2a976ef52c53e20d6c6918312353a91850e2b76f1ea44f languageName: node linkType: hard "typescript@patch:typescript@npm%3A5#optional!builtin, typescript@patch:typescript@npm%3A^5.0.4#optional!builtin": - version: 5.3.2 - resolution: "typescript@patch:typescript@npm%3A5.3.2#optional!builtin::version=5.3.2&hash=e012d7" + version: 5.3.3 + resolution: "typescript@patch:typescript@npm%3A5.3.3#optional!builtin::version=5.3.3&hash=e012d7" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 73c8bad74e732d93211c9d77f28b03307e2f5fc6a0afc73f4b783261ab567686a16d6ae958bdaef383a00be1b0b8c8b6741dd6ca3d13af4963fa7e47456d49c7 + checksum: 1d0a5f4ce496c42caa9a30e659c467c5686eae15d54b027ee7866744952547f1be1262f2d40de911618c242b510029d51d43ff605dba8fb740ec85ca2d3f9500 languageName: node linkType: hard From 7ddd937330103cc9030ee375c3e62904b0b7508f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 08:53:32 +0100 Subject: [PATCH 04/40] Update dependency prettier to v3.1.1 (#28311) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 34e22f0521db0a..7a152420419d68 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13312,11 +13312,11 @@ __metadata: linkType: hard "prettier@npm:^3.0.0": - version: 3.1.0 - resolution: "prettier@npm:3.1.0" + version: 3.1.1 + resolution: "prettier@npm:3.1.1" bin: prettier: bin/prettier.cjs - checksum: a45ea70aa97fde162ea4c4aba3dfc7859aa6a732a1db34458d9535dc3c2c16d3bc3fb5689e6cd76aa835562555303b02d9449fd2e15af3b73c8053557e25c5b6 + checksum: facc944ba20e194ff4db765e830ffbcb642803381f0d2033ed397e79904fa4ccc877dc25ad68f42d36985c01d051c990ca1b905fb83d2d7d65fe69e4386fa1a3 languageName: node linkType: hard From a117155728319e36f3a5d2256de83b0985a40e0c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 07:54:01 +0000 Subject: [PATCH 05/40] Update DefinitelyTyped types (non-major) (#28310) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7a152420419d68..f246cf412c07e0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3027,11 +3027,11 @@ __metadata: linkType: hard "@types/emoji-mart@npm:^3.0.9": - version: 3.0.13 - resolution: "@types/emoji-mart@npm:3.0.13" + version: 3.0.14 + resolution: "@types/emoji-mart@npm:3.0.14" dependencies: "@types/react": "npm:*" - checksum: 840f920c3242e1d274f0102e67cb2d00434e1fd370e0bcc8983b43b6b62322b01e3ddcd5fb078c60883e613530a7c70b8c40060624897543cd4da9441ca81486 + checksum: 23ded65fce9b3355fbe903d3971cb67cc827a5d587464bb7e3f349615527ef4a9197b3bb59fa84c4391d1b901e7f200f686a7fc83f649ae2a51a0fb948cbadfb languageName: node linkType: hard @@ -3175,12 +3175,12 @@ __metadata: linkType: hard "@types/jest@npm:^29.5.2": - version: 29.5.10 - resolution: "@types/jest@npm:29.5.10" + version: 29.5.11 + resolution: "@types/jest@npm:29.5.11" dependencies: expect: "npm:^29.0.0" pretty-format: "npm:^29.0.0" - checksum: b46171d59d12a5f69bbe710f65eaf59a8073337c6b4a67dff8158575caec53f1c61f8a7d645b34d6ac3c4ea398acd30f0c5d1c4a131c0c918798019264a3397d + checksum: 524a3394845214581278bf4d75055927261fbeac7e1a89cd621bd0636da37d265fe0a85eac58b5778758faad1cbd7c7c361dfc190c78ebde03a91cce33463261 languageName: node linkType: hard @@ -3374,11 +3374,11 @@ __metadata: linkType: hard "@types/react-helmet@npm:^6.1.6": - version: 6.1.9 - resolution: "@types/react-helmet@npm:6.1.9" + version: 6.1.11 + resolution: "@types/react-helmet@npm:6.1.11" dependencies: "@types/react": "npm:*" - checksum: d1823582903d6e70f1f447c7bec9e844b6f85f5de84cbcde5c8bbeecc064db1394c786ed9b9ded30544afe5c91e57c7e8105171df1643998f64c0aeab9f7f2aa + checksum: f7b3bb2151d992a108ae46fed876fb9c8119108397d9a01d150c5642782997542c8b3c52e742b56e8689b7dbfa62ca9cfc76aa7e05dec4e60c652f7ef53fa783 languageName: node linkType: hard @@ -3495,13 +3495,13 @@ __metadata: linkType: hard "@types/react@npm:*, @types/react@npm:16 || 17 || 18, @types/react@npm:>=16.9.11, @types/react@npm:^18.2.7": - version: 18.2.41 - resolution: "@types/react@npm:18.2.41" + version: 18.2.43 + resolution: "@types/react@npm:18.2.43" dependencies: "@types/prop-types": "npm:*" "@types/scheduler": "npm:*" csstype: "npm:^3.0.2" - checksum: 5cc72491ce8be95e7bbedd8bf039ca971772ecd22d989feb045af7e73247c7e6cff25a2f1c2200be461fb2f6b5aacef739e1ba9fd83c744209dfd3ce8aa75afe + checksum: 10477a50fbd3c0cc5b8a2ade679f442717f68fb27c8460b2aa1d3256cd18c48f742bbe5b9ee37a8c4c5f832ffa37b3a23c09fd96dd880a8e3182d8929c05e803 languageName: node linkType: hard From b82fc8a2ca29f03f821add41bea5221ceac9cafd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 07:54:22 +0000 Subject: [PATCH 06/40] Update dependency ws to v8.15.0 (#28308) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index f246cf412c07e0..0ef881126d4dd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17738,8 +17738,8 @@ __metadata: linkType: hard "ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.14.2": - version: 8.14.2 - resolution: "ws@npm:8.14.2" + version: 8.15.0 + resolution: "ws@npm:8.15.0" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -17748,7 +17748,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: 35b4c2da048b8015c797fd14bcb5a5766216ce65c8a5965616a5440ca7b6c3681ee3cbd0ea0c184a59975556e9d58f2002abf8485a14d11d3371770811050a16 + checksum: b778a405b2589ffbf549323e2f404f1f72e372a049d332d2f0b1f33057e9fbb14a05aa474cb156e4584b418cd95edf4297c0ca5263d6519e8009064bf8e0b80d languageName: node linkType: hard From 11d2bd97165bf68439a8d2293c48b1fcefc8930c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 02:55:07 -0500 Subject: [PATCH 07/40] Fix intermittent failure from unspecified order in `api/v1/accounts/relationships` spec (#28306) --- .../api/v1/accounts/relationships_spec.rb | 42 +++++++++++-------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/spec/requests/api/v1/accounts/relationships_spec.rb b/spec/requests/api/v1/accounts/relationships_spec.rb index cea45168a218dc..b06ce0509df366 100644 --- a/spec/requests/api/v1/accounts/relationships_spec.rb +++ b/spec/requests/api/v1/accounts/relationships_spec.rb @@ -31,8 +31,8 @@ .to have_http_status(200) expect(body_as_json) .to be_an(Enumerable) - .and have_attributes( - first: include( + .and contain_exactly( + include( following: true, followed_by: false ) @@ -53,9 +53,11 @@ expect(body_as_json) .to be_an(Enumerable) .and have_attributes( - size: 2, - first: include(simon_item), - second: include(lewis_item) + size: 2 + ) + .and contain_exactly( + include(simon_item), + include(lewis_item) ) end end @@ -71,10 +73,12 @@ expect(body_as_json) .to be_an(Enumerable) .and have_attributes( - size: 3, - first: include(simon_item), - second: include(lewis_item), - third: include(bob_item) + size: 3 + ) + .and contain_exactly( + include(simon_item), + include(lewis_item), + include(bob_item) ) end end @@ -88,9 +92,11 @@ expect(body_as_json) .to be_an(Enumerable) .and have_attributes( - size: 2, - first: include(simon_item), - second: include(lewis_item) + size: 2 + ) + .and contain_exactly( + include(simon_item), + include(lewis_item) ) end end @@ -116,7 +122,6 @@ def lewis_item muting: false, requested: false, domain_blocking: false, - } end @@ -129,7 +134,6 @@ def bob_item muting: false, requested: false, domain_blocking: false, - } end end @@ -149,8 +153,10 @@ def bob_item expect(body_as_json) .to be_an(Enumerable) .and have_attributes( - size: 1, - first: include( + size: 1 + ) + .and contain_exactly( + include( following: true, showing_reblogs: true ) @@ -168,8 +174,8 @@ def bob_item expect(body_as_json) .to be_an(Enumerable) - .and have_attributes( - first: include( + .and contain_exactly( + include( following: false, showing_reblogs: false ) From 78347d25567b1b8cf2cb9e1fd4cab002fd6aff59 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 02:55:45 -0500 Subject: [PATCH 08/40] Controller spec to request spec: `api/v1/accounts/familiar_followers` (#28305) --- .../v1/accounts/familiar_followers_spec.rb} | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) rename spec/{controllers/api/v1/accounts/familiar_followers_controller_spec.rb => requests/api/v1/accounts/familiar_followers_spec.rb} (53%) diff --git a/spec/controllers/api/v1/accounts/familiar_followers_controller_spec.rb b/spec/requests/api/v1/accounts/familiar_followers_spec.rb similarity index 53% rename from spec/controllers/api/v1/accounts/familiar_followers_controller_spec.rb rename to spec/requests/api/v1/accounts/familiar_followers_spec.rb index 3c7c7e8b84c297..fdc0a3a9323e1a 100644 --- a/spec/controllers/api/v1/accounts/familiar_followers_controller_spec.rb +++ b/spec/requests/api/v1/accounts/familiar_followers_spec.rb @@ -2,20 +2,16 @@ require 'rails_helper' -describe Api::V1::Accounts::FamiliarFollowersController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:follows') } +describe 'Accounts Familiar Followers API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:follows' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } let(:account) { Fabricate(:account) } - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do + describe 'GET /api/v1/accounts/familiar_followers' do it 'returns http success' do - get :index, params: { account_id: account.id, limit: 2 } + get '/api/v1/accounts/familiar_followers', params: { account_id: account.id, limit: 2 }, headers: headers expect(response).to have_http_status(200) end @@ -26,7 +22,7 @@ it 'removes duplicate account IDs from params' do account_ids = [account_a, account_b, account_b, account_a, account_a].map { |a| a.id.to_s } - get :index, params: { id: account_ids } + get '/api/v1/accounts/familiar_followers', params: { id: account_ids }, headers: headers expect(body_as_json.pluck(:id)).to contain_exactly(account_a.id.to_s, account_b.id.to_s) end From 8f94502e7d092584c7bd723ae3e866c0aae2c95b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 02:56:13 -0500 Subject: [PATCH 09/40] Controller spec to request spec: `api/v1/accounts/identify_proofs` (#28304) --- .../identity_proofs_controller_spec.rb | 23 ------------------- .../api/v1/accounts/identity_proofs_spec.rb | 19 +++++++++++++++ 2 files changed, 19 insertions(+), 23 deletions(-) delete mode 100644 spec/controllers/api/v1/accounts/identity_proofs_controller_spec.rb create mode 100644 spec/requests/api/v1/accounts/identity_proofs_spec.rb diff --git a/spec/controllers/api/v1/accounts/identity_proofs_controller_spec.rb b/spec/controllers/api/v1/accounts/identity_proofs_controller_spec.rb deleted file mode 100644 index 6351de761651f1..00000000000000 --- a/spec/controllers/api/v1/accounts/identity_proofs_controller_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Accounts::IdentityProofsController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } - let(:account) { Fabricate(:account) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do - it 'returns http success' do - get :index, params: { account_id: account.id, limit: 2 } - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/accounts/identity_proofs_spec.rb b/spec/requests/api/v1/accounts/identity_proofs_spec.rb new file mode 100644 index 00000000000000..3727af7e8931bb --- /dev/null +++ b/spec/requests/api/v1/accounts/identity_proofs_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Accounts Identity Proofs API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + let(:account) { Fabricate(:account) } + + describe 'GET /api/v1/accounts/identity_proofs' do + it 'returns http success' do + get "/api/v1/accounts/#{account.id}/identity_proofs", params: { limit: 2 }, headers: headers + + expect(response).to have_http_status(200) + end + end +end From a968898dc7d7a9c6ddea850a40d4f2fc9e7b446f Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 02:56:47 -0500 Subject: [PATCH 10/40] Controller spec to request spec: `api/v1/accounts/lists` (#28303) --- .../api/v1/accounts/lists_controller_spec.rb | 25 ------------------- spec/requests/api/v1/accounts/lists_spec.rb | 25 +++++++++++++++++++ 2 files changed, 25 insertions(+), 25 deletions(-) delete mode 100644 spec/controllers/api/v1/accounts/lists_controller_spec.rb create mode 100644 spec/requests/api/v1/accounts/lists_spec.rb diff --git a/spec/controllers/api/v1/accounts/lists_controller_spec.rb b/spec/controllers/api/v1/accounts/lists_controller_spec.rb deleted file mode 100644 index 418839cfa57154..00000000000000 --- a/spec/controllers/api/v1/accounts/lists_controller_spec.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Accounts::ListsController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:lists') } - let(:account) { Fabricate(:account) } - let(:list) { Fabricate(:list, account: user.account) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - user.account.follow!(account) - list.accounts << account - end - - describe 'GET #index' do - it 'returns http success' do - get :index, params: { account_id: account.id } - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/accounts/lists_spec.rb b/spec/requests/api/v1/accounts/lists_spec.rb new file mode 100644 index 00000000000000..48c0337e5497cf --- /dev/null +++ b/spec/requests/api/v1/accounts/lists_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Accounts Lists API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:lists' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + let(:account) { Fabricate(:account) } + let(:list) { Fabricate(:list, account: user.account) } + + before do + user.account.follow!(account) + list.accounts << account + end + + describe 'GET /api/v1/accounts/lists' do + it 'returns http success' do + get "/api/v1/accounts/#{account.id}/lists", headers: headers + + expect(response).to have_http_status(200) + end + end +end From e544b6df42a5ed8c2365f0a95d7e3e94c53c61f9 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 02:57:33 -0500 Subject: [PATCH 11/40] Controller spec to request spec: `api/v1/accounts/lookup` (#28302) --- .../api/v1/accounts/lookup_controller_spec.rb | 23 ------------------- spec/requests/api/v1/accounts/lookup_spec.rb | 19 +++++++++++++++ 2 files changed, 19 insertions(+), 23 deletions(-) delete mode 100644 spec/controllers/api/v1/accounts/lookup_controller_spec.rb create mode 100644 spec/requests/api/v1/accounts/lookup_spec.rb diff --git a/spec/controllers/api/v1/accounts/lookup_controller_spec.rb b/spec/controllers/api/v1/accounts/lookup_controller_spec.rb deleted file mode 100644 index 37407766f228ca..00000000000000 --- a/spec/controllers/api/v1/accounts/lookup_controller_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Accounts::LookupController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } - let(:account) { Fabricate(:account) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #show' do - it 'returns http success' do - get :show, params: { account_id: account.id, acct: account.acct } - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/accounts/lookup_spec.rb b/spec/requests/api/v1/accounts/lookup_spec.rb new file mode 100644 index 00000000000000..4c022c7c1316fe --- /dev/null +++ b/spec/requests/api/v1/accounts/lookup_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Accounts Lookup API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + let(:account) { Fabricate(:account) } + + describe 'GET /api/v1/accounts/lookup' do + it 'returns http success' do + get '/api/v1/accounts/lookup', params: { account_id: account.id, acct: account.acct }, headers: headers + + expect(response).to have_http_status(200) + end + end +end From 94cc707ab398339dfe74472300056876fac81856 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 02:58:48 -0500 Subject: [PATCH 12/40] Controller spec to request spec: `api/v1/accounts/notes` (#28301) --- .../api/v1/accounts/notes_spec.rb} | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) rename spec/{controllers/api/v1/accounts/notes_controller_spec.rb => requests/api/v1/accounts/notes_spec.rb} (66%) diff --git a/spec/controllers/api/v1/accounts/notes_controller_spec.rb b/spec/requests/api/v1/accounts/notes_spec.rb similarity index 66% rename from spec/controllers/api/v1/accounts/notes_controller_spec.rb rename to spec/requests/api/v1/accounts/notes_spec.rb index 75599b32b2a069..4f3ac68c7479c8 100644 --- a/spec/controllers/api/v1/accounts/notes_controller_spec.rb +++ b/spec/requests/api/v1/accounts/notes_spec.rb @@ -2,21 +2,17 @@ require 'rails_helper' -describe Api::V1::Accounts::NotesController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'write:accounts') } +describe 'Accounts Notes API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'write:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } let(:account) { Fabricate(:account) } let(:comment) { 'foo' } - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'POST #create' do + describe 'POST /api/v1/accounts/:account_id/note' do subject do - post :create, params: { account_id: account.id, comment: comment } + post "/api/v1/accounts/#{account.id}/note", params: { comment: comment }, headers: headers end context 'when account note has reasonable length', :aggregate_failures do From 809506bdd40871ae8c56fa755d8d61bc279095a0 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 02:59:40 -0500 Subject: [PATCH 13/40] Controller spec to request spec: `api/v1/accounts/pins` (#28300) --- .../api/v1/accounts/pins_controller_spec.rb | 40 ------------------ spec/requests/api/v1/accounts/pins_spec.rb | 41 +++++++++++++++++++ 2 files changed, 41 insertions(+), 40 deletions(-) delete mode 100644 spec/controllers/api/v1/accounts/pins_controller_spec.rb create mode 100644 spec/requests/api/v1/accounts/pins_spec.rb diff --git a/spec/controllers/api/v1/accounts/pins_controller_spec.rb b/spec/controllers/api/v1/accounts/pins_controller_spec.rb deleted file mode 100644 index 36f525e756bfe1..00000000000000 --- a/spec/controllers/api/v1/accounts/pins_controller_spec.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Api::V1::Accounts::PinsController do - let(:john) { Fabricate(:user) } - let(:kevin) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: john.id, scopes: 'write:accounts') } - - before do - kevin.account.followers << john.account - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'POST #create' do - subject { post :create, params: { account_id: kevin.account.id } } - - it 'creates account_pin', :aggregate_failures do - expect do - subject - end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(1) - expect(response).to have_http_status(200) - end - end - - describe 'DELETE #destroy' do - subject { delete :destroy, params: { account_id: kevin.account.id } } - - before do - Fabricate(:account_pin, account: john.account, target_account: kevin.account) - end - - it 'destroys account_pin', :aggregate_failures do - expect do - subject - end.to change { AccountPin.where(account: john.account, target_account: kevin.account).count }.by(-1) - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/accounts/pins_spec.rb b/spec/requests/api/v1/accounts/pins_spec.rb new file mode 100644 index 00000000000000..c293715f7ed237 --- /dev/null +++ b/spec/requests/api/v1/accounts/pins_spec.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Accounts Pins API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'write:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + let(:kevin) { Fabricate(:user) } + + before do + kevin.account.followers << user.account + end + + describe 'POST /api/v1/accounts/:account_id/pin' do + subject { post "/api/v1/accounts/#{kevin.account.id}/pin", headers: headers } + + it 'creates account_pin', :aggregate_failures do + expect do + subject + end.to change { AccountPin.where(account: user.account, target_account: kevin.account).count }.by(1) + expect(response).to have_http_status(200) + end + end + + describe 'POST /api/v1/accounts/:account_id/unpin' do + subject { post "/api/v1/accounts/#{kevin.account.id}/unpin", headers: headers } + + before do + Fabricate(:account_pin, account: user.account, target_account: kevin.account) + end + + it 'destroys account_pin', :aggregate_failures do + expect do + subject + end.to change { AccountPin.where(account: user.account, target_account: kevin.account).count }.by(-1) + expect(response).to have_http_status(200) + end + end +end From 16ede59d0a01759a32e3abb6a352a3c397bd982c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 03:00:41 -0500 Subject: [PATCH 14/40] Controller spec to request spec: `api/v1/featured_tags/suggestions` (#28298) --- .../suggestions_controller_spec.rb | 23 ------------------- .../api/v1/featured_tags/suggestions_spec.rb | 19 +++++++++++++++ 2 files changed, 19 insertions(+), 23 deletions(-) delete mode 100644 spec/controllers/api/v1/featured_tags/suggestions_controller_spec.rb create mode 100644 spec/requests/api/v1/featured_tags/suggestions_spec.rb diff --git a/spec/controllers/api/v1/featured_tags/suggestions_controller_spec.rb b/spec/controllers/api/v1/featured_tags/suggestions_controller_spec.rb deleted file mode 100644 index 54c63dcc6f19b5..00000000000000 --- a/spec/controllers/api/v1/featured_tags/suggestions_controller_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::FeaturedTags::SuggestionsController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } - let(:account) { Fabricate(:account) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do - it 'returns http success' do - get :index, params: { account_id: account.id, limit: 2 } - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/featured_tags/suggestions_spec.rb b/spec/requests/api/v1/featured_tags/suggestions_spec.rb new file mode 100644 index 00000000000000..f7b453b740afc4 --- /dev/null +++ b/spec/requests/api/v1/featured_tags/suggestions_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Featured Tags Suggestions API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + let(:account) { Fabricate(:account) } + + describe 'GET /api/v1/featured_tags/suggestions' do + it 'returns http success' do + get '/api/v1/featured_tags/suggestions', params: { account_id: account.id, limit: 2 }, headers: headers + + expect(response).to have_http_status(200) + end + end +end From f5d6143aa1eba03391841d6df8ed80e09a4b5e05 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 09:01:17 +0100 Subject: [PATCH 15/40] Update dependency addressable to v2.8.6 (#28296) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7a7fdb01c4fc84..738bc7b8bc1b18 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -118,7 +118,7 @@ GEM minitest (>= 5.1) mutex_m tzinfo (~> 2.0) - addressable (2.8.5) + addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) aes_key_wrap (1.1.0) android_key_attestation (0.3.0) From 253393f3a8281dcf5850aabd917da727518f49c4 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 03:04:45 -0500 Subject: [PATCH 16/40] Only attempt to remove indexes that exist in `CLI::Maintenance` script (#28286) --- lib/mastodon/cli/maintenance.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mastodon/cli/maintenance.rb b/lib/mastodon/cli/maintenance.rb index d0eff7da619af5..553ca056dc86cf 100644 --- a/lib/mastodon/cli/maintenance.rb +++ b/lib/mastodon/cli/maintenance.rb @@ -712,7 +712,7 @@ def find_duplicate_accounts end def remove_index_if_exists!(table, name) - ActiveRecord::Base.connection.remove_index(table, name: name) + ActiveRecord::Base.connection.remove_index(table, name: name) if ActiveRecord::Base.connection.index_name_exists?(table, name) rescue ArgumentError, ActiveRecord::StatementInvalid nil end From 0c640925009a8dbfb8a2be9e4b45d3e40f727a52 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 03:13:28 -0500 Subject: [PATCH 17/40] Controller spec to request spec: `api/v1/accounts/search` (#28299) --- .../api/v1/accounts/search_controller_spec.rb | 22 ------------------- spec/requests/api/v1/accounts/search_spec.rb | 18 +++++++++++++++ 2 files changed, 18 insertions(+), 22 deletions(-) delete mode 100644 spec/controllers/api/v1/accounts/search_controller_spec.rb create mode 100644 spec/requests/api/v1/accounts/search_spec.rb diff --git a/spec/controllers/api/v1/accounts/search_controller_spec.rb b/spec/controllers/api/v1/accounts/search_controller_spec.rb deleted file mode 100644 index aa9455a4a33b56..00000000000000 --- a/spec/controllers/api/v1/accounts/search_controller_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -RSpec.describe Api::V1::Accounts::SearchController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #show' do - it 'returns http success' do - get :show, params: { q: 'query' } - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/accounts/search_spec.rb b/spec/requests/api/v1/accounts/search_spec.rb new file mode 100644 index 00000000000000..76b32e7b2ca3af --- /dev/null +++ b/spec/requests/api/v1/accounts/search_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Accounts Search API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v1/accounts/search' do + it 'returns http success' do + get '/api/v1/accounts/search', params: { q: 'query' }, headers: headers + + expect(response).to have_http_status(200) + end + end +end From 0e4233de9d8a0912b0d837e32043c325dfc2e0ff Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 03:13:57 -0500 Subject: [PATCH 18/40] Controller spec to request spec: `api/v2/suggestions` (#28297) --- .../api/v2/suggestions_controller_spec.rb | 22 ------------------- spec/requests/api/v2/suggestions_spec.rb | 18 +++++++++++++++ 2 files changed, 18 insertions(+), 22 deletions(-) delete mode 100644 spec/controllers/api/v2/suggestions_controller_spec.rb create mode 100644 spec/requests/api/v2/suggestions_spec.rb diff --git a/spec/controllers/api/v2/suggestions_controller_spec.rb b/spec/controllers/api/v2/suggestions_controller_spec.rb deleted file mode 100644 index 5e6508bfda38d9..00000000000000 --- a/spec/controllers/api/v2/suggestions_controller_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V2::SuggestionsController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read') } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do - it 'returns http success' do - get :index - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v2/suggestions_spec.rb b/spec/requests/api/v2/suggestions_spec.rb new file mode 100644 index 00000000000000..5f1c97b8ae3aba --- /dev/null +++ b/spec/requests/api/v2/suggestions_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'Suggestions API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + + describe 'GET /api/v2/suggestions' do + it 'returns http success' do + get '/api/v2/suggestions', headers: headers + + expect(response).to have_http_status(200) + end + end +end From 79a81da69c86276fe17143954f06f6e6b58356d4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 09:22:52 +0100 Subject: [PATCH 19/40] New Crowdin Translations (automated) (#28291) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/en-GB.json | 7 +++ app/javascript/mastodon/locales/eo.json | 50 ++++++++++++++++++++ app/javascript/mastodon/locales/ko.json | 2 +- app/javascript/mastodon/locales/la.json | 16 +++---- app/javascript/mastodon/locales/ne.json | 54 +++++++++++++++++++++- app/javascript/mastodon/locales/sk.json | 1 + config/locales/activerecord.hr.yml | 15 ++++++ config/locales/activerecord.ru.yml | 2 +- config/locales/en-GB.yml | 16 +++++++ config/locales/sk.yml | 4 ++ 10 files changed, 156 insertions(+), 11 deletions(-) diff --git a/app/javascript/mastodon/locales/en-GB.json b/app/javascript/mastodon/locales/en-GB.json index 7745311be5a7e5..1a67fecb6059a1 100644 --- a/app/javascript/mastodon/locales/en-GB.json +++ b/app/javascript/mastodon/locales/en-GB.json @@ -21,6 +21,7 @@ "account.blocked": "Blocked", "account.browse_more_on_origin_server": "Browse more on the original profile", "account.cancel_follow_request": "Cancel follow", + "account.copy": "Copy link to profile", "account.direct": "Privately mention @{name}", "account.disable_notifications": "Stop notifying me when @{name} posts", "account.domain_blocked": "Domain blocked", @@ -191,6 +192,7 @@ "conversation.mark_as_read": "Mark as read", "conversation.open": "View conversation", "conversation.with": "With {names}", + "copy_icon_button.copied": "Copied to clipboard", "copypaste.copied": "Copied", "copypaste.copy_to_clipboard": "Copy to clipboard", "directory.federated": "From known fediverse", @@ -222,6 +224,7 @@ "emoji_button.search_results": "Search results", "emoji_button.symbols": "Symbols", "emoji_button.travel": "Travel & Places", + "empty_column.account_hides_collections": "This user has chosen to not make this information available", "empty_column.account_suspended": "Account suspended", "empty_column.account_timeline": "No posts here!", "empty_column.account_unavailable": "Profile unavailable", @@ -478,6 +481,8 @@ "onboarding.follows.empty": "Unfortunately, no results can be shown right now. You can try using search or browsing the explore page to find people to follow, or try again later.", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Personalize your home feed", + "onboarding.profile.discoverable": "Make my profile discoverable", + "onboarding.profile.discoverable_hint": "When you opt in to discoverability on Mastodon, your posts may appear in search results and trending, and your profile may be suggested to people with similar interests to you.", "onboarding.profile.display_name": "Display name", "onboarding.profile.display_name_hint": "Your full name or your fun name…", "onboarding.profile.lead": "You can always complete this later in the settings, where even more customisation options are available.", @@ -530,6 +535,7 @@ "privacy.unlisted.short": "Unlisted", "privacy_policy.last_updated": "Last updated {date}", "privacy_policy.title": "Privacy Policy", + "recommended": "Recommended", "refresh": "Refresh", "regeneration_indicator.label": "Loading…", "regeneration_indicator.sublabel": "Your home feed is being prepared!", @@ -600,6 +606,7 @@ "search.quick_action.status_search": "Posts matching {x}", "search.search_or_paste": "Search or paste URL", "search_popout.full_text_search_disabled_message": "Unavailable on {domain}.", + "search_popout.full_text_search_logged_out_message": "Only available when logged in.", "search_popout.language_code": "ISO language code", "search_popout.options": "Search options", "search_popout.quick_actions": "Quick actions", diff --git a/app/javascript/mastodon/locales/eo.json b/app/javascript/mastodon/locales/eo.json index 537b8d0af1412f..2678d83a505419 100644 --- a/app/javascript/mastodon/locales/eo.json +++ b/app/javascript/mastodon/locales/eo.json @@ -21,6 +21,7 @@ "account.blocked": "Blokita", "account.browse_more_on_origin_server": "Foliumi pli ĉe la originala profilo", "account.cancel_follow_request": "Nuligi peton por sekvado", + "account.copy": "Kopii ligilon al profilo", "account.direct": "Private mencii @{name}", "account.disable_notifications": "Ne plu sciigi min, kiam @{name} mesaĝas", "account.domain_blocked": "Domajno blokita", @@ -191,6 +192,7 @@ "conversation.mark_as_read": "Marki legita", "conversation.open": "Vidi konversacion", "conversation.with": "Kun {names}", + "copy_icon_button.copied": "Kopiis al kliptabulo", "copypaste.copied": "Kopiita", "copypaste.copy_to_clipboard": "Kopii al dosierujo", "directory.federated": "El konata fediverso", @@ -202,7 +204,9 @@ "dismissable_banner.community_timeline": "Jen la plej novaj publikaj afiŝoj de uzantoj, kies kontojn gastigas {domain}.", "dismissable_banner.dismiss": "Eksigi", "dismissable_banner.explore_links": "Tiuj novaĵoj estas aktuale priparolataj de uzantoj en tiu ĉi kaj aliaj serviloj, sur la malcentrigita reto.", + "dismissable_banner.explore_statuses": "Ĉi tioj estas afiŝoj de socia reto kiu populariĝas hodiau.", "dismissable_banner.explore_tags": "Ĉi tiuj kradvostoj populariĝas en ĉi tiu kaj aliaj serviloj en la malcentraliza reto nun.", + "dismissable_banner.public_timeline": "Ĉi tioj estas plej lastaj publikaj afiŝoj de personoj ĉe socia reto kiu personoj ĉe {domain} sekvas.", "embed.instructions": "Enkorpigu ĉi tiun afiŝon en vian retejon per kopio de la suba kodo.", "embed.preview": "Ĝi aperos tiel:", "emoji_button.activity": "Agadoj", @@ -220,6 +224,7 @@ "emoji_button.search_results": "Serĉaj rezultoj", "emoji_button.symbols": "Simboloj", "emoji_button.travel": "Vojaĝoj kaj lokoj", + "empty_column.account_hides_collections": "Ĉi tiu uzanto elektis ne disponebligi ĉi tiu informon", "empty_column.account_suspended": "Konto suspendita", "empty_column.account_timeline": "Neniu afiŝo ĉi tie!", "empty_column.account_unavailable": "Profilo ne disponebla", @@ -229,6 +234,8 @@ "empty_column.direct": "Vi ankoraŭ ne havas privatan mencion. Kiam vi sendos aŭ ricevos iun, tiu aperos ĉi tie.", "empty_column.domain_blocks": "Ankoraŭ neniu domajno estas blokita.", "empty_column.explore_statuses": "Nenio tendencas nun. Rekontrolu poste!", + "empty_column.favourited_statuses": "Vi ankoraŭ ne havas stelumitan afiŝon.", + "empty_column.favourites": "Ankoraŭ neniu stelumis tiun afiŝon.", "empty_column.follow_requests": "Vi ne ankoraŭ havas iun peton de sekvado. Kiam vi ricevos unu, ĝi aperos ĉi tie.", "empty_column.followed_tags": "Vi ankoraŭ ne sekvas iujn kradvortojn. Kiam vi faras, ili aperos ĉi tie.", "empty_column.hashtag": "Ankoraŭ estas nenio per ĉi tiu kradvorto.", @@ -292,19 +299,36 @@ "hashtag.column_settings.tag_mode.any": "Iu ajn", "hashtag.column_settings.tag_mode.none": "Neniu", "hashtag.column_settings.tag_toggle": "Aldoni pliajn etikedojn por ĉi tiu kolumno", + "hashtag.counter_by_accounts": "{count, plural,one {{counter} partoprenanto} other {{counter} partoprenantoj}}", + "hashtag.counter_by_uses": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}}", + "hashtag.counter_by_uses_today": "{count, plural,one {{counter} afiŝo} other {{counter} afiŝoj}} hodiau", "hashtag.follow": "Sekvi la kradvorton", "hashtag.unfollow": "Ne plu sekvi la kradvorton", + "hashtags.and_other": "…kaj {count, plural,other {# pli}}", + "home.actions.go_to_explore": "Vidi kio populariĝas", "home.actions.go_to_suggestions": "Trovi homojn por sekvi", "home.column_settings.basic": "Bazaj agordoj", "home.column_settings.show_reblogs": "Montri diskonigojn", "home.column_settings.show_replies": "Montri respondojn", + "home.explore_prompt.body": "Via hejmafiŝaro havos miksitajn afiŝojn de kradvortoj kiujn vi elektis sekvi, personoj kiujn vi elektis sekvi, kaj afiŝoj kiujn ili suprenigis.", + "home.explore_prompt.title": "Ĉi tio estas via hejma paĝo en Mastodon.", "home.hide_announcements": "Kaŝi la anoncojn", + "home.pending_critical_update.body": "Ĝisdatigu vian servilon de Mastodon kiel eble plej baldau!", + "home.pending_critical_update.link": "Vidi ĝisdatigojn", + "home.pending_critical_update.title": "Kritika sekurĝisdatigo estas disponebla!", "home.show_announcements": "Montri anoncojn", + "interaction_modal.description.favourite": "Per konto ĉe Mastodon, vi povas stelumiti ĉi tiun afiŝon por sciigi la afiŝanton ke vi aprezigas ŝin kaj konservas por la estonteco.", "interaction_modal.description.follow": "Kun konto ĉe Mastodon, vi povos sekvi {name} por vidi ties mesaĝojn en via hejmo.", "interaction_modal.description.reblog": "Kun konto ĉe Mastodon, vi povas diskonigi ĉi tiun afiŝon, por ke viaj propraj sekvantoj vidu ĝin.", "interaction_modal.description.reply": "Kun konto ĉe Mastodon, vi povos respondi al ĉi tiu mesaĝo.", + "interaction_modal.login.action": "Prenu min hejmen", + "interaction_modal.login.prompt": "Domajno de via hejma servilo, ekz. mastodon.social", + "interaction_modal.no_account_yet": "Ĉu ne estas ĉe Mastodon?", "interaction_modal.on_another_server": "En alia servilo", "interaction_modal.on_this_server": "En ĉi tiu servilo", + "interaction_modal.sign_in": "Vi ne estas ensalutita al ĉi tiu servilo.", + "interaction_modal.sign_in_hint": "Gvideto: Tio estas la retejo kie vi registris. Vi ankau povas tajpi vian plenan uzantonomon!", + "interaction_modal.title.favourite": "Stelumi la afiŝon de {name}", "interaction_modal.title.follow": "Sekvi {name}", "interaction_modal.title.reblog": "Akceli la afiŝon de {name}", "interaction_modal.title.reply": "Respondi al la afiŝo de {name}", @@ -320,6 +344,8 @@ "keyboard_shortcuts.direct": "por malfermi la kolumnon pri privataj mencioj", "keyboard_shortcuts.down": "iri suben en la listo", "keyboard_shortcuts.enter": "malfermi mesaĝon", + "keyboard_shortcuts.favourite": "Stelumi afiŝon", + "keyboard_shortcuts.favourites": "Malfermi la liston de la stelumoj", "keyboard_shortcuts.federated": "Malfermi la frataran templinion", "keyboard_shortcuts.heading": "Klavaraj mallongigoj", "keyboard_shortcuts.home": "Malfermi la hejman templinion", @@ -366,6 +392,7 @@ "lists.search": "Serĉi inter la homoj, kiujn vi sekvas", "lists.subheading": "Viaj listoj", "load_pending": "{count,plural, one {# nova elemento} other {# novaj elementoj}}", + "loading_indicator.label": "Ŝargado…", "media_gallery.toggle_visible": "{number, plural, one {Kaŝi la bildon} other {Kaŝi la bildojn}}", "moved_to_account_banner.text": "Via konto {disabledAccount} estas malvalidigita ĉar vi movis ĝin al {movedToAccount}.", "mute_modal.duration": "Daŭro", @@ -382,6 +409,7 @@ "navigation_bar.domain_blocks": "Blokitaj domajnoj", "navigation_bar.edit_profile": "Redakti profilon", "navigation_bar.explore": "Esplori", + "navigation_bar.favourites": "Stelumoj", "navigation_bar.filters": "Silentigitaj vortoj", "navigation_bar.follow_requests": "Petoj de sekvado", "navigation_bar.followed_tags": "Sekvataj kradvortoj", @@ -389,6 +417,7 @@ "navigation_bar.lists": "Listoj", "navigation_bar.logout": "Adiaŭi", "navigation_bar.mutes": "Silentigitaj uzantoj", + "navigation_bar.opened_in_classic_interface": "Afiŝoj, kontoj, kaj aliaj specifaj paĝoj kiuj estas malfermititaj defaulta en la klasika reta interfaco.", "navigation_bar.personal": "Persone", "navigation_bar.pins": "Alpinglitaj mesaĝoj", "navigation_bar.preferences": "Preferoj", @@ -398,6 +427,7 @@ "not_signed_in_indicator.not_signed_in": "Necesas saluti por aliri tiun rimedon.", "notification.admin.report": "{name} raportis {target}", "notification.admin.sign_up": "{name} kreis konton", + "notification.favourite": "{name} stelumis vian afiŝon", "notification.follow": "{name} eksekvis vin", "notification.follow_request": "{name} petis sekvi vin", "notification.mention": "{name} menciis vin", @@ -411,6 +441,7 @@ "notifications.column_settings.admin.report": "Novaj raportoj:", "notifications.column_settings.admin.sign_up": "Novaj registriĝoj:", "notifications.column_settings.alert": "Sciigoj de la retumilo", + "notifications.column_settings.favourite": "Stelumoj:", "notifications.column_settings.filter_bar.advanced": "Montri ĉiujn kategoriojn", "notifications.column_settings.filter_bar.category": "Rapida filtra breto", "notifications.column_settings.filter_bar.show_bar": "Montri la breton de filtrilo", @@ -428,6 +459,7 @@ "notifications.column_settings.update": "Redaktoj:", "notifications.filter.all": "Ĉiuj", "notifications.filter.boosts": "Diskonigoj", + "notifications.filter.favourites": "Stelumoj", "notifications.filter.follows": "Sekvoj", "notifications.filter.mentions": "Mencioj", "notifications.filter.polls": "Balotenketaj rezultoj", @@ -441,14 +473,29 @@ "notifications_permission_banner.enable": "Ŝalti retumilajn sciigojn", "notifications_permission_banner.how_to_control": "Por ricevi sciigojn kiam Mastodon ne estas malfermita, ebligu labortablajn sciigojn. Vi povas regi precize kiuj specoj de interagoj generas labortablajn sciigojn per la supra butono {icon} post kiam ili estas ebligitaj.", "notifications_permission_banner.title": "Neniam preterlasas iun ajn", + "onboarding.action.back": "Prenu min reen", + "onboarding.actions.back": "Prenu min reen", "onboarding.actions.go_to_explore": "See what's trending", "onboarding.actions.go_to_home": "Go to your home feed", "onboarding.compose.template": "Saluton #Mastodon!", "onboarding.follows.empty": "Bedaŭrinde, neniu rezulto estas montrebla nuntempe. Vi povas provi serĉi aŭ foliumi la esploran paĝon por trovi kontojn por sekvi, aŭ retrovi baldaŭ.", "onboarding.follows.lead": "You curate your own home feed. The more people you follow, the more active and interesting it will be. These profiles may be a good starting point—you can always unfollow them later!", "onboarding.follows.title": "Popular on Mastodon", + "onboarding.profile.discoverable": "Trovebligi mian profilon", + "onboarding.profile.discoverable_hint": "Kiam vi aliĝi al trovebleco ĉe Mastodon, viaj afiŝoj eble aperos en serĉaj rezultoj kaj populariĝoj, kaj via profilo eble estas sugestota al personoj kun similaj intereseoj al vi.", + "onboarding.profile.display_name": "Publika nomo", + "onboarding.profile.display_name_hint": "Via plena nomo aŭ via kromnomo…", + "onboarding.profile.lead": "Vi ĉiam povas plenigi ĉi tion poste en la agordoj, kie eĉ pli da personecigagordoj estas disponeblaj.", + "onboarding.profile.note": "Sinprezento", + "onboarding.profile.note_hint": "Vi povas @mencii aliajn homojn aŭ #kradvortojn…", "onboarding.profile.save_and_continue": "Konservi kaj daŭrigi", + "onboarding.profile.title": "Profila fikso", + "onboarding.profile.upload_avatar": "Alŝuti profilbildon", + "onboarding.profile.upload_header": "Alŝuti profilkapbildon", + "onboarding.share.lead": "Sciigi personojn pri kiel ili povas trovi vin ĉe Mastodon!", "onboarding.share.message": "Mi estas {username} en #Mastodon! Sekvu min ĉe {url}", + "onboarding.share.next_steps": "Eblaj malantauaj paŝoj:", + "onboarding.share.title": "Disvastigi vian profilon", "onboarding.start.lead": "Your new Mastodon account is ready to go. Here's how you can make the most of it:", "onboarding.start.skip": "Want to skip right ahead?", "onboarding.start.title": "Vi atingas ĝin!", @@ -460,6 +507,9 @@ "onboarding.steps.setup_profile.title": "Customize your profile", "onboarding.steps.share_profile.body": "Let your friends know how to find you on Mastodon!", "onboarding.steps.share_profile.title": "Share your profile", + "onboarding.tips.2fa": "Ĉu vi scias? Vi povas sekurigi vian konton per efektivigi dufaktora autentigo en via kontoagordoj.", + "onboarding.tips.accounts_from_other_servers": "Ĉu vi scias? Ĉar Mastodon estas sencentra, kelkaj profiloj kiujn vi trovi estas gastigitaj ĉe aliaj serviloj kiuj ne estas via.", + "onboarding.tips.migration": "Ĉu vi scias? Se vi sentas ke {domain} ne estas bona servilelekto por vi en la estonteco, vi povas translokiĝi al alia servilo de Mastodon sen malgajni viajn sekvantojn.", "password_confirmation.mismatching": "Pasvorto konfirmo ne kongruas", "picture_in_picture.restore": "Remetu ĝin", "poll.closed": "Finita", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index 5b76cd67c5a8fb..4606916c1dde22 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -239,7 +239,7 @@ "empty_column.follow_requests": "아직 팔로우 요청이 없습니다. 요청을 받았을 때 여기에 나타납니다.", "empty_column.followed_tags": "아직 아무 해시태그도 팔로우하고 있지 않습니다. 해시태그를 팔로우하면, 여기에 표시됩니다.", "empty_column.hashtag": "이 해시태그는 아직 사용되지 않았습니다.", - "empty_column.home": "당신의 홈 타임라인은 비어있습니다! 더 많은 사람들을 팔로우 하여 채워보세요. {suggestions}", + "empty_column.home": "당신의 홈 타임라인은 비어있습니다! 더 많은 사람을 팔로우하여 채워보세요. {suggestions}", "empty_column.list": "리스트에 아직 아무것도 없습니다. 리스트의 누군가가 게시물을 올리면 여기에 나타납니다.", "empty_column.lists": "아직 리스트가 없습니다. 리스트를 만들면 여기에 나타납니다.", "empty_column.mutes": "아직 아무도 뮤트하지 않았습니다.", diff --git a/app/javascript/mastodon/locales/la.json b/app/javascript/mastodon/locales/la.json index e4bd9365a87c74..3e5747ba8ba5a1 100644 --- a/app/javascript/mastodon/locales/la.json +++ b/app/javascript/mastodon/locales/la.json @@ -1,6 +1,6 @@ { "about.contact": "Ratio:", - "about.domain_blocks.no_reason_available": "ratio abdere est", + "about.domain_blocks.no_reason_available": "Ratio abdere est", "account.account_note_header": "Annotatio", "account.badges.bot": "Robotum", "account.badges.group": "Congregatio", @@ -49,7 +49,7 @@ "dismissable_banner.explore_links": "These news stories are being talked about by people on this and other servers of the decentralized network right now.", "dismissable_banner.explore_tags": "These hashtags are gaining traction among people on this and other servers of the decentralized network right now.", "embed.instructions": "Embed this status on your website by copying the code below.", - "emoji_button.food": "cibus et potus", + "emoji_button.food": "Cibus et potus", "emoji_button.people": "Homines", "emoji_button.search": "Quaerere...", "empty_column.account_timeline": "Hic nulla contributa!", @@ -57,13 +57,13 @@ "empty_column.home": "Your home timeline is empty! Follow more people to fill it up. {suggestions}", "empty_column.list": "There is nothing in this list yet. When members of this list post new statuses, they will appear here.", "explore.trending_statuses": "Contributa", - "generic.saved": "servavit", + "generic.saved": "Servavit", "hashtag.column_settings.tag_toggle": "Include additional tags in this column", - "keyboard_shortcuts.back": "to navigate back", - "keyboard_shortcuts.blocked": "to open blocked users list", - "keyboard_shortcuts.boost": "to boost", - "keyboard_shortcuts.column": "to focus a status in one of the columns", - "keyboard_shortcuts.compose": "to focus the compose textarea", + "keyboard_shortcuts.back": "Re navigare", + "keyboard_shortcuts.blocked": "Aperire listam usorum obstructorum", + "keyboard_shortcuts.boost": "Inlustrare publicatio", + "keyboard_shortcuts.column": "Columnam dirigere", + "keyboard_shortcuts.compose": "TextArea Compositi Attendere", "keyboard_shortcuts.description": "Descriptio", "keyboard_shortcuts.direct": "to open direct messages column", "keyboard_shortcuts.down": "to move down in the list", diff --git a/app/javascript/mastodon/locales/ne.json b/app/javascript/mastodon/locales/ne.json index 0967ef424bce67..95f8e703c96c3a 100644 --- a/app/javascript/mastodon/locales/ne.json +++ b/app/javascript/mastodon/locales/ne.json @@ -1 +1,53 @@ -{} +{ + "about.contact": "सम्पर्क:", + "about.disclaimer": "Mastodon नि:शुल्क, खुला स्रोत सफ्टवेयर, र Mastodon gGmbH को ट्रेडमार्क हो।", + "about.domain_blocks.no_reason_available": "कारण उपलब्ध छैन", + "about.domain_blocks.preamble": "Mastodon ले तपाइँलाई सामान्यतया फेडिभर्समा कुनै पनि अन्य सर्भरका सामग्री हेर्न र प्रयोगकर्ताहरूसँग अन्तरक्रिया गर्न दिन्छ। यी अपवादहरू हुन् जुन यस विशेष सर्भरमा बनाइएका छन्।", + "about.domain_blocks.silenced.title": "सीमित", + "about.domain_blocks.suspended.explanation": "यस सर्भरबाट कुनै पनि डेटा प्रशोधन, भण्डारण वा आदानप्रदान गरिने छैन, जसले यस सर्भरका प्रयोगकर्ताहरूसँग कुनै पनि अन्तरक्रिया वा सञ्चारलाई असम्भव बनाउँछ।", + "about.domain_blocks.suspended.title": "निलम्बित", + "about.not_available": "यो जानकारी यस सर्भरमा उपलब्ध गराइएको छैन।", + "about.powered_by": "{mastodon} द्वारा संचालित विकेन्द्रीकृत सामाजिक मिडिया", + "about.rules": "सर्भर नियमहरू", + "account.add_or_remove_from_list": "सूचीबाट थप्नुहोस् वा हटाउनुहोस्", + "account.badges.group": "समूह", + "account.block": "@{name} लाई ब्लक गर्नुहोस्", + "account.block_domain": "{domain} डोमेनलाई ब्लक गर्नुहोस्", + "account.block_short": "ब्लक", + "account.blocked": "ब्लक गरिएको", + "account.browse_more_on_origin_server": "मूल प्रोफाइलमा थप ब्राउज गर्नुहोस्", + "account.cancel_follow_request": "फलो अनुरोध रद्द गर्नुहोस", + "account.copy": "प्रोफाइलको लिङ्क प्रतिलिपि गर्नुहोस्", + "account.direct": "@{name} लाई निजी रूपमा उल्लेख गर्नुहोस्", + "account.disable_notifications": "@{name} ले पोस्ट गर्दा मलाई सूचित नगर्नुहोस्", + "account.domain_blocked": "डोमेन ब्लक गरिएको छ", + "account.edit_profile": "प्रोफाइल सम्पादन गर्नुहोस्", + "account.enable_notifications": "@{name} ले पोस्ट गर्दा मलाई सूचित गर्नुहोस्", + "account.endorse": "प्रोफाइलमा फिचर गर्नुहोस्", + "account.featured_tags.last_status_never": "कुनै पोस्ट छैन", + "account.follow": "फलो गर्नुहोस", + "account.followers.empty": "यस प्रयोगकर्तालाई अहिलेसम्म कसैले फलो गर्दैन।", + "account.follows.empty": "यो प्रयोगकर्ताले अहिलेसम्म कसैलाई फलो गरेको छैन।", + "account.go_to_profile": "प्रोफाइलमा जानुहोस्", + "account.hide_reblogs": "@{name} को बूस्टहरू लुकाउनुहोस्", + "account.link_verified_on": "यस लिङ्कको स्वामित्व {date} मा जाँच गरिएको थियो", + "account.media": "मिडिया", + "account.mention": "@{name} लाई उल्लेख गर्नुहोस्", + "account.no_bio": "कुनै विवरण प्रदान गरिएको छैन।", + "account.posts": "पोस्टहरू", + "account.requested": "स्वीकृतिको पर्खाइमा। फलो अनुरोध रद्द गर्न क्लिक गर्नुहोस्", + "account.requested_follow": "{name} ले तपाईंलाई फलो गर्न अनुरोध गर्नुभएको छ", + "account.share": "@{name} को प्रोफाइल सेयर गर्नुहोस्", + "account.show_reblogs": "@{name} को बूस्टहरू देखाउनुहोस्", + "account.statuses_counter": "{count, plural, one {{counter} पोस्ट} other {{counter} पोस्टहरू}}", + "account.unblock": "@{name} लाई अनब्लक गर्नुहोस्", + "account.unblock_domain": "{domain} डोमेनलाई अनब्लक गर्नुहोस्", + "account.unblock_short": "अनब्लक गर्नुहोस्", + "account.unendorse": "प्रोफाइलमा फिचर नगर्नुहोस्", + "account.unfollow": "अनफलो गर्नुहोस्", + "account_note.placeholder": "नोट लेख्न क्लिक गर्नुहोस्", + "admin.dashboard.retention.average": "औसत", + "admin.dashboard.retention.cohort_size": "नयाँ प्रयोगकर्ताहरू", + "alert.rate_limited.message": "कृपया {retry_time, time, medium} पछि पुन: प्रयास गर्नुहोस्।", + "alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।" +} diff --git a/app/javascript/mastodon/locales/sk.json b/app/javascript/mastodon/locales/sk.json index c4ce6f8cfdbabe..46fcc01160b986 100644 --- a/app/javascript/mastodon/locales/sk.json +++ b/app/javascript/mastodon/locales/sk.json @@ -224,6 +224,7 @@ "emoji_button.search_results": "Výsledky hľadania", "emoji_button.symbols": "Symboly", "emoji_button.travel": "Cestovanie a miesta", + "empty_column.account_hides_collections": "Tento užívateľ si zvolil nesprístupniť túto informáciu", "empty_column.account_suspended": "Účet bol pozastavený", "empty_column.account_timeline": "Nie sú tu žiadne príspevky!", "empty_column.account_unavailable": "Profil nedostupný", diff --git a/config/locales/activerecord.hr.yml b/config/locales/activerecord.hr.yml index b095244dd6bc8a..a3e7d6d49289e8 100644 --- a/config/locales/activerecord.hr.yml +++ b/config/locales/activerecord.hr.yml @@ -6,7 +6,9 @@ hr: expires_at: Krajnji rok options: Opcije user: + agreement: Ugovor o uslugama email: E-mail adresa + locale: Lokalitet password: Lozinka user/account: username: Korisničko ime @@ -18,3 +20,16 @@ hr: attributes: username: invalid: mora sadržavati samo slova, brojeve i _ + reserved: je rezervisano + admin/webhook: + attributes: + url: + invalid: nije validan URL + doorkeeper/application: + attributes: + website: + invalid: nije validan URL + import: + attributes: + data: + malformed: je neispravan diff --git a/config/locales/activerecord.ru.yml b/config/locales/activerecord.ru.yml index 14f9f61f6cd54b..92d85af4d9d28d 100644 --- a/config/locales/activerecord.ru.yml +++ b/config/locales/activerecord.ru.yml @@ -36,7 +36,7 @@ ru: status: attributes: reblog: - taken: поста уже существует + taken: пост уже существует user: attributes: email: diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index 987788a7ade5d1..a6e74c4836da50 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -534,6 +534,7 @@ en-GB: total_reported: Reports about them total_storage: Media attachments totals_time_period_hint_html: The totals displayed below include data for all time. + unknown_instance: There is currently no record of this domain on this server. invites: deactivate_all: Deactivate all filter: @@ -610,6 +611,7 @@ en-GB: created_at: Reported delete_and_resolve: Delete posts forwarded: Forwarded + forwarded_replies_explanation: This report is from a remote user and about remote content. It has been forwarded to you because the reported content is in reply to one of your users. forwarded_to: Forwarded to %{domain} mark_as_resolved: Mark as resolved mark_as_sensitive: Mark as sensitive @@ -1038,6 +1040,14 @@ en-GB: hint_html: Just one more thing! We need to confirm you're a human (this is so we can keep the spam out!). Solve the CAPTCHA below and click "Continue". title: Security check confirmations: + awaiting_review: Your e-mail address is confirmed! The %{domain} staff is now reviewing your registration. You will receive an e-mail if they approve your account! + awaiting_review_title: Your registration is being reviewed + clicking_this_link: clicking this link + login_link: log in + proceed_to_login_html: You can now proceed to %{login_link}. + redirect_to_app_html: You should have been redirected to the %{app_name} app. If that did not happen, try %{clicking_this_link} or manually return to the app. + registration_complete: Your registration on %{domain} is now complete! + welcome_title: Welcome, %{name}! wrong_email_hint: If that e-mail address is not correct, you can change it in account settings. delete_account: Delete account delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation. @@ -1099,6 +1109,7 @@ en-GB: functional: Your account is fully operational. pending: Your application is pending review by our staff. This may take some time. You will receive an e-mail if your application is approved. redirecting_to: Your account is inactive because it is currently redirecting to %{acct}. + self_destruct: As %{domain} is closing down, you will only get limited access to your account. view_strikes: View past strikes against your account too_fast: Form submitted too fast, try again. use_security_key: Use security key @@ -1356,6 +1367,7 @@ en-GB: '86400': 1 day expires_in_prompt: Never generate: Generate invite link + invalid: This invite is not valid invited_by: 'You were invited by:' max_uses: one: 1 use @@ -1568,6 +1580,9 @@ en-GB: over_daily_limit: You have exceeded the limit of %{limit} scheduled posts for today over_total_limit: You have exceeded the limit of %{limit} scheduled posts too_soon: The scheduled date must be in the future + self_destruct: + lead_html: Unfortunately, %{domain} is permanently closing down. If you had an account there, you will not be able to continue using it, but you can still request a backup of your data. + title: This server is closing down sessions: activity: Last activity browser: Browser @@ -1736,6 +1751,7 @@ en-GB: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%b %d, %Y, %H:%M %Z" translation: errors: quota_exceeded: The server-wide usage quota for the translation service has been exceeded. diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 63779e5bd5a23b..caf253c69c03b3 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -656,6 +656,10 @@ sk: rules_check: action: Spravuj serverové pravidlá message_html: Neurčil/a si žiadne serverové pravidlá. + software_version_critical_check: + action: Pozri dostupné aktualizácie + software_version_patch_check: + action: Pozri dostupné aktualizácie upload_check_privacy_error: action: Pozri tu pre viac informácií upload_check_privacy_error_object_storage: From 4ad2e87c48f8ebdeeb6eab56dc195b9e28f7a5d2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 09:45:30 +0100 Subject: [PATCH 20/40] Update dependency debug to v1.9.0 (#28315) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 738bc7b8bc1b18..4b39692d031222 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -220,9 +220,9 @@ GEM database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) date (3.3.4) - debug (1.8.0) - irb (>= 1.5.0) - reline (>= 0.3.1) + debug (1.9.0) + irb (~> 1.10) + reline (>= 0.3.8) debug_inspector (1.1.0) devise (4.9.3) bcrypt (~> 3.0) From b5a1013ae36a0ab495aa727a397b9fc9f4340a2c Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 05:23:45 -0500 Subject: [PATCH 21/40] Combine `CLI::...` spec example subjects (#28285) --- spec/lib/mastodon/cli/accounts_spec.rb | 259 ++++++++---------------- spec/lib/mastodon/cli/ip_blocks_spec.rb | 87 ++++---- spec/lib/mastodon/cli/settings_spec.rb | 37 ++-- 3 files changed, 135 insertions(+), 248 deletions(-) diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb index 06860c2ff86ffd..563f6e877d4a3b 100644 --- a/spec/lib/mastodon/cli/accounts_spec.rb +++ b/spec/lib/mastodon/cli/accounts_spec.rb @@ -34,23 +34,21 @@ def stub_parallelize_with_progress! let(:action) { :create } shared_examples 'a new user with given email address and username' do - it 'creates a new user with the specified email address' do - subject + it 'creates user and accounts from options and displays success message' do + allow(SecureRandom).to receive(:hex).and_return('test_password') - expect(User.find_by(email: options[:email])).to be_present + expect { subject } + .to output_results('OK', 'New password: test_password') + expect(user_from_options).to be_present + expect(account_from_options).to be_present end - it 'creates a new local account with the specified username' do - subject - - expect(Account.find_local('tootctl_username')).to be_present + def user_from_options + User.find_by(email: options[:email]) end - it 'returns "OK" and newly generated password' do - allow(SecureRandom).to receive(:hex).and_return('test_password') - - expect { subject } - .to output_results("OK\nNew password: test_password") + def account_from_options + Account.find_local('tootctl_username') end end @@ -199,14 +197,9 @@ def stub_parallelize_with_progress! let(:arguments) { [user.account.username] } context 'when no option is provided' do - it 'returns a successful message' do + it 'returns a successful message and preserves user' do expect { subject } .to output_results('OK') - end - - it 'does not modify the user' do - subject - expect(user).to eq(user.reload) end end @@ -400,15 +393,10 @@ def stub_parallelize_with_progress! context 'with --dry-run option' do let(:options) { { dry_run: true } } - it 'does not delete the specified user' do - subject - - expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false) - end - - it 'outputs a successful message in dry run mode' do + it 'outputs a successful message in dry run mode and does not delete the user' do expect { subject } .to output_results('OK (DRY RUN)') + expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false) end end @@ -435,15 +423,12 @@ def stub_parallelize_with_progress! context 'with --dry-run option' do let(:options) { { email: account.user.email, dry_run: true } } - it 'does not delete the user' do - subject - - expect(delete_account_service).to_not have_received(:call).with(account, reserve_email: false) - end - - it 'outputs a successful message in dry run mode' do + it 'outputs a successful message in dry run mode and does not delete the user' do expect { subject } .to output_results('OK (DRY RUN)') + expect(delete_account_service) + .to_not have_received(:call) + .with(account, reserve_email: false) end end @@ -482,20 +467,19 @@ def stub_parallelize_with_progress! context 'when the number is positive' do let(:options) { { number: 2 } } - it 'approves the earliest n pending registrations' do + it 'approves the earliest n pending registrations but not the remaining ones' do subject - n_earliest_pending_registrations = User.order(created_at: :asc).first(options[:number]) - expect(n_earliest_pending_registrations.all?(&:approved?)).to be(true) + expect(pending_registrations.all?(&:approved?)).to be(false) end - it 'does not approve the remaining pending registrations' do - subject - - pending_registrations = User.order(created_at: :asc).last(total_users - options[:number]) + def n_earliest_pending_registrations + User.order(created_at: :asc).first(options[:number]) + end - expect(pending_registrations.all?(&:approved?)).to be(false) + def pending_registrations + User.order(created_at: :asc).last(total_users - options[:number]) end end @@ -512,15 +496,10 @@ def stub_parallelize_with_progress! context 'when the given number is greater than the number of users' do let(:options) { { number: total_users * 2 } } - it 'approves all users' do - subject - - expect(User.pluck(:approved).all?(true)).to be(true) - end - - it 'does not raise any error' do + it 'approves all users and does not raise any error' do expect { subject } .to_not raise_error + expect(User.pluck(:approved).all?(true)).to be(true) end end end @@ -575,18 +554,13 @@ def stub_parallelize_with_progress! stub_parallelize_with_progress! end - it 'makes all local accounts follow the target account' do - subject - + it 'displays a successful message and makes all local accounts follow the target account' do + expect { subject } + .to output_results("OK, followed target from #{Account.local.count} accounts") expect(follow_service).to have_received(:call).with(follower_bob, target_account, any_args).once expect(follow_service).to have_received(:call).with(follower_rony, target_account, any_args).once expect(follow_service).to have_received(:call).with(follower_charles, target_account, any_args).once end - - it 'displays a successful message' do - expect { subject } - .to output_results("OK, followed target from #{Account.local.count} accounts") - end end end @@ -618,18 +592,13 @@ def stub_parallelize_with_progress! stub_parallelize_with_progress! end - it 'makes all local accounts unfollow the target account' do - subject - + it 'displays a successful message and makes all local accounts unfollow the target account' do + expect { subject } + .to output_results('OK, unfollowed target from 3 accounts') expect(unfollow_service).to have_received(:call).with(follower_chris, target_account).once expect(unfollow_service).to have_received(:call).with(follower_rambo, target_account).once expect(unfollow_service).to have_received(:call).with(follower_ana, target_account).once end - - it 'displays a successful message' do - expect { subject } - .to output_results('OK, unfollowed target from 3 accounts') - end end end @@ -651,22 +620,17 @@ def stub_parallelize_with_progress! let(:user) { account.user } let(:arguments) { [account.username] } - it 'creates a new backup for the specified user' do - expect { subject }.to change { user.backups.count }.by(1) - end - - it 'creates a backup job' do - allow(BackupWorker).to receive(:perform_async) - - subject - latest_backup = user.backups.last + before { allow(BackupWorker).to receive(:perform_async) } + it 'creates a new backup and backup job for the specified user and outputs success message' do + expect { subject } + .to change { user.backups.count }.by(1) + .and output_results('OK') expect(BackupWorker).to have_received(:perform_async).with(latest_backup.id).once end - it 'displays a successful message' do - expect { subject } - .to output_results('OK') + def latest_backup + user.backups.last end end end @@ -963,15 +927,15 @@ def stub_parallelize_with_progress! expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_in).with(anything, account.id, anything).once end + end - context 'when the given username is not found' do - let(:arguments) { ['non_existent_username'] } + context 'when the given username is not found' do + let(:arguments) { ['non_existent_username'] } - it 'exits with an error message when the specified username is not found' do - expect { subject } - .to output_results('No such account') - .and raise_error(SystemExit) - end + it 'exits with an error message when the specified username is not found' do + expect { subject } + .to output_results('No such account') + .and raise_error(SystemExit) end end @@ -1071,15 +1035,10 @@ def stub_parallelize_with_progress! allow(from_account).to receive(:destroy) end - it 'merges "from_account" into "to_account"' do + it 'merges `from_account` into `to_account` and deletes `from_account`' do subject expect(to_account).to have_received(:merge_with!).with(from_account).once - end - - it 'deletes "from_account"' do - subject - expect(from_account).to have_received(:destroy).once end end @@ -1099,15 +1058,10 @@ def stub_parallelize_with_progress! allow(from_account).to receive(:destroy) end - it 'merges "from_account" into "to_account"' do + it 'merges "from_account" into "to_account" and deletes from_account' do subject expect(to_account).to have_received(:merge_with!).with(from_account).once - end - - it 'deletes "from_account"' do - subject - expect(from_account).to have_received(:destroy) end end @@ -1134,28 +1088,23 @@ def stub_parallelize_with_progress! stub_request(:head, 'https://example.net/users/tales').to_return(status: 200) end - it 'deletes all inactive remote accounts that longer exist in the origin server' do - subject - + def expect_delete_inactive_remote_accounts expect(delete_account_service).to have_received(:call).with(bob, reserve_username: false).once expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once end - it 'does not delete any active remote account that still exists in the origin server' do - subject - + def expect_not_delete_active_accounts expect(delete_account_service).to_not have_received(:call).with(tom, reserve_username: false) expect(delete_account_service).to_not have_received(:call).with(ana, reserve_username: false) expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false) end - it 'touches inactive remote accounts that have not been deleted' do - expect { subject }.to(change { tales.reload.updated_at }) - end - - it 'displays the summary correctly' do + it 'touches inactive remote accounts that have not been deleted and summarizes activity' do expect { subject } - .to output_results('Visited 5 accounts, removed 2') + .to change { tales.reload.updated_at } + .and output_results('Visited 5 accounts, removed 2') + expect_delete_inactive_remote_accounts + expect_not_delete_active_accounts end end @@ -1168,16 +1117,15 @@ def stub_parallelize_with_progress! stub_request(:head, 'https://example.net/users/tales').to_return(status: 404) end - it 'deletes inactive remote accounts that longer exist in the specified domain' do - subject - + def expect_delete_inactive_remote_accounts expect(delete_account_service).to have_received(:call).with(gon, reserve_username: false).once expect(delete_account_service).to have_received(:call).with(tales, reserve_username: false).once end - it 'displays the summary correctly' do + it 'displays the summary correctly and deletes inactive remote accounts' do expect { subject } .to output_results('Visited 2 accounts, removed 2') + expect_delete_inactive_remote_accounts end end @@ -1189,15 +1137,14 @@ def stub_parallelize_with_progress! stub_request(:head, 'https://example.net/users/gon').to_return(status: 200) end - it 'skips accounts from the unavailable domain' do - subject - + def expect_skip_accounts_from_unavailable_domain expect(delete_account_service).to_not have_received(:call).with(tales, reserve_username: false) end - it 'displays the summary correctly' do + it 'displays the summary correctly and skip accounts from unavailable domains' do expect { subject } .to output_results("Visited 5 accounts, removed 0\nThe following domains were not available during the check:\n example.net") + expect_skip_accounts_from_unavailable_domain end end @@ -1268,25 +1215,14 @@ def stub_parallelize_with_progress! before do accounts.each { |account| target_account.follow!(account) } - end - - it 'resets all "following" relationships from the target account' do - subject - - expect(target_account.reload.following).to be_empty - end - - it 'calls BootstrapTimelineWorker once to rebuild the timeline' do allow(BootstrapTimelineWorker).to receive(:perform_async) - - subject - - expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once end - it 'displays a successful message' do + it 'resets following relationships and displays a successful message and rebuilds timeline' do expect { subject } .to output_results("Processed #{total_relationships} relationships") + expect(target_account.reload.following).to be_empty + expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once end end @@ -1297,15 +1233,10 @@ def stub_parallelize_with_progress! accounts.each { |account| account.follow!(target_account) } end - it 'resets all "followers" relationships from the target account' do - subject - - expect(target_account.reload.followers).to be_empty - end - - it 'displays a successful message' do + it 'resets followers relationships and displays a successful message' do expect { subject } .to output_results("Processed #{total_relationships} relationships") + expect(target_account.reload.followers).to be_empty end end @@ -1315,31 +1246,15 @@ def stub_parallelize_with_progress! before do accounts.first(2).each { |account| account.follow!(target_account) } accounts.last(1).each { |account| target_account.follow!(account) } - end - - it 'resets all "followers" relationships from the target account' do - subject - - expect(target_account.reload.followers).to be_empty - end - - it 'resets all "following" relationships from the target account' do - subject - - expect(target_account.reload.following).to be_empty - end - - it 'calls BootstrapTimelineWorker once to rebuild the timeline' do allow(BootstrapTimelineWorker).to receive(:perform_async) - - subject - - expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once end - it 'displays a successful message' do + it 'resets followers and following and displays a successful message and rebuilds timeline' do expect { subject } .to output_results("Processed #{total_relationships} relationships") + expect(target_account.reload.followers).to be_empty + expect(target_account.reload.following).to be_empty + expect(BootstrapTimelineWorker).to have_received(:perform_async).with(target_account.id).once end end end @@ -1360,57 +1275,51 @@ def stub_parallelize_with_progress! stub_parallelize_with_progress! end - it 'prunes all remote accounts with no interactions with local users' do - subject - + def expect_prune_remote_accounts_without_interaction prunable_account_ids = prunable_accounts.pluck(:id) expect(Account.where(id: prunable_account_ids).count).to eq(0) end - it 'displays a successful message' do + it 'displays a successful message and handles accounts correctly' do expect { subject } .to output_results("OK, pruned #{prunable_accounts.size} accounts") + expect_prune_remote_accounts_without_interaction + expect_not_prune_local_accounts + expect_not_prune_bot_accounts + expect_not_prune_group_accounts + expect_not_prune_mentioned_accounts end - it 'does not prune local accounts' do - subject - + def expect_not_prune_local_accounts expect(Account.exists?(id: local_account.id)).to be(true) end - it 'does not prune bot accounts' do - subject - + def expect_not_prune_bot_accounts expect(Account.exists?(id: bot_account.id)).to be(true) end - it 'does not prune group accounts' do - subject - + def expect_not_prune_group_accounts expect(Account.exists?(id: group_account.id)).to be(true) end - it 'does not prune accounts that have been mentioned' do - subject - + def expect_not_prune_mentioned_accounts expect(Account.exists?(id: mentioned_account.id)).to be true end context 'with --dry-run option' do let(:options) { { dry_run: true } } - it 'does not prune any account' do - subject - + def expect_no_account_prunes prunable_account_ids = prunable_accounts.pluck(:id) expect(Account.where(id: prunable_account_ids).count).to eq(prunable_accounts.size) end - it 'displays a successful message with (DRY RUN)' do + it 'displays a successful message with (DRY RUN) and doesnt prune anything' do expect { subject } .to output_results("OK, pruned #{prunable_accounts.size} accounts (DRY RUN)") + expect_no_account_prunes end end end diff --git a/spec/lib/mastodon/cli/ip_blocks_spec.rb b/spec/lib/mastodon/cli/ip_blocks_spec.rb index dc967a69c97be7..1d6c47268e65f2 100644 --- a/spec/lib/mastodon/cli/ip_blocks_spec.rb +++ b/spec/lib/mastodon/cli/ip_blocks_spec.rb @@ -33,26 +33,25 @@ let(:arguments) { ip_list } shared_examples 'ip address blocking' do - it 'blocks all specified IP addresses' do - subject - - blocked_ip_addresses = IpBlock.where(ip: ip_list).pluck(:ip) - expected_ip_addresses = ip_list.map { |ip| IPAddr.new(ip) } - - expect(blocked_ip_addresses).to match_array(expected_ip_addresses) + def blocked_ip_addresses + IpBlock.where(ip: ip_list).pluck(:ip) end - it 'sets the severity for all blocked IP addresses' do - subject - - blocked_ips_severity = IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity]) + def expected_ip_addresses + ip_list.map { |ip| IPAddr.new(ip) } + end - expect(blocked_ips_severity).to be(true) + def blocked_ips_severity + IpBlock.where(ip: ip_list).pluck(:severity).all?(options[:severity]) end - it 'displays a success message with a summary' do + it 'blocks and sets severity for ip address and displays summary' do expect { subject } .to output_results("Added #{ip_list.size}, skipped 0, failed 0") + expect(blocked_ip_addresses) + .to match_array(expected_ip_addresses) + expect(blocked_ips_severity) + .to be(true) end end @@ -64,17 +63,13 @@ let!(:blocked_ip) { IpBlock.create(ip: ip_list.last, severity: options[:severity]) } let(:arguments) { ip_list } - it 'skips the already blocked IP address' do - allow(IpBlock).to receive(:new).and_call_original - - subject - - expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last) - end + before { allow(IpBlock).to receive(:new).and_call_original } - it 'displays the correct summary' do + it 'skips already block ip and displays the correct summary' do expect { subject } .to output_results("#{ip_list.last} is already blocked\nAdded #{ip_list.size - 1}, skipped 1, failed 0") + + expect(IpBlock).to_not have_received(:new).with(ip: ip_list.last) end context 'with --force option' do @@ -179,15 +174,10 @@ ip_list.each { |ip| IpBlock.create(ip: ip, severity: :no_access) } end - it 'removes exact IP blocks' do - subject - - expect(IpBlock.where(ip: ip_list)).to_not exist - end - - it 'displays success message with a summary' do + it 'removes exact ip blocks and displays success message with a summary' do expect { subject } .to output_results("Removed #{ip_list.size}, skipped 0") + expect(IpBlock.where(ip: ip_list)).to_not exist end end @@ -198,16 +188,19 @@ let(:arguments) { ['192.168.0.5', '10.0.1.50'] } let(:options) { { force: true } } - it 'removes blocks for IP ranges that cover given IP(s)' do + it 'removes blocks for IP ranges that cover given IP(s) and keeps other ranges' do subject - expect(IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id])).to_not exist + expect(covered_ranges).to_not exist + expect(other_ranges).to exist end - it 'does not remove other IP ranges' do - subject + def covered_ranges + IpBlock.where(id: [first_ip_range_block.id, second_ip_range_block.id]) + end - expect(IpBlock.where(id: third_ip_range_block.id)).to exist + def other_ranges + IpBlock.where(id: third_ip_range_block.id) end end @@ -215,14 +208,12 @@ let(:unblocked_ip) { '192.0.2.1' } let(:arguments) { [unblocked_ip] } - it 'skips the IP address' do - expect { subject } - .to output_results("#{unblocked_ip} is not yet blocked") - end - - it 'displays the summary correctly' do + it 'skips the IP address and displays summary' do expect { subject } - .to output_results('Removed 0, skipped 1') + .to output_results( + "#{unblocked_ip} is not yet blocked", + 'Removed 0, skipped 1' + ) end end @@ -230,14 +221,12 @@ let(:invalid_ip) { '320.15.175.0' } let(:arguments) { [invalid_ip] } - it 'skips the invalid IP address' do - expect { subject } - .to output_results("#{invalid_ip} is invalid") - end - - it 'displays the summary correctly' do + it 'skips the invalid IP address and displays summary' do expect { subject } - .to output_results('Removed 0, skipped 1') + .to output_results( + "#{invalid_ip} is invalid", + 'Removed 0, skipped 1' + ) end end @@ -265,7 +254,7 @@ .to output_results("#{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}\n#{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix}") end - it 'does not export bloked IPs with different severities' do + it 'does not export blocked IPs with different severities' do expect { subject } .to_not output_results("#{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix}") end @@ -279,7 +268,7 @@ .to output_results("deny #{first_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};\ndeny #{second_ip_range_block.ip}/#{second_ip_range_block.ip.prefix};") end - it 'does not export bloked IPs with different severities' do + it 'does not export blocked IPs with different severities' do expect { subject } .to_not output_results("deny #{third_ip_range_block.ip}/#{first_ip_range_block.ip.prefix};") end diff --git a/spec/lib/mastodon/cli/settings_spec.rb b/spec/lib/mastodon/cli/settings_spec.rb index 02d1042c567aaf..568ee00393a1ef 100644 --- a/spec/lib/mastodon/cli/settings_spec.rb +++ b/spec/lib/mastodon/cli/settings_spec.rb @@ -20,37 +20,29 @@ describe '#open' do let(:action) { :open } - it 'changes "registrations_mode" to "open"' do - expect { subject }.to change(Setting, :registrations_mode).from(nil).to('open') - end - - it 'displays success message' do + it 'changes "registrations_mode" to "open" and displays success' do expect { subject } - .to output_results('OK') + .to change(Setting, :registrations_mode).from(nil).to('open') + .and output_results('OK') end end describe '#approved' do let(:action) { :approved } - it 'changes "registrations_mode" to "approved"' do - expect { subject }.to change(Setting, :registrations_mode).from(nil).to('approved') - end - - it 'displays success message' do + it 'changes "registrations_mode" to "approved" and displays success' do expect { subject } - .to output_results('OK') + .to change(Setting, :registrations_mode).from(nil).to('approved') + .and output_results('OK') end context 'with --require-reason' do let(:options) { { require_reason: true } } - it 'changes "registrations_mode" to "approved"' do - expect { subject }.to change(Setting, :registrations_mode).from(nil).to('approved') - end - - it 'sets "require_invite_text" to "true"' do - expect { subject }.to change(Setting, :require_invite_text).from(false).to(true) + it 'changes registrations_mode and require_invite_text' do + expect { subject } + .to change(Setting, :registrations_mode).from(nil).to('approved') + .and change(Setting, :require_invite_text).from(false).to(true) end end end @@ -58,13 +50,10 @@ describe '#close' do let(:action) { :close } - it 'changes "registrations_mode" to "none"' do - expect { subject }.to change(Setting, :registrations_mode).from(nil).to('none') - end - - it 'displays success message' do + it 'changes "registrations_mode" to "none" and displays success' do expect { subject } - .to output_results('OK') + .to change(Setting, :registrations_mode).from(nil).to('none') + .and output_results('OK') end end end From f3864db4090b8cec212fb99c3dabccfb6a6c7642 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 11 Dec 2023 15:23:30 +0100 Subject: [PATCH 22/40] Fix notification sounds (#28316) --- app/javascript/mastodon/actions/notifications_typed.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/actions/notifications_typed.ts b/app/javascript/mastodon/actions/notifications_typed.ts index 7e51fa51e7b7e8..176362f4b1edd4 100644 --- a/app/javascript/mastodon/actions/notifications_typed.ts +++ b/app/javascript/mastodon/actions/notifications_typed.ts @@ -18,6 +18,6 @@ export const notificationsUpdate = createAction( playSound: boolean; }) => ({ payload: args, - meta: { playSound: playSound ? { sound: 'boop' } : undefined }, + meta: { sound: playSound ? 'boop' : undefined }, }), ); From 9dfa94063626bc2351e2098e226deee7b0e3eff8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:58:10 +0100 Subject: [PATCH 23/40] Update babel monorepo to v7.23.6 (#28319) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 159 +++++++++++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 79 deletions(-) diff --git a/yarn.lock b/yarn.lock index 0ef881126d4dd6..71f1ad160c5c1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -52,7 +52,7 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.22.9, @babel/compat-data@npm:^7.23.3, @babel/compat-data@npm:^7.23.5": +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.23.3, @babel/compat-data@npm:^7.23.5": version: 7.23.5 resolution: "@babel/compat-data@npm:7.23.5" checksum: 081278ed46131a890ad566a59c61600a5f9557bd8ee5e535890c8548192532ea92590742fd74bd9db83d74c669ef8a04a7e1c85cdea27f960233e3b83c3a957c @@ -60,37 +60,37 @@ __metadata: linkType: hard "@babel/core@npm:^7.10.4, @babel/core@npm:^7.11.1, @babel/core@npm:^7.11.6, @babel/core@npm:^7.12.3, @babel/core@npm:^7.22.1": - version: 7.23.5 - resolution: "@babel/core@npm:7.23.5" + version: 7.23.6 + resolution: "@babel/core@npm:7.23.6" dependencies: "@ampproject/remapping": "npm:^2.2.0" "@babel/code-frame": "npm:^7.23.5" - "@babel/generator": "npm:^7.23.5" - "@babel/helper-compilation-targets": "npm:^7.22.15" + "@babel/generator": "npm:^7.23.6" + "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-module-transforms": "npm:^7.23.3" - "@babel/helpers": "npm:^7.23.5" - "@babel/parser": "npm:^7.23.5" + "@babel/helpers": "npm:^7.23.6" + "@babel/parser": "npm:^7.23.6" "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.5" - "@babel/types": "npm:^7.23.5" + "@babel/traverse": "npm:^7.23.6" + "@babel/types": "npm:^7.23.6" convert-source-map: "npm:^2.0.0" debug: "npm:^4.1.0" gensync: "npm:^1.0.0-beta.2" json5: "npm:^2.2.3" semver: "npm:^6.3.1" - checksum: 311a512a870ee330a3f9a7ea89e5df790b2b5af0b1bd98b10b4edc0de2ac440f0df4d69ea2c0ee38a4b89041b9a495802741d93603be7d4fd834ec8bb6970bd2 + checksum: a02bae7d916029b70706dc301535e1b31e5d216f55d4ee6f64a15825c6b69ee2c14c52a213d1497ec414e925ed4e9d897d41fb0d75df9fea28ed2c0008790e31 languageName: node linkType: hard -"@babel/generator@npm:^7.23.5, @babel/generator@npm:^7.7.2": - version: 7.23.5 - resolution: "@babel/generator@npm:7.23.5" +"@babel/generator@npm:^7.23.6, @babel/generator@npm:^7.7.2": + version: 7.23.6 + resolution: "@babel/generator@npm:7.23.6" dependencies: - "@babel/types": "npm:^7.23.5" + "@babel/types": "npm:^7.23.6" "@jridgewell/gen-mapping": "npm:^0.3.2" "@jridgewell/trace-mapping": "npm:^0.3.17" jsesc: "npm:^2.5.1" - checksum: 14c6e874f796c4368e919bed6003bb0adc3ce837760b08f9e646d20aeb5ae7d309723ce6e4f06bcb4a2b5753145446c8e4425851380f695e40e71e1760f49e7b + checksum: 53540e905cd10db05d9aee0a5304e36927f455ce66f95d1253bb8a179f286b88fa7062ea0db354c566fe27f8bb96567566084ffd259f8feaae1de5eccc8afbda languageName: node linkType: hard @@ -122,16 +122,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.6": - version: 7.22.15 - resolution: "@babel/helper-compilation-targets@npm:7.22.15" +"@babel/helper-compilation-targets@npm:^7.22.15, @babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/helper-compilation-targets@npm:7.23.6" dependencies: - "@babel/compat-data": "npm:^7.22.9" - "@babel/helper-validator-option": "npm:^7.22.15" - browserslist: "npm:^4.21.9" + "@babel/compat-data": "npm:^7.23.5" + "@babel/helper-validator-option": "npm:^7.23.5" + browserslist: "npm:^4.22.2" lru-cache: "npm:^5.1.1" semver: "npm:^6.3.1" - checksum: 45b9286861296e890f674a3abb199efea14a962a27d9b8adeb44970a9fd5c54e73a9e342e8414d2851cf4f98d5994537352fbce7b05ade32e9849bbd327f9ff1 + checksum: ba38506d11185f48b79abf439462ece271d3eead1673dd8814519c8c903c708523428806f05f2ec5efd0c56e4e278698fac967e5a4b5ee842c32415da54bc6fa languageName: node linkType: hard @@ -342,14 +342,14 @@ __metadata: languageName: node linkType: hard -"@babel/helpers@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/helpers@npm:7.23.5" +"@babel/helpers@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/helpers@npm:7.23.6" dependencies: "@babel/template": "npm:^7.22.15" - "@babel/traverse": "npm:^7.23.5" - "@babel/types": "npm:^7.23.5" - checksum: a37e2728eb4378a4888e5d614e28de7dd79b55ac8acbecd0e5c761273e2a02a8f33b34b1932d9069db55417ace2937cbf8ec37c42f1030ce6d228857d7ccaa4f + "@babel/traverse": "npm:^7.23.6" + "@babel/types": "npm:^7.23.6" + checksum: df1cf6607676ad36f52f652ec03536f2732d70aef5e76dba5c964e34d49f3c2d3dcf9fb3740db359f53071d74b64606a833d5ba156f79f437f71bfe06e2e7e19 languageName: node linkType: hard @@ -364,12 +364,12 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/parser@npm:7.23.5" +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.22.15, @babel/parser@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/parser@npm:7.23.6" bin: parser: ./bin/babel-parser.js - checksum: 3356aa90d7bafb4e2c7310e7c2c3d443c4be4db74913f088d3d577a1eb914ea4188e05fd50a47ce907a27b755c4400c4e3cbeee73dbeb37761f6ca85954f5a20 + checksum: 6f76cd5ccae1fa9bcab3525b0865c6222e9c1d22f87abc69f28c5c7b2c8816a13361f5bd06bddbd5faf903f7320a8feba02545c981468acec45d12a03db7755e languageName: node linkType: hard @@ -836,14 +836,15 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.23.3": - version: 7.23.3 - resolution: "@babel/plugin-transform-for-of@npm:7.23.3" +"@babel/plugin-transform-for-of@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/plugin-transform-for-of@npm:7.23.6" dependencies: "@babel/helper-plugin-utils": "npm:^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers": "npm:^7.22.5" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8a36202cfee312ba80e509c7c2131e6773524e572b4dc64a8ee95bd912634fdeb5ea91c6c7747ee30e03562d0f0d333f88ed7dbb929b36b60b8d74189189e12f + checksum: 46681b6ab10f3ca2d961f50d4096b62ab5d551e1adad84e64be1ee23e72eb2f26a1e30e617e853c74f1349fffe4af68d33921a128543b6f24b6d46c09a3e2aec languageName: node linkType: hard @@ -1200,8 +1201,8 @@ __metadata: linkType: hard "@babel/plugin-transform-runtime@npm:^7.22.4": - version: 7.23.4 - resolution: "@babel/plugin-transform-runtime@npm:7.23.4" + version: 7.23.6 + resolution: "@babel/plugin-transform-runtime@npm:7.23.6" dependencies: "@babel/helper-module-imports": "npm:^7.22.15" "@babel/helper-plugin-utils": "npm:^7.22.5" @@ -1211,7 +1212,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 6ac29012550cdd10b65ec43fef0c7f43904ec458c43d597f627d8f52807413e57ea94e3986dbace576d734e67c2d09be5e43e77c72567d18f8c4ac5e19844625 + checksum: 94a7ee92f073df53fd8bebf9ed391a95553716077da1c6c3a57f10f042358c938495d55e6b09b4b50544c01f03560c4770c17698e1c24817a15d3668e8231249 languageName: node linkType: hard @@ -1333,11 +1334,11 @@ __metadata: linkType: hard "@babel/preset-env@npm:^7.11.0, @babel/preset-env@npm:^7.12.1, @babel/preset-env@npm:^7.22.4": - version: 7.23.5 - resolution: "@babel/preset-env@npm:7.23.5" + version: 7.23.6 + resolution: "@babel/preset-env@npm:7.23.6" dependencies: "@babel/compat-data": "npm:^7.23.5" - "@babel/helper-compilation-targets": "npm:^7.22.15" + "@babel/helper-compilation-targets": "npm:^7.23.6" "@babel/helper-plugin-utils": "npm:^7.22.5" "@babel/helper-validator-option": "npm:^7.23.5" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "npm:^7.23.3" @@ -1377,7 +1378,7 @@ __metadata: "@babel/plugin-transform-dynamic-import": "npm:^7.23.4" "@babel/plugin-transform-exponentiation-operator": "npm:^7.23.3" "@babel/plugin-transform-export-namespace-from": "npm:^7.23.4" - "@babel/plugin-transform-for-of": "npm:^7.23.3" + "@babel/plugin-transform-for-of": "npm:^7.23.6" "@babel/plugin-transform-function-name": "npm:^7.23.3" "@babel/plugin-transform-json-strings": "npm:^7.23.4" "@babel/plugin-transform-literals": "npm:^7.23.3" @@ -1418,7 +1419,7 @@ __metadata: semver: "npm:^6.3.1" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2a0e1274dec045186e131c6433659b75492583290e8d41633c616f6bff829cb2e4b2f9a57f556283a54db3bd6aa697911e56a36f607911a29b731c445a5b5a06 + checksum: 5b24d179af52f082d04b9b98cc4777e37bf31a97cef5a91d8917e996dbd75f2f743c88c40f80744cb8529355bb674619d150c0260c32d834aa4067e21d0c8962 languageName: node linkType: hard @@ -1483,11 +1484,11 @@ __metadata: linkType: hard "@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.0, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.13, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.13.8, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.22.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": - version: 7.23.5 - resolution: "@babel/runtime@npm:7.23.5" + version: 7.23.6 + resolution: "@babel/runtime@npm:7.23.6" dependencies: regenerator-runtime: "npm:^0.14.0" - checksum: ca679cc91bb7e424bc2db87bb58cc3b06ade916b9adb21fbbdc43e54cdaacb3eea201ceba2a0464b11d2eb65b9fe6a6ffcf4d7521fa52994f19be96f1af14788 + checksum: d886954e985ef8e421222f7a2848884d96a752e0020d3078b920dd104e672fdf23bcc6f51a44313a048796319f1ac9d09c2c88ec8cbb4e1f09174bcd3335b9ff languageName: node linkType: hard @@ -1502,32 +1503,32 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.5": - version: 7.23.5 - resolution: "@babel/traverse@npm:7.23.5" +"@babel/traverse@npm:7, @babel/traverse@npm:^7.23.6": + version: 7.23.6 + resolution: "@babel/traverse@npm:7.23.6" dependencies: "@babel/code-frame": "npm:^7.23.5" - "@babel/generator": "npm:^7.23.5" + "@babel/generator": "npm:^7.23.6" "@babel/helper-environment-visitor": "npm:^7.22.20" "@babel/helper-function-name": "npm:^7.23.0" "@babel/helper-hoist-variables": "npm:^7.22.5" "@babel/helper-split-export-declaration": "npm:^7.22.6" - "@babel/parser": "npm:^7.23.5" - "@babel/types": "npm:^7.23.5" - debug: "npm:^4.1.0" + "@babel/parser": "npm:^7.23.6" + "@babel/types": "npm:^7.23.6" + debug: "npm:^4.3.1" globals: "npm:^11.1.0" - checksum: c5ea793080ca6719b0a1612198fd25e361cee1f3c14142d7a518d2a1eeb5c1d21f7eec1b26c20ea6e1ddd8ed12ab50b960ff95ffd25be353b6b46e1b54d6f825 + checksum: 5b4ebb94a00a7e1daf111e4b0b45a7998d5b7598637a14e75e855e88cc1b702789e09a958726b5d599a003be1e9032dbdfde4b88ea6061332228738950d5582d languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.10, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.5, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": - version: 7.23.5 - resolution: "@babel/types@npm:7.23.5" +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.0.0-beta.49, @babel/types@npm:^7.12.11, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.10, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.6, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4, @babel/types@npm:^7.8.3": + version: 7.23.6 + resolution: "@babel/types@npm:7.23.6" dependencies: "@babel/helper-string-parser": "npm:^7.23.4" "@babel/helper-validator-identifier": "npm:^7.22.20" to-fast-properties: "npm:^2.0.0" - checksum: 7dd5e2f59828ed046ad0b06b039df2524a8b728d204affb4fc08da2502b9dd3140b1356b5166515d229dc811539a8b70dcd4bc507e06d62a89f4091a38d0b0fb + checksum: 42cefce8a68bd09bb5828b4764aa5586c53c60128ac2ac012e23858e1c179347a4aac9c66fc577994fbf57595227611c5ec8270bf0cfc94ff033bbfac0550b70 languageName: node linkType: hard @@ -5170,17 +5171,17 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.21.9, browserslist@npm:^4.22.1": - version: 4.22.1 - resolution: "browserslist@npm:4.22.1" +"browserslist@npm:^4.0.0, browserslist@npm:^4.21.10, browserslist@npm:^4.21.4, browserslist@npm:^4.22.1, browserslist@npm:^4.22.2": + version: 4.22.2 + resolution: "browserslist@npm:4.22.2" dependencies: - caniuse-lite: "npm:^1.0.30001541" - electron-to-chromium: "npm:^1.4.535" - node-releases: "npm:^2.0.13" + caniuse-lite: "npm:^1.0.30001565" + electron-to-chromium: "npm:^1.4.601" + node-releases: "npm:^2.0.14" update-browserslist-db: "npm:^1.0.13" bin: browserslist: cli.js - checksum: 6810f2d63f171d0b7b8d38cf091708e00cb31525501810a507839607839320d66e657293b0aa3d7f051ecbc025cb07390a90c037682c1d05d12604991e41050b + checksum: 2a331aab90503130043ca41dd5d281fa1e89d5e076d07a2d75e76bf4d693bd56e73d5abcd8c4f39119da6328d450578c216cf1cd5c99b82d8a90a2ae6271b465 languageName: node linkType: hard @@ -5408,10 +5409,10 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001541": - version: 1.0.30001561 - resolution: "caniuse-lite@npm:1.0.30001561" - checksum: 6e84c84026fee53edbdbb5aded7a04a036aae4c2e367cf6bdc90c6783a591e2fdcfcdebcc4e774aca61092e542a61200c8c16b06659396492426033c4dbcc618 +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001538, caniuse-lite@npm:^1.0.30001565": + version: 1.0.30001568 + resolution: "caniuse-lite@npm:1.0.30001568" + checksum: 13f01e5a2481134bd61cf565ce9fecbd8e107902927a0dcf534230a92191a81f1715792170f5f39719c767c3a96aa6df9917a8d5601f15bbd5e4041a8cfecc99 languageName: node linkType: hard @@ -6413,7 +6414,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.4": +"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -6955,10 +6956,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.4.535": - version: 1.4.576 - resolution: "electron-to-chromium@npm:1.4.576" - checksum: b0b9e7ba803bf93ffac9cb830ed2b0e0eb07f20066127065f9ab9e08e4e6a5812040e03d76f6ee9bc59e03fb938fd414e83d4883b29111303e9e88633cf2dce4 +"electron-to-chromium@npm:^1.4.601": + version: 1.4.609 + resolution: "electron-to-chromium@npm:1.4.609" + checksum: 9675a79388acbaff5953a4c61589af7da93e0d1f9d6a3b284c7630f10126eb0998557b07448514214d5a3d19025310039b55f405ab701b1253130fc94907f743 languageName: node linkType: hard @@ -11930,10 +11931,10 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.13": - version: 2.0.13 - resolution: "node-releases@npm:2.0.13" - checksum: 2fb44bf70fc949d27f3a48a7fd1a9d1d603ddad4ccd091f26b3fb8b1da976605d919330d7388ccd55ca2ade0dc8b2e12841ba19ef249c8bb29bf82532d401af7 +"node-releases@npm:^2.0.14": + version: 2.0.14 + resolution: "node-releases@npm:2.0.14" + checksum: 199fc93773ae70ec9969bc6d5ac5b2bbd6eb986ed1907d751f411fef3ede0e4bfdb45ceb43711f8078bea237b6036db8b1bf208f6ff2b70c7d615afd157f3ab9 languageName: node linkType: hard From 2c6369918c61a7f948f39926f987fcfa0b02fb82 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 11 Dec 2023 09:58:29 -0500 Subject: [PATCH 24/40] Fix `Style/RedundantArgument` cop (#28321) --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 48d9119fbd5a14..135bbb0fd4fa1a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -114,7 +114,7 @@ def can?(action, record) end def fa_icon(icon, attributes = {}) - class_names = attributes[:class]&.split(' ') || [] + class_names = attributes[:class]&.split || [] class_names << 'fa' class_names += icon.split.map { |cl| "fa-#{cl}" } From a8a5c6514f6676155661846398fa0398e7355f5d Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 12 Dec 2023 09:29:46 +0100 Subject: [PATCH 25/40] Fix `LinkCrawlWorker` error when encountering empty OEmbed response (#28268) --- app/services/fetch_oembed_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/fetch_oembed_service.rb b/app/services/fetch_oembed_service.rb index 1ae592238efc15..dc84b16b684a7d 100644 --- a/app/services/fetch_oembed_service.rb +++ b/app/services/fetch_oembed_service.rb @@ -100,7 +100,7 @@ def parse_for_format(body) end def validate(oembed) - oembed if oembed[:version].to_s == '1.0' && oembed[:type].present? + oembed if oembed.present? && oembed[:version].to_s == '1.0' && oembed[:type].present? end def html From 89a496b42ff94536fc4aa1a8f41651f8bfd52944 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 12 Dec 2023 11:39:21 +0100 Subject: [PATCH 26/40] Fix status edits not always being streamed to mentioned users (#28324) --- app/services/fan_out_on_write_service.rb | 13 +++++++++++ .../services/fan_out_on_write_service_spec.rb | 22 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/app/services/fan_out_on_write_service.rb b/app/services/fan_out_on_write_service.rb index f2a79c9fc96068..50b414bc52bf91 100644 --- a/app/services/fan_out_on_write_service.rb +++ b/app/services/fan_out_on_write_service.rb @@ -74,6 +74,15 @@ def notify_mentioned_accounts! LocalNotificationWorker.push_bulk(mentions) do |mention| [mention.account_id, mention.id, 'Mention', 'mention'] end + + next unless update? + + # This may result in duplicate update payloads, but this ensures clients + # are aware of edits to posts only appearing in mention notifications + # (e.g. private mentions or mentions by people they do not follow) + PushUpdateWorker.push_bulk(mentions.filter { |mention| subscribed_to_streaming_api?(mention.account_id) }) do |mention| + [mention.account_id, @status.id, "timeline:#{mention.account_id}:notifications", { 'update' => true }] + end end end @@ -162,4 +171,8 @@ def update? def broadcastable? @status.public_visibility? && !@status.reblog? && !@account.silenced? end + + def subscribed_to_streaming_api?(account_id) + redis.exists?("subscribed:timeline:#{account_id}") || redis.exists?("subscribed:timeline:#{account_id}:notifications") + end end diff --git a/spec/services/fan_out_on_write_service_spec.rb b/spec/services/fan_out_on_write_service_spec.rb index 3b554f9ea3bbfc..f657f298de8b0c 100644 --- a/spec/services/fan_out_on_write_service_spec.rb +++ b/spec/services/fan_out_on_write_service_spec.rb @@ -6,11 +6,12 @@ subject { described_class.new } let(:last_active_at) { Time.now.utc } - let(:status) { Fabricate(:status, account: alice, visibility: visibility, text: 'Hello @bob #hoge') } + let(:status) { Fabricate(:status, account: alice, visibility: visibility, text: 'Hello @bob @eve #hoge') } let!(:alice) { Fabricate(:user, current_sign_in_at: last_active_at).account } let!(:bob) { Fabricate(:user, current_sign_in_at: last_active_at, account_attributes: { username: 'bob' }).account } let!(:tom) { Fabricate(:user, current_sign_in_at: last_active_at).account } + let!(:eve) { Fabricate(:user, current_sign_in_at: last_active_at, account_attributes: { username: 'eve' }).account } before do bob.follow!(alice) @@ -109,5 +110,24 @@ def home_feed_of(account) expect(redis).to_not have_received(:publish).with('timeline:hashtag:hoge', anything) expect(redis).to_not have_received(:publish).with('timeline:public', anything) end + + context 'when handling status updates', :sidekiq_fake do + before do + subject.call(status) + + status.snapshot!(at_time: status.created_at, rate_limit: false) + status.update!(text: 'Hello @bob @eve #hoge (edited)') + status.snapshot!(account_id: status.account_id) + + redis.set("subscribed:timeline:#{eve.id}:notifications", '1') + + Sidekiq::Worker.clear_all + end + + it 'pushes the update to mentioned users through the notifications streaming channel' do + subject.call(status, update: true) + expect(PushUpdateWorker).to have_enqueued_sidekiq_job(anything, status.id, "timeline:#{eve.id}:notifications", { 'update' => true }) + end + end end end From 8078520c762e15aedbdf11a50d9c033e7c1f8271 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 11:40:54 +0100 Subject: [PATCH 27/40] Update dependency oj to v3.16.3 (#28332) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4b39692d031222..405c31ae1aaa0f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -484,8 +484,8 @@ GEM nokogiri (1.15.5) mini_portile2 (~> 2.8.2) racc (~> 1.4) - oj (3.16.2) - bigdecimal (~> 3.1) + oj (3.16.3) + bigdecimal (>= 3.0) omniauth (2.1.1) hashie (>= 3.4.6) rack (>= 2.2.3) From 14e64bc880ca1e301c6fdd69cb880a9c615efe6d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:45:10 +0100 Subject: [PATCH 28/40] New Crowdin Translations (automated) (#28334) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/zh-TW.json | 36 +++++++++++----------- config/locales/activerecord.zh-TW.yml | 2 +- config/locales/doorkeeper.zh-TW.yml | 2 +- config/locales/simple_form.zh-TW.yml | 2 +- config/locales/zh-TW.yml | 10 +++--- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/app/javascript/mastodon/locales/zh-TW.json b/app/javascript/mastodon/locales/zh-TW.json index e6dd008bf27bcf..4fb5a12de3d134 100644 --- a/app/javascript/mastodon/locales/zh-TW.json +++ b/app/javascript/mastodon/locales/zh-TW.json @@ -8,7 +8,7 @@ "about.domain_blocks.silenced.title": "已受限", "about.domain_blocks.suspended.explanation": "來自此伺服器的資料都不會被處理、儲存或交換,也無法與此伺服器上的使用者互動或交流。", "about.domain_blocks.suspended.title": "已停權", - "about.not_available": "無法於本伺服器上使用此資訊。", + "about.not_available": "無法於此伺服器上使用此資訊。", "about.powered_by": "由 {mastodon} 提供的去中心化社群媒體", "about.rules": "伺服器規則", "account.account_note_header": "備註", @@ -34,9 +34,9 @@ "account.follow": "跟隨", "account.followers": "跟隨者", "account.followers.empty": "尚未有人跟隨這位使用者。", - "account.followers_counter": "被 {count, plural,one {{counter} 人}other {{counter} 人}}跟隨", + "account.followers_counter": "被 {count, plural, other {{counter} 人}}跟隨", "account.following": "跟隨中", - "account.following_counter": "正在跟隨 {count, plural, one {{counter} 人} other {{counter} 人}}", + "account.following_counter": "正在跟隨 {count,plural,other {{counter} 人}}", "account.follows.empty": "這位使用者尚未跟隨任何人。", "account.follows_you": "跟隨了您", "account.go_to_profile": "前往個人檔案", @@ -72,8 +72,8 @@ "account.unmute_notifications_short": "取消靜音推播通知", "account.unmute_short": "解除靜音", "account_note.placeholder": "按此新增備註", - "admin.dashboard.daily_retention": "註冊後使用者存留率(日)", - "admin.dashboard.monthly_retention": "註冊後使用者存留率(月)", + "admin.dashboard.daily_retention": "註冊後使用者存留率(日)", + "admin.dashboard.monthly_retention": "註冊後使用者存留率(月)", "admin.dashboard.retention.average": "平均", "admin.dashboard.retention.cohort": "註冊月份", "admin.dashboard.retention.cohort_size": "新使用者", @@ -103,9 +103,9 @@ "bundle_modal_error.message": "載入此元件時發生錯誤。", "bundle_modal_error.retry": "重試", "closed_registrations.other_server_instructions": "因為 Mastodon 是去中心化的,所以您也能於其他伺服器上建立帳號,並仍然與這個伺服器互動。", - "closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon 。", + "closed_registrations_modal.description": "目前無法於 {domain} 建立新帳號,但也請別忘了,您並不一定需要有 {domain} 伺服器的帳號,也能使用 Mastodon。", "closed_registrations_modal.find_another_server": "尋找另一個伺服器", - "closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您於哪個伺服器新增帳號,都可以與此伺服器上的任何人跟隨及互動。您甚至能自行架一個自己的伺服器!", + "closed_registrations_modal.preamble": "Mastodon 是去中心化的,所以無論您於哪個伺服器新增帳號,都可以與此伺服器上的任何人跟隨及互動。您甚至能自行架設一個自己的伺服器!", "closed_registrations_modal.title": "註冊 Mastodon", "column.about": "關於", "column.blocks": "已封鎖的使用者", @@ -155,7 +155,7 @@ "compose_form.publish_form": "嘟出去", "compose_form.publish_loud": "{publish}!", "compose_form.save_changes": "儲存變更", - "compose_form.sensitive.hide": "標記媒體為敏感內容", + "compose_form.sensitive.hide": "{count, plural, other {將媒體標記為敏感內容}}", "compose_form.sensitive.marked": "此媒體被標記為敏感內容", "compose_form.sensitive.unmarked": "此媒體未被標記為敏感內容", "compose_form.spoiler.marked": "移除內容警告", @@ -207,14 +207,14 @@ "dismissable_banner.explore_statuses": "這些於此伺服器以及去中心化網路中其他伺服器發出的嘟文正在被此伺服器上的人們熱烈討論著。越多不同人轉嘟及最愛排名更高。", "dismissable_banner.explore_tags": "這些主題標籤正在被此伺服器以及去中心化網路上的人們熱烈討論著。越多不同人所嘟出的主題標籤排名更高。", "dismissable_banner.public_timeline": "這些是來自 {domain} 使用者們跟隨中帳號所發表之最新公開嘟文。", - "embed.instructions": "若您欲於您的網站嵌入此嘟文,請複製以下程式碼。", + "embed.instructions": "如要將此嘟文嵌入您的網站,請複製以下程式碼。", "embed.preview": "它將顯示成這樣:", "emoji_button.activity": "活動", "emoji_button.clear": "清除", "emoji_button.custom": "自訂", "emoji_button.flags": "旗幟", "emoji_button.food": "食物 & 飲料", - "emoji_button.label": "插入表情符號", + "emoji_button.label": "插入表情圖案", "emoji_button.nature": "自然", "emoji_button.not_found": "啊就沒這表情符號吼!! (╯°□°)╯︵ ┻━┻", "emoji_button.objects": "物件", @@ -353,11 +353,11 @@ "keyboard_shortcuts.legend": "顯示此說明選單", "keyboard_shortcuts.local": "開啟本站時間軸", "keyboard_shortcuts.mention": "提及作者", - "keyboard_shortcuts.muted": "開啟靜音使用者列表", + "keyboard_shortcuts.muted": "開啟靜音使用者清單", "keyboard_shortcuts.my_profile": "開啟個人檔案頁面", "keyboard_shortcuts.notifications": "開啟通知欄", "keyboard_shortcuts.open_media": "開啟媒體", - "keyboard_shortcuts.pinned": "開啟釘選的嘟文列表", + "keyboard_shortcuts.pinned": "開啟釘選的嘟文清單", "keyboard_shortcuts.profile": "開啟作者的個人檔案頁面", "keyboard_shortcuts.reply": "回應嘟文", "keyboard_shortcuts.requests": "開啟跟隨請求列表", @@ -386,7 +386,7 @@ "lists.new.create": "新增列表", "lists.new.title_placeholder": "新列表標題", "lists.replies_policy.followed": "任何跟隨的使用者", - "lists.replies_policy.list": "列表成員", + "lists.replies_policy.list": "成員清單", "lists.replies_policy.none": "沒有人", "lists.replies_policy.title": "顯示回覆:", "lists.search": "搜尋您跟隨的使用者", @@ -452,7 +452,7 @@ "notifications.column_settings.push": "推播通知", "notifications.column_settings.reblog": "轉嘟:", "notifications.column_settings.show": "於欄位中顯示", - "notifications.column_settings.sound": "播放聲音", + "notifications.column_settings.sound": "播放音效", "notifications.column_settings.status": "新嘟文:", "notifications.column_settings.unread_notifications.category": "未讀通知", "notifications.column_settings.unread_notifications.highlight": "突顯未讀通知", @@ -477,7 +477,7 @@ "onboarding.actions.back": "返回", "onboarding.actions.go_to_explore": "看看發生什麼新鮮事", "onboarding.actions.go_to_home": "前往您的首頁時間軸", - "onboarding.compose.template": "哈囉 #Mastodon!", + "onboarding.compose.template": "你好 #Mastodon!", "onboarding.follows.empty": "很遺憾,目前未能顯示任何結果。您可以嘗試使用搜尋、瀏覽探索頁面以找尋人們跟隨、或稍候再試。", "onboarding.follows.lead": "您的首頁時間軸是 Mastodon 的核心體驗。若您跟隨更多人的話,它將會變得更活躍有趣。這些個人檔案也許是個好起點,您可以隨時取消跟隨他們!", "onboarding.follows.title": "客製化您的首頁時間軸", @@ -540,7 +540,7 @@ "regeneration_indicator.label": "載入中…", "regeneration_indicator.sublabel": "您的首頁時間軸正在準備中!", "relative_time.days": "{number} 天", - "relative_time.full.days": "{number, plural, one {# 天} other {# 天}}前", + "relative_time.full.days": "{number, plural, other {# 天}}前", "relative_time.full.hours": "{number, plural, one {# 小時} other {# 小時}}前", "relative_time.full.just_now": "剛剛", "relative_time.full.minutes": "{number, plural, one {# 分鐘} other {# 分鐘}}前", @@ -620,7 +620,7 @@ "search_results.see_all": "檢視全部", "search_results.statuses": "嘟文", "search_results.title": "搜尋:{q}", - "server_banner.about_active_users": "最近三十日內使用此伺服器的人 (月活躍使用者)", + "server_banner.about_active_users": "最近三十日內使用此伺服器的人(月活躍使用者)", "server_banner.active_users": "活躍使用者", "server_banner.administered_by": "管理者:", "server_banner.introduction": "{domain} 是由 {mastodon} 提供之去中心化社群網路一部分。", @@ -687,7 +687,7 @@ "status.translated_from_with": "透過 {provider} 翻譯 {lang}", "status.uncached_media_warning": "無法預覽", "status.unmute_conversation": "解除此對話的靜音", - "status.unpin": "自個人檔案頁面取消釘選", + "status.unpin": "從個人檔案頁面取消釘選", "subscribed_languages.lead": "僅選定語言的嘟文才會出現於您的首頁上,並於變更後列出時間軸。選取「無」以接收所有語言的嘟文。", "subscribed_languages.save": "儲存變更", "subscribed_languages.target": "變更 {target} 的訂閱語言", diff --git a/config/locales/activerecord.zh-TW.yml b/config/locales/activerecord.zh-TW.yml index 792a9dbb2229fc..24609332cd273a 100644 --- a/config/locales/activerecord.zh-TW.yml +++ b/config/locales/activerecord.zh-TW.yml @@ -28,7 +28,7 @@ zh-TW: doorkeeper/application: attributes: website: - invalid: 不是有效的 URL + invalid: 不是有效的網址 import: attributes: data: diff --git a/config/locales/doorkeeper.zh-TW.yml b/config/locales/doorkeeper.zh-TW.yml index c0d42ec7b3ce7f..8ceaf36f3c6019 100644 --- a/config/locales/doorkeeper.zh-TW.yml +++ b/config/locales/doorkeeper.zh-TW.yml @@ -29,7 +29,7 @@ zh-TW: edit: title: 編輯應用程式 form: - error: 唉呦!請看看表單以排查錯誤 + error: 糟糕!請檢查表單以排查錯誤 help: native_redirect_uri: 請使用 %{native_redirect_uri} 作本站測試 redirect_uri: 每行輸入一個 URI diff --git a/config/locales/simple_form.zh-TW.yml b/config/locales/simple_form.zh-TW.yml index 13b2ad30af6d46..a31ad5eb1190d8 100644 --- a/config/locales/simple_form.zh-TW.yml +++ b/config/locales/simple_form.zh-TW.yml @@ -16,7 +16,7 @@ zh-TW: acct: 指定要移動至的帳號的「使用者名稱@網域名稱」 account_warning_preset: text: 您可使用嘟文語法,例如網址、「#」標籤與提及功能 - title: 可選的。不會向收件者顯示 + title: 可選。不會向收件者顯示 admin_account_action: include_statuses: 使用者可看到導致檢舉或警告的嘟文 send_email_notification: 使用者將收到帳號發生之事情的解釋 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 755ac340381115..e17228da32f077 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -467,7 +467,7 @@ zh-TW: other: 錯誤嘗試於 %{count} 天。 no_failures_recorded: 報告中沒有錯誤。 title: 可用狀態 - warning: 上一次嘗試連線至本伺服器失敗 + warning: 上一次嘗試連線至此伺服器失敗 back_to_all: 所有 back_to_limited: 受限制的 back_to_warning: 警告 @@ -876,7 +876,7 @@ zh-TW: publishers: no_publisher_selected: 因未選取任何發行者,所以什麼事都沒發生 shared_by_over_week: - other: 上週被 %{count} 名使用者分享 + other: 上週被 %{count} 位使用者分享 title: 熱門連結 usage_comparison: 於今日被 %{today} 人分享,相較於昨日 %{yesterday} 人 not_allowed_to_trend: 不允許登上熱門 @@ -1273,7 +1273,7 @@ zh-TW: other: 選取 %{count} 個符合您搜尋的項目。 today: 今天 validation_errors: - other: 恩...似乎不太對勁耶?請檢查以下 %{count} 項錯誤 + other: 恩...似乎發生了點錯誤?請檢查以下 %{count} 項錯誤 imports: errors: empty: 空的 CSV 檔案 @@ -1796,7 +1796,7 @@ zh-TW: welcome: edit_profile_action: 設定個人檔案 edit_profile_step: 您可以設定您的個人檔案,包括上傳大頭貼、變更顯示名稱等等。您也可以選擇於新的跟隨者跟隨前,先對他們進行審核。 - explanation: 下面是幾個小幫助,希望它們能幫到您 + explanation: 以下是幾個小技巧,希望它們能幫到您 final_action: 開始嘟嘟 final_step: '開始嘟嘟吧!即使您現在沒有跟隨者,其他人仍然能於本站時間軸、主題標籤等地方,看到您的公開嘟文。試著用 #introductions 這個主題標籤介紹一下自己吧。' full_handle: 您的完整帳號名稱 @@ -1805,7 +1805,7 @@ zh-TW: title: "%{name} 誠摯歡迎您的加入!" users: follow_limit_reached: 您無法跟隨多於 %{limit} 個人 - go_to_sso_account_settings: 前往您的身分提供商 (identity provider) 之帳號設定 + go_to_sso_account_settings: 前往您的身分識別提供者(IdP)之帳號設定 invalid_otp_token: 兩階段認證碼不正確 otp_lost_help_html: 如果您無法存取這兩者,您可以透過 %{email} 與我們聯繫 seamless_external_login: 由於您是由外部系統登入,所以不能設定密碼與電子郵件。 From ca51e412394cc10460ff121125262b8593e60729 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 12:45:39 +0100 Subject: [PATCH 29/40] Update dependency stylelint-config-standard-scss to v12 (#28333) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 62 ++++++++++++++++++++++++++-------------------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/package.json b/package.json index 500d6d2cde763e..37139254c1ad8a 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "prettier": "^3.0.0", "react-test-renderer": "^18.2.0", "stylelint": "^15.10.1", - "stylelint-config-standard-scss": "^11.0.0", + "stylelint-config-standard-scss": "^12.0.0", "typescript": "^5.0.4", "webpack-dev-server": "^3.11.3", "yargs": "^17.7.2" diff --git a/yarn.lock b/yarn.lock index 71f1ad160c5c1d..7903ecc5cad8b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2433,7 +2433,7 @@ __metadata: stacktrace-js: "npm:^2.0.2" stringz: "npm:^2.1.0" stylelint: "npm:^15.10.1" - stylelint-config-standard-scss: "npm:^11.0.0" + stylelint-config-standard-scss: "npm:^12.0.0" substring-trie: "npm:^1.0.2" terser-webpack-plugin: "npm:^4.2.3" tesseract.js: "npm:^2.1.5" @@ -15758,62 +15758,62 @@ __metadata: languageName: node linkType: hard -"stylelint-config-recommended-scss@npm:^13.1.0": - version: 13.1.0 - resolution: "stylelint-config-recommended-scss@npm:13.1.0" +"stylelint-config-recommended-scss@npm:^14.0.0": + version: 14.0.0 + resolution: "stylelint-config-recommended-scss@npm:14.0.0" dependencies: postcss-scss: "npm:^4.0.9" - stylelint-config-recommended: "npm:^13.0.0" - stylelint-scss: "npm:^5.3.0" + stylelint-config-recommended: "npm:^14.0.0" + stylelint-scss: "npm:^6.0.0" peerDependencies: postcss: ^8.3.3 - stylelint: ^15.10.0 + stylelint: ^16.0.2 peerDependenciesMeta: postcss: optional: true - checksum: e07d0172c7936b4f644138e4129df2f187d297f1f96ce5865ab21ccd1c22caf94220f7caf9d6985e93e515de4c0356f6cb9c924d00df2eee5b3bc237f7e5bb48 + checksum: 9ddc92e7a5fa131b41cee1ab1f69251934ca35c0e2803dc613329cdead7b8b27d8457048a63db29f61a1442e7cdef14207f88a3abce00ec53fdefe0d604f7de3 languageName: node linkType: hard -"stylelint-config-recommended@npm:^13.0.0": - version: 13.0.0 - resolution: "stylelint-config-recommended@npm:13.0.0" +"stylelint-config-recommended@npm:^14.0.0": + version: 14.0.0 + resolution: "stylelint-config-recommended@npm:14.0.0" peerDependencies: - stylelint: ^15.10.0 - checksum: 80420a1ab616e8637b66223f88c597388990d9991cd6a28b8372049b83329d893412f83029bb253a82b52387e497b62e042bc898064a2f22574b0d8921f01dd2 + stylelint: ^16.0.0 + checksum: 4ad15c36e8c03291aa7bbe4b672ebfb0f46ab698e7580a0da8d29644046d102d7f31dbf00a2a6eab94b565c390c6fb0d5d528737b83ac3acf6dc2ef085a90b11 languageName: node linkType: hard -"stylelint-config-standard-scss@npm:^11.0.0": - version: 11.1.0 - resolution: "stylelint-config-standard-scss@npm:11.1.0" +"stylelint-config-standard-scss@npm:^12.0.0": + version: 12.0.0 + resolution: "stylelint-config-standard-scss@npm:12.0.0" dependencies: - stylelint-config-recommended-scss: "npm:^13.1.0" - stylelint-config-standard: "npm:^34.0.0" + stylelint-config-recommended-scss: "npm:^14.0.0" + stylelint-config-standard: "npm:^35.0.0" peerDependencies: postcss: ^8.3.3 - stylelint: ^15.10.0 + stylelint: ^16.0.2 peerDependenciesMeta: postcss: optional: true - checksum: 22d00e75c1eacce9883fd48c3d67b1107b0e39d7d86e9f73deaa332b11c39a9678c947ae2c34cd5159a452ec9a857694ed58b5a851087480d3c9a66dab629415 + checksum: 7f3ccfb4175f9c50b69d30ca35a97887008c5ba493dbe7d5bce0b57b1eafd21b268177b82404368e7780600077cba784f98e1046671724be3b29a00c6a7913a4 languageName: node linkType: hard -"stylelint-config-standard@npm:^34.0.0": - version: 34.0.0 - resolution: "stylelint-config-standard@npm:34.0.0" +"stylelint-config-standard@npm:^35.0.0": + version: 35.0.0 + resolution: "stylelint-config-standard@npm:35.0.0" dependencies: - stylelint-config-recommended: "npm:^13.0.0" + stylelint-config-recommended: "npm:^14.0.0" peerDependencies: - stylelint: ^15.10.0 - checksum: 2494468af2359490b6ebb9723d9653f9e31db3a0772b8d9f0e081018b0079ef84ae6f90dcf94c879a3c374f299e334941e3dcff1afb603c2284d3103085b71fb + stylelint: ^16.0.0 + checksum: 791fbc26cc3029ce3c2423a643e903545b5e4cd605251b18f0ce790bac6fbaaf380469845c1ff45f4e320126af9f8a9dc1ca85d0df9274277ae60da91e81895b languageName: node linkType: hard -"stylelint-scss@npm:^5.3.0": - version: 5.3.1 - resolution: "stylelint-scss@npm:5.3.1" +"stylelint-scss@npm:^6.0.0": + version: 6.0.0 + resolution: "stylelint-scss@npm:6.0.0" dependencies: known-css-properties: "npm:^0.29.0" postcss-media-query-parser: "npm:^0.2.3" @@ -15821,8 +15821,8 @@ __metadata: postcss-selector-parser: "npm:^6.0.13" postcss-value-parser: "npm:^4.2.0" peerDependencies: - stylelint: ^14.5.1 || ^15.0.0 - checksum: 5dfed5f9ac9812cd2ac6ef0272c720dee0326aaaee2998315a23bdcd71b8f04427f29cad634793eea2b45984182e20f03e90d43501e8e4d55bc956f80e2de477 + stylelint: ^16.0.2 + checksum: f5e971d19ef6879ae5c18cb8fba8033fe7928f241178e6afd80357cc080d2feddfd6f7fe564aaa696008aa10345df5885d9a4471c926b3e266088e015927782e languageName: node linkType: hard From 4a7395d989e40c3bd4ef18173aa5ea850c8ddcdd Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 12 Dec 2023 06:56:39 -0500 Subject: [PATCH 30/40] Add `migrator_version` method to CLI maintenance script (#28323) --- lib/mastodon/cli/maintenance.rb | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/mastodon/cli/maintenance.rb b/lib/mastodon/cli/maintenance.rb index 553ca056dc86cf..43fd7fab33e9b1 100644 --- a/lib/mastodon/cli/maintenance.rb +++ b/lib/mastodon/cli/maintenance.rb @@ -185,15 +185,15 @@ def refresh_instances_view end def schema_has_instances_view? - ActiveRecord::Migrator.current_version >= 2020_12_06_004238 + migrator_version >= 2020_12_06_004238 end def verify_schema_version! - if ActiveRecord::Migrator.current_version < MIN_SUPPORTED_VERSION + if migrator_version < MIN_SUPPORTED_VERSION say 'Your version of the database schema is too old and is not supported by this script.', :red say 'Please update to at least Mastodon 3.0.0 before running this script.', :red exit(1) - elsif ActiveRecord::Migrator.current_version > MAX_SUPPORTED_VERSION + elsif migrator_version > MAX_SUPPORTED_VERSION say 'Your version of the database schema is more recent than this script, this may cause unexpected errors.', :yellow exit(1) unless yes?('Continue anyway? (Yes/No)') end @@ -228,7 +228,7 @@ def deduplicate_accounts! end say 'Restoring index_accounts_on_username_and_domain_lower…' - if ActiveRecord::Migrator.current_version < 2020_06_20_164023 + if migrator_version < 2020_06_20_164023 ActiveRecord::Base.connection.add_index :accounts, 'lower (username), lower(domain)', name: 'index_accounts_on_username_and_domain_lower', unique: true else ActiveRecord::Base.connection.add_index :accounts, "lower (username), COALESCE(lower(domain), '')", name: 'index_accounts_on_username_and_domain_lower', unique: true @@ -238,7 +238,7 @@ def deduplicate_accounts! ActiveRecord::Base.connection.execute('REINDEX INDEX search_index;') ActiveRecord::Base.connection.execute('REINDEX INDEX index_accounts_on_uri;') ActiveRecord::Base.connection.execute('REINDEX INDEX index_accounts_on_url;') - ActiveRecord::Base.connection.execute('REINDEX INDEX index_accounts_on_domain_and_id;') if ActiveRecord::Migrator.current_version >= 2023_05_24_190515 + ActiveRecord::Base.connection.execute('REINDEX INDEX index_accounts_on_domain_and_id;') if migrator_version >= 2023_05_24_190515 end def deduplicate_users! @@ -269,15 +269,15 @@ def deduplicate_users! say 'Restoring users indexes…' ActiveRecord::Base.connection.add_index :users, ['confirmation_token'], name: 'index_users_on_confirmation_token', unique: true ActiveRecord::Base.connection.add_index :users, ['email'], name: 'index_users_on_email', unique: true - ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if ActiveRecord::Migrator.current_version < 2022_01_18_183010 + ActiveRecord::Base.connection.add_index :users, ['remember_token'], name: 'index_users_on_remember_token', unique: true if migrator_version < 2022_01_18_183010 - if ActiveRecord::Migrator.current_version < 2022_03_10_060641 + if migrator_version < 2022_03_10_060641 ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true else ActiveRecord::Base.connection.add_index :users, ['reset_password_token'], name: 'index_users_on_reset_password_token', unique: true, where: 'reset_password_token IS NOT NULL', opclass: :text_pattern_ops end - ActiveRecord::Base.connection.execute('REINDEX INDEX index_users_on_unconfirmed_email;') if ActiveRecord::Migrator.current_version >= 2023_07_02_151753 + ActiveRecord::Base.connection.execute('REINDEX INDEX index_users_on_unconfirmed_email;') if migrator_version >= 2023_07_02_151753 end def deduplicate_users_process_confirmation_token @@ -292,7 +292,7 @@ def deduplicate_users_process_confirmation_token end def deduplicate_users_process_remember_token - if ActiveRecord::Migrator.current_version < 2022_01_18_183010 + if migrator_version < 2022_01_18_183010 ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM users WHERE remember_token IS NOT NULL GROUP BY remember_token HAVING count(*) > 1").each do |row| users = User.where(id: row['ids'].split(',')).sort_by(&:updated_at).reverse.drop(1) say "Unsetting remember token for those accounts: #{users.map { |user| user.account.acct }.join(', ')}", :yellow @@ -371,7 +371,7 @@ def deduplicate_conversations! end say 'Restoring conversations indexes…' - if ActiveRecord::Migrator.current_version < 2022_03_07_083603 + if migrator_version < 2022_03_07_083603 ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true else ActiveRecord::Base.connection.add_index :conversations, ['uri'], name: 'index_conversations_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops @@ -488,7 +488,7 @@ def deduplicate_media_attachments! end say 'Restoring media_attachments indexes…' - if ActiveRecord::Migrator.current_version < 2022_03_10_060626 + if migrator_version < 2022_03_10_060626 ActiveRecord::Base.connection.add_index :media_attachments, ['shortcode'], name: 'index_media_attachments_on_shortcode', unique: true else ActiveRecord::Base.connection.add_index :media_attachments, ['shortcode'], name: 'index_media_attachments_on_shortcode', unique: true, where: 'shortcode IS NOT NULL', opclass: :text_pattern_ops @@ -521,7 +521,7 @@ def deduplicate_statuses! end say 'Restoring statuses indexes…' - if ActiveRecord::Migrator.current_version < 2022_03_10_060706 + if migrator_version < 2022_03_10_060706 ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true else ActiveRecord::Base.connection.add_index :statuses, ['uri'], name: 'index_statuses_on_uri', unique: true, where: 'uri IS NOT NULL', opclass: :text_pattern_ops @@ -543,7 +543,7 @@ def deduplicate_tags! end say 'Restoring tags indexes…' - if ActiveRecord::Migrator.current_version < 2021_04_21_121431 + if migrator_version < 2021_04_21_121431 ActiveRecord::Base.connection.add_index :tags, 'lower((name)::text)', name: 'index_tags_on_name_lower', unique: true else ActiveRecord::Base.connection.execute 'CREATE UNIQUE INDEX CONCURRENTLY index_tags_on_name_lower_btree ON tags (lower(name) text_pattern_ops)' @@ -707,6 +707,10 @@ def merge_tags!(main_tag, duplicate_tag) end end + def migrator_version + ActiveRecord::Migrator.current_version + end + def find_duplicate_accounts ActiveRecord::Base.connection.select_all("SELECT string_agg(id::text, ',') AS ids FROM accounts GROUP BY lower(username), COALESCE(lower(domain), '') HAVING count(*) > 1") end From 393e85164980b945ad9bdfda8e906e128f5700a3 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 12 Dec 2023 13:00:23 +0100 Subject: [PATCH 31/40] Change Rails' cache format to 7.0 (#27393) --- config/application.rb | 7 ------- 1 file changed, 7 deletions(-) diff --git a/config/application.rb b/config/application.rb index b6426516eee17e..990a89383e0346 100644 --- a/config/application.rb +++ b/config/application.rb @@ -63,13 +63,6 @@ class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 7.0 - # TODO: Release a version which uses the 7.0 defaults as specified above, - # but preserves the 6.1 cache format as set below. In a subsequent change, - # remove this line setting to 6.1 cache format, and then release another version. - # https://guides.rubyonrails.org/upgrading_ruby_on_rails.html#new-activesupport-cache-serialization-format - # https://github.com/mastodon/mastodon/pull/24241#discussion_r1162890242 - config.active_support.cache_format_version = 6.1 - # Please, add to the `ignore` list any other `lib` subdirectories that do # not contain `.rb` files, or that should not be reloaded or eager loaded. # Common ones are `templates`, `generators`, or `middleware`, for example. From f37c93f3d76bcc83f20b83cfc121ff5a08d43706 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 12 Dec 2023 13:01:08 +0100 Subject: [PATCH 32/40] Change cookie rotator to use SHA1 digest for new cookies (#27392) --- config/initializers/cookie_rotator.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/config/initializers/cookie_rotator.rb b/config/initializers/cookie_rotator.rb index b829b1a90b7296..ccc2c6b21f786b 100644 --- a/config/initializers/cookie_rotator.rb +++ b/config/initializers/cookie_rotator.rb @@ -1,9 +1,6 @@ # frozen_string_literal: true -# TODO: Remove after 4.2.0 -Rails.application.configure do - config.active_support.key_generator_hash_digest_class = OpenSSL::Digest::SHA1 -end +# TODO: remove this file some time after 4.3.0 Rails.application.config.after_initialize do Rails.application.config.action_dispatch.cookies_rotations.tap do |cookies| @@ -12,9 +9,8 @@ secret_key_base = Rails.application.secret_key_base - # TODO: Switch to SHA1 after 4.2.0 key_generator = ActiveSupport::KeyGenerator.new( - secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA256 + secret_key_base, iterations: 1000, hash_digest_class: OpenSSL::Digest::SHA1 ) key_len = ActiveSupport::MessageEncryptor.key_len From db3220ff77b828870fcb21e0b50a12da0e19b2e6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 12 Dec 2023 15:18:30 +0100 Subject: [PATCH 33/40] Update dependency rubocop to v1.59.0 (#28320) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 405c31ae1aaa0f..378102437adf05 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -381,7 +381,7 @@ GEM rdoc reline (>= 0.3.8) jmespath (1.6.2) - json (2.7.0) + json (2.7.1) json-canonicalization (1.0.0) json-jwt (1.15.3) activesupport (>= 4.2) @@ -622,7 +622,7 @@ GEM redis (>= 4) redlock (1.3.2) redis (>= 3.0.0, < 6.0) - regexp_parser (2.8.2) + regexp_parser (2.8.3) reline (0.4.1) io-console (~> 0.5) request_store (1.5.1) @@ -662,7 +662,7 @@ GEM rspec-mocks (~> 3.0) sidekiq (>= 5, < 8) rspec-support (3.12.1) - rubocop (1.58.0) + rubocop (1.59.0) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) From 3f1ec16377c11d2d7a48ccc735ed87d6619f6275 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 12 Dec 2023 15:31:37 +0100 Subject: [PATCH 34/40] Fix empty column explainer getting cropped under certain conditions (#28337) --- app/javascript/styles/mastodon/components.scss | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 2106b529d6c639..462dd82ac0206a 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -4398,11 +4398,6 @@ a.status-card { align-items: center; justify-content: center; - @supports (display: grid) { - // hack to fix Chrome <57 - contain: strict; - } - & > span { max-width: 500px; } From dcc24db793dc926823439b81839be1a3bc8e29d3 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 13 Dec 2023 08:47:32 +0100 Subject: [PATCH 35/40] Fix N+1s because of association preloaders not actually getting called (#28339) --- app/lib/inline_renderer.rb | 4 ++-- app/models/announcement.rb | 4 ++-- app/models/concerns/account/search.rb | 4 ++-- app/models/notification.rb | 2 +- app/serializers/initial_state_serializer.rb | 4 ++-- app/services/account_search_service.rb | 2 +- app/services/batched_remove_status_service.rb | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/app/lib/inline_renderer.rb b/app/lib/inline_renderer.rb index eda3da2c29b2db..0aebb13fce4476 100644 --- a/app/lib/inline_renderer.rb +++ b/app/lib/inline_renderer.rb @@ -37,13 +37,13 @@ def self.render(object, current_account, template) private def preload_associations_for_status - ActiveRecord::Associations::Preloader.new(records: @object, associations: { + ActiveRecord::Associations::Preloader.new(records: [@object], associations: { active_mentions: :account, reblog: { active_mentions: :account, }, - }) + }).call end def current_user diff --git a/app/models/announcement.rb b/app/models/announcement.rb index c5d6dd62e19a72..2cd7c1d5ed9813 100644 --- a/app/models/announcement.rb +++ b/app/models/announcement.rb @@ -78,9 +78,9 @@ def reactions(account = nil) else scope.select("name, custom_emoji_id, count(*) as count, exists(select 1 from announcement_reactions r where r.account_id = #{account.id} and r.announcement_id = announcement_reactions.announcement_id and r.name = announcement_reactions.name) as me") end - end + end.to_a - ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji) + ActiveRecord::Associations::Preloader.new(records: records, associations: :custom_emoji).call records end diff --git a/app/models/concerns/account/search.rb b/app/models/concerns/account/search.rb index b02b9bd4611783..40d87aaaa19e09 100644 --- a/app/models/concerns/account/search.rb +++ b/app/models/concerns/account/search.rb @@ -124,7 +124,7 @@ def search_for(terms, limit: DEFAULT_LIMIT, offset: 0) tsquery = generate_query_for_search(terms) find_by_sql([BASIC_SEARCH_SQL, { limit: limit, offset: offset, tsquery: tsquery }]).tap do |records| - ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat) + ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call end end @@ -133,7 +133,7 @@ def advanced_search_for(terms, account, limit: DEFAULT_LIMIT, following: false, sql_template = following ? ADVANCED_SEARCH_WITH_FOLLOWING : ADVANCED_SEARCH_WITHOUT_FOLLOWING find_by_sql([sql_template, { id: account.id, limit: limit, offset: offset, tsquery: tsquery }]).tap do |records| - ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat) + ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call end end diff --git a/app/models/notification.rb b/app/models/notification.rb index 60f834a633358b..54212d675f1f9b 100644 --- a/app/models/notification.rb +++ b/app/models/notification.rb @@ -111,7 +111,7 @@ def preload_cache_collection_target_statuses(notifications, &_block) # Instead of using the usual `includes`, manually preload each type. # If polymorphic associations are loaded with the usual `includes`, other types of associations will be loaded more. - ActiveRecord::Associations::Preloader.new(records: grouped_notifications, associations: associations) + ActiveRecord::Associations::Preloader.new(records: grouped_notifications, associations: associations).call end unique_target_statuses = notifications.filter_map(&:target_status).uniq diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index a8af45990f5a9a..f606836ba4f212 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -86,8 +86,8 @@ def accounts ActiveRecord::Associations::Preloader.new( records: [object.current_account, object.admin, object.owner, object.disabled_account, object.moved_to_account].compact, - associations: [:account_stat, :user, { moved_to_account: [:account_stat, :user] }] - ) + associations: [:account_stat, { user: :role, moved_to_account: [:account_stat, { user: :role }] }] + ).call store[object.current_account.id.to_s] = serialized_account(object.current_account) if object.current_account store[object.admin.id.to_s] = serialized_account(object.admin) if object.admin diff --git a/app/services/account_search_service.rb b/app/services/account_search_service.rb index b437ff47593ee4..7b85b09d8f0e77 100644 --- a/app/services/account_search_service.rb +++ b/app/services/account_search_service.rb @@ -218,7 +218,7 @@ def from_elasticsearch records = query_builder.build.limit(limit_for_non_exact_results).offset(offset).objects.compact - ActiveRecord::Associations::Preloader.new(records: records, associations: :account_stat) + ActiveRecord::Associations::Preloader.new(records: records, associations: [:account_stat, { user: :role }]).call records rescue Faraday::ConnectionFailed, Parslet::ParseFailed diff --git a/app/services/batched_remove_status_service.rb b/app/services/batched_remove_status_service.rb index c54cc1d350d339..de4ee16e910278 100644 --- a/app/services/batched_remove_status_service.rb +++ b/app/services/batched_remove_status_service.rb @@ -11,7 +11,7 @@ def call(statuses, **options) ActiveRecord::Associations::Preloader.new( records: statuses, associations: options[:skip_side_effects] ? :reblogs : [:account, :tags, reblogs: :account] - ) + ).call statuses_and_reblogs = statuses.flat_map { |status| [status] + status.reblogs } @@ -23,7 +23,7 @@ def call(statuses, **options) ActiveRecord::Associations::Preloader.new( records: statuses_with_account_conversations, associations: [mentions: :account] - ) + ).call statuses_with_account_conversations.each(&:unlink_from_conversations!) From aae4b5644f0fb02ce811f8f9a13d0965621d05a2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:52:33 +0100 Subject: [PATCH 36/40] Update dependency haml_lint to v0.52.0 (#28345) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 378102437adf05..07b1a4bbe33527 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -326,7 +326,7 @@ GEM ruby-progressbar (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) - haml (6.2.0) + haml (6.3.0) temple (>= 0.8.2) thor tilt @@ -335,7 +335,7 @@ GEM activesupport (>= 5.1) haml (>= 4.0.6) railties (>= 5.1) - haml_lint (0.51.0) + haml_lint (0.52.0) haml (>= 4.0) parallel (~> 1.10) rainbow From b2f915b31ae884e3893e93a99da4e2b8d7e9ef7b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:52:37 +0100 Subject: [PATCH 37/40] New Crowdin Translations (automated) (#28344) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/et.json | 1 + app/javascript/mastodon/locales/ja.json | 23 ++++++++++---------- app/javascript/mastodon/locales/ne.json | 29 ++++++++++++++++++++++++- config/locales/et.yml | 29 +++++++++++++++++++++++++ config/locales/ja.yml | 2 +- 5 files changed, 71 insertions(+), 13 deletions(-) diff --git a/app/javascript/mastodon/locales/et.json b/app/javascript/mastodon/locales/et.json index a67aa6feeddbd3..a41aa02f802840 100644 --- a/app/javascript/mastodon/locales/et.json +++ b/app/javascript/mastodon/locales/et.json @@ -606,6 +606,7 @@ "search.quick_action.status_search": "Sobivad postitused {x}", "search.search_or_paste": "Otsi või kleebi URL", "search_popout.full_text_search_disabled_message": "Pole saadaval kohas {domain}.", + "search_popout.full_text_search_logged_out_message": "Saadaval vaid kui sisse logitud.", "search_popout.language_code": "Keele ISO-kood", "search_popout.options": "Otsimisvalikud", "search_popout.quick_actions": "Kiirtegevused", diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json index 3cb0565d0e6d9b..5ad9d6dc942eb1 100644 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@ -21,7 +21,7 @@ "account.blocked": "ブロック済み", "account.browse_more_on_origin_server": "リモートで表示", "account.cancel_follow_request": "フォローリクエストの取り消し", - "account.copy": "プロフィールのリンクをコピーして下さい", + "account.copy": "プロフィールへのリンクをコピー", "account.direct": "@{name}さんに非公開でメンション", "account.disable_notifications": "@{name}さんの投稿時の通知を停止", "account.domain_blocked": "ドメインブロック中", @@ -192,7 +192,7 @@ "conversation.mark_as_read": "既読にする", "conversation.open": "会話を表示", "conversation.with": "{names}", - "copy_icon_button.copied": "クリップボードにコピーされた", + "copy_icon_button.copied": "コピーしました", "copypaste.copied": "コピーしました", "copypaste.copy_to_clipboard": "クリップボードにコピー", "directory.federated": "既知の連合より", @@ -392,7 +392,7 @@ "lists.search": "フォローしている人の中から検索", "lists.subheading": "あなたのリスト", "load_pending": "{count}件の新着", - "loading_indicator.label": "", + "loading_indicator.label": "読み込み中…", "media_gallery.toggle_visible": "{number, plural, one {画像を閉じる} other {画像を閉じる}}", "moved_to_account_banner.text": "あなたのアカウント『{disabledAccount}』は『{movedToAccount}』に移動したため現在無効になっています。", "mute_modal.duration": "ミュートする期間", @@ -481,17 +481,17 @@ "onboarding.follows.empty": "表示できる結果はありません。検索やエクスプローラーを使ったり、ほかのアカウントをフォローしたり、後でもう一度試しください。", "onboarding.follows.lead": "ホームタイムラインはMastodonの軸足となる場所です。たくさんのユーザーをフォローすることで、ホームタイムラインはよりにぎやかでおもしろいものになります。手はじめに、おすすめのアカウントから何人かフォローしてみましょう:", "onboarding.follows.title": "ホームタイムラインを埋める", - "onboarding.profile.discoverable": "自分のプロフィールが発見できないようにする", - "onboarding.profile.discoverable_hint": "マストドンの見つけやすくする機能が個人情報を利用することに承諾すると、あなたの投稿が検索結果やトレンドに表示されることがあります。また、あなたのプロフィールがあなたと似た興味関心を持つ人に提案されることがあります。", + "onboarding.profile.discoverable": "自分のプロフィールが見つけられるようにする", + "onboarding.profile.discoverable_hint": "Mastodonの「見つける」機能にオプトインすると、あなたの投稿が検索結果やトレンドに表示されることがあります。また、あなたに似た関心を持つ人にプロフィールがおすすめされることがあります。", "onboarding.profile.display_name": "表示名", - "onboarding.profile.display_name_hint": "あなたのフルネーム、または楽しい名前…", - "onboarding.profile.lead": "このことは後でいつでも設定から完了させることが出来ますし、設定では更に多くのカスタマイズが利用可能になっています。", + "onboarding.profile.display_name_hint": "フルネーム、あるいは面白い名前など", + "onboarding.profile.lead": "あとでいつでも修正できますし、設定画面にはこれ以外のカスタマイズ項目もあります。", "onboarding.profile.note": "自己紹介", - "onboarding.profile.note_hint": "@を使用して他の人々にメンションをすることができます。また#でハッシュタグが使用できます", - "onboarding.profile.save_and_continue": "保存してから続行して下さい", + "onboarding.profile.note_hint": "ほかの人に @言及 したり、#ハッシュタグ を付けたりできます", + "onboarding.profile.save_and_continue": "保存して続ける", "onboarding.profile.title": "プロフィールの設定", - "onboarding.profile.upload_avatar": "プロフィール画像をアップロードしてください", - "onboarding.profile.upload_header": "プロフィールのヘッダー画像をアップロードして下さい", + "onboarding.profile.upload_avatar": "プロフィール画像をアップロード", + "onboarding.profile.upload_header": "プロフィールのヘッダー画像をアップロード", "onboarding.share.lead": "新しいMastodonのアカウントをみんなに紹介しましょう。", "onboarding.share.message": "「{username}」で #Mastodon はじめました! {url}", "onboarding.share.next_steps": "次のステップに進む:", @@ -606,6 +606,7 @@ "search.quick_action.status_search": "{x}に該当する投稿", "search.search_or_paste": "検索またはURLを入力", "search_popout.full_text_search_disabled_message": "{domain}では利用できません。", + "search_popout.full_text_search_logged_out_message": "ログイン時のみ利用できます。", "search_popout.language_code": "ISO言語コード", "search_popout.options": "検索オプション", "search_popout.quick_actions": "クイック操作", diff --git a/app/javascript/mastodon/locales/ne.json b/app/javascript/mastodon/locales/ne.json index 95f8e703c96c3a..229d4f4718d40b 100644 --- a/app/javascript/mastodon/locales/ne.json +++ b/app/javascript/mastodon/locales/ne.json @@ -49,5 +49,32 @@ "admin.dashboard.retention.average": "औसत", "admin.dashboard.retention.cohort_size": "नयाँ प्रयोगकर्ताहरू", "alert.rate_limited.message": "कृपया {retry_time, time, medium} पछि पुन: प्रयास गर्नुहोस्।", - "alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।" + "alert.unexpected.message": "एउटा अनपेक्षित त्रुटि भयो।", + "bundle_column_error.retry": "पुन: प्रयास गर्नुहोस्", + "bundle_modal_error.close": "बन्द गर्नुहोस्", + "bundle_modal_error.message": "यो कम्पोनेन्ट लोड गर्दा केही गडबड भयो।", + "bundle_modal_error.retry": "Try again", + "closed_registrations.other_server_instructions": "Mastodon विकेन्द्रीकृत भएकोले, तपाइँ अर्को सर्भरमा खाता खोल्न सक्नुहुन्छ र पनि यो सर्भरसँग अन्तरक्रिया गर्न सक्नुहुन्छ।", + "closed_registrations_modal.description": "हाल {domain} मा खाता सिर्जना गर्न सम्भव छैन, तर कृपया ध्यान राख्नुहोस् कि तपाईंले Mastodon प्रयोग गर्नको लागि {domain} मा नै खाता खोल्न आवश्यक छैन।", + "closed_registrations_modal.find_another_server": "अर्को सर्भर खोज्नुहोस्", + "closed_registrations_modal.title": "Mastodon मा साइन अप गर्दै", + "column.blocks": "ब्लक गरिएको प्रयोगकर्ताहरु", + "column.directory": "प्रोफाइल ब्राउज गर्नुहोस्", + "column.domain_blocks": "ब्लक गरिएको डोमेन", + "column.follow_requests": "फलो अनुरोधहरू", + "column.lists": "सूचीहरू", + "column.notifications": "सूचनाहरू", + "column_header.hide_settings": "सेटिङ्हरू लुकाउनुहोस्", + "column_subheading.settings": "सेटिङहरू", + "compose.language.change": "भाषा परिवर्तन गर्नुहोस्", + "compose.language.search": "भाषाहरू खोज्नुहोस्...", + "compose_form.direct_message_warning_learn_more": "थप जान्नुहोस्", + "compose_form.poll.add_option": "विकल्प थप्नुहोस्", + "compose_form.poll.remove_option": "यो विकल्प हटाउनुहोस्", + "compose_form.publish_form": "नयाँ पोस्ट", + "compose_form.save_changes": "परिवर्तनहरू सेभ गर्नुहोस", + "compose_form.sensitive.hide": "{count, plural, one {संवेदनशील मिडियाको रूपमा चिन्ह लगाउनुहोस्} other {संवेदनशील मिडियाहरूको रूपमा चिन्ह लगाउनुहोस्}}", + "compose_form.sensitive.marked": "{count, plural, one {मिडियालाई संवेदनशील रूपमा चिन्ह लगाइएको छ} other {मिडियाहरूलाई संवेदनशील रूपमा चिन्ह लगाइएको छ}}", + "compose_form.sensitive.unmarked": "{count, plural, one {मिडियालाई संवेदनशील रूपमा चिन्ह लगाइएको छैन} other {मिडियाहरूलाई संवेदनशील रूपमा चिन्ह लगाइएको छैन}}", + "compose_form.spoiler_placeholder": "यहाँ आफ्नो चेतावनी लेख्नुहोस्" } diff --git a/config/locales/et.yml b/config/locales/et.yml index fb0fdc3a3e3471..2d48edc295dae0 100644 --- a/config/locales/et.yml +++ b/config/locales/et.yml @@ -534,6 +534,7 @@ et: total_reported: Nende kohta teateid total_storage: Lisatud meedia totals_time_period_hint_html: Allpool kuvatud summad sisaldavad andmed kogu aja kohta. + unknown_instance: Hetkel pole selle domeeni jaoks siin serveris kirjet. invites: deactivate_all: Peata kõik filter: @@ -610,6 +611,7 @@ et: created_at: Teavitatud delete_and_resolve: Kustuta postitused forwarded: Edastatud + forwarded_replies_explanation: See aruanne pärineb kaugkasutajalt ja käsitleb kaugsisu. See on edastatud sulle, sest raporteeritud sisu on vastus ühele sinu kasutajale. forwarded_to: Edastatud %{domain} domeeni mark_as_resolved: Märgi lahendatuks mark_as_sensitive: Märgi kui tundlik sisu @@ -832,6 +834,20 @@ et: system_checks: database_schema_check: message_html: On ootel andmebaasi migreerimisi. Rakenduse ootuspäraseks toimimiseks palun käivita need + elasticsearch_health_red: + message_html: Elasticsearch klaster on ebaterve (punane staatus), otsingufunktsioonid ei ole saadaval + elasticsearch_health_yellow: + message_html: Elasticsearch klaster on ebaterve (kollane staatus), võiksid uurida põhjust + elasticsearch_index_mismatch: + message_html: Elasticsearchi indeksite kaardistused on vananenud. Palun käivita tootctl search deploy --only=%{value} + elasticsearch_preset: + action: Vaata dokumentatsiooni + message_html: Elasticsearchi klastris on rohkem kui üks sõlme, kuid Mastodon ei ole nende kasutamiseks konfigureeritud. + elasticsearch_preset_single_node: + action: Vaata dokumentatsiooni + message_html: Elasticsearchi klastris on ainult üks sõlm ES_PRESET peaks olema seatud väärtusele single_node_cluster. + elasticsearch_reset_chewy: + message_html: Elasticsearchi süsteemiindeks on seadistuse muutumise tõttu vananenud. Palun käivita tootctl search deploy --reset-chewy selle uuendamiseks. elasticsearch_running_check: message_html: Elasticsearch ei vasta. Kontrolli, kas see töötab või keela täistekstiotsing elasticsearch_version_check: @@ -1024,6 +1040,14 @@ et: hint_html: Üks asi veel! Me peame veenduma, et oled inimene (et me saaksime spämmi väljaspoole jätta!). Lahenda allpool olev CAPTCHA ja klõpsa "Jätka". title: Turvalisuse kontroll confirmations: + awaiting_review: E-posti aadress on kinnitatud! %{domain} töötajad vaatavad praegu registreeringut läbi. Saad e-kirja, kui nad kiidavad konto heaks! + awaiting_review_title: Su registreeringut vaadatakse läbi + clicking_this_link: klõpsates seda linki + login_link: logi sisse + proceed_to_login_html: Saad nüüd jätkata valikuga %{login_link}. + redirect_to_app_html: Sind oleks pidanud suunatama rakendusse %{app_name}. Kui seda ei juhtunud, proovi %{clicking_this_link} või naase käsitsi rakendusse. + registration_complete: Sinu registreering domeenil %{domain} on nüüd valmis! + welcome_title: Tere tulemast, %{name}! wrong_email_hint: Kui see e-postiaadress pole korrektne, saad seda kontosätetes muuta. delete_account: Konto kustutamine delete_account_html: Kui soovid oma konto kustutada, siis jätka siit. Pead kustutamise eraldi kinnitama. @@ -1085,6 +1109,7 @@ et: functional: Konto on täies mahus kasutatav. pending: Taotlus ootab ülevaatamist meie personali poolt. See võib võtta mõne aja. Kui taotlus on vastu võetud, saadetakse sulle e-kiri. redirecting_to: See konto pole aktiivne, sest on suunatud aadressile %{acct}. + self_destruct: Kuna %{domain} on sulgemisel, saad oma kontole vaid piiratud ligipääsu. view_strikes: Vaata enda eelnevaid juhtumeid too_fast: Vorm esitatud liiga kiirelt, proovi uuesti. use_security_key: Kasuta turvavõtit @@ -1342,6 +1367,7 @@ et: '86400': 1 päev expires_in_prompt: Mitte kunagi generate: Loo + invalid: See kutse pole kehtiv invited_by: 'Sind kutsus:' max_uses: one: 1 kasutus @@ -1554,6 +1580,9 @@ et: over_daily_limit: Lubatud ajastatud postituste arv %{limit} päevas on tänaseks ületatud over_total_limit: Oled jõudnud ajastatud postituste lubatud maksimumarvuni %{limit} too_soon: Ajastatud kuupäev peab olema tukevikus + self_destruct: + lead_html: Kahjuks suletakse %{domain} lõplikult. Kui sul oli seal konto, ei saa sa seda enam kasutada, kuid siiski võid taotleda oma andmete varukoopiat. + title: See server suletakse sessions: activity: Viimane aktiivsus browser: Veebilehitseja diff --git a/config/locales/ja.yml b/config/locales/ja.yml index f7a2c281793cf8..8682f37eec9237 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -599,7 +599,7 @@ ja: created_at: 通報日時 delete_and_resolve: 投稿を削除 forwarded: 転送済み - forwarded_replies_explanation: この報告はリモートユーザーからのものであり、またリモートコンテンツに関するものです。報告されたコンテンツがあなたのユーザーの内の一人に対するリプライの中にあるため、あなたに転送されました。 + forwarded_replies_explanation: これはリモートユーザーによる、リモートコンテンツについての報告です。問題のコンテンツはあなたのサーバー利用者への返信なので、こちらにも転送されて来ました。 forwarded_to: "%{domain}に転送されました" mark_as_resolved: 解決済みとしてマーク mark_as_sensitive: 閲覧注意にする From 49150e2f1d6ae197b160a9dc701f5ac154929ca2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:52:40 +0100 Subject: [PATCH 38/40] Update dependency ws to v8.15.1 (#28343) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 7903ecc5cad8b0..bd2545cf6af90a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17739,8 +17739,8 @@ __metadata: linkType: hard "ws@npm:^8.11.0, ws@npm:^8.12.1, ws@npm:^8.14.2": - version: 8.15.0 - resolution: "ws@npm:8.15.0" + version: 8.15.1 + resolution: "ws@npm:8.15.1" peerDependencies: bufferutil: ^4.0.1 utf-8-validate: ">=5.0.2" @@ -17749,7 +17749,7 @@ __metadata: optional: true utf-8-validate: optional: true - checksum: b778a405b2589ffbf549323e2f404f1f72e372a049d332d2f0b1f33057e9fbb14a05aa474cb156e4584b418cd95edf4297c0ca5263d6519e8009064bf8e0b80d + checksum: 9964360dd5ab35c7376bd7c4295a3c8bd44ea0838c9413742548a6fb3ec371fc6c18552d5b8e76bdc21536db1909765612815bae072674b5ec69971605395a96 languageName: node linkType: hard From 3a59365e40733a502b4a20515e15f8e18b7abe5f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 13 Dec 2023 10:52:43 +0100 Subject: [PATCH 39/40] Update dependency test-prof to v1.3.1 (#28342) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 07b1a4bbe33527..e53e18292e60d1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -759,7 +759,7 @@ GEM unicode-display_width (>= 1.1.1, < 3) terrapin (0.6.0) climate_control (>= 0.0.3, < 1.0) - test-prof (1.3.0) + test-prof (1.3.1) thor (1.3.0) tilt (2.3.0) timeout (0.4.1) From 8a3d8c6c14f4e9b57967104286fa6eaa305e6412 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Wed, 13 Dec 2023 05:14:19 -0500 Subject: [PATCH 40/40] Remove the `stub_stdout` wrapper around CLI specs (#28340) --- lib/mastodon/cli/search.rb | 12 ++- spec/lib/mastodon/cli/accounts_spec.rb | 138 ++++++++++++++++-------- spec/lib/mastodon/cli/ip_blocks_spec.rb | 6 +- spec/lib/mastodon/cli/settings_spec.rb | 3 +- spec/rails_helper.rb | 9 -- 5 files changed, 110 insertions(+), 58 deletions(-) diff --git a/lib/mastodon/cli/search.rb b/lib/mastodon/cli/search.rb index 25a595aadd6d93..77c455f0498bda 100644 --- a/lib/mastodon/cli/search.rb +++ b/lib/mastodon/cli/search.rb @@ -42,7 +42,13 @@ def deploy pool = Concurrent::FixedThreadPool.new(options[:concurrency], max_queue: options[:concurrency] * 10) importers = indices.index_with { |index| "Importer::#{index.name}Importer".constantize.new(batch_size: options[:batch_size], executor: pool) } - progress = ProgressBar.create(total: nil, format: '%t%c/%u |%b%i| %e (%r docs/s)', autofinish: false) + progress = ProgressBar.create( + { + total: nil, + format: '%t%c/%u |%b%i| %e (%r docs/s)', + autofinish: false, + }.merge(progress_output_options) + ) Chewy::Stash::Specification.reset! if options[:reset_chewy] @@ -116,5 +122,9 @@ def verify_deploy_batch_size! say('Cannot run with this batch_size setting, must be at least 1', :red) exit(1) end + + def progress_output_options + Rails.env.test? ? { output: ProgressBar::Outputs::Null } : {} + end end end diff --git a/spec/lib/mastodon/cli/accounts_spec.rb b/spec/lib/mastodon/cli/accounts_spec.rb index 563f6e877d4a3b..64df29ebb33330 100644 --- a/spec/lib/mastodon/cli/accounts_spec.rb +++ b/spec/lib/mastodon/cli/accounts_spec.rb @@ -77,7 +77,8 @@ def account_from_options it_behaves_like 'a new user with given email address and username' it 'creates a new user with confirmed status' do - subject + expect { subject } + .to output_results('New password') user = User.find_by(email: options[:email]) @@ -95,7 +96,8 @@ def account_from_options it_behaves_like 'a new user with given email address and username' it 'creates a new user with approved status' do - subject + expect { subject } + .to output_results('New password') user = User.find_by(email: options[:email]) @@ -111,7 +113,8 @@ def account_from_options it_behaves_like 'a new user with given email address and username' it 'creates a new user and assigns the specified role' do - subject + expect { subject } + .to output_results('New password') role = User.find_by(email: options[:email])&.role @@ -148,7 +151,8 @@ def account_from_options let(:options) { { email: 'tootctl_new@example.com', reattach: true, force: true } } it 'reattaches the account to the new user and deletes the previous user' do - subject + expect { subject } + .to output_results('New password') user = Account.find_local('tootctl_username')&.user @@ -220,7 +224,8 @@ def account_from_options let(:options) { { role: default_role.name } } it "updates the user's role to the specified role" do - subject + expect { subject } + .to output_results('OK') role = user.reload.role @@ -235,7 +240,8 @@ def account_from_options let(:user) { Fabricate(:user, role: role) } it "removes the user's role successfully" do - subject + expect { subject } + .to output_results('OK') role = user.reload.role @@ -248,13 +254,15 @@ def account_from_options let(:options) { { email: 'new_email@email.com' } } it "sets the user's unconfirmed email to the provided email address" do - subject + expect { subject } + .to output_results('OK') expect(user.reload.unconfirmed_email).to eq(options[:email]) end it "does not update the user's original email address" do - subject + expect { subject } + .to output_results('OK') expect(user.reload.email).to eq('old_email@email.com') end @@ -264,13 +272,15 @@ def account_from_options let(:options) { { email: 'new_email@email.com', confirm: true } } it "updates the user's email address to the provided email" do - subject + expect { subject } + .to output_results('OK') expect(user.reload.email).to eq(options[:email]) end it "sets the user's email address as confirmed" do - subject + expect { subject } + .to output_results('OK') expect(user.reload.confirmed?).to be(true) end @@ -282,7 +292,8 @@ def account_from_options let(:options) { { confirm: true } } it "confirms the user's email address" do - subject + expect { subject } + .to output_results('OK') expect(user.reload.confirmed?).to be(true) end @@ -297,7 +308,9 @@ def account_from_options end it 'approves the user' do - expect { subject }.to change { user.reload.approved }.from(false).to(true) + expect { subject } + .to output_results('OK') + .and change { user.reload.approved }.from(false).to(true) end end @@ -306,7 +319,9 @@ def account_from_options let(:options) { { disable: true } } it 'disables the user' do - expect { subject }.to change { user.reload.disabled }.from(false).to(true) + expect { subject } + .to output_results('OK') + .and change { user.reload.disabled }.from(false).to(true) end end @@ -315,7 +330,9 @@ def account_from_options let(:options) { { enable: true } } it 'enables the user' do - expect { subject }.to change { user.reload.disabled }.from(true).to(false) + expect { subject } + .to output_results('OK') + .and change { user.reload.disabled }.from(true).to(false) end end @@ -335,7 +352,9 @@ def account_from_options let(:options) { { disable_2fa: true } } it 'disables the two-factor authentication for the user' do - expect { subject }.to change { user.reload.otp_required_for_login }.from(true).to(false) + expect { subject } + .to output_results('OK') + .and change { user.reload.otp_required_for_login }.from(true).to(false) end end @@ -385,7 +404,8 @@ def account_from_options let(:arguments) { [account.username] } it 'deletes the specified user successfully' do - subject + expect { subject } + .to output_results('Deleting') expect(delete_account_service).to have_received(:call).with(account, reserve_email: false).once end @@ -415,7 +435,8 @@ def account_from_options let(:options) { { email: account.user.email } } it 'deletes the specified user successfully' do - subject + expect { subject } + .to output_results('Deleting') expect(delete_account_service).to have_received(:call).with(account, reserve_email: false).once end @@ -457,7 +478,8 @@ def account_from_options let(:options) { { all: true } } it 'approves all pending registrations' do - subject + expect { subject } + .to output_results('OK') expect(User.pluck(:approved).all?(true)).to be(true) end @@ -468,7 +490,8 @@ def account_from_options let(:options) { { number: 2 } } it 'approves the earliest n pending registrations but not the remaining ones' do - subject + expect { subject } + .to output_results('OK') expect(n_earliest_pending_registrations.all?(&:approved?)).to be(true) expect(pending_registrations.all?(&:approved?)).to be(false) @@ -498,7 +521,7 @@ def pending_registrations it 'approves all users and does not raise any error' do expect { subject } - .to_not raise_error + .to output_results('OK') expect(User.pluck(:approved).all?(true)).to be(true) end end @@ -510,7 +533,8 @@ def pending_registrations let(:arguments) { [user.account.username] } it 'approves the specified user successfully' do - subject + expect { subject } + .to output_results('OK') expect(user.reload.approved?).to be(true) end @@ -655,7 +679,8 @@ def latest_backup allow(remote_account_example_com).to receive(:reset_avatar!) allow(account_example_net).to receive(:reset_avatar!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(remote_account_example_com).to have_received(:reset_avatar!).once @@ -665,7 +690,8 @@ def latest_backup it 'does not refresh avatar for local accounts' do allow(local_account).to receive(:reset_avatar!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(local_account).to_not have_received(:reset_avatar!) @@ -675,7 +701,8 @@ def latest_backup allow(remote_account_example_com).to receive(:reset_header!) allow(account_example_net).to receive(:reset_header!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(remote_account_example_com).to have_received(:reset_header!).once @@ -685,7 +712,8 @@ def latest_backup it 'does not refresh the header for local accounts' do allow(local_account).to receive(:reset_header!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(local_account).to_not have_received(:reset_header!) @@ -706,7 +734,8 @@ def latest_backup allow(remote_account_example_com).to receive(:reset_avatar!) allow(account_example_net).to receive(:reset_avatar!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(local_account).to_not have_received(:reset_avatar!) @@ -719,7 +748,8 @@ def latest_backup allow(remote_account_example_com).to receive(:reset_header!) allow(account_example_net).to receive(:reset_header!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(local_account).to_not have_received(:reset_header!) @@ -752,7 +782,8 @@ def latest_backup allow(account_example_com_a).to receive(:reset_avatar!) allow(account_example_com_b).to receive(:reset_avatar!) - cli.refresh(*arguments) + expect { cli.refresh(*arguments) } + .to output_results('OK') expect(account_example_com_a).to have_received(:reset_avatar!).once expect(account_example_com_b).to have_received(:reset_avatar!).once @@ -761,7 +792,8 @@ def latest_backup it 'does not reset the avatar for unspecified accounts' do allow(account_example_net).to receive(:reset_avatar!) - cli.refresh(*arguments) + expect { cli.refresh(*arguments) } + .to output_results('OK') expect(account_example_net).to_not have_received(:reset_avatar!) end @@ -770,7 +802,8 @@ def latest_backup allow(account_example_com_a).to receive(:reset_header!) allow(account_example_com_b).to receive(:reset_header!) - cli.refresh(*arguments) + expect { cli.refresh(*arguments) } + .to output_results('OK') expect(account_example_com_a).to have_received(:reset_header!).once expect(account_example_com_b).to have_received(:reset_header!).once @@ -779,7 +812,8 @@ def latest_backup it 'does not reset the header for unspecified accounts' do allow(account_example_net).to receive(:reset_header!) - cli.refresh(*arguments) + expect { cli.refresh(*arguments) } + .to output_results('OK') expect(account_example_net).to_not have_received(:reset_header!) end @@ -812,7 +846,8 @@ def latest_backup allow(account_example_com_a).to receive(:reset_avatar!) allow(account_example_com_b).to receive(:reset_avatar!) - cli.refresh(*arguments) + expect { cli.refresh(*arguments) } + .to output_results('OK (DRY RUN)') expect(account_example_com_a).to_not have_received(:reset_avatar!) expect(account_example_com_b).to_not have_received(:reset_avatar!) @@ -822,7 +857,8 @@ def latest_backup allow(account_example_com_a).to receive(:reset_header!) allow(account_example_com_b).to receive(:reset_header!) - cli.refresh(*arguments) + expect { cli.refresh(*arguments) } + .to output_results('OK (DRY RUN)') expect(account_example_com_a).to_not have_received(:reset_header!) expect(account_example_com_b).to_not have_received(:reset_header!) @@ -848,7 +884,8 @@ def latest_backup allow(account_example_com_a).to receive(:reset_avatar!) allow(account_example_com_b).to receive(:reset_avatar!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(account_example_com_a).to have_received(:reset_avatar!).once @@ -858,7 +895,8 @@ def latest_backup it 'does not refresh the avatar for accounts outside specified domain' do allow(account_example_net).to receive(:reset_avatar!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(account_example_net).to_not have_received(:reset_avatar!) @@ -868,7 +906,8 @@ def latest_backup allow(account_example_com_a).to receive(:reset_header!) allow(account_example_com_b).to receive(:reset_header!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope) expect(account_example_com_a).to have_received(:reset_header!).once @@ -878,7 +917,8 @@ def latest_backup it 'does not refresh the header for accounts outside specified domain' do allow(account_example_net).to receive(:reset_header!) - cli.refresh + expect { cli.refresh } + .to output_results('Refreshed 2 accounts') expect(cli).to have_received(:parallelize_with_progress).with(scope).once expect(account_example_net).to_not have_received(:reset_header!) @@ -913,7 +953,8 @@ def latest_backup old_private_key = account.private_key old_public_key = account.public_key - subject + expect { subject } + .to output_results('OK') account.reload expect(account.private_key).to_not eq(old_private_key) @@ -923,7 +964,8 @@ def latest_backup it 'broadcasts the new keys for the specified account' do allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_in) - subject + expect { subject } + .to output_results('OK') expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_in).with(anything, account.id, anything).once end @@ -947,7 +989,8 @@ def latest_backup old_private_keys = accounts.map(&:private_key) old_public_keys = accounts.map(&:public_key) - subject + expect { subject } + .to output_results('rotated') accounts.each(&:reload) expect(accounts.map(&:private_key)).to_not eq(old_private_keys) @@ -957,7 +1000,8 @@ def latest_backup it 'broadcasts the new keys for each account' do allow(ActivityPub::UpdateDistributionWorker).to receive(:perform_in) - subject + expect { subject } + .to output_results('rotated') accounts.each do |account| expect(ActivityPub::UpdateDistributionWorker).to have_received(:perform_in).with(anything, account.id, anything).once @@ -1036,7 +1080,8 @@ def latest_backup end it 'merges `from_account` into `to_account` and deletes `from_account`' do - subject + expect { subject } + .to output_results('OK') expect(to_account).to have_received(:merge_with!).with(from_account).once expect(from_account).to have_received(:destroy).once @@ -1059,7 +1104,8 @@ def latest_backup end it 'merges "from_account" into "to_account" and deletes from_account' do - subject + expect { subject } + .to output_results('OK') expect(to_account).to have_received(:merge_with!).with(from_account).once expect(from_account).to have_received(:destroy) @@ -1339,7 +1385,8 @@ def expect_no_account_prunes shared_examples 'a successful migration' do it 'calls the MoveService for the last migration' do - subject + expect { subject } + .to output_results('OK') last_migration = source_account.migrations.last @@ -1449,7 +1496,8 @@ def expect_no_account_prunes end it 'creates a migration for the specified account with the target account' do - subject + expect { subject } + .to output_results('migrated') last_migration = source_account.migrations.last diff --git a/spec/lib/mastodon/cli/ip_blocks_spec.rb b/spec/lib/mastodon/cli/ip_blocks_spec.rb index 1d6c47268e65f2..82be10813ed02a 100644 --- a/spec/lib/mastodon/cli/ip_blocks_spec.rb +++ b/spec/lib/mastodon/cli/ip_blocks_spec.rb @@ -78,7 +78,8 @@ def blocked_ips_severity it 'overwrites the existing IP block record' do expect { subject } - .to change { blocked_ip.reload.severity } + .to output_results('Added 11') + .and change { blocked_ip.reload.severity } .from('no_access') .to('sign_up_requires_approval') end @@ -189,7 +190,8 @@ def blocked_ips_severity let(:options) { { force: true } } it 'removes blocks for IP ranges that cover given IP(s) and keeps other ranges' do - subject + expect { subject } + .to output_results('Removed 2') expect(covered_ranges).to_not exist expect(other_ranges).to exist diff --git a/spec/lib/mastodon/cli/settings_spec.rb b/spec/lib/mastodon/cli/settings_spec.rb index 568ee00393a1ef..e1b353eb90296d 100644 --- a/spec/lib/mastodon/cli/settings_spec.rb +++ b/spec/lib/mastodon/cli/settings_spec.rb @@ -41,7 +41,8 @@ it 'changes registrations_mode and require_invite_text' do expect { subject } - .to change(Setting, :registrations_mode).from(nil).to('approved') + .to output_results('OK') + .and change(Setting, :registrations_mode).from(nil).to('approved') .and change(Setting, :require_invite_text).from(false).to(true) end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 4394b470e6e284..0e68fbe1219ffe 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -104,7 +104,6 @@ def sign_in(resource, _deprecated = nil, scope: nil) end config.before :each, type: :cli do - stub_stdout stub_reset_connection_pools end @@ -163,14 +162,6 @@ def attachment_fixture(name) Rails.root.join('spec', 'fixtures', 'files', name).open end -def stub_stdout - # TODO: Is there a bettery way to: - # - Avoid CLI command output being printed out - # - Allow rspec to assert things against STDOUT - # - Avoid disabling stdout for other desirable output (deprecation warnings, for example) - allow($stdout).to receive(:write) -end - def stub_reset_connection_pools # TODO: Is there a better way to correctly run specs without stubbing this? # (Avoids reset_connection_pools! in test env)