diff --git a/lib/pleroma/emoji-test.txt b/lib/pleroma/emoji-test.txt
index dd5493366..87d093d64 100644
--- a/lib/pleroma/emoji-test.txt
+++ b/lib/pleroma/emoji-test.txt
@@ -1,13 +1,13 @@
# emoji-test.txt
-# Date: 2021-08-26, 17:22:23 GMT
-# ยฉ 2021 Unicodeยฎ, Inc.
+# Date: 2022-08-12, 20:24:39 GMT
+# ยฉ 2022 Unicodeยฎ, Inc.
# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
-# For terms of use, see http://www.unicode.org/terms_of_use.html
+# For terms of use, see https://www.unicode.org/terms_of_use.html
#
# Emoji Keyboard/Display Test Data for UTS #51
-# Version: 14.0
+# Version: 15.0
#
-# For documentation and usage, see http://www.unicode.org/reports/tr51
+# For documentation and usage, see https://www.unicode.org/reports/tr51
#
# This file provides data for testing which emoji forms should be in keyboards and which should also be displayed/processed.
# Format: code points; status # emoji name
@@ -92,6 +92,7 @@
1F62C ; fully-qualified # ๐ฌ E1.0 grimacing face
1F62E 200D 1F4A8 ; fully-qualified # ๐ฎโ๐จ E13.1 face exhaling
1F925 ; fully-qualified # ๐คฅ E3.0 lying face
+1FAE8 ; fully-qualified # ๐ซจ E15.0 shaking face
# subgroup: face-sleepy
1F60C ; fully-qualified # ๐ E0.6 relieved face
@@ -155,7 +156,7 @@
# subgroup: face-negative
1F624 ; fully-qualified # ๐ค E0.6 face with steam from nose
-1F621 ; fully-qualified # ๐ก E0.6 pouting face
+1F621 ; fully-qualified # ๐ก E0.6 enraged face
1F620 ; fully-qualified # ๐ E0.6 angry face
1F92C ; fully-qualified # ๐คฌ E5.0 face with symbols on mouth
1F608 ; fully-qualified # ๐ E1.0 smiling face with horns
@@ -190,8 +191,7 @@
1F649 ; fully-qualified # ๐ E0.6 hear-no-evil monkey
1F64A ; fully-qualified # ๐ E0.6 speak-no-evil monkey
-# subgroup: emotion
-1F48B ; fully-qualified # ๐ E0.6 kiss mark
+# subgroup: heart
1F48C ; fully-qualified # ๐ E0.6 love letter
1F498 ; fully-qualified # ๐ E0.6 heart with arrow
1F49D ; fully-qualified # ๐ E0.6 heart with ribbon
@@ -210,14 +210,20 @@
2764 200D 1FA79 ; unqualified # โคโ๐ฉน E13.1 mending heart
2764 FE0F ; fully-qualified # โค๏ธ E0.6 red heart
2764 ; unqualified # โค E0.6 red heart
+1FA77 ; fully-qualified # ๐ฉท E15.0 pink heart
1F9E1 ; fully-qualified # ๐งก E5.0 orange heart
1F49B ; fully-qualified # ๐ E0.6 yellow heart
1F49A ; fully-qualified # ๐ E0.6 green heart
1F499 ; fully-qualified # ๐ E0.6 blue heart
+1FA75 ; fully-qualified # ๐ฉต E15.0 light blue heart
1F49C ; fully-qualified # ๐ E0.6 purple heart
1F90E ; fully-qualified # ๐ค E12.0 brown heart
1F5A4 ; fully-qualified # ๐ค E3.0 black heart
+1FA76 ; fully-qualified # ๐ฉถ E15.0 grey heart
1F90D ; fully-qualified # ๐ค E12.0 white heart
+
+# subgroup: emotion
+1F48B ; fully-qualified # ๐ E0.6 kiss mark
1F4AF ; fully-qualified # ๐ฏ E0.6 hundred points
1F4A2 ; fully-qualified # ๐ข E0.6 anger symbol
1F4A5 ; fully-qualified # ๐ฅ E0.6 collision
@@ -226,21 +232,20 @@
1F4A8 ; fully-qualified # ๐จ E0.6 dashing away
1F573 FE0F ; fully-qualified # ๐ณ๏ธ E0.7 hole
1F573 ; unqualified # ๐ณ E0.7 hole
-1F4A3 ; fully-qualified # ๐ฃ E0.6 bomb
1F4AC ; fully-qualified # ๐ฌ E0.6 speech balloon
1F441 FE0F 200D 1F5E8 FE0F ; fully-qualified # ๐๏ธโ๐จ๏ธ E2.0 eye in speech bubble
1F441 200D 1F5E8 FE0F ; unqualified # ๐โ๐จ๏ธ E2.0 eye in speech bubble
-1F441 FE0F 200D 1F5E8 ; unqualified # ๐๏ธโ๐จ E2.0 eye in speech bubble
+1F441 FE0F 200D 1F5E8 ; minimally-qualified # ๐๏ธโ๐จ E2.0 eye in speech bubble
1F441 200D 1F5E8 ; unqualified # ๐โ๐จ E2.0 eye in speech bubble
1F5E8 FE0F ; fully-qualified # ๐จ๏ธ E2.0 left speech bubble
1F5E8 ; unqualified # ๐จ E2.0 left speech bubble
1F5EF FE0F ; fully-qualified # ๐ฏ๏ธ E0.7 right anger bubble
1F5EF ; unqualified # ๐ฏ E0.7 right anger bubble
1F4AD ; fully-qualified # ๐ญ E1.0 thought balloon
-1F4A4 ; fully-qualified # ๐ค E0.6 zzz
+1F4A4 ; fully-qualified # ๐ค E0.6 ZZZ
-# Smileys & Emotion subtotal: 177
-# Smileys & Emotion subtotal: 177 w/o modifiers
+# Smileys & Emotion subtotal: 180
+# Smileys & Emotion subtotal: 180 w/o modifiers
# group: People & Body
@@ -300,6 +305,18 @@
1FAF4 1F3FD ; fully-qualified # ๐ซด๐ฝ E14.0 palm up hand: medium skin tone
1FAF4 1F3FE ; fully-qualified # ๐ซด๐พ E14.0 palm up hand: medium-dark skin tone
1FAF4 1F3FF ; fully-qualified # ๐ซด๐ฟ E14.0 palm up hand: dark skin tone
+1FAF7 ; fully-qualified # ๐ซท E15.0 leftwards pushing hand
+1FAF7 1F3FB ; fully-qualified # ๐ซท๐ป E15.0 leftwards pushing hand: light skin tone
+1FAF7 1F3FC ; fully-qualified # ๐ซท๐ผ E15.0 leftwards pushing hand: medium-light skin tone
+1FAF7 1F3FD ; fully-qualified # ๐ซท๐ฝ E15.0 leftwards pushing hand: medium skin tone
+1FAF7 1F3FE ; fully-qualified # ๐ซท๐พ E15.0 leftwards pushing hand: medium-dark skin tone
+1FAF7 1F3FF ; fully-qualified # ๐ซท๐ฟ E15.0 leftwards pushing hand: dark skin tone
+1FAF8 ; fully-qualified # ๐ซธ E15.0 rightwards pushing hand
+1FAF8 1F3FB ; fully-qualified # ๐ซธ๐ป E15.0 rightwards pushing hand: light skin tone
+1FAF8 1F3FC ; fully-qualified # ๐ซธ๐ผ E15.0 rightwards pushing hand: medium-light skin tone
+1FAF8 1F3FD ; fully-qualified # ๐ซธ๐ฝ E15.0 rightwards pushing hand: medium skin tone
+1FAF8 1F3FE ; fully-qualified # ๐ซธ๐พ E15.0 rightwards pushing hand: medium-dark skin tone
+1FAF8 1F3FF ; fully-qualified # ๐ซธ๐ฟ E15.0 rightwards pushing hand: dark skin tone
# subgroup: hand-fingers-partial
1F44C ; fully-qualified # ๐ E0.6 OK hand
@@ -473,11 +490,11 @@
1F932 1F3FE ; fully-qualified # ๐คฒ๐พ E5.0 palms up together: medium-dark skin tone
1F932 1F3FF ; fully-qualified # ๐คฒ๐ฟ E5.0 palms up together: dark skin tone
1F91D ; fully-qualified # ๐ค E3.0 handshake
-1F91D 1F3FB ; fully-qualified # ๐ค๐ป E3.0 handshake: light skin tone
-1F91D 1F3FC ; fully-qualified # ๐ค๐ผ E3.0 handshake: medium-light skin tone
-1F91D 1F3FD ; fully-qualified # ๐ค๐ฝ E3.0 handshake: medium skin tone
-1F91D 1F3FE ; fully-qualified # ๐ค๐พ E3.0 handshake: medium-dark skin tone
-1F91D 1F3FF ; fully-qualified # ๐ค๐ฟ E3.0 handshake: dark skin tone
+1F91D 1F3FB ; fully-qualified # ๐ค๐ป E14.0 handshake: light skin tone
+1F91D 1F3FC ; fully-qualified # ๐ค๐ผ E14.0 handshake: medium-light skin tone
+1F91D 1F3FD ; fully-qualified # ๐ค๐ฝ E14.0 handshake: medium skin tone
+1F91D 1F3FE ; fully-qualified # ๐ค๐พ E14.0 handshake: medium-dark skin tone
+1F91D 1F3FF ; fully-qualified # ๐ค๐ฟ E14.0 handshake: dark skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FC ; fully-qualified # ๐ซฑ๐ปโ๐ซฒ๐ผ E14.0 handshake: light skin tone, medium-light skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FD ; fully-qualified # ๐ซฑ๐ปโ๐ซฒ๐ฝ E14.0 handshake: light skin tone, medium skin tone
1FAF1 1F3FB 200D 1FAF2 1F3FE ; fully-qualified # ๐ซฑ๐ปโ๐ซฒ๐พ E14.0 handshake: light skin tone, medium-dark skin tone
@@ -1455,7 +1472,7 @@
1F575 1F3FF ; fully-qualified # ๐ต๐ฟ E2.0 detective: dark skin tone
1F575 FE0F 200D 2642 FE0F ; fully-qualified # ๐ต๏ธโโ๏ธ E4.0 man detective
1F575 200D 2642 FE0F ; unqualified # ๐ตโโ๏ธ E4.0 man detective
-1F575 FE0F 200D 2642 ; unqualified # ๐ต๏ธโโ E4.0 man detective
+1F575 FE0F 200D 2642 ; minimally-qualified # ๐ต๏ธโโ E4.0 man detective
1F575 200D 2642 ; unqualified # ๐ตโโ E4.0 man detective
1F575 1F3FB 200D 2642 FE0F ; fully-qualified # ๐ต๐ปโโ๏ธ E4.0 man detective: light skin tone
1F575 1F3FB 200D 2642 ; minimally-qualified # ๐ต๐ปโโ E4.0 man detective: light skin tone
@@ -1469,7 +1486,7 @@
1F575 1F3FF 200D 2642 ; minimally-qualified # ๐ต๐ฟโโ E4.0 man detective: dark skin tone
1F575 FE0F 200D 2640 FE0F ; fully-qualified # ๐ต๏ธโโ๏ธ E4.0 woman detective
1F575 200D 2640 FE0F ; unqualified # ๐ตโโ๏ธ E4.0 woman detective
-1F575 FE0F 200D 2640 ; unqualified # ๐ต๏ธโโ E4.0 woman detective
+1F575 FE0F 200D 2640 ; minimally-qualified # ๐ต๏ธโโ E4.0 woman detective
1F575 200D 2640 ; unqualified # ๐ตโโ E4.0 woman detective
1F575 1F3FB 200D 2640 FE0F ; fully-qualified # ๐ต๐ปโโ๏ธ E4.0 woman detective: light skin tone
1F575 1F3FB 200D 2640 ; minimally-qualified # ๐ต๐ปโโ E4.0 woman detective: light skin tone
@@ -2302,7 +2319,7 @@
1F3CC 1F3FF ; fully-qualified # ๐๐ฟ E4.0 person golfing: dark skin tone
1F3CC FE0F 200D 2642 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 man golfing
1F3CC 200D 2642 FE0F ; unqualified # ๐โโ๏ธ E4.0 man golfing
-1F3CC FE0F 200D 2642 ; unqualified # ๐๏ธโโ E4.0 man golfing
+1F3CC FE0F 200D 2642 ; minimally-qualified # ๐๏ธโโ E4.0 man golfing
1F3CC 200D 2642 ; unqualified # ๐โโ E4.0 man golfing
1F3CC 1F3FB 200D 2642 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 man golfing: light skin tone
1F3CC 1F3FB 200D 2642 ; minimally-qualified # ๐๐ปโโ E4.0 man golfing: light skin tone
@@ -2316,7 +2333,7 @@
1F3CC 1F3FF 200D 2642 ; minimally-qualified # ๐๐ฟโโ E4.0 man golfing: dark skin tone
1F3CC FE0F 200D 2640 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 woman golfing
1F3CC 200D 2640 FE0F ; unqualified # ๐โโ๏ธ E4.0 woman golfing
-1F3CC FE0F 200D 2640 ; unqualified # ๐๏ธโโ E4.0 woman golfing
+1F3CC FE0F 200D 2640 ; minimally-qualified # ๐๏ธโโ E4.0 woman golfing
1F3CC 200D 2640 ; unqualified # ๐โโ E4.0 woman golfing
1F3CC 1F3FB 200D 2640 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 woman golfing: light skin tone
1F3CC 1F3FB 200D 2640 ; minimally-qualified # ๐๐ปโโ E4.0 woman golfing: light skin tone
@@ -2427,7 +2444,7 @@
26F9 1F3FF ; fully-qualified # โน๐ฟ E2.0 person bouncing ball: dark skin tone
26F9 FE0F 200D 2642 FE0F ; fully-qualified # โน๏ธโโ๏ธ E4.0 man bouncing ball
26F9 200D 2642 FE0F ; unqualified # โนโโ๏ธ E4.0 man bouncing ball
-26F9 FE0F 200D 2642 ; unqualified # โน๏ธโโ E4.0 man bouncing ball
+26F9 FE0F 200D 2642 ; minimally-qualified # โน๏ธโโ E4.0 man bouncing ball
26F9 200D 2642 ; unqualified # โนโโ E4.0 man bouncing ball
26F9 1F3FB 200D 2642 FE0F ; fully-qualified # โน๐ปโโ๏ธ E4.0 man bouncing ball: light skin tone
26F9 1F3FB 200D 2642 ; minimally-qualified # โน๐ปโโ E4.0 man bouncing ball: light skin tone
@@ -2441,7 +2458,7 @@
26F9 1F3FF 200D 2642 ; minimally-qualified # โน๐ฟโโ E4.0 man bouncing ball: dark skin tone
26F9 FE0F 200D 2640 FE0F ; fully-qualified # โน๏ธโโ๏ธ E4.0 woman bouncing ball
26F9 200D 2640 FE0F ; unqualified # โนโโ๏ธ E4.0 woman bouncing ball
-26F9 FE0F 200D 2640 ; unqualified # โน๏ธโโ E4.0 woman bouncing ball
+26F9 FE0F 200D 2640 ; minimally-qualified # โน๏ธโโ E4.0 woman bouncing ball
26F9 200D 2640 ; unqualified # โนโโ E4.0 woman bouncing ball
26F9 1F3FB 200D 2640 FE0F ; fully-qualified # โน๐ปโโ๏ธ E4.0 woman bouncing ball: light skin tone
26F9 1F3FB 200D 2640 ; minimally-qualified # โน๐ปโโ E4.0 woman bouncing ball: light skin tone
@@ -2462,7 +2479,7 @@
1F3CB 1F3FF ; fully-qualified # ๐๐ฟ E2.0 person lifting weights: dark skin tone
1F3CB FE0F 200D 2642 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 man lifting weights
1F3CB 200D 2642 FE0F ; unqualified # ๐โโ๏ธ E4.0 man lifting weights
-1F3CB FE0F 200D 2642 ; unqualified # ๐๏ธโโ E4.0 man lifting weights
+1F3CB FE0F 200D 2642 ; minimally-qualified # ๐๏ธโโ E4.0 man lifting weights
1F3CB 200D 2642 ; unqualified # ๐โโ E4.0 man lifting weights
1F3CB 1F3FB 200D 2642 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 man lifting weights: light skin tone
1F3CB 1F3FB 200D 2642 ; minimally-qualified # ๐๐ปโโ E4.0 man lifting weights: light skin tone
@@ -2476,7 +2493,7 @@
1F3CB 1F3FF 200D 2642 ; minimally-qualified # ๐๐ฟโโ E4.0 man lifting weights: dark skin tone
1F3CB FE0F 200D 2640 FE0F ; fully-qualified # ๐๏ธโโ๏ธ E4.0 woman lifting weights
1F3CB 200D 2640 FE0F ; unqualified # ๐โโ๏ธ E4.0 woman lifting weights
-1F3CB FE0F 200D 2640 ; unqualified # ๐๏ธโโ E4.0 woman lifting weights
+1F3CB FE0F 200D 2640 ; minimally-qualified # ๐๏ธโโ E4.0 woman lifting weights
1F3CB 200D 2640 ; unqualified # ๐โโ E4.0 woman lifting weights
1F3CB 1F3FB 200D 2640 FE0F ; fully-qualified # ๐๐ปโโ๏ธ E4.0 woman lifting weights: light skin tone
1F3CB 1F3FB 200D 2640 ; minimally-qualified # ๐๐ปโโ E4.0 woman lifting weights: light skin tone
@@ -3262,8 +3279,8 @@
1FAC2 ; fully-qualified # ๐ซ E13.0 people hugging
1F463 ; fully-qualified # ๐ฃ E0.6 footprints
-# People & Body subtotal: 2986
-# People & Body subtotal: 506 w/o modifiers
+# People & Body subtotal: 2998
+# People & Body subtotal: 508 w/o modifiers
# group: Component
@@ -3306,6 +3323,8 @@
1F405 ; fully-qualified # ๐
E1.0 tiger
1F406 ; fully-qualified # ๐ E1.0 leopard
1F434 ; fully-qualified # ๐ด E0.6 horse face
+1FACE ; fully-qualified # ๐ซ E15.0 moose
+1FACF ; fully-qualified # ๐ซ E15.0 donkey
1F40E ; fully-qualified # ๐ E0.6 horse
1F984 ; fully-qualified # ๐ฆ E1.0 unicorn
1F993 ; fully-qualified # ๐ฆ E5.0 zebra
@@ -3373,6 +3392,9 @@
1F9A9 ; fully-qualified # ๐ฆฉ E12.0 flamingo
1F99A ; fully-qualified # ๐ฆ E11.0 peacock
1F99C ; fully-qualified # ๐ฆ E11.0 parrot
+1FABD ; fully-qualified # ๐ชฝ E15.0 wing
+1F426 200D 2B1B ; fully-qualified # ๐ฆโโฌ E15.0 black bird
+1FABF ; fully-qualified # ๐ชฟ E15.0 goose
# subgroup: animal-amphibian
1F438 ; fully-qualified # ๐ธ E0.6 frog
@@ -3399,6 +3421,7 @@
1F419 ; fully-qualified # ๐ E0.6 octopus
1F41A ; fully-qualified # ๐ E0.6 spiral shell
1FAB8 ; fully-qualified # ๐ชธ E14.0 coral
+1FABC ; fully-qualified # ๐ชผ E15.0 jellyfish
# subgroup: animal-bug
1F40C ; fully-qualified # ๐ E0.6 snail
@@ -3433,6 +3456,7 @@
1F33B ; fully-qualified # ๐ป E0.6 sunflower
1F33C ; fully-qualified # ๐ผ E0.6 blossom
1F337 ; fully-qualified # ๐ท E0.6 tulip
+1FABB ; fully-qualified # ๐ชป E15.0 hyacinth
# subgroup: plant-other
1F331 ; fully-qualified # ๐ฑ E0.6 seedling
@@ -3451,9 +3475,10 @@
1F343 ; fully-qualified # ๐ E0.6 leaf fluttering in wind
1FAB9 ; fully-qualified # ๐ชน E14.0 empty nest
1FABA ; fully-qualified # ๐ชบ E14.0 nest with eggs
+1F344 ; fully-qualified # ๐ E0.6 mushroom
-# Animals & Nature subtotal: 151
-# Animals & Nature subtotal: 151 w/o modifiers
+# Animals & Nature subtotal: 159
+# Animals & Nature subtotal: 159 w/o modifiers
# group: Food & Drink
@@ -3492,10 +3517,11 @@
1F966 ; fully-qualified # ๐ฅฆ E5.0 broccoli
1F9C4 ; fully-qualified # ๐ง E12.0 garlic
1F9C5 ; fully-qualified # ๐ง
E12.0 onion
-1F344 ; fully-qualified # ๐ E0.6 mushroom
1F95C ; fully-qualified # ๐ฅ E3.0 peanuts
1FAD8 ; fully-qualified # ๐ซ E14.0 beans
1F330 ; fully-qualified # ๐ฐ E0.6 chestnut
+1FADA ; fully-qualified # ๐ซ E15.0 ginger root
+1FADB ; fully-qualified # ๐ซ E15.0 pea pod
# subgroup: food-prepared
1F35E ; fully-qualified # ๐ E0.6 bread
@@ -3607,8 +3633,8 @@
1FAD9 ; fully-qualified # ๐ซ E14.0 jar
1F3FA ; fully-qualified # ๐บ E1.0 amphora
-# Food & Drink subtotal: 134
-# Food & Drink subtotal: 134 w/o modifiers
+# Food & Drink subtotal: 135
+# Food & Drink subtotal: 135 w/o modifiers
# group: Travel & Places
@@ -3974,11 +4000,10 @@
1F3AF ; fully-qualified # ๐ฏ E0.6 bullseye
1FA80 ; fully-qualified # ๐ช E12.0 yo-yo
1FA81 ; fully-qualified # ๐ช E12.0 kite
+1F52B ; fully-qualified # ๐ซ E0.6 water pistol
1F3B1 ; fully-qualified # ๐ฑ E0.6 pool 8 ball
1F52E ; fully-qualified # ๐ฎ E0.6 crystal ball
1FA84 ; fully-qualified # ๐ช E13.0 magic wand
-1F9FF ; fully-qualified # ๐งฟ E11.0 nazar amulet
-1FAAC ; fully-qualified # ๐ชฌ E14.0 hamsa
1F3AE ; fully-qualified # ๐ฎ E0.6 video game
1F579 FE0F ; fully-qualified # ๐น๏ธ E0.7 joystick
1F579 ; unqualified # ๐น E0.7 joystick
@@ -4013,8 +4038,8 @@
1F9F6 ; fully-qualified # ๐งถ E11.0 yarn
1FAA2 ; fully-qualified # ๐ชข E13.0 knot
-# Activities subtotal: 97
-# Activities subtotal: 97 w/o modifiers
+# Activities subtotal: 96
+# Activities subtotal: 96 w/o modifiers
# group: Objects
@@ -4040,6 +4065,7 @@
1FA73 ; fully-qualified # ๐ฉณ E12.0 shorts
1F459 ; fully-qualified # ๐ E0.6 bikini
1F45A ; fully-qualified # ๐ E0.6 womanโs clothes
+1FAAD ; fully-qualified # ๐ชญ E15.0 folding hand fan
1F45B ; fully-qualified # ๐ E0.6 purse
1F45C ; fully-qualified # ๐ E0.6 handbag
1F45D ; fully-qualified # ๐ E0.6 clutch bag
@@ -4055,6 +4081,7 @@
1F461 ; fully-qualified # ๐ก E0.6 womanโs sandal
1FA70 ; fully-qualified # ๐ฉฐ E12.0 ballet shoes
1F462 ; fully-qualified # ๐ข E0.6 womanโs boot
+1FAAE ; fully-qualified # ๐ชฎ E15.0 hair pick
1F451 ; fully-qualified # ๐ E0.6 crown
1F452 ; fully-qualified # ๐ E0.6 womanโs hat
1F3A9 ; fully-qualified # ๐ฉ E0.6 top hat
@@ -4103,6 +4130,8 @@
1FA95 ; fully-qualified # ๐ช E12.0 banjo
1F941 ; fully-qualified # ๐ฅ E3.0 drum
1FA98 ; fully-qualified # ๐ช E13.0 long drum
+1FA87 ; fully-qualified # ๐ช E15.0 maracas
+1FA88 ; fully-qualified # ๐ช E15.0 flute
# subgroup: phone
1F4F1 ; fully-qualified # ๐ฑ E0.6 mobile phone
@@ -4275,7 +4304,7 @@
1F5E1 ; unqualified # ๐ก E0.7 dagger
2694 FE0F ; fully-qualified # โ๏ธ E1.0 crossed swords
2694 ; unqualified # โ E1.0 crossed swords
-1F52B ; fully-qualified # ๐ซ E0.6 water pistol
+1F4A3 ; fully-qualified # ๐ฃ E0.6 bomb
1FA83 ; fully-qualified # ๐ช E13.0 boomerang
1F3F9 ; fully-qualified # ๐น E1.0 bow and arrow
1F6E1 FE0F ; fully-qualified # ๐ก๏ธ E0.7 shield
@@ -4354,12 +4383,14 @@
1FAA6 ; fully-qualified # ๐ชฆ E13.0 headstone
26B1 FE0F ; fully-qualified # โฑ๏ธ E1.0 funeral urn
26B1 ; unqualified # โฑ E1.0 funeral urn
+1F9FF ; fully-qualified # ๐งฟ E11.0 nazar amulet
+1FAAC ; fully-qualified # ๐ชฌ E14.0 hamsa
1F5FF ; fully-qualified # ๐ฟ E0.6 moai
1FAA7 ; fully-qualified # ๐ชง E13.0 placard
1FAAA ; fully-qualified # ๐ชช E14.0 identification card
-# Objects subtotal: 304
-# Objects subtotal: 304 w/o modifiers
+# Objects subtotal: 310
+# Objects subtotal: 310 w/o modifiers
# group: Symbols
@@ -4455,6 +4486,7 @@
262E ; unqualified # โฎ E1.0 peace symbol
1F54E ; fully-qualified # ๐ E1.0 menorah
1F52F ; fully-qualified # ๐ฏ E0.6 dotted six-pointed star
+1FAAF ; fully-qualified # ๐ชฏ E15.0 khanda
# subgroup: zodiac
2648 ; fully-qualified # โ E0.6 Aries
@@ -4503,6 +4535,7 @@
1F505 ; fully-qualified # ๐
E1.0 dim button
1F506 ; fully-qualified # ๐ E1.0 bright button
1F4F6 ; fully-qualified # ๐ถ E0.6 antenna bars
+1F6DC ; fully-qualified # ๐ E15.0 wireless
1F4F3 ; fully-qualified # ๐ณ E0.6 vibration mode
1F4F4 ; fully-qualified # ๐ด E0.6 mobile phone off
@@ -4693,8 +4726,8 @@
1F533 ; fully-qualified # ๐ณ E0.6 white square button
1F532 ; fully-qualified # ๐ฒ E0.6 black square button
-# Symbols subtotal: 302
-# Symbols subtotal: 302 w/o modifiers
+# Symbols subtotal: 304
+# Symbols subtotal: 304 w/o modifiers
# group: Flags
@@ -4709,7 +4742,7 @@
1F3F3 200D 1F308 ; unqualified # ๐ณโ๐ E4.0 rainbow flag
1F3F3 FE0F 200D 26A7 FE0F ; fully-qualified # ๐ณ๏ธโโง๏ธ E13.0 transgender flag
1F3F3 200D 26A7 FE0F ; unqualified # ๐ณโโง๏ธ E13.0 transgender flag
-1F3F3 FE0F 200D 26A7 ; unqualified # ๐ณ๏ธโโง E13.0 transgender flag
+1F3F3 FE0F 200D 26A7 ; minimally-qualified # ๐ณ๏ธโโง E13.0 transgender flag
1F3F3 200D 26A7 ; unqualified # ๐ณโโง E13.0 transgender flag
1F3F4 200D 2620 FE0F ; fully-qualified # ๐ดโโ ๏ธ E11.0 pirate flag
1F3F4 200D 2620 ; minimally-qualified # ๐ดโโ E11.0 pirate flag
@@ -4983,9 +5016,9 @@
# Flags subtotal: 275 w/o modifiers
# Status Counts
-# fully-qualified : 3624
-# minimally-qualified : 817
-# unqualified : 252
+# fully-qualified : 3655
+# minimally-qualified : 827
+# unqualified : 242
# component : 9
#EOF
diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex
index 00af77f57..a75d85c47 100644
--- a/lib/pleroma/object.ex
+++ b/lib/pleroma/object.ex
@@ -145,7 +145,7 @@ defp warn_on_no_object_preloaded(ap_id) do
Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}")
end
- def normalize(_, options \\ [fetch: false])
+ def normalize(_, options \\ [fetch: false, id_only: false])
# If we pass an Activity to Object.normalize(), we can try to use the preloaded object.
# Use this whenever possible, especially when walking graphs in an O(N) loop!
@@ -173,10 +173,15 @@ def normalize(%Activity{data: %{"object" => ap_id}}, options) do
def normalize(%{"id" => ap_id}, options), do: normalize(ap_id, options)
def normalize(ap_id, options) when is_binary(ap_id) do
- if Keyword.get(options, :fetch) do
- Fetcher.fetch_object_from_id!(ap_id, options)
- else
- get_cached_by_ap_id(ap_id)
+ cond do
+ Keyword.get(options, :id_only) ->
+ ap_id
+
+ Keyword.get(options, :fetch) ->
+ Fetcher.fetch_object_from_id!(ap_id, options)
+
+ true ->
+ get_cached_by_ap_id(ap_id)
end
end
diff --git a/lib/pleroma/signature.ex b/lib/pleroma/signature.ex
index a71a504b3..043a0643e 100644
--- a/lib/pleroma/signature.ex
+++ b/lib/pleroma/signature.ex
@@ -66,9 +66,8 @@ def refetch_public_key(conn) do
end
end
- def sign(%User{} = user, headers) do
- with {:ok, %{keys: keys}} <- User.ensure_keys_present(user),
- {:ok, private_key, _} <- Keys.keys_from_pem(keys) do
+ def sign(%User{keys: keys} = user, headers) do
+ with {:ok, private_key, _} <- Keys.keys_from_pem(keys) do
HTTPSignatures.sign(private_key, user.ap_id <> "#main-key", headers)
end
end
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 4383f8f53..138f3c851 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -681,9 +681,9 @@ def register_changeset_ldap(struct, params = %{password: password})
|> validate_exclusion(:nickname, Config.get([User, :restricted_nicknames]))
|> validate_format(:nickname, local_nickname_regex())
|> put_ap_id()
- |> put_keys()
|> unique_constraint(:ap_id)
|> put_following_and_follower_and_featured_address()
+ |> put_private_key()
end
def register_changeset(struct, params \\ %{}, opts \\ []) do
@@ -741,10 +741,10 @@ def register_changeset(struct, params \\ %{}, opts \\ []) do
|> validate_length(:registration_reason, max: reason_limit)
|> maybe_validate_required_email(opts[:external])
|> put_password_hash
- |> put_keys()
|> put_ap_id()
|> unique_constraint(:ap_id)
|> put_following_and_follower_and_featured_address()
+ |> put_private_key()
end
def maybe_validate_required_email(changeset, true), do: changeset
@@ -757,11 +757,6 @@ def maybe_validate_required_email(changeset, _) do
end
end
- def put_keys(changeset) do
- {:ok, pem} = Keys.generate_rsa_pem()
- put_change(changeset, :keys, pem)
- end
-
def put_ap_id(changeset) do
ap_id = ap_id(%User{nickname: get_field(changeset, :nickname)})
put_change(changeset, :ap_id, ap_id)
@@ -779,6 +774,11 @@ def put_following_and_follower_and_featured_address(changeset) do
|> put_change(:featured_address, featured)
end
+ defp put_private_key(changeset) do
+ {:ok, pem} = Keys.generate_rsa_pem()
+ put_change(changeset, :keys, pem)
+ end
+
defp autofollow_users(user) do
candidates = Config.get([:instance, :autofollowed_nicknames])
@@ -1955,6 +1955,7 @@ defp create_service_actor(uri, nickname) do
follower_address: uri <> "/followers"
}
|> change
+ |> put_private_key()
|> unique_constraint(:nickname)
|> Repo.insert()
|> set_cache()
@@ -2220,17 +2221,6 @@ def get_mascot(%{mascot: mascot}) when is_nil(mascot) do
}
end
- def ensure_keys_present(%{keys: keys} = user) when not is_nil(keys), do: {:ok, user}
-
- def ensure_keys_present(%User{} = user) do
- with {:ok, pem} <- Keys.generate_rsa_pem() do
- user
- |> cast(%{keys: pem}, [:keys])
- |> validate_required([:keys])
- |> update_and_set_cache()
- end
- end
-
def get_ap_ids_by_nicknames(nicknames) do
from(u in User,
where: u.nickname in ^nicknames,
diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
index 1eb0a3620..c07f91b2e 100644
--- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex
+++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex
@@ -66,8 +66,7 @@ defp relay_active?(conn, _) do
end
def user(conn, %{"nickname" => nickname}) do
- with %User{local: true} = user <- User.get_cached_by_nickname(nickname),
- {:ok, user} <- User.ensure_keys_present(user) do
+ with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do
conn
|> put_resp_content_type("application/activity+json")
|> put_view(UserView)
@@ -174,7 +173,6 @@ def relay_following(conn, _params) do
def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do
with %User{} = user <- User.get_cached_by_nickname(nickname),
- {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user),
{:show_follows, true} <-
{:show_follows, (for_user && for_user == user) || !user.hide_follows} do
{page, _} = Integer.parse(page)
@@ -192,8 +190,7 @@ def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "p
end
def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do
- with %User{} = user <- User.get_cached_by_nickname(nickname),
- {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do
+ with %User{} = user <- User.get_cached_by_nickname(nickname) do
conn
|> put_resp_content_type("application/activity+json")
|> put_view(UserView)
@@ -213,7 +210,6 @@ def relay_followers(conn, _params) do
def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do
with %User{} = user <- User.get_cached_by_nickname(nickname),
- {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user),
{:show_followers, true} <-
{:show_followers, (for_user && for_user == user) || !user.hide_followers} do
{page, _} = Integer.parse(page)
@@ -231,8 +227,7 @@ def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "p
end
def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do
- with %User{} = user <- User.get_cached_by_nickname(nickname),
- {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do
+ with %User{} = user <- User.get_cached_by_nickname(nickname) do
conn
|> put_resp_content_type("application/activity+json")
|> put_view(UserView)
@@ -245,8 +240,7 @@ def outbox(
%{"nickname" => nickname, "page" => page?} = params
)
when page? in [true, "true"] do
- with %User{} = user <- User.get_cached_by_nickname(nickname),
- {:ok, user} <- User.ensure_keys_present(user) do
+ with %User{} = user <- User.get_cached_by_nickname(nickname) do
# "include_poll_votes" is a hack because postgres generates inefficient
# queries when filtering by 'Answer', poll votes will be hidden by the
# visibility filter in this case anyway
@@ -270,8 +264,7 @@ def outbox(
end
def outbox(conn, %{"nickname" => nickname}) do
- with %User{} = user <- User.get_cached_by_nickname(nickname),
- {:ok, user} <- User.ensure_keys_present(user) do
+ with %User{} = user <- User.get_cached_by_nickname(nickname) do
conn
|> put_resp_content_type("application/activity+json")
|> put_view(UserView)
@@ -328,14 +321,10 @@ defp post_inbox_relayed_create(conn, params) do
end
defp represent_service_actor(%User{} = user, conn) do
- with {:ok, user} <- User.ensure_keys_present(user) do
- conn
- |> put_resp_content_type("application/activity+json")
- |> put_view(UserView)
- |> render("user.json", %{user: user})
- else
- nil -> {:error, :not_found}
- end
+ conn
+ |> put_resp_content_type("application/activity+json")
+ |> put_view(UserView)
+ |> render("user.json", %{user: user})
end
defp represent_service_actor(nil, _), do: {:error, :not_found}
@@ -388,12 +377,10 @@ def read_inbox(
def read_inbox(%{assigns: %{user: %User{nickname: nickname} = user}} = conn, %{
"nickname" => nickname
}) do
- with {:ok, user} <- User.ensure_keys_present(user) do
- conn
- |> put_resp_content_type("application/activity+json")
- |> put_view(UserView)
- |> render("activity_collection.json", %{iri: "#{user.ap_id}/inbox"})
- end
+ conn
+ |> put_resp_content_type("application/activity+json")
+ |> put_view(UserView)
+ |> render("activity_collection.json", %{iri: "#{user.ap_id}/inbox"})
end
def read_inbox(%{assigns: %{user: %User{nickname: as_nickname}}} = conn, %{
@@ -530,19 +517,6 @@ defp set_requester_reachable(%Plug.Conn{} = conn, _) do
conn
end
- defp ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do
- {:ok, new_user} = User.ensure_keys_present(user)
-
- for_user =
- if new_user != user and match?(%User{}, for_user) do
- User.get_cached_by_nickname(for_user.nickname)
- else
- for_user
- end
-
- {new_user, for_user}
- end
-
def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do
with {:ok, object} <-
ActivityPub.upload(
diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex
index d9b59406c..29e2bbc81 100644
--- a/lib/pleroma/web/activity_pub/views/object_view.ex
+++ b/lib/pleroma/web/activity_pub/views/object_view.ex
@@ -29,11 +29,11 @@ def render("object.json", %{object: %Activity{data: %{"type" => activity_type}}
def render("object.json", %{object: %Activity{} = activity}) do
base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header()
- object = Object.normalize(activity, fetch: false)
+ object_id = Object.normalize(activity, id_only: true)
additional =
Transmogrifier.prepare_object(activity.data)
- |> Map.put("object", object.data["id"])
+ |> Map.put("object", object_id)
Map.merge(base, additional)
end
diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
index 760515f34..310f3ce3e 100644
--- a/lib/pleroma/web/activity_pub/views/user_view.ex
+++ b/lib/pleroma/web/activity_pub/views/user_view.ex
@@ -34,7 +34,6 @@ def render("endpoints.json", %{user: %User{local: true} = _user}) do
def render("endpoints.json", _), do: %{}
def render("service.json", %{user: user}) do
- {:ok, user} = User.ensure_keys_present(user)
{:ok, _, public_key} = Keys.keys_from_pem(user.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
@@ -71,7 +70,6 @@ def render("user.json", %{user: %User{nickname: "internal." <> _} = user}),
do: render("service.json", %{user: user}) |> Map.put("preferredUsername", user.nickname)
def render("user.json", %{user: user}) do
- {:ok, user} = User.ensure_keys_present(user)
{:ok, _, public_key} = Keys.keys_from_pem(user.keys)
public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key)
public_key = :public_key.pem_encode([public_key])
diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex
index 82fb9e4e0..bc61130f1 100644
--- a/lib/pleroma/web/federator.ex
+++ b/lib/pleroma/web/federator.ex
@@ -69,10 +69,8 @@ def perform(:publish_one, module, params) do
def perform(:publish, activity) do
Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end)
- with %User{} = actor <- User.get_cached_by_ap_id(activity.data["actor"]),
- {:ok, actor} <- User.ensure_keys_present(actor) do
- Publisher.publish(actor, activity)
- end
+ %User{} = actor = User.get_cached_by_ap_id(activity.data["actor"])
+ Publisher.publish(actor, activity)
end
def perform(:incoming_ap_doc, params) do
diff --git a/lib/pleroma/web/metadata/utils.ex b/lib/pleroma/web/metadata/utils.ex
index caca42934..8990bef54 100644
--- a/lib/pleroma/web/metadata/utils.ex
+++ b/lib/pleroma/web/metadata/utils.ex
@@ -8,8 +8,8 @@ defmodule Pleroma.Web.Metadata.Utils do
alias Pleroma.Formatter
alias Pleroma.HTML
- def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do
- content
+ defp scrub_html_and_truncate_object_field(field, object) do
+ field
# html content comes from DB already encoded, decode first and scrub after
|> HtmlEntities.decode()
|> String.replace(~r/
/, " ")
@@ -19,6 +19,17 @@ def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do
|> Formatter.truncate()
end
+ def scrub_html_and_truncate(%{data: %{"summary" => summary}} = object)
+ when is_binary(summary) and summary != "" do
+ summary
+ |> scrub_html_and_truncate_object_field(object)
+ end
+
+ def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do
+ content
+ |> scrub_html_and_truncate_object_field(object)
+ end
+
def scrub_html_and_truncate(content, max_length \\ 200) when is_binary(content) do
content
|> scrub_html
diff --git a/lib/pleroma/web/plugs/o_auth_plug.ex b/lib/pleroma/web/plugs/o_auth_plug.ex
index 5e06ac3f6..91f6e9974 100644
--- a/lib/pleroma/web/plugs/o_auth_plug.ex
+++ b/lib/pleroma/web/plugs/o_auth_plug.ex
@@ -47,15 +47,17 @@ def call(conn, _) do
#
@spec fetch_user_and_token(String.t()) :: {:ok, User.t(), Token.t()} | nil
defp fetch_user_and_token(token) do
- query =
+ token_query =
from(t in Token,
- where: t.token == ^token,
- join: user in assoc(t, :user),
- preload: [user: user]
+ where: t.token == ^token
)
- with %Token{user: user} = token_record <- Repo.one(query) do
+ with %Token{user_id: user_id} = token_record <- Repo.one(token_query),
+ false <- is_nil(user_id),
+ %User{} = user <- User.get_cached_by_id(user_id) do
{:ok, user, token_record}
+ else
+ _ -> nil
end
end
diff --git a/lib/pleroma/web/web_finger.ex b/lib/pleroma/web/web_finger.ex
index b5f2cb72e..f5a46ce25 100644
--- a/lib/pleroma/web/web_finger.ex
+++ b/lib/pleroma/web/web_finger.ex
@@ -69,8 +69,6 @@ defp gather_aliases(%User{} = user) do
end
def represent_user(user, "JSON") do
- {:ok, user} = User.ensure_keys_present(user)
-
%{
"subject" => "acct:#{user.nickname}@#{domain()}",
"aliases" => gather_aliases(user),
@@ -79,8 +77,6 @@ def represent_user(user, "JSON") do
end
def represent_user(user, "XML") do
- {:ok, user} = User.ensure_keys_present(user)
-
aliases =
user
|> gather_aliases()
diff --git a/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs b/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs
new file mode 100644
index 000000000..43bc7100b
--- /dev/null
+++ b/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs
@@ -0,0 +1,28 @@
+# Pleroma: A lightweight social networking server
+# Copyright ยฉ 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Repo.Migrations.GenerateUnsetUserKeys do
+ use Ecto.Migration
+ import Ecto.Query
+ alias Pleroma.Keys
+ alias Pleroma.Repo
+ alias Pleroma.User
+
+ def change do
+ query =
+ from(u in User,
+ where: u.local == true,
+ where: is_nil(u.keys),
+ select: u
+ )
+
+ Repo.stream(query)
+ |> Enum.each(fn user ->
+ with {:ok, pem} <- Keys.generate_rsa_pem() do
+ Ecto.Changeset.cast(user, %{keys: pem}, [:keys])
+ |> Repo.update()
+ end
+ end)
+ end
+end
diff --git a/test/fixtures/rsa_keys/key_1.pem b/test/fixtures/rsa_keys/key_1.pem
new file mode 100644
index 000000000..3da357500
--- /dev/null
+++ b/test/fixtures/rsa_keys/key_1.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEA2gdPJM5bWarGZ6QujfQ296l1yEQohS5fdtnxYQc+RXuS1gqZ
+R/jVGHG25o4tmwyCLClyREU1CBTOCQBsg+BSehXlxNR9fiB4KaVQW9MMNa2vhHuG
+f7HLdILiC+SPPTV1Bi8LCpxJowiSpnFPP4BDDeRKib7nOxll9Ln9gEpUueKKabsQ
+EQKCmEJYhIz/8g5R0Qz+6VjASdejDjTEdZbr/rwyldRRjIklyeZ3lBzB/c8/51wn
+HT2Dt0r9NiapxYC3oNhbE2A+4FU9pZTqS8yc3KqWZAy74snaRO9QQSednKlOJpXP
+V3vwWo5CxuSNLttV7zRcrqeYOkIVNF4dQ/bHzQIDAQABAoIBADTCfglnEj4BkF92
+IHnjdgW6cTEUJUYNMba+CKY1LYF85Mx85hi/gzmWEu95yllxznJHWUpiAPJCrpUJ
+EDldaDf44pAd53xE+S8CvQ5rZNH8hLOnfKWb7aL1JSRBm9PxAq+LZL2dkkgsg+hZ
+FRdFv3Q2IT9x/dyUSdLNyyVnV1dfoya/7zOFc7+TwqlofznzrlBgNoAe8Lb4AN/q
+itormPxskqATiq11XtP4F6eQ556eRgHCBxmktx/rRDl6f9G9dvjRQOA2qZlHQdFq
+kjOZsrvItL46LdVoLPOdCYG+3HFeKoDUR1NNXEkt66eqmEhLY4MgzGUT1wqXWk7N
+XowZc9UCgYEA+L5h4PhANiY5Kd+PkRI8zTlJMv8hFqLK17Q0p9eL+mAyOgXjH9so
+QutJf4wU+h6ESDxH+1tCjCN307uUqT7YnT2zHf3b6GcmA+t6ewxfxOY2nJ82HENq
+hK1aodnPTvRRRqCGfrx9qUHRTarTzi+2u86zH+KoMHSiuzn4VpQhg4MCgYEA4GOL
+1tLR9+hyfYuMFo2CtQjp3KpJeGNKEqc33vFD05xJQX+m5THamBv8vzdVlVrMh/7j
+iV85mlA7HaaP+r5DGwtonw9bqY76lYRgJJprsS5lHcRnXsDmU4Ne8RdB3dHNsT5P
+n4P6v8y4jaT638iJ/qLt4e8itOBlZwS//VIglm8CgYEA7KXD3RKRlHK9A7drkOs2
+6VBM8bWEN1LdhGYvilcpFyUZ49XiBVatcS0EGdKdym/qDgc7vElQgJ7ly4y0nGfs
+EXy3whrYcrxfkG8hcZuOKXeUEWHvSuhgmKWMilr8PfN2t6jVDBIrwzGY/Tk+lPUT
+9o1qITW0KZVtlI5MU6JOWB0CgYAHwwnETZibxbuoIhqfcRezYXKNgop2EqEuUgB5
+wsjA2igijuLcDMRt/JHan3RjbTekAKooR1X7w4i39toGJ2y008kzr1lRXTPH1kNp
+ILpW767pv7B/s5aEDwhKuK47mRVPa0Nf1jXnSpKbu7g943b6ivJFnXsK3LRFQwHN
+JnkgGwKBgGUleQVd2GPr1dkqLVOF/s2aNB/+h2b1WFWwq0YTnW81OLwAcUVE4p58
+3GQgz8PCsWbNdTb9yFY5fq0fXgi0+T54FEoZWH09DrOepA433llAwI6sq7egrFdr
+kKQttZMzs6ST9q/IOF4wgqSnBjjTC06vKSkNAlXJz+LMvIRMeBr0
+-----END RSA PRIVATE KEY-----
diff --git a/test/fixtures/rsa_keys/key_2.pem b/test/fixtures/rsa_keys/key_2.pem
new file mode 100644
index 000000000..7a8e8e670
--- /dev/null
+++ b/test/fixtures/rsa_keys/key_2.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAwu0VqVGRVDW09V3zZ0+08K9HMKivIzIInO0xim3jbfVcg8r1
+sR7vNLorYAB6TDDlXYAWKx1OxUMZusbOigrpQd+5wy8VdCogDD7qk4bbZ+NjXkuD
+ETzrQsGWUXe+IdeH8L0Zh0bGjbarCuA0qAeY1TEteGl+Qwo2dsrBUH7yKmWO6Mz9
+XfPshrIDOGo4QNyVfEBNGq2K9eRrQUHeAPcM2/qu4ZAZRK+VCifDZrF8ZNpoAsnS
+R2mJDhOBUMvI/ZaxOc2ry4EzwcS4uBaM2wONkGWDaqO6jNAQflaX7vtzOAeJB7Dt
+VKXUUcZAGN7uI3c2mG5IKGMhTYUtUdrzmqmtZwIDAQABAoIBAQCHBJfTf3dt4AGn
+T9twfSp06MQj9UPS2i5THI0LONCm8qSReX0zoZzJZgbzaYFM0zWczUMNvDA6vR7O
+XDTmM2acxW4zv6JZo3Ata0sqwuepDz1eLGnt/8dppxQK/ClL4bH8088h/6k6sgPJ
+9cEjfpejXHwFgvT9VM6i/BBpRHVTXWuJqwpDtg+bleQNN3L3RapluDd7BGiKoCwQ
+cCTKd+lxTu9gVJkbRTI/Jn3kV+rnedYxHTxVp5cU1qIabsJWBcdDz25mRHupxQsn
+JbQR4+ZnRLeAsC6WJZtEJz2KjXgBaYroHbGZY3KcGW95ILqiCJoJJugbW1eABKnN
+Q5k8XVspAoGBAPzGJBZuX3c0quorhMIpREmGq2vS6VCQwLhH5qayYYH1LiPDfpdq
+69lOROxZodzLxBgTf5z/a5kBF+eNKvOqfZJeRTxmllxxO1MuJQuRLi/b7BHHLuyN
+Eea+YwtehA0T0CbD2hydefARNDruor2BLvt/kt6qEoIFiPauTsMfXP39AoGBAMVp
+8argtnB+vsk5Z7rpQ4b9gF5QxfNbA0Hpg5wUUdYrUjFr50KWt1iowj6AOVp/EYgr
+xRfvOQdYODDH7R5cjgMbwvtpHo39Zwq7ewaiT1sJXnpGmCDVh+pdTHePC5OOXnxN
+0USK3M4KjltjVqJo7xPPElgJvCejudD47mtHMaQzAoGBAIFQ/PVc0goyL55NVUXf
+xse21cv7wtEsvOuKHT361FegD1LMmN7uHGq32BryYBSNSmzmzMqNAYbtQEV9uxOd
+jVBsWg9kjFgOtcMAQIOCapahdExEEoWCRj49+H3AhN4L3Nl4KQWqqs9efdIIc8lv
+ZZHU2lZ/u6g5HLDWzASW7wQhAoGAdERPRrqN+HdNWinrA9Q6JxjKL8IWs5rYsksb
+biMxh5eAEwdf7oHhfd/2duUB4mCQLMjKjawgxEia33AAIS+VnBMPpQ5mJm4l79Y3
+QNL7Nbyw3gcRtdTM9aT5Ujj3MnJZB5C1PU8jeF4TNZOuBH0UwW/ld+BT5myxFXhm
+wtvtSq0CgYEA19b0/7il4Em6uiLOmYUuqaUoFhUPqzjaS6OM/lRAw12coWv/8/1P
+cwaNZHNMW9Me/bNH3zcOTz0lxnYp2BeRehjFYVPRuS1GU7uwqKtlL2wCPptTfAhN
+aJWIplzUCTg786u+sdNZ0umWRuCLoUpsKTgP/yt4RglzEcfxAuBDljk=
+-----END RSA PRIVATE KEY-----
diff --git a/test/fixtures/rsa_keys/key_3.pem b/test/fixtures/rsa_keys/key_3.pem
new file mode 100644
index 000000000..fbd25c80f
--- /dev/null
+++ b/test/fixtures/rsa_keys/key_3.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEA0GvzqZ3r78GLa7guGn+palKRLGru4D4jnriHgfrUAJrdLyZ5
+9d0zAA4qnS2L6YAMoPPBhBUtIV5e2sn1+rwTClWU3dm3FyBAeqdeIBKN+04AyrUc
+HXYaZtOPJXCTeytzoSQE359Tq6+xwgoHlUWSWxQF51/z/PDQcUvqFjJqAtdiDchd
+3CiFRtdjegyxXGnqvPmBix+vEjDytcVydfch+R1Twf6f5EL7a1jFVWNGcratYBEl
+nqOWKI2fBu/WA8QlrcVW5zmtZo9aJ6IrFddQgQTxPk/mEHgCzv8tbCRI9TxiXeYH
+YqxZFYBW40xbZQwGRjaYHJlIRYp9+TOynW9OZQIDAQABAoIBAQC97cIMDbdVsyAk
+N6D70N5H35ofygqJGtdG6o3B6xuKuZVaREvbu4mgQUigF0Nqs5/OhJMSlGGeCOuT
+oXug1Abd4gNY7++jCWb43tAtlfsAyaJ7FvPZ/SguEBhgW+hp07z5WWN/jSeoSuFI
+G++xHcczbFm88XncRG8O78kQFTz5/DlQYkFXfbqpuS3BqxnrACpDCUfrUwZNYFIp
+CUNq21jdifhHwlS0K3PX8A5HdOYeVnVHaE78LGE4oJVHwcokELv+PYqarWZq/a6L
+vKU3yn2+4pj2WO490iGQaRKVM35vrtjdVxiWEIUiFc3Jg5fKZA3wuHXoF1N1DpPO
+BO6Att55AoGBAP/nC2szmDcnU5Sh8LDeQbL+FpSBwOmFnmel5uqbjKnDzf9emPQu
+NFUls1N9OGgyUq08TnmcY/7wLZzcu7Y9XOUURuYtx9nGRs4RmE2VEBhK1r7CkDIx
+oOb+NtdqnPtQASAxCHszoGCFxpuV7UVoo2SRgc+M4ceX128arvBUtvdrAoGBANCA
+RuO3eelkXaJoCeogEUVWXZ6QmPeYzbMD4vg2DM0ynUbReyuEIIhn+SR7tehlj5ie
+4T3ixVdur6k+YUdiFhUYgXaHBJWHoHl1lrU3ZON8n7AeEk9ft6gg4L07ouj78UMZ
+sArJIlU5mLnW02zbV9XryU39dIgpQREqC0bIOtVvAoGBAORv1JKq6Rt7ALJy6VCJ
+5y4ogfGp7pLHk8NEpuERYDz/rLllMbbwNAk6cV17L8pb+c/pQMhwohcnQiCALxUc
+q/tW4X+CqJ+vzu8PZ90Bzu9Qh2iceGpGQTNTBZPA+UeigI7DFqYcTPM9GDE1YiyO
+nyUcezvSsI4i7s6gjD+/7+DnAoGABm3+QaV1z/m1XX3B2IN2pOG971bcML54kW2s
+QSVBjc5ixT1OhBAGBM7YAwUBnhILtJQptAPbPBAAwMJYs5/VuH7R9zrArG/LRhOX
+Oy1jIhTEw+SZgfMcscWZyJwfMPob/Yq8QAjl0yT8jbaPPIsjEUi9I3eOcWh8RjA6
+ussP7WcCgYEAm3yvJR9z6QGoQQwtDbwjyZPYOSgK9wFS/65aupi6cm/Qk2N1YaLY
+q2amNrzNsIc9vQwYGEHUwogn4MieHk96V7m2f0Hx9EHCMwizU9EiS6oyiLVowTG6
+YsBgSzcpnt0Vkgil4CQks5uQoan0tubEUQ5DI79lLnb02n4o46iAYK0=
+-----END RSA PRIVATE KEY-----
diff --git a/test/fixtures/rsa_keys/key_4.pem b/test/fixtures/rsa_keys/key_4.pem
new file mode 100644
index 000000000..f72b29fb1
--- /dev/null
+++ b/test/fixtures/rsa_keys/key_4.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAw6MLRbP/henX2JxwdMkQlskKghBoMyUPu9kZpUQ9yYfIm9I4
+a3gEfzef75jKLOSf+BkZulvEUGjC+VnkpV3s+OZCSq81Ykv5PHuTqbj8Cn/dEt/g
+lBXxPcOBKWqa+1cDX6QVIVJsBihLB/1b64H3U96Yu9+knmXvT1Az5MFA2KtSq7HJ
+O+GJNn0EMI7xwPz/atUGlMLrhzwS4UDpw9CAaRPojplJYl4K1JMCFTgTt3hJILXZ
+tw1MKTeeyWzNiuQRBQJuCnqfvsBYsasIlHWfqIL/uBzcGHHCIK5ZW9luntJXyLVj
+zzaF7etIJk1uddM2wnqOOaVyqbssZXGt7Tb9IQIDAQABAoIBAH5QJRUKFK8Xvp9C
+0nD06NsSTtCPW1e6VCBLGf3Uw7f9DY9d+cOZp/2jooYGNnMp4gdD3ZKvcV8hZNGu
+Mqx6qmhB8wdZfLRMrU1Z1Is+vqzgxZJMLiouyKXCNwDQreQd2DXGMUZkew62sUsl
+UFYMge4KyL50tUr4Mb0Z4YePJxk804tcqgw0n+D0lR7ZKhSqoQpoMqEiO+27Yw7E
+Txj/MKH8f/ZJ6LBLRISOdBOrxonHqqeYWchczykCwojOZc3bIlWZGhg727dFTHDC
+yrj3/zsZ2hy+TQsucCFY0RljIbacmHvrF/VqfhTIhg98H0F27V/jiPGsdKhptyst
+E9iQVMkCgYEA42ge4H2Wl42sRh61GOrOgzzr0WZS54bF5skMxiGGnLwnb82rwUBt
+xw94PRORJbV9l+2fkxbfiW0uzornfN8OBHSB64Pcjzzbl5Qm+eaDOiuTLtakYOWQ
+/ipGqw8iE4J9iRteZCo8GnMxWbTkYCporTlFDTeYguXmwR4yCXtlCbMCgYEA3DxM
+7R5HMUWRe64ucdekMh742McS8q/X5jdN9iFGy0M8P1WTyspSlaPDXgjaO4XqpRqg
+djkL993kCDvOAiDl6Tpdiu1iFcOaRLb19Tj1pm8sKdk6X4d10U9lFri4NVYCmvVi
+yOahUYFK/k5bA+1o+KU9Pi82H36H3WNeF4evC9sCgYEAs1zNdc04uQKiTZAs0KFr
+DzI+4aOuYjT35ObQr3mD/h2dkV6MSNmzfF1kPfAv/KkgjXN7+H0DBRbb40bF/MTF
+/peSXZtcnJGote7Bqzu4Z2o1Ja1ga5jF+uKHaKZ//xleQIUYtzJkw4v18cZulrb8
+ZxyTrTAbl6sTjWBuoPH1qGcCgYEAsQNahR9X81dKJpGKTQAYvhw8wOfI5/zD2ArN
+g62dXBRPYUxkPJM/q3xzs6oD1eG+BjQPktYpM3FKLf/7haRxhnLd6qL/uiR8Ywx3
+RkEg2EP0yDIMA+o5nSFmS8vuaxgVgf0HCBiuwnbcEuhhqRdxzp/pSIjjxI6LnzqV
+zu3EmQ8CgYEAhq8Uhvw+79tK7q2PCjDbiucA0n/4a3aguuvRoEh7F93Pf6VGZmT+
+Yld54Cd4P5ATI3r5YdD+JBuvgNMOTVPCaD/WpjbJKnrpNEXtXRQD6LzAXZDNk0sF
+IO9i4gjhBolRykWn10khoPdxw/34FWBP5SxU1JYk75NQXvI3TD+5xbU=
+-----END RSA PRIVATE KEY-----
diff --git a/test/fixtures/rsa_keys/key_5.pem b/test/fixtures/rsa_keys/key_5.pem
new file mode 100644
index 000000000..49342b54e
--- /dev/null
+++ b/test/fixtures/rsa_keys/key_5.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpgIBAAKCAQEA0jdKtMkgqnEGO3dn4OKxtggfFDzv+ddXToO0cdPXkUgPajCo
+UGPunz+A1KmkAmLY0Vwk0tkOmKK8GFHek/5zQ+1N2FHBi19fbwlJk7hzh5OiYRhu
+YZi0d6LsqEMKhDk6NqIeiFmOe2YHgklVvZV0hebvHlHLgzDhYrDltSPe33UZa3MS
+g2Knf4WQAjLOo2BAb+oyj/UNXeAqaMGcOr6/kAHPcODW2EGhF3H3umFLv7t/Kq5i
+WPBgarbCGPR5qq9SW5ZIjS3Sz0dl105Grw8wU23CC/2IBZ5vNiu+bkmLEoh/KpX2
+YBILoLmwtVX0Qxc15CrpOi12p+/4pLR8kuEowQIDAQABAoIBAQDMDQ3AJMdHisSQ
+7pvvyDzWRFXesDQE4YmG1gNOxmImTLthyW9n8UjMXbjxNOXVxxtNRdMcs8MeWECa
+nsWeBEzgr7VzeBCV9/LL9kjsUgwamyzwcOWcaL0ssAJmZgUMSfx+0akvkzbiAyzg
+w8ytZSihXYPYe28/ni/5O1sOFI6feenOnJ9NSmVUA24c9TTJGNQs7XRUMZ8f9wt6
+KwRmYeNDKyqH7NvLmmKoDp6m7bMDQxWArVTAoRWTVApnj35iLQtmSi8DBdw6xSzQ
+fKpUe/B4iQmMNxUW7KmolOvCIS5wcYZJE+/j7xshA2GGnOpx4aC+N+w2GSX4Bz/q
+OnYSpGUBAoGBAOwnSeg17xlZqmd86qdiCxg0hRtAjwrd7btYq6nkK+t9woXgcV99
+FBS3nLbk/SIdXCW8vHFJTmld60j2q2kdestYBdHznwNZJ4Ee8JhamzcC64wY7O0x
+RameO/6uoKS4C3VF+Zc9CCPfZOqYujkGvSqbTjFZWuFtDp0GHDk+qEIRAoGBAOPh
++PCB2QkGgiujSPmuCT5PTuNylAug3D4ZdMRKpQb9Rnzlia1Rpdrihq+PvB2vwa+S
+mB6dgb0E7M2AyEMVu5buris0mVpRdmEeLCXR8mYJ48kOslIGArEStXDetfbRaXdK
+7vf4APq2d78AQYldU2fYlo754Dh/3MZIguzpqMuxAoGBAIDJqG/AQiYkFV+c62ff
+e0d3FQRYv+ngQE9Eu1HKwv0Jt7VFQu8din8F56yC013wfxmBhY+Ot/mUo8VF6RNJ
+ZXdSCNKINzcfPwEW+4VLHIzyxbzAty1gCqrHRdbOK4PJb05EnCqTuUW/Bg0+v4hs
+GWwMCKe3IG4CCM8vzuKVPjPRAoGBANYCQtJDb3q9ZQPsTb1FxyKAQprx4Lzm7c9Y
+AsPRQhhFRaxHuLtPQU5FjK1VdBoBFAl5x2iBDPVhqa348pml0E0Xi/PBav9aH61n
+M5i1CUrwoL4SEj9bq61133XHgeXwlnZUpgW0H99T+zMh32pMfea5jfNqETueQMzq
+DiLF8SKRAoGBAOFlU0kRZmAx3Y4rhygp1ydPBt5+zfDaGINRWEN7QWjhX2QQan3C
+SnXZlP3POXLessKxdCpBDq/RqVQhLea6KJMfP3F0YbohfWHt96WjiriJ0d0ZYVhu
+34aUM2UGGG0Kia9OVvftESBaXk02vrY9zU3LAVAv0eLgIADm1kpj85v7
+-----END RSA PRIVATE KEY-----
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index 645622e43..9d35f9780 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -620,15 +620,15 @@ test "it blocks blacklisted email domains" do
assert changeset.valid?
end
- test "it sets the password_hash, ap_id and PEM key" do
+ test "it sets the password_hash, ap_id, private key and followers collection address" do
changeset = User.register_changeset(%User{}, @full_user_data)
assert changeset.valid?
assert is_binary(changeset.changes[:password_hash])
+ assert is_binary(changeset.changes[:keys])
assert changeset.changes[:ap_id] == User.ap_id(%User{nickname: @full_user_data.nickname})
assert is_binary(changeset.changes[:keys])
-
assert changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
end
@@ -2130,21 +2130,6 @@ test "Only includes users with no read notifications" do
end
end
- describe "ensure_keys_present" do
- test "it creates keys for a user and stores them in info" do
- user = insert(:user)
- refute is_binary(user.keys)
- {:ok, user} = User.ensure_keys_present(user)
- assert is_binary(user.keys)
- end
-
- test "it doesn't create keys if there already are some" do
- user = insert(:user, keys: "xxx")
- {:ok, user} = User.ensure_keys_present(user)
- assert user.keys == "xxx"
- end
- end
-
describe "get_ap_ids_by_nicknames" do
test "it returns a list of AP ids for a given set of nicknames" do
user = insert(:user)
diff --git a/test/pleroma/web/activity_pub/views/object_view_test.exs b/test/pleroma/web/activity_pub/views/object_view_test.exs
index 923515dec..9348c09be 100644
--- a/test/pleroma/web/activity_pub/views/object_view_test.exs
+++ b/test/pleroma/web/activity_pub/views/object_view_test.exs
@@ -81,4 +81,18 @@ test "renders an announce activity" do
assert result["object"] == object.data["id"]
assert result["type"] == "Announce"
end
+
+ test "renders an undo announce activity" do
+ note = insert(:note_activity)
+ user = insert(:user)
+
+ {:ok, announce} = CommonAPI.repeat(note.id, user)
+ {:ok, undo} = CommonAPI.unrepeat(note.id, user)
+
+ result = ObjectView.render("object.json", %{object: undo})
+
+ assert result["id"] == undo.data["id"]
+ assert result["object"] == announce.data["id"]
+ assert result["type"] == "Undo"
+ end
end
diff --git a/test/pleroma/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs
index e49cb99d3..5501e64d6 100644
--- a/test/pleroma/web/activity_pub/views/user_view_test.exs
+++ b/test/pleroma/web/activity_pub/views/user_view_test.exs
@@ -12,7 +12,6 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do
test "Renders a user, including the public key" do
user = insert(:user)
- {:ok, user} = User.ensure_keys_present(user)
result = UserView.render("user.json", %{user: user})
@@ -55,7 +54,6 @@ test "Renders with emoji tags" do
test "Does not add an avatar image if the user hasn't set one" do
user = insert(:user)
- {:ok, user} = User.ensure_keys_present(user)
result = UserView.render("user.json", %{user: user})
refute result["icon"]
@@ -67,8 +65,6 @@ test "Does not add an avatar image if the user hasn't set one" do
banner: %{"url" => [%{"href" => "https://somebanner"}]}
)
- {:ok, user} = User.ensure_keys_present(user)
-
result = UserView.render("user.json", %{user: user})
assert result["icon"]["url"] == "https://someurl"
assert result["image"]["url"] == "https://somebanner"
@@ -89,7 +85,6 @@ test "renders AKAs" do
describe "endpoints" do
test "local users have a usable endpoints structure" do
user = insert(:user)
- {:ok, user} = User.ensure_keys_present(user)
result = UserView.render("user.json", %{user: user})
@@ -105,7 +100,6 @@ test "local users have a usable endpoints structure" do
test "remote users have an empty endpoints structure" do
user = insert(:user, local: false)
- {:ok, user} = User.ensure_keys_present(user)
result = UserView.render("user.json", %{user: user})
@@ -115,7 +109,6 @@ test "remote users have an empty endpoints structure" do
test "instance users do not expose oAuth endpoints" do
user = insert(:user, nickname: nil, local: true)
- {:ok, user} = User.ensure_keys_present(user)
result = UserView.render("user.json", %{user: user})
diff --git a/test/pleroma/web/metadata/providers/twitter_card_test.exs b/test/pleroma/web/metadata/providers/twitter_card_test.exs
index 1b8d27cda..5d7ad08ef 100644
--- a/test/pleroma/web/metadata/providers/twitter_card_test.exs
+++ b/test/pleroma/web/metadata/providers/twitter_card_test.exs
@@ -39,6 +39,7 @@ test "it uses summary twittercard if post has no attachment" do
"actor" => user.ap_id,
"tag" => [],
"id" => "https://pleroma.gov/objects/whatever",
+ "summary" => "",
"content" => "pleroma in a nutshell"
}
})
@@ -54,6 +55,36 @@ test "it uses summary twittercard if post has no attachment" do
] == result
end
+ test "it uses summary as description if post has one" do
+ user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
+ {:ok, activity} = CommonAPI.post(user, %{status: "HI"})
+
+ note =
+ insert(:note, %{
+ data: %{
+ "actor" => user.ap_id,
+ "tag" => [],
+ "id" => "https://pleroma.gov/objects/whatever",
+ "summary" => "Public service announcement on caffeine consumption",
+ "content" => "cofe"
+ }
+ })
+
+ result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
+
+ assert [
+ {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
+ {:meta,
+ [
+ property: "twitter:description",
+ content: "Public service announcement on caffeine consumption"
+ ], []},
+ {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
+ []},
+ {:meta, [property: "twitter:card", content: "summary"], []}
+ ] == result
+ end
+
test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabled" do
clear_config([Pleroma.Web.Metadata, :unfurl_nsfw], false)
user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
@@ -65,6 +96,7 @@ test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabl
"actor" => user.ap_id,
"tag" => [],
"id" => "https://pleroma.gov/objects/whatever",
+ "summary" => "",
"content" => "pleroma in a nutshell",
"sensitive" => true,
"attachment" => [
@@ -109,6 +141,7 @@ test "it renders supported types of attachments and skips unknown types" do
"actor" => user.ap_id,
"tag" => [],
"id" => "https://pleroma.gov/objects/whatever",
+ "summary" => "",
"content" => "pleroma in a nutshell",
"attachment" => [
%{
diff --git a/test/pleroma/web/metadata/utils_test.exs b/test/pleroma/web/metadata/utils_test.exs
index c99d11596..665efb9ca 100644
--- a/test/pleroma/web/metadata/utils_test.exs
+++ b/test/pleroma/web/metadata/utils_test.exs
@@ -8,7 +8,7 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
alias Pleroma.Web.Metadata.Utils
describe "scrub_html_and_truncate/1" do
- test "it returns text without encode HTML" do
+ test "it returns content text without encode HTML if summary is nil" do
user = insert(:user)
note =
@@ -16,6 +16,7 @@ test "it returns text without encode HTML" do
data: %{
"actor" => user.ap_id,
"id" => "https://pleroma.gov/objects/whatever",
+ "summary" => nil,
"content" => "Pleroma's really cool!"
}
})
@@ -23,6 +24,39 @@ test "it returns text without encode HTML" do
assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
end
+ test "it returns context text without encode HTML if summary is empty" do
+ user = insert(:user)
+
+ note =
+ insert(:note, %{
+ data: %{
+ "actor" => user.ap_id,
+ "id" => "https://pleroma.gov/objects/whatever",
+ "summary" => "",
+ "content" => "Pleroma's really cool!"
+ }
+ })
+
+ assert Utils.scrub_html_and_truncate(note) == "Pleroma's really cool!"
+ end
+
+ test "it returns summary text without encode HTML if summary is filled" do
+ user = insert(:user)
+
+ note =
+ insert(:note, %{
+ data: %{
+ "actor" => user.ap_id,
+ "id" => "https://pleroma.gov/objects/whatever",
+ "summary" => "Public service announcement on caffeine consumption",
+ "content" => "cofe"
+ }
+ })
+
+ assert Utils.scrub_html_and_truncate(note) ==
+ "Public service announcement on caffeine consumption"
+ end
+
test "it does not return old content after editing" do
user = insert(:user)
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 6695886dc..efcd8039e 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -10,6 +10,15 @@ defmodule Pleroma.Factory do
alias Pleroma.Object
alias Pleroma.User
+ @rsa_keys [
+ "test/fixtures/rsa_keys/key_1.pem",
+ "test/fixtures/rsa_keys/key_2.pem",
+ "test/fixtures/rsa_keys/key_3.pem",
+ "test/fixtures/rsa_keys/key_4.pem",
+ "test/fixtures/rsa_keys/key_5.pem"
+ ]
+ |> Enum.map(&File.read!/1)
+
def participation_factory do
conversation = insert(:conversation)
user = insert(:user)
@@ -28,6 +37,8 @@ def conversation_factory do
end
def user_factory(attrs \\ %{}) do
+ pem = Enum.random(@rsa_keys)
+
user = %User{
name: sequence(:name, &"Test ใในใ User #{&1}"),
email: sequence(:email, &"user#{&1}@example.com"),
@@ -39,7 +50,8 @@ def user_factory(attrs \\ %{}) do
last_refreshed_at: NaiveDateTime.utc_now(),
notification_settings: %Pleroma.User.NotificationSetting{},
multi_factor_authentication_settings: %Pleroma.MFA.Settings{},
- ap_enabled: true
+ ap_enabled: true,
+ keys: pem
}
urls =