Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into fine_grained_moderation_privileges
This commit is contained in:
commit
60df2d8a97
308 changed files with 36503 additions and 1957 deletions
2
test/fixtures/config/temp.secret.exs
vendored
2
test/fixtures/config/temp.secret.exs
vendored
|
|
@ -8,8 +8,6 @@ config :pleroma, :first_setting, key: "value", key2: [Pleroma.Repo]
|
|||
|
||||
config :pleroma, :second_setting, key: "value2", key2: ["Activity"]
|
||||
|
||||
config :quack, level: :info
|
||||
|
||||
config :pleroma, Pleroma.Repo, pool: Ecto.Adapters.SQL.Sandbox
|
||||
|
||||
config :postgrex, :json_library, Poison
|
||||
|
|
|
|||
61
test/fixtures/create-pleroma-reply-to-misskey-thread.json
vendored
Normal file
61
test/fixtures/create-pleroma-reply-to-misskey-thread.json
vendored
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://p.helene.moe/schemas/litepub-0.1.jsonld",
|
||||
{
|
||||
"@language": "und"
|
||||
}
|
||||
],
|
||||
"actor": "https://p.helene.moe/users/helene",
|
||||
"attachment": [],
|
||||
"attributedTo": "https://p.helene.moe/users/helene",
|
||||
"cc": [
|
||||
"https://p.helene.moe/users/helene/followers"
|
||||
],
|
||||
"context": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d",
|
||||
"conversation": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d",
|
||||
"directMessage": false,
|
||||
"id": "https://p.helene.moe/activities/5f80db86-a9bb-4883-9845-fbdbd1478f3a",
|
||||
"object": {
|
||||
"actor": "https://p.helene.moe/users/helene",
|
||||
"attachment": [],
|
||||
"attributedTo": "https://p.helene.moe/users/helene",
|
||||
"cc": [
|
||||
"https://p.helene.moe/users/helene/followers"
|
||||
],
|
||||
"content": "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"AHntpQ4T3J4OSnpgMC\" href=\"https://mk.absturztau.be/@mametsuko\" rel=\"ugc\">@<span>mametsuko</span></a></span> meow",
|
||||
"context": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d",
|
||||
"conversation": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d",
|
||||
"id": "https://p.helene.moe/objects/fd5910ac-d9dc-412e-8d1d-914b203296c4",
|
||||
"inReplyTo": "https://mk.absturztau.be/notes/93e7nm8wqg",
|
||||
"published": "2022-08-02T13:46:58.403996Z",
|
||||
"sensitive": null,
|
||||
"source": "@mametsuko@mk.absturztau.be meow",
|
||||
"summary": "",
|
||||
"tag": [
|
||||
{
|
||||
"href": "https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"name": "@mametsuko@mk.absturztau.be",
|
||||
"type": "Mention"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
"https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type": "Note"
|
||||
},
|
||||
"published": "2022-08-02T13:46:58.403883Z",
|
||||
"tag": [
|
||||
{
|
||||
"href": "https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"name": "@mametsuko@mk.absturztau.be",
|
||||
"type": "Mention"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
"https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type": "Create"
|
||||
}
|
||||
31
test/fixtures/owncast-note-with-attachment.json
vendored
Normal file
31
test/fixtures/owncast-note-with-attachment.json
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"attachment": {
|
||||
"content": "Live stream preview",
|
||||
"type": "Image",
|
||||
"url": "https://owncast.localhost.localdomain/preview.gif?us=KjfNX387gm"
|
||||
},
|
||||
"attributedTo": "https://owncast.localhost.localdomain/federation/user/streamer",
|
||||
"audience": "https://www.w3.org/ns/activitystreams#Public",
|
||||
"content": "<p>I've gone live!</p><p></p><p><a class=\"hashtag\" href=\"https://directory.owncast.online/tags/owncast\">#owncast</a> <a class=\"hashtag\" href=\"https://directory.owncast.online/tags/streaming\">#streaming</a></p><a href=\"https://owncast.localhost.localdomain\">https://owncast.localhost.localdomain</a>",
|
||||
"id": "https://owncast.localhost.localdomain/federation/KjBNuq8ng",
|
||||
"published": "2022-04-17T15:42:03Z",
|
||||
"tag": [
|
||||
{
|
||||
"href": "https://directory.owncast.online/tags/owncast",
|
||||
"name": "#owncast",
|
||||
"type": "Hashtag"
|
||||
},
|
||||
{
|
||||
"href": "https://directory.owncast.online/tags/streaming",
|
||||
"name": "#streaming",
|
||||
"type": "Hashtag"
|
||||
},
|
||||
{
|
||||
"href": "https://directory.owncast.online/tags/owncast",
|
||||
"name": "#owncast",
|
||||
"type": "Hashtag"
|
||||
}
|
||||
],
|
||||
"to": "https://www.w3.org/ns/activitystreams#Public",
|
||||
"type": "Note"
|
||||
}
|
||||
27
test/fixtures/rsa_keys/key_1.pem
vendored
Normal file
27
test/fixtures/rsa_keys/key_1.pem
vendored
Normal file
|
|
@ -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-----
|
||||
27
test/fixtures/rsa_keys/key_2.pem
vendored
Normal file
27
test/fixtures/rsa_keys/key_2.pem
vendored
Normal file
|
|
@ -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-----
|
||||
27
test/fixtures/rsa_keys/key_3.pem
vendored
Normal file
27
test/fixtures/rsa_keys/key_3.pem
vendored
Normal file
|
|
@ -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-----
|
||||
27
test/fixtures/rsa_keys/key_4.pem
vendored
Normal file
27
test/fixtures/rsa_keys/key_4.pem
vendored
Normal file
|
|
@ -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-----
|
||||
27
test/fixtures/rsa_keys/key_5.pem
vendored
Normal file
27
test/fixtures/rsa_keys/key_5.pem
vendored
Normal file
|
|
@ -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-----
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><hm:Host xmlns:hm="http://host-meta.net/xrd/1.0">framatube.org</hm:Host><Link rel="lrdd" template="http://framatube.org/main/xrd?uri={uri}"><Title>Resource Descriptor</Title></Link></XRD>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><hm:Host xmlns:hm="http://host-meta.net/xrd/1.0">framatube.org</hm:Host><Link rel="lrdd" template="https://framatube.org/main/xrd?uri={uri}"><Title>Resource Descriptor</Title></Link></XRD>
|
||||
|
|
|
|||
50
test/fixtures/tesla_mock/helene@p.helene.moe.json
vendored
Normal file
50
test/fixtures/tesla_mock/helene@p.helene.moe.json
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://p.helene.moe/schemas/litepub-0.1.jsonld",
|
||||
{
|
||||
"@language": "und"
|
||||
}
|
||||
],
|
||||
"alsoKnownAs": [],
|
||||
"attachment": [
|
||||
{
|
||||
"name": "Timezone",
|
||||
"type": "PropertyValue",
|
||||
"value": "UTC+2 (Paris/Berlin)"
|
||||
}
|
||||
],
|
||||
"capabilities": {
|
||||
"acceptsChatMessages": true
|
||||
},
|
||||
"discoverable": true,
|
||||
"endpoints": {
|
||||
"oauthAuthorizationEndpoint": "https://p.helene.moe/oauth/authorize",
|
||||
"oauthRegistrationEndpoint": "https://p.helene.moe/api/v1/apps",
|
||||
"oauthTokenEndpoint": "https://p.helene.moe/oauth/token",
|
||||
"sharedInbox": "https://p.helene.moe/inbox",
|
||||
"uploadMedia": "https://p.helene.moe/api/ap/upload_media"
|
||||
},
|
||||
"featured": "https://p.helene.moe/users/helene/collections/featured",
|
||||
"followers": "https://p.helene.moe/users/helene/followers",
|
||||
"following": "https://p.helene.moe/users/helene/following",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": "https://p.helene.moe/media/9a39209daa5a66b7ebb0547b08bf8360aa9d8d65a4ffba2603c6ffbe6aecb432.jpg"
|
||||
},
|
||||
"id": "https://p.helene.moe/users/helene",
|
||||
"inbox": "https://p.helene.moe/users/helene/inbox",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"name": "Hélène",
|
||||
"outbox": "https://p.helene.moe/users/helene/outbox",
|
||||
"preferredUsername": "helene",
|
||||
"publicKey": {
|
||||
"id": "https://p.helene.moe/users/helene#main-key",
|
||||
"owner": "https://p.helene.moe/users/helene",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtoSBPU/VS2Kx3f6ap3zv\nZVacJsgUfaoFb3c2ii/FRh9RmRVlarq8sJXcjsQt1e0oxWaWJaIDDwyKZPt6hXae\nrY/AiGGeNu+NA+BtY7l7+9Yu67HUyT62+1qAwYHKBXX3fLOPs/YmQI0Tt0c4wKAG\nKEkiYsRizghgpzUC6jqdKV71DJkUZ8yhckCGb2fLko1ajbWEssdaP51aLsyRMyC2\nuzeWrxtD4O/HG0ea4S6y5X6hnsAHIK4Y3nnyIQ6pn4tOsl3HgqkjXE9MmZSvMCFx\nBq89TfZrVXNa2gSZdZLdbbJstzEScQWNt1p6tA6rM+e4JXYGr+rMdF3G+jV7afI2\nFQIDAQAB\n-----END PUBLIC KEY-----\n\n"
|
||||
},
|
||||
"summary": "I can speak: Français, English, Deutsch (nicht sehr gut), 日本語 (not very well)",
|
||||
"tag": [],
|
||||
"type": "Person",
|
||||
"url": "https://p.helene.moe/users/helene"
|
||||
}
|
||||
1
test/fixtures/tesla_mock/https___lm.kazv.moe_users_mewmew.xml
vendored
Normal file
1
test/fixtures/tesla_mock/https___lm.kazv.moe_users_mewmew.xml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Subject>acct:mewmew@lm.kazv.moe</Subject><Alias>https://lm.kazv.moe/users/mewmew</Alias><Alias>https://lm.kazv.moe/users/tester</Alias><Alias>https://lm.kazv.moe/users/testuser</Alias><Link href="https://lm.kazv.moe/users/mewmew" rel="http://webfinger.net/rel/profile-page" type="text/html" /><Link href="https://lm.kazv.moe/users/mewmew" rel="self" type="application/activity+json" /><Link href="https://lm.kazv.moe/users/mewmew" rel="self" type="application/ld+json; profile="https://www.w3.org/ns/activitystreams"" /><Link rel="http://ostatus.org/schema/1.0/subscribe" template="https://lm.kazv.moe/ostatus_subscribe?acct={uri}" /></XRD>
|
||||
1
test/fixtures/tesla_mock/lm.kazv.moe_host_meta
vendored
Normal file
1
test/fixtures/tesla_mock/lm.kazv.moe_host_meta
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="https://lm.kazv.moe/.well-known/webfinger?resource={uri}" type="application/xrd+xml" /></XRD>
|
||||
65
test/fixtures/tesla_mock/mametsuko@mk.absturztau.be.json
vendored
Normal file
65
test/fixtures/tesla_mock/mametsuko@mk.absturztau.be.json
vendored
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"sensitive": "as:sensitive",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"quoteUrl": "as:quoteUrl",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"Emoji": "toot:Emoji",
|
||||
"featured": "toot:featured",
|
||||
"discoverable": "toot:discoverable",
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value",
|
||||
"misskey": "https://misskey-hub.net/ns#",
|
||||
"_misskey_content": "misskey:_misskey_content",
|
||||
"_misskey_quote": "misskey:_misskey_quote",
|
||||
"_misskey_reaction": "misskey:_misskey_reaction",
|
||||
"_misskey_votes": "misskey:_misskey_votes",
|
||||
"_misskey_talk": "misskey:_misskey_talk",
|
||||
"isCat": "misskey:isCat",
|
||||
"vcard": "http://www.w3.org/2006/vcard/ns#"
|
||||
}
|
||||
],
|
||||
"type": "Person",
|
||||
"id": "https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"inbox": "https://mk.absturztau.be/users/8ozbzjs3o8/inbox",
|
||||
"outbox": "https://mk.absturztau.be/users/8ozbzjs3o8/outbox",
|
||||
"followers": "https://mk.absturztau.be/users/8ozbzjs3o8/followers",
|
||||
"following": "https://mk.absturztau.be/users/8ozbzjs3o8/following",
|
||||
"featured": "https://mk.absturztau.be/users/8ozbzjs3o8/collections/featured",
|
||||
"sharedInbox": "https://mk.absturztau.be/inbox",
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://mk.absturztau.be/inbox"
|
||||
},
|
||||
"url": "https://mk.absturztau.be/@mametsuko",
|
||||
"preferredUsername": "mametsuko",
|
||||
"name": "mametschko",
|
||||
"summary": "<p><span>nya, ich bin eine Brotperson</span></p>",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": "https://mk.absturztau.be/files/webpublic-3b5594f4-fa52-4548-b4e3-c379ae2143ed",
|
||||
"sensitive": false,
|
||||
"name": null
|
||||
},
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"url": "https://mk.absturztau.be/files/webpublic-0d03b03d-b14b-4916-ac3d-8a137118ec84",
|
||||
"sensitive": false,
|
||||
"name": null
|
||||
},
|
||||
"tag": [],
|
||||
"manuallyApprovesFollowers": true,
|
||||
"discoverable": false,
|
||||
"publicKey": {
|
||||
"id": "https://mk.absturztau.be/users/8ozbzjs3o8#main-key",
|
||||
"type": "Key",
|
||||
"owner": "https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuN/S1spBGmh8FXI1Bt16\nXB7Cc0QutBp7UPgmDNHjOfsq0zrF4g3L1UBxvrpU0XX77XPMCd9yPvGwAYURH2mv\ntIcYuE+R90VLDmBu5MTVthcG2D874eCZ2rD2YsEYmN5AjTX7QBIqCck+qDhVWkkM\nEZ6S5Ht6IJ5Of74eKffXElQI/C6QB+9uEDOmPk0jCzgI5gw7xvJqFj/DIF4kUUAu\nA89JqaFZzZlkrSrj4cr48bLN/YOmpdaHu0BKHaDSHct4+MqlixqovgdB6RboCEDw\ne4Aeav7+Q0Y9oGIvuggg0Q+nCubnVNnaPyzd817tpPVzyZmTts+DKyDuv90SX3nR\nsPaNa5Ty60eqplUk4b7X1gSvuzBJUFBxTVV84WnjwoeoydaS6rSyjCDPGLBjaByc\nFyWMMEb/zlQyhLZfBlvT7k96wRSsMszh2hDALWmgYIhq/jNwINvALJ1GKLNHHKZ4\nyz2LnxVpRm2rWrZzbvtcnSQOt3LaPSZn8Wgwv4buyHF02iuVuIamZVtKexsE1Ixl\nIi9qa3AKEc5gOzYXhRhvHaruzoCehUbb/UHC5c8Tto8L5G1xYzjLP3qj3PT9w/wM\n+k1Ra/4JhuAnVFROOoOmx9rIELLHH7juY2nhM7plGhyt1M5gysgqEloij8QzyQU2\nZK1YlAERG2XFO6br8omhcmECAwEAAQ==\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"isCat": true,
|
||||
"vcard:Address": "Vienna, Austria"
|
||||
}
|
||||
1
test/fixtures/tesla_mock/mewmew@lm.kazv.moe.json
vendored
Normal file
1
test/fixtures/tesla_mock/mewmew@lm.kazv.moe.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"@context":["https://www.w3.org/ns/activitystreams","https://lm.kazv.moe/schemas/litepub-0.1.jsonld",{"@language":"und"}],"alsoKnownAs":["https://lm.kazv.moe/users/tester","https://lm.kazv.moe/users/testuser"],"attachment":[],"capabilities":{"acceptsChatMessages":true},"discoverable":false,"endpoints":{"oauthAuthorizationEndpoint":"https://lm.kazv.moe/oauth/authorize","oauthRegistrationEndpoint":"https://lm.kazv.moe/api/v1/apps","oauthTokenEndpoint":"https://lm.kazv.moe/oauth/token","sharedInbox":"https://lm.kazv.moe/inbox","uploadMedia":"https://lm.kazv.moe/api/ap/upload_media"},"featured":"https://lm.kazv.moe/users/mewmew/collections/featured","followers":"https://lm.kazv.moe/users/mewmew/followers","following":"https://lm.kazv.moe/users/mewmew/following","id":"https://lm.kazv.moe/users/mewmew","inbox":"https://lm.kazv.moe/users/mewmew/inbox","manuallyApprovesFollowers":false,"name":"mew","outbox":"https://lm.kazv.moe/users/mewmew/outbox","preferredUsername":"mewmew","publicKey":{"id":"https://lm.kazv.moe/users/mewmew#main-key","owner":"https://lm.kazv.moe/users/mewmew","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0nT3IVUwx799FSJyJEOY\n5D2c5zgtt2Z+BD9417eVLmVQF5fJlWgcKS4pbFc76zkYoBkZtV7XbzvN9KTNulpa\nUGNOM0/UdEoQLB8xbVCMm0ABUU8vbTWoMTxp93bfVHBz+33FPYdH1JHX4TCU/mJF\nX4UJMvFmMn5BFjSQm9GG6Eq2j6SAUsaTa8+Rrd8FzS6zb/dk3N/Llz0tfsZYS0sq\nEy9OYhsKOQ6eegULFJOF3Hz04vzwftmeXFsbb3aO2zKz3uAMYZglWHNBYJAePBtJ\ng362kqdJwgT14TFnZ0K2ziDPbkRULG1Kke/lsqw2rPF6Q6P4PeO1shCEDthoDoID\newIDAQAB\n-----END PUBLIC KEY-----\n\n"},"summary":"","tag":[],"type":"Person","url":"https://lm.kazv.moe/users/mewmew"}
|
||||
1
test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json
vendored
Normal file
1
test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","sensitive":"as:sensitive","Hashtag":"as:Hashtag","quoteUrl":"as:quoteUrl","toot":"http://joinmastodon.org/ns#","Emoji":"toot:Emoji","featured":"toot:featured","discoverable":"toot:discoverable","schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value","misskey":"https://misskey-hub.net/ns#","_misskey_content":"misskey:_misskey_content","_misskey_quote":"misskey:_misskey_quote","_misskey_reaction":"misskey:_misskey_reaction","_misskey_votes":"misskey:_misskey_votes","_misskey_talk":"misskey:_misskey_talk","isCat":"misskey:isCat","vcard":"http://www.w3.org/2006/vcard/ns#"}],"id":"https://mk.absturztau.be/notes/93e7nm8wqg/activity","actor":"https://mk.absturztau.be/users/8ozbzjs3o8","type":"Create","published":"2022-08-01T11:06:49.568Z","object":{"id":"https://mk.absturztau.be/notes/93e7nm8wqg","type":"Note","attributedTo":"https://mk.absturztau.be/users/8ozbzjs3o8","summary":null,"content":"<p><span>meow</span></p>","_misskey_content":"meow","published":"2022-08-01T11:06:49.568Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mk.absturztau.be/users/8ozbzjs3o8/followers"],"inReplyTo":null,"attachment":[],"sensitive":false,"tag":[]},"to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://mk.absturztau.be/users/8ozbzjs3o8/followers"]}
|
||||
44
test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg.json
vendored
Normal file
44
test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg.json
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"sensitive": "as:sensitive",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"quoteUrl": "as:quoteUrl",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"Emoji": "toot:Emoji",
|
||||
"featured": "toot:featured",
|
||||
"discoverable": "toot:discoverable",
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value",
|
||||
"misskey": "https://misskey-hub.net/ns#",
|
||||
"_misskey_content": "misskey:_misskey_content",
|
||||
"_misskey_quote": "misskey:_misskey_quote",
|
||||
"_misskey_reaction": "misskey:_misskey_reaction",
|
||||
"_misskey_votes": "misskey:_misskey_votes",
|
||||
"_misskey_talk": "misskey:_misskey_talk",
|
||||
"isCat": "misskey:isCat",
|
||||
"vcard": "http://www.w3.org/2006/vcard/ns#"
|
||||
}
|
||||
],
|
||||
"id": "https://mk.absturztau.be/notes/93e7nm8wqg",
|
||||
"type": "Note",
|
||||
"attributedTo": "https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"summary": null,
|
||||
"content": "<p><span>meow</span></p>",
|
||||
"_misskey_content": "meow",
|
||||
"published": "2022-08-01T11:06:49.568Z",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://mk.absturztau.be/users/8ozbzjs3o8/followers"
|
||||
],
|
||||
"inReplyTo": null,
|
||||
"attachment": [],
|
||||
"sensitive": false,
|
||||
"tag": []
|
||||
}
|
||||
36
test/fixtures/tesla_mock/p.helene.moe-AM7S6vZQmL6pI9TgPY.json
vendored
Normal file
36
test/fixtures/tesla_mock/p.helene.moe-AM7S6vZQmL6pI9TgPY.json
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://p.helene.moe/schemas/litepub-0.1.jsonld",
|
||||
{
|
||||
"@language": "und"
|
||||
}
|
||||
],
|
||||
"actor": "https://p.helene.moe/users/helene",
|
||||
"attachment": [],
|
||||
"attributedTo": "https://p.helene.moe/users/helene",
|
||||
"cc": [
|
||||
"https://p.helene.moe/users/helene/followers"
|
||||
],
|
||||
"content": "<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"AHntpQ4T3J4OSnpgMC\" href=\"https://mk.absturztau.be/@mametsuko\" rel=\"ugc\">@<span>mametsuko</span></a></span> meow",
|
||||
"context": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d",
|
||||
"conversation": "https://p.helene.moe/contexts/cc324643-5583-4c3f-91d2-c6ed37db159d",
|
||||
"id": "https://p.helene.moe/objects/fd5910ac-d9dc-412e-8d1d-914b203296c4",
|
||||
"inReplyTo": "https://mk.absturztau.be/notes/93e7nm8wqg",
|
||||
"published": "2022-08-02T13:46:58.403996Z",
|
||||
"sensitive": null,
|
||||
"source": "@mametsuko@mk.absturztau.be meow",
|
||||
"summary": "",
|
||||
"tag": [
|
||||
{
|
||||
"href": "https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"name": "@mametsuko@mk.absturztau.be",
|
||||
"type": "Mention"
|
||||
}
|
||||
],
|
||||
"to": [
|
||||
"https://mk.absturztau.be/users/8ozbzjs3o8",
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type": "Note"
|
||||
}
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><hm:Host xmlns:hm="http://host-meta.net/xrd/1.0">status.alpicola.com</hm:Host><Link rel="lrdd" template="http://status.alpicola.com/main/xrd?uri={uri}"><Title>Resource Descriptor</Title></Link></XRD>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><hm:Host xmlns:hm="http://host-meta.net/xrd/1.0">status.alpicola.com</hm:Host><Link rel="lrdd" template="https://status.alpicola.com/main/xrd?uri={uri}"><Title>Resource Descriptor</Title></Link></XRD>
|
||||
|
|
|
|||
4
test/fixtures/webfinger/masto-host-meta.xml
vendored
Normal file
4
test/fixtures/webfinger/masto-host-meta.xml
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
|
||||
<Link rel="lrdd" template="https://{{domain}}/.well-known/webfinger?resource={uri}"/>
|
||||
</XRD>
|
||||
92
test/fixtures/webfinger/masto-user.json
vendored
Normal file
92
test/fixtures/webfinger/masto-user.json
vendored
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"featured": {
|
||||
"@id": "toot:featured",
|
||||
"@type": "@id"
|
||||
},
|
||||
"featuredTags": {
|
||||
"@id": "toot:featuredTags",
|
||||
"@type": "@id"
|
||||
},
|
||||
"alsoKnownAs": {
|
||||
"@id": "as:alsoKnownAs",
|
||||
"@type": "@id"
|
||||
},
|
||||
"movedTo": {
|
||||
"@id": "as:movedTo",
|
||||
"@type": "@id"
|
||||
},
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value",
|
||||
"IdentityProof": "toot:IdentityProof",
|
||||
"discoverable": "toot:discoverable",
|
||||
"Device": "toot:Device",
|
||||
"Ed25519Signature": "toot:Ed25519Signature",
|
||||
"Ed25519Key": "toot:Ed25519Key",
|
||||
"Curve25519Key": "toot:Curve25519Key",
|
||||
"EncryptedMessage": "toot:EncryptedMessage",
|
||||
"publicKeyBase64": "toot:publicKeyBase64",
|
||||
"deviceId": "toot:deviceId",
|
||||
"claim": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:claim"
|
||||
},
|
||||
"fingerprintKey": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:fingerprintKey"
|
||||
},
|
||||
"identityKey": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:identityKey"
|
||||
},
|
||||
"devices": {
|
||||
"@type": "@id",
|
||||
"@id": "toot:devices"
|
||||
},
|
||||
"messageFranking": "toot:messageFranking",
|
||||
"messageType": "toot:messageType",
|
||||
"cipherText": "toot:cipherText",
|
||||
"suspended": "toot:suspended",
|
||||
"focalPoint": {
|
||||
"@container": "@list",
|
||||
"@id": "toot:focalPoint"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://{{domain}}/users/{{nickname}}",
|
||||
"type": "Person",
|
||||
"following": "https://{{domain}}/users/{{nickname}}/following",
|
||||
"followers": "https://{{domain}}/users/{{nickname}}/followers",
|
||||
"inbox": "https://{{domain}}/users/{{nickname}}/inbox",
|
||||
"outbox": "https://{{domain}}/users/{{nickname}}/outbox",
|
||||
"featured": "https://{{domain}}/users/{{nickname}}/collections/featured",
|
||||
"featuredTags": "https://{{domain}}/users/{{nickname}}/collections/tags",
|
||||
"preferredUsername": "{{nickname}}",
|
||||
"name": "Name Name",
|
||||
"summary": "<p>Summary</p>",
|
||||
"url": "https://{{domain}}/@{{nickname}}",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"discoverable": false,
|
||||
"devices": "https://{{domain}}/users/{{nickname}}/collections/devices",
|
||||
"publicKey": {
|
||||
"id": "https://{{domain}}/users/{{nickname}}#main-key",
|
||||
"owner": "https://{{domain}}/users/{{nickname}}",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvwDujxmxoYHs64MyVB3L\nG5ZyBxV3ufaMRBFu42bkcTpISq1WwZ+3Zb6CI8zOO+nM+Q2llrVRYjZa4ZFnOLvM\nTq/Kf+Zf5wy2aCRer88gX+MsJOAtItSi412y0a/rKOuFaDYLOLeTkRvmGLgZWbsr\nZJOp+YWb3zQ5qsIOInkc5BwI172tMsGeFtsnbNApPV4lrmtTGaJ8RiM8MR7XANBO\nfOHggSt1+eAIKGIsCmINEMzs1mG9D75xKtC/sM8GfbvBclQcBstGkHAEj1VHPW0c\nh6Bok5/QQppicyb8UA1PAA9bznSFtKlYE4xCH8rlCDSDTBRtdnBWHKcj619Ujz4Q\nawIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"tag": [],
|
||||
"attachment": [],
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://{{domain}}/inbox"
|
||||
},
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/jpeg",
|
||||
"url": "https://s3.wasabisys.com/merp/accounts/avatars/000/000/001/original/6fdd3eee632af247.jpg"
|
||||
}
|
||||
}
|
||||
23
test/fixtures/webfinger/masto-webfinger.json
vendored
Normal file
23
test/fixtures/webfinger/masto-webfinger.json
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"subject": "acct:{{nickname}}@{{domain}}",
|
||||
"aliases": [
|
||||
"https://{{subdomain}}/@{{nickname}}",
|
||||
"https://{{subdomain}}/users/{{nickname}}"
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"rel": "http://webfinger.net/rel/profile-page",
|
||||
"type": "text/html",
|
||||
"href": "https://{{subdomain}}/@{{nickname}}"
|
||||
},
|
||||
{
|
||||
"rel": "self",
|
||||
"type": "application/activity+json",
|
||||
"href": "https://{{subdomain}}/users/{{nickname}}"
|
||||
},
|
||||
{
|
||||
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||
"template": "https://{{subdomain}}/authorize_interaction?uri={uri}"
|
||||
}
|
||||
]
|
||||
}
|
||||
1
test/fixtures/webfinger/pleroma-host-meta.xml
vendored
Normal file
1
test/fixtures/webfinger/pleroma-host-meta.xml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"><Link rel="lrdd" template="https://{{domain}}/.well-known/webfinger?resource={uri}" type="application/xrd+xml" /></XRD>
|
||||
58
test/fixtures/webfinger/pleroma-user.json
vendored
Normal file
58
test/fixtures/webfinger/pleroma-user.json
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://{{domain}}/schemas/litepub-0.1.jsonld",
|
||||
{
|
||||
"@language": "und"
|
||||
}
|
||||
],
|
||||
"alsoKnownAs": [],
|
||||
"attachment": [],
|
||||
"capabilities": {
|
||||
"acceptsChatMessages": true
|
||||
},
|
||||
"discoverable": true,
|
||||
"endpoints": {
|
||||
"oauthAuthorizationEndpoint": "https://{{domain}}/oauth/authorize",
|
||||
"oauthRegistrationEndpoint": "https://{{domain}}/api/v1/apps",
|
||||
"oauthTokenEndpoint": "https://{{domain}}/oauth/token",
|
||||
"sharedInbox": "https://{{domain}}/inbox",
|
||||
"uploadMedia": "https://{{domain}}/api/ap/upload_media"
|
||||
},
|
||||
"followers": "https://{{domain}}/users/{{nickname}}/followers",
|
||||
"following": "https://{{domain}}/users/{{nickname}}/following",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": "https://{{domain}}/media/a932a27f158b63c3a97e3a57d5384f714a82249274c6fc66c9eca581b4fd8af2.jpg"
|
||||
},
|
||||
"id": "https://{{domain}}/users/{{nickname}}",
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"url": "https://{{domain}}/media/db15f476d0ad14488db4762b7800479e6ef67b1824f8b9ea5c1fa05b7525c5b7.jpg"
|
||||
},
|
||||
"inbox": "https://{{domain}}/users/{{nickname}}/inbox",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"name": "{{nickname}} :verified:",
|
||||
"outbox": "https://{{domain}}/users/{{nickname}}/outbox",
|
||||
"preferredUsername": "{{nickname}}",
|
||||
"publicKey": {
|
||||
"id": "https://{{domain}}/users/{{nickname}}#main-key",
|
||||
"owner": "https://{{domain}}/users/{{nickname}}",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu4XOAopC4nRIxNlHlt60\n//nCicuedu5wvLGIoQ+KUM2u7/PhLrrTDEqr1A7yQL95S0X8ryYtALgFLI5A54ww\nqjMIbIGAs44lEmDLMEd+XI+XxREE8wdsFpb4QQzWug0DTyqlMouTU25k0tfKh1rF\n4PMJ3uBSjDTAGgFvLNyFWTiVVgChbTNgGOmrEBucRl4NmKzQ69/FIUwENV88oQSU\n3bWvQTEH9rWH1rCLpkmQwdRiWfnhFX/4EUqXukfgoskvenKR8ff3nYhElDqFoE0e\nqUnIW1OZceyl8JewVLcL6m0/wdKeosTsfrcWc8DKfnRYQcBGNoBEq9GrOHDU0q2v\nyQIDAQAB\n-----END PUBLIC KEY-----\n\n"
|
||||
},
|
||||
"summary": "Pleroma BE dev",
|
||||
"tag": [
|
||||
{
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"url": "https://{{domain}}/emoji/mine/6143373a807b1ae7.png"
|
||||
},
|
||||
"id": "https://{{domain}}/emoji/mine/6143373a807b1ae7.png",
|
||||
"name": ":verified:",
|
||||
"type": "Emoji",
|
||||
"updated": "1970-01-01T00:00:00Z"
|
||||
}
|
||||
],
|
||||
"type": "Person",
|
||||
"url": "https://{{domain}}/users/{{nickname}}"
|
||||
}
|
||||
27
test/fixtures/webfinger/pleroma-webfinger.json
vendored
Normal file
27
test/fixtures/webfinger/pleroma-webfinger.json
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"aliases": [
|
||||
"https://{{subdomain}}/users/{{nickname}}"
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"href": "https://{{subdomain}}/users/{{nickname}}",
|
||||
"rel": "http://webfinger.net/rel/profile-page",
|
||||
"type": "text/html"
|
||||
},
|
||||
{
|
||||
"href": "https://{{subdomain}}/users/{{nickname}}",
|
||||
"rel": "self",
|
||||
"type": "application/activity+json"
|
||||
},
|
||||
{
|
||||
"href": "https://{{subdomain}}/users/{{nickname}}",
|
||||
"rel": "self",
|
||||
"type": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
|
||||
},
|
||||
{
|
||||
"rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||
"template": "https://{{subdomain}}/ostatus_subscribe?acct={uri}"
|
||||
}
|
||||
],
|
||||
"subject": "acct:{{nickname}}@{{domain}}"
|
||||
}
|
||||
|
|
@ -49,7 +49,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
describe "migrate_to_db/1" do
|
||||
setup do
|
||||
clear_config(:configurable_from_database, true)
|
||||
clear_config([:quack, :level])
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
|
|
@ -72,14 +71,12 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
|
||||
config1 = ConfigDB.get_by_params(%{group: ":pleroma", key: ":first_setting"})
|
||||
config2 = ConfigDB.get_by_params(%{group: ":pleroma", key: ":second_setting"})
|
||||
config3 = ConfigDB.get_by_params(%{group: ":quack", key: ":level"})
|
||||
refute ConfigDB.get_by_params(%{group: ":pleroma", key: "Pleroma.Repo"})
|
||||
refute ConfigDB.get_by_params(%{group: ":postgrex", key: ":json_library"})
|
||||
refute ConfigDB.get_by_params(%{group: ":pleroma", key: ":database"})
|
||||
|
||||
assert config1.value == [key: "value", key2: [Repo]]
|
||||
assert config2.value == [key: "value2", key2: ["Activity"]]
|
||||
assert config3.value == :info
|
||||
end
|
||||
|
||||
test "config table is truncated before migration" do
|
||||
|
|
@ -108,7 +105,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
test "settings are migrated to file and deleted from db", %{temp_file: temp_file} do
|
||||
insert_config_record(:pleroma, :setting_first, key: "value", key2: ["Activity"])
|
||||
insert_config_record(:pleroma, :setting_second, key: "value2", key2: [Repo])
|
||||
insert_config_record(:quack, :level, :info)
|
||||
|
||||
MixTask.run(["migrate_from_db", "--env", "temp", "-d"])
|
||||
|
||||
|
|
@ -117,7 +113,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
file = File.read!(temp_file)
|
||||
assert file =~ "config :pleroma, :setting_first,"
|
||||
assert file =~ "config :pleroma, :setting_second,"
|
||||
assert file =~ "config :quack, :level, :info"
|
||||
end
|
||||
|
||||
test "load a settings with large values and pass to file", %{temp_file: temp_file} do
|
||||
|
|
@ -199,7 +194,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
setup do
|
||||
insert_config_record(:pleroma, :setting_first, key: "value", key2: ["Activity"])
|
||||
insert_config_record(:pleroma, :setting_second, key: "value2", key2: [Repo])
|
||||
insert_config_record(:quack, :level, :info)
|
||||
|
||||
path = "test/instance_static"
|
||||
file_path = Path.join(path, "temp.exported_from_db.secret.exs")
|
||||
|
|
@ -215,7 +209,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
file = File.read!(file_path)
|
||||
assert file =~ "config :pleroma, :setting_first,"
|
||||
assert file =~ "config :pleroma, :setting_second,"
|
||||
assert file =~ "config :quack, :level, :info"
|
||||
end
|
||||
|
||||
test "release", %{file_path: file_path} do
|
||||
|
|
@ -227,7 +220,6 @@ defmodule Mix.Tasks.Pleroma.ConfigTest do
|
|||
file = File.read!(file_path)
|
||||
assert file =~ "config :pleroma, :setting_first,"
|
||||
assert file =~ "config :pleroma, :setting_second,"
|
||||
assert file =~ "config :quack, :level, :info"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,29 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
|
|||
|
||||
import Mock
|
||||
|
||||
describe "chat message" do
|
||||
test "Create produces no topics" do
|
||||
activity = %Activity{
|
||||
object: %Object{data: %{"type" => "ChatMessage"}},
|
||||
data: %{"type" => "Create"}
|
||||
}
|
||||
|
||||
assert [] == Topics.get_activity_topics(activity)
|
||||
end
|
||||
|
||||
test "Delete produces user and user:pleroma_chat" do
|
||||
activity = %Activity{
|
||||
object: %Object{data: %{"type" => "ChatMessage"}},
|
||||
data: %{"type" => "Delete"}
|
||||
}
|
||||
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
assert [_, _] = topics
|
||||
assert "user" in topics
|
||||
assert "user:pleroma_chat" in topics
|
||||
end
|
||||
end
|
||||
|
||||
describe "poll answer" do
|
||||
test "produce no topics" do
|
||||
activity = %Activity{object: %Object{data: %{"type" => "Answer"}}}
|
||||
|
|
@ -35,7 +58,7 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
|
|||
setup do
|
||||
activity = %Activity{
|
||||
object: %Object{data: %{"type" => "Note"}},
|
||||
data: %{"to" => [Pleroma.Constants.as_public()]}
|
||||
data: %{"to" => [Pleroma.Constants.as_public()], "type" => "Create"}
|
||||
}
|
||||
|
||||
{:ok, activity: activity}
|
||||
|
|
@ -114,6 +137,55 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "public visibility Announces" do
|
||||
setup do
|
||||
activity = %Activity{
|
||||
object: %Object{data: %{"attachment" => []}},
|
||||
data: %{"type" => "Announce", "to" => [Pleroma.Constants.as_public()]}
|
||||
}
|
||||
|
||||
{:ok, activity: activity}
|
||||
end
|
||||
|
||||
test "does not generate public topics", %{activity: activity} do
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
|
||||
refute "public" in topics
|
||||
refute "public:remote" in topics
|
||||
refute "public:local" in topics
|
||||
end
|
||||
end
|
||||
|
||||
describe "local-public visibility create events" do
|
||||
setup do
|
||||
activity = %Activity{
|
||||
object: %Object{data: %{"attachment" => []}},
|
||||
data: %{"type" => "Create", "to" => [Pleroma.Web.ActivityPub.Utils.as_local_public()]}
|
||||
}
|
||||
|
||||
{:ok, activity: activity}
|
||||
end
|
||||
|
||||
test "doesn't produce public topics", %{activity: activity} do
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
|
||||
refute Enum.member?(topics, "public")
|
||||
end
|
||||
|
||||
test "produces public:local topics", %{activity: activity} do
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
|
||||
assert Enum.member?(topics, "public:local")
|
||||
end
|
||||
|
||||
test "with no attachments doesn't produce public:media topics", %{activity: activity} do
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
|
||||
refute Enum.member?(topics, "public:media")
|
||||
refute Enum.member?(topics, "public:local:media")
|
||||
end
|
||||
end
|
||||
|
||||
describe "public visibility create events with attachments" do
|
||||
setup do
|
||||
activity = %Activity{
|
||||
|
|
@ -152,9 +224,36 @@ defmodule Pleroma.Activity.Ir.TopicsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "local-public visibility create events with attachments" do
|
||||
setup do
|
||||
activity = %Activity{
|
||||
object: %Object{data: %{"attachment" => ["foo"]}},
|
||||
data: %{"type" => "Create", "to" => [Pleroma.Web.ActivityPub.Utils.as_local_public()]}
|
||||
}
|
||||
|
||||
{:ok, activity: activity}
|
||||
end
|
||||
|
||||
test "do not produce public:media topics", %{activity: activity} do
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
|
||||
refute Enum.member?(topics, "public:media")
|
||||
end
|
||||
|
||||
test "produces public:local:media topics", %{activity: activity} do
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
|
||||
assert Enum.member?(topics, "public:local:media")
|
||||
end
|
||||
end
|
||||
|
||||
describe "non-public visibility" do
|
||||
test "produces direct topic" do
|
||||
activity = %Activity{object: %Object{data: %{"type" => "Note"}}, data: %{"to" => []}}
|
||||
activity = %Activity{
|
||||
object: %Object{data: %{"type" => "Note"}},
|
||||
data: %{"to" => [], "type" => "Create"}
|
||||
}
|
||||
|
||||
topics = Topics.get_activity_topics(activity)
|
||||
|
||||
assert Enum.member?(topics, "direct")
|
||||
|
|
|
|||
|
|
@ -18,6 +18,23 @@ defmodule Pleroma.Activity.SearchTest do
|
|||
assert result.id == post.id
|
||||
end
|
||||
|
||||
test "it finds local-only posts for authenticated users" do
|
||||
user = insert(:user)
|
||||
reader = insert(:user)
|
||||
{:ok, post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"})
|
||||
|
||||
[result] = Search.search(reader, "wednesday")
|
||||
|
||||
assert result.id == post.id
|
||||
end
|
||||
|
||||
test "it does not find local-only posts for anonymous users" do
|
||||
user = insert(:user)
|
||||
{:ok, _post} = CommonAPI.post(user, %{status: "it's wednesday my dudes", visibility: "local"})
|
||||
|
||||
assert [] = Search.search(nil, "wednesday")
|
||||
end
|
||||
|
||||
test "using plainto_tsquery on postgres < 11" do
|
||||
old_version = :persistent_term.get({Pleroma.Repo, :postgres_version})
|
||||
:persistent_term.put({Pleroma.Repo, :postgres_version}, 10.0)
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ defmodule Pleroma.ActivityTest do
|
|||
|
||||
setup do: clear_config([:instance, :limit_to_local_content])
|
||||
|
||||
@tag :skip_on_mac
|
||||
test "finds utf8 text in statuses", %{
|
||||
japanese_activity: japanese_activity,
|
||||
user: user
|
||||
|
|
@ -278,4 +279,78 @@ defmodule Pleroma.ActivityTest do
|
|||
|
||||
assert Repo.aggregate(Activity, :count, :id) == 2
|
||||
end
|
||||
|
||||
describe "associated_object_id() sql function" do
|
||||
test "with json object" do
|
||||
%{rows: [[object_id]]} =
|
||||
Ecto.Adapters.SQL.query!(
|
||||
Pleroma.Repo,
|
||||
"""
|
||||
select associated_object_id('{"object": {"id":"foobar"}}'::jsonb);
|
||||
"""
|
||||
)
|
||||
|
||||
assert object_id == "foobar"
|
||||
end
|
||||
|
||||
test "with string object" do
|
||||
%{rows: [[object_id]]} =
|
||||
Ecto.Adapters.SQL.query!(
|
||||
Pleroma.Repo,
|
||||
"""
|
||||
select associated_object_id('{"object": "foobar"}'::jsonb);
|
||||
"""
|
||||
)
|
||||
|
||||
assert object_id == "foobar"
|
||||
end
|
||||
|
||||
test "with array object" do
|
||||
%{rows: [[object_id]]} =
|
||||
Ecto.Adapters.SQL.query!(
|
||||
Pleroma.Repo,
|
||||
"""
|
||||
select associated_object_id('{"object": ["foobar", {}]}'::jsonb);
|
||||
"""
|
||||
)
|
||||
|
||||
assert object_id == "foobar"
|
||||
end
|
||||
|
||||
test "invalid" do
|
||||
%{rows: [[object_id]]} =
|
||||
Ecto.Adapters.SQL.query!(
|
||||
Pleroma.Repo,
|
||||
"""
|
||||
select associated_object_id('{"object": {}}'::jsonb);
|
||||
"""
|
||||
)
|
||||
|
||||
assert is_nil(object_id)
|
||||
end
|
||||
|
||||
test "invalid object id" do
|
||||
%{rows: [[object_id]]} =
|
||||
Ecto.Adapters.SQL.query!(
|
||||
Pleroma.Repo,
|
||||
"""
|
||||
select associated_object_id('{"object": {"id": 123}}'::jsonb);
|
||||
"""
|
||||
)
|
||||
|
||||
assert is_nil(object_id)
|
||||
end
|
||||
|
||||
test "no object field" do
|
||||
%{rows: [[object_id]]} =
|
||||
Ecto.Adapters.SQL.query!(
|
||||
Pleroma.Repo,
|
||||
"""
|
||||
select associated_object_id('{}'::jsonb);
|
||||
"""
|
||||
)
|
||||
|
||||
assert is_nil(object_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ defmodule Pleroma.Config.LoaderTest do
|
|||
config = Loader.read("test/fixtures/config/temp.secret.exs")
|
||||
assert config[:pleroma][:first_setting][:key] == "value"
|
||||
assert config[:pleroma][:first_setting][:key2] == [Pleroma.Repo]
|
||||
assert config[:quack][:level] == :info
|
||||
end
|
||||
|
||||
test "filter_group/2" do
|
||||
|
|
|
|||
|
|
@ -15,13 +15,11 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
test "transfer config values from db to env" do
|
||||
refute Application.get_env(:pleroma, :test_key)
|
||||
refute Application.get_env(:idna, :test_key)
|
||||
refute Application.get_env(:quack, :test_key)
|
||||
refute Application.get_env(:postgrex, :test_key)
|
||||
initial = Application.get_env(:logger, :level)
|
||||
|
||||
insert(:config, key: :test_key, value: [live: 2, com: 3])
|
||||
insert(:config, group: :idna, key: :test_key, value: [live: 15, com: 35])
|
||||
insert(:config, group: :quack, key: :test_key, value: [:test_value1, :test_value2])
|
||||
insert(:config, group: :postgrex, key: :test_key, value: :value)
|
||||
insert(:config, group: :logger, key: :level, value: :debug)
|
||||
|
||||
|
|
@ -29,36 +27,32 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
|
||||
assert Application.get_env(:pleroma, :test_key) == [live: 2, com: 3]
|
||||
assert Application.get_env(:idna, :test_key) == [live: 15, com: 35]
|
||||
assert Application.get_env(:quack, :test_key) == [:test_value1, :test_value2]
|
||||
assert Application.get_env(:logger, :level) == :debug
|
||||
assert Application.get_env(:postgrex, :test_key) == :value
|
||||
|
||||
on_exit(fn ->
|
||||
Application.delete_env(:pleroma, :test_key)
|
||||
Application.delete_env(:idna, :test_key)
|
||||
Application.delete_env(:quack, :test_key)
|
||||
Application.delete_env(:postgrex, :test_key)
|
||||
Application.put_env(:logger, :level, initial)
|
||||
end)
|
||||
end
|
||||
|
||||
test "transfer config values for 1 group and some keys" do
|
||||
level = Application.get_env(:quack, :level)
|
||||
meta = Application.get_env(:quack, :meta)
|
||||
level = Application.get_env(:somegroup, :level)
|
||||
meta = Application.get_env(:somegroup, :meta)
|
||||
|
||||
insert(:config, group: :quack, key: :level, value: :info)
|
||||
insert(:config, group: :quack, key: :meta, value: [:none])
|
||||
insert(:config, group: :somegroup, key: :level, value: :info)
|
||||
insert(:config, group: :somegroup, key: :meta, value: [:none])
|
||||
|
||||
TransferTask.start_link([])
|
||||
|
||||
assert Application.get_env(:quack, :level) == :info
|
||||
assert Application.get_env(:quack, :meta) == [:none]
|
||||
default = Pleroma.Config.Holder.default_config(:quack, :webhook_url)
|
||||
assert Application.get_env(:quack, :webhook_url) == default
|
||||
assert Application.get_env(:somegroup, :level) == :info
|
||||
assert Application.get_env(:somegroup, :meta) == [:none]
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:quack, :level, level)
|
||||
Application.put_env(:quack, :meta, meta)
|
||||
Application.put_env(:somegroup, :level, level)
|
||||
Application.put_env(:somegroup, :meta, meta)
|
||||
end)
|
||||
end
|
||||
|
||||
|
|
@ -79,35 +73,70 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
|
||||
describe "pleroma restart" do
|
||||
setup do
|
||||
on_exit(fn -> Restarter.Pleroma.refresh() end)
|
||||
on_exit(fn ->
|
||||
Restarter.Pleroma.refresh()
|
||||
|
||||
# Restarter.Pleroma.refresh/0 is an asynchronous call.
|
||||
# A GenServer will first finish the previous call before starting a new one.
|
||||
# Here we do a synchronous call.
|
||||
# That way we are sure that the previous call has finished before we continue.
|
||||
# See https://stackoverflow.com/questions/51361856/how-to-use-task-await-with-genserver
|
||||
Restarter.Pleroma.rebooted?()
|
||||
end)
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "don't restart if no reboot time settings were changed" do
|
||||
clear_config(:emoji)
|
||||
insert(:config, key: :emoji, value: [groups: [a: 1, b: 2]])
|
||||
|
||||
refute String.contains?(
|
||||
capture_log(fn -> TransferTask.start_link([]) end),
|
||||
capture_log(fn ->
|
||||
TransferTask.start_link([])
|
||||
|
||||
# TransferTask.start_link/1 is an asynchronous call.
|
||||
# A GenServer will first finish the previous call before starting a new one.
|
||||
# Here we do a synchronous call.
|
||||
# That way we are sure that the previous call has finished before we continue.
|
||||
Restarter.Pleroma.rebooted?()
|
||||
end),
|
||||
"pleroma restarted"
|
||||
)
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "on reboot time key" do
|
||||
clear_config(:shout)
|
||||
insert(:config, key: :shout, value: [enabled: false])
|
||||
assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted"
|
||||
|
||||
# Note that we don't actually restart Pleroma.
|
||||
# See module Restarter.Pleroma
|
||||
assert capture_log(fn ->
|
||||
TransferTask.start_link([])
|
||||
|
||||
# TransferTask.start_link/1 is an asynchronous call.
|
||||
# A GenServer will first finish the previous call before starting a new one.
|
||||
# Here we do a synchronous call.
|
||||
# That way we are sure that the previous call has finished before we continue.
|
||||
Restarter.Pleroma.rebooted?()
|
||||
end) =~ "pleroma restarted"
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "on reboot time subkey" do
|
||||
clear_config(Pleroma.Captcha)
|
||||
insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60])
|
||||
assert capture_log(fn -> TransferTask.start_link([]) end) =~ "pleroma restarted"
|
||||
|
||||
# Note that we don't actually restart Pleroma.
|
||||
# See module Restarter.Pleroma
|
||||
assert capture_log(fn ->
|
||||
TransferTask.start_link([])
|
||||
|
||||
# TransferTask.start_link/1 is an asynchronous call.
|
||||
# A GenServer will first finish the previous call before starting a new one.
|
||||
# Here we do a synchronous call.
|
||||
# That way we are sure that the previous call has finished before we continue.
|
||||
Restarter.Pleroma.rebooted?()
|
||||
end) =~ "pleroma restarted"
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "don't restart pleroma on reboot time key and subkey if there is false flag" do
|
||||
clear_config(:shout)
|
||||
clear_config(Pleroma.Captcha)
|
||||
|
|
@ -116,7 +145,15 @@ defmodule Pleroma.Config.TransferTaskTest do
|
|||
insert(:config, key: Pleroma.Captcha, value: [seconds_valid: 60])
|
||||
|
||||
refute String.contains?(
|
||||
capture_log(fn -> TransferTask.load_and_update_env([], false) end),
|
||||
capture_log(fn ->
|
||||
TransferTask.load_and_update_env([], false)
|
||||
|
||||
# TransferTask.start_link/1 is an asynchronous call.
|
||||
# A GenServer will first finish the previous call before starting a new one.
|
||||
# Here we do a synchronous call.
|
||||
# That way we are sure that the previous call has finished before we continue.
|
||||
Restarter.Pleroma.rebooted?()
|
||||
end),
|
||||
"pleroma restarted"
|
||||
)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@ defmodule Pleroma.ConfigDBTest do
|
|||
|
||||
test "get_all_as_keyword/0" do
|
||||
saved = insert(:config)
|
||||
insert(:config, group: ":quack", key: ":level", value: :info)
|
||||
insert(:config, group: ":quack", key: ":meta", value: [:none])
|
||||
insert(:config, group: ":goose", key: ":level", value: :info)
|
||||
insert(:config, group: ":goose", key: ":meta", value: [:none])
|
||||
|
||||
insert(:config,
|
||||
group: ":quack",
|
||||
group: ":goose",
|
||||
key: ":webhook_url",
|
||||
value: "https://hooks.slack.com/services/KEY/some_val"
|
||||
value: "https://gander.com/"
|
||||
)
|
||||
|
||||
config = ConfigDB.get_all_as_keyword()
|
||||
|
|
@ -31,9 +31,9 @@ defmodule Pleroma.ConfigDBTest do
|
|||
{saved.key, saved.value}
|
||||
]
|
||||
|
||||
assert config[:quack][:level] == :info
|
||||
assert config[:quack][:meta] == [:none]
|
||||
assert config[:quack][:webhook_url] == "https://hooks.slack.com/services/KEY/some_val"
|
||||
assert config[:goose][:level] == :info
|
||||
assert config[:goose][:meta] == [:none]
|
||||
assert config[:goose][:webhook_url] == "https://gander.com/"
|
||||
end
|
||||
|
||||
describe "update_or_create/1" do
|
||||
|
|
@ -267,10 +267,6 @@ defmodule Pleroma.ConfigDBTest do
|
|||
assert ConfigDB.to_elixir_types("ExSyslogger") == ExSyslogger
|
||||
end
|
||||
|
||||
test "Quack.Logger module" do
|
||||
assert ConfigDB.to_elixir_types("Quack.Logger") == Quack.Logger
|
||||
end
|
||||
|
||||
test "Swoosh.Adapters modules" do
|
||||
assert ConfigDB.to_elixir_types("Swoosh.Adapters.SMTP") == Swoosh.Adapters.SMTP
|
||||
assert ConfigDB.to_elixir_types("Swoosh.Adapters.AmazonSES") == Swoosh.Adapters.AmazonSES
|
||||
|
|
|
|||
|
|
@ -122,11 +122,11 @@ defmodule Pleroma.Conversation.ParticipationTest do
|
|||
end
|
||||
|
||||
test "it marks a participation as read" do
|
||||
participation = insert(:participation, %{read: false})
|
||||
participation = insert(:participation, %{updated_at: ~N[2017-07-17 17:09:58], read: false})
|
||||
{:ok, updated_participation} = Participation.mark_as_read(participation)
|
||||
|
||||
assert updated_participation.read
|
||||
assert updated_participation.updated_at == participation.updated_at
|
||||
assert :gt = NaiveDateTime.compare(updated_participation.updated_at, participation.updated_at)
|
||||
end
|
||||
|
||||
test "it marks a participation as unread" do
|
||||
|
|
|
|||
90
test/pleroma/docs/translator/compiler_test.exs
Normal file
90
test/pleroma/docs/translator/compiler_test.exs
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Docs.Translator.CompilerTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
alias Pleroma.Docs.Translator.Compiler
|
||||
|
||||
@descriptions [
|
||||
%{
|
||||
key: "1",
|
||||
label: "1",
|
||||
description: "2",
|
||||
children: [
|
||||
%{
|
||||
key: "3",
|
||||
label: "3",
|
||||
description: "4"
|
||||
},
|
||||
%{
|
||||
key: "5",
|
||||
label: "5",
|
||||
description: "6"
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
key: "7",
|
||||
label: "7",
|
||||
description: "8",
|
||||
children: [
|
||||
%{
|
||||
key: "9",
|
||||
description: "9",
|
||||
children: [
|
||||
%{
|
||||
key: "10",
|
||||
description: "10",
|
||||
children: [
|
||||
%{key: "11", description: "11"},
|
||||
%{description: "12"}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
label: "13"
|
||||
}
|
||||
]
|
||||
},
|
||||
%{
|
||||
group: "14",
|
||||
label: "14"
|
||||
},
|
||||
%{
|
||||
group: "15",
|
||||
key: "15",
|
||||
label: "15"
|
||||
},
|
||||
%{
|
||||
group: {":subgroup", "16"},
|
||||
label: "16"
|
||||
}
|
||||
]
|
||||
|
||||
describe "extract_strings/1" do
|
||||
test "it extracts all labels and descriptions" do
|
||||
strings = Compiler.extract_strings(@descriptions)
|
||||
assert length(strings) == 16
|
||||
|
||||
assert {["1"], "label", "1"} in strings
|
||||
assert {["1"], "description", "2"} in strings
|
||||
assert {["1", "3"], "label", "3"} in strings
|
||||
assert {["1", "3"], "description", "4"} in strings
|
||||
assert {["1", "5"], "label", "5"} in strings
|
||||
assert {["1", "5"], "description", "6"} in strings
|
||||
assert {["7"], "label", "7"} in strings
|
||||
assert {["7"], "description", "8"} in strings
|
||||
assert {["7", "9"], "description", "9"} in strings
|
||||
assert {["7", "9", "10"], "description", "10"} in strings
|
||||
assert {["7", "9", "10", "11"], "description", "11"} in strings
|
||||
assert {["7", "9", "10", nil], "description", "12"} in strings
|
||||
assert {["7", nil], "label", "13"} in strings
|
||||
assert {["14"], "label", "14"} in strings
|
||||
assert {["15-15"], "label", "15"} in strings
|
||||
assert {["16"], "label", "16"} in strings
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -17,6 +17,7 @@ defmodule Pleroma.HTMLTest do
|
|||
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
|
||||
this is a link with not allowed "rel" attribute: <a href="http://example.com/" rel="tag noallowed">example.com</a>
|
||||
this is an image: <img src="http://example.com/image.jpg"><br />
|
||||
this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"><br />
|
||||
<script>alert('hacked')</script>
|
||||
"""
|
||||
|
||||
|
|
@ -24,6 +25,10 @@ defmodule Pleroma.HTMLTest do
|
|||
<img src="http://example.com/image.jpg" onerror="alert('hacked')">
|
||||
"""
|
||||
|
||||
@html_stillimage_sample """
|
||||
<img class="still-image" src="http://example.com/image.jpg">
|
||||
"""
|
||||
|
||||
@html_span_class_sample """
|
||||
<span class="animate-spin">hi</span>
|
||||
"""
|
||||
|
|
@ -45,6 +50,7 @@ defmodule Pleroma.HTMLTest do
|
|||
this is a link with allowed "rel" attribute: example.com
|
||||
this is a link with not allowed "rel" attribute: example.com
|
||||
this is an image:
|
||||
this is an inline emoji:
|
||||
alert('hacked')
|
||||
"""
|
||||
|
||||
|
|
@ -67,6 +73,7 @@ defmodule Pleroma.HTMLTest do
|
|||
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
|
||||
this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a>
|
||||
this is an image: <img src="http://example.com/image.jpg"/><br/>
|
||||
this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"/><br/>
|
||||
alert('hacked')
|
||||
"""
|
||||
|
||||
|
|
@ -90,6 +97,15 @@ defmodule Pleroma.HTMLTest do
|
|||
HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.TwitterText)
|
||||
end
|
||||
|
||||
test "does not allow images with invalid classes" do
|
||||
expected = """
|
||||
<img src="http://example.com/image.jpg"/>
|
||||
"""
|
||||
|
||||
assert expected ==
|
||||
HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText)
|
||||
end
|
||||
|
||||
test "does allow microformats" do
|
||||
expected = """
|
||||
<span class="h-card"><a class="u-url mention">@<span>foo</span></a></span>
|
||||
|
|
@ -121,6 +137,7 @@ defmodule Pleroma.HTMLTest do
|
|||
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
|
||||
this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a>
|
||||
this is an image: <img src="http://example.com/image.jpg"/><br/>
|
||||
this is an inline emoji: <img class="emoji" src="http://example.com/image.jpg"/><br/>
|
||||
alert('hacked')
|
||||
"""
|
||||
|
||||
|
|
@ -143,6 +160,15 @@ defmodule Pleroma.HTMLTest do
|
|||
assert expected == HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.Default)
|
||||
end
|
||||
|
||||
test "does not allow images with invalid classes" do
|
||||
expected = """
|
||||
<img src="http://example.com/image.jpg"/>
|
||||
"""
|
||||
|
||||
assert expected ==
|
||||
HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText)
|
||||
end
|
||||
|
||||
test "does allow microformats" do
|
||||
expected = """
|
||||
<span class="h-card"><a class="u-url mention">@<span>foo</span></a></span>
|
||||
|
|
|
|||
|
|
@ -33,16 +33,18 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
|
||||
test "refuses invalid requests" do
|
||||
capture_log(fn ->
|
||||
assert {:error, {404, _}} = start_socket()
|
||||
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
|
||||
assert {:error, %WebSockex.RequestError{code: 404}} = start_socket()
|
||||
assert {:error, %WebSockex.RequestError{code: 404}} = start_socket("?stream=ncjdk")
|
||||
Process.sleep(30)
|
||||
end)
|
||||
end
|
||||
|
||||
test "requires authentication and a valid token for protected streams" do
|
||||
capture_log(fn ->
|
||||
assert {:error, {401, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
||||
assert {:error, {401, _}} = start_socket("?stream=user")
|
||||
assert {:error, %WebSockex.RequestError{code: 401}} =
|
||||
start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
||||
|
||||
assert {:error, %WebSockex.RequestError{code: 401}} = start_socket("?stream=user")
|
||||
Process.sleep(30)
|
||||
end)
|
||||
end
|
||||
|
|
@ -91,7 +93,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
|
||||
{:ok, token} = OAuth.Token.exchange_token(app, auth)
|
||||
|
||||
%{user: user, token: token}
|
||||
%{app: app, user: user, token: token}
|
||||
end
|
||||
|
||||
test "accepts valid tokens", state do
|
||||
|
|
@ -102,7 +104,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
||||
|
||||
capture_log(fn ->
|
||||
assert {:error, {401, _}} = start_socket("?stream=user")
|
||||
assert {:error, %WebSockex.RequestError{code: 401}} = start_socket("?stream=user")
|
||||
Process.sleep(30)
|
||||
end)
|
||||
end
|
||||
|
|
@ -111,7 +113,9 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
|
||||
|
||||
capture_log(fn ->
|
||||
assert {:error, {401, _}} = start_socket("?stream=user:notification")
|
||||
assert {:error, %WebSockex.RequestError{code: 401}} =
|
||||
start_socket("?stream=user:notification")
|
||||
|
||||
Process.sleep(30)
|
||||
end)
|
||||
end
|
||||
|
|
@ -120,11 +124,27 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
|||
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
|
||||
|
||||
capture_log(fn ->
|
||||
assert {:error, {401, _}} =
|
||||
assert {:error, %WebSockex.RequestError{code: 401}} =
|
||||
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
|
||||
|
||||
Process.sleep(30)
|
||||
end)
|
||||
end
|
||||
|
||||
test "disconnect when token is revoked", %{app: app, user: user, token: token} do
|
||||
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
|
||||
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
||||
|
||||
{:ok, auth} = OAuth.Authorization.create_authorization(app, user)
|
||||
|
||||
{:ok, token2} = OAuth.Token.exchange_token(app, auth)
|
||||
assert {:ok, _} = start_socket("?stream=user&access_token=#{token2.token}")
|
||||
|
||||
OAuth.Token.Strategy.Revoke.revoke(token)
|
||||
|
||||
assert_receive {:close, _}
|
||||
assert_receive {:close, _}
|
||||
refute_receive {:close, _}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -133,6 +133,28 @@ defmodule Pleroma.NotificationTest do
|
|||
subscriber_notifications = Notification.for_user(subscriber)
|
||||
assert Enum.empty?(subscriber_notifications)
|
||||
end
|
||||
|
||||
test "it sends edited notifications to those who repeated a status" do
|
||||
user = insert(:user)
|
||||
repeated_user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity_one} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "hey @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
{:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user)
|
||||
|
||||
{:ok, _edit_activity} =
|
||||
CommonAPI.update(user, activity_one, %{
|
||||
status: "hey @#{other_user.nickname}! mew mew"
|
||||
})
|
||||
|
||||
assert [%{type: "reblog"}] = Notification.for_user(user)
|
||||
assert [%{type: "update"}] = Notification.for_user(repeated_user)
|
||||
assert [%{type: "mention"}] = Notification.for_user(other_user)
|
||||
end
|
||||
end
|
||||
|
||||
test "create_poll_notifications/1" do
|
||||
|
|
@ -826,6 +848,30 @@ defmodule Pleroma.NotificationTest do
|
|||
assert [other_user] == enabled_receivers
|
||||
assert [] == disabled_receivers
|
||||
end
|
||||
|
||||
test "it sends edited notifications to those who repeated a status" do
|
||||
user = insert(:user)
|
||||
repeated_user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity_one} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "hey @#{other_user.nickname}!"
|
||||
})
|
||||
|
||||
{:ok, _activity_two} = CommonAPI.repeat(activity_one.id, repeated_user)
|
||||
|
||||
{:ok, edit_activity} =
|
||||
CommonAPI.update(user, activity_one, %{
|
||||
status: "hey @#{other_user.nickname}! mew mew"
|
||||
})
|
||||
|
||||
{enabled_receivers, _disabled_receivers} =
|
||||
Notification.get_notified_from_activity(edit_activity)
|
||||
|
||||
assert repeated_user in enabled_receivers
|
||||
assert other_user not in enabled_receivers
|
||||
end
|
||||
end
|
||||
|
||||
describe "notification lifecycle" do
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
use Pleroma.DataCase
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Instances
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Fetcher
|
||||
|
||||
|
|
@ -159,6 +160,17 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
"https://patch.cx/media/03ca3c8b4ac3ddd08bf0f84be7885f2f88de0f709112131a22d83650819e36c2.json"
|
||||
)
|
||||
end
|
||||
|
||||
test "it resets instance reachability on successful fetch" do
|
||||
id = "http://mastodon.example.org/@admin/99541947525187367"
|
||||
Instances.set_consistently_unreachable(id)
|
||||
refute Instances.reachable?(id)
|
||||
|
||||
{:ok, _object} =
|
||||
Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367")
|
||||
|
||||
assert Instances.reachable?(id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "implementation quirks" do
|
||||
|
|
@ -269,4 +281,271 @@ defmodule Pleroma.Object.FetcherTest do
|
|||
refute called(Pleroma.Signature.sign(:_, :_))
|
||||
end
|
||||
end
|
||||
|
||||
describe "refetching" do
|
||||
setup do
|
||||
object1 = %{
|
||||
"id" => "https://mastodon.social/1",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"type" => "Note",
|
||||
"content" => "test 1",
|
||||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
}
|
||||
|
||||
object2 = %{
|
||||
"id" => "https://mastodon.social/2",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"type" => "Note",
|
||||
"content" => "test 2",
|
||||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "orig 2",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
}
|
||||
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://mastodon.social/1"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(object1)
|
||||
}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://mastodon.social/2"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(object2)
|
||||
}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://mastodon.social/users/emelie/collections/featured"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body:
|
||||
Jason.encode!(%{
|
||||
"id" => "https://mastodon.social/users/emelie/collections/featured",
|
||||
"type" => "OrderedCollection",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"orderedItems" => [],
|
||||
"totalItems" => 0
|
||||
})
|
||||
}
|
||||
|
||||
env ->
|
||||
apply(HttpRequestMock, :request, [env])
|
||||
end)
|
||||
|
||||
%{object1: object1, object2: object2}
|
||||
end
|
||||
|
||||
test "it keeps formerRepresentations if remote does not have this attr", %{object1: object1} do
|
||||
full_object1 =
|
||||
object1
|
||||
|> Map.merge(%{
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "orig 2",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => [],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
})
|
||||
|
||||
{:ok, o} = Object.create(full_object1)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"content" => "orig 2"}]}} =
|
||||
refetched.data
|
||||
end
|
||||
|
||||
test "it uses formerRepresentations from remote if possible", %{object2: object2} do
|
||||
{:ok, o} = Object.create(object2)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"content" => "orig 2"}]}} =
|
||||
refetched.data
|
||||
end
|
||||
|
||||
test "it replaces formerRepresentations with the one from remote", %{object2: object2} do
|
||||
full_object2 =
|
||||
object2
|
||||
|> Map.merge(%{
|
||||
"content" => "mew mew #def",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"type" => "Note", "content" => "mew mew 2"}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
})
|
||||
|
||||
{:ok, o} = Object.create(full_object2)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{
|
||||
"content" => "test 2",
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => "orig 2"}]}
|
||||
} = refetched.data
|
||||
end
|
||||
|
||||
test "it adds to formerRepresentations if the remote does not have one and the object has changed",
|
||||
%{object1: object1} do
|
||||
full_object1 =
|
||||
object1
|
||||
|> Map.merge(%{
|
||||
"content" => "mew mew #def",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"type" => "Note", "content" => "mew mew 1"}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
})
|
||||
|
||||
{:ok, o} = Object.create(full_object1)
|
||||
|
||||
assert {:ok, refetched} = Fetcher.refetch_object(o)
|
||||
|
||||
assert %{
|
||||
"content" => "test 1",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{"content" => "mew mew #def"},
|
||||
%{"content" => "mew mew 1"}
|
||||
],
|
||||
"totalItems" => 2
|
||||
}
|
||||
} = refetched.data
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetch with history" do
|
||||
setup do
|
||||
object2 = %{
|
||||
"id" => "https://mastodon.social/2",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"type" => "Note",
|
||||
"content" => "test 2",
|
||||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => ["https://mastodon.social/users/emelie/followers"],
|
||||
"to" => [],
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "orig 2",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"bcc" => [],
|
||||
"bto" => [],
|
||||
"cc" => ["https://mastodon.social/users/emelie/followers"],
|
||||
"to" => [],
|
||||
"summary" => ""
|
||||
}
|
||||
],
|
||||
"totalItems" => 1
|
||||
}
|
||||
}
|
||||
|
||||
mock(fn
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://mastodon.social/2"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body: Jason.encode!(object2)
|
||||
}
|
||||
|
||||
%{
|
||||
method: :get,
|
||||
url: "https://mastodon.social/users/emelie/collections/featured"
|
||||
} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
headers: [{"content-type", "application/activity+json"}],
|
||||
body:
|
||||
Jason.encode!(%{
|
||||
"id" => "https://mastodon.social/users/emelie/collections/featured",
|
||||
"type" => "OrderedCollection",
|
||||
"actor" => "https://mastodon.social/users/emelie",
|
||||
"attributedTo" => "https://mastodon.social/users/emelie",
|
||||
"orderedItems" => [],
|
||||
"totalItems" => 0
|
||||
})
|
||||
}
|
||||
|
||||
env ->
|
||||
apply(HttpRequestMock, :request, [env])
|
||||
end)
|
||||
|
||||
%{object2: object2}
|
||||
end
|
||||
|
||||
test "it gets history", %{object2: object2} do
|
||||
{:ok, object} = Fetcher.fetch_object_from_id(object2["id"])
|
||||
|
||||
assert %{
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [%{}]
|
||||
}
|
||||
} = object.data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
76
test/pleroma/object/updater_test.exs
Normal file
76
test/pleroma/object/updater_test.exs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Object.UpdaterTest do
|
||||
use Pleroma.DataCase
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Object.Updater
|
||||
|
||||
describe "make_update_object_data/3" do
|
||||
setup do
|
||||
note = insert(:note)
|
||||
%{original_data: note.data}
|
||||
end
|
||||
|
||||
test "it makes an updated field", %{original_data: original_data} do
|
||||
new_data = Map.put(original_data, "content", "new content")
|
||||
|
||||
date = Pleroma.Web.ActivityPub.Utils.make_date()
|
||||
update_object_data = Updater.make_update_object_data(original_data, new_data, date)
|
||||
assert %{"updated" => ^date} = update_object_data
|
||||
end
|
||||
|
||||
test "it creates formerRepresentations", %{original_data: original_data} do
|
||||
new_data = Map.put(original_data, "content", "new content")
|
||||
|
||||
date = Pleroma.Web.ActivityPub.Utils.make_date()
|
||||
update_object_data = Updater.make_update_object_data(original_data, new_data, date)
|
||||
|
||||
history_item = original_data |> Map.drop(["id", "formerRepresentations"])
|
||||
|
||||
assert %{
|
||||
"formerRepresentations" => %{
|
||||
"totalItems" => 1,
|
||||
"orderedItems" => [^history_item]
|
||||
}
|
||||
} = update_object_data
|
||||
end
|
||||
end
|
||||
|
||||
describe "make_new_object_data_from_update_object/2" do
|
||||
test "it reuses formerRepresentations if it exists" do
|
||||
%{data: original_data} = insert(:note)
|
||||
|
||||
new_data =
|
||||
original_data
|
||||
|> Map.put("content", "edited")
|
||||
|
||||
date = Pleroma.Web.ActivityPub.Utils.make_date()
|
||||
update_object_data = Updater.make_update_object_data(original_data, new_data, date)
|
||||
|
||||
history = update_object_data["formerRepresentations"]["orderedItems"]
|
||||
|
||||
update_object_data =
|
||||
update_object_data
|
||||
|> put_in(
|
||||
["formerRepresentations", "orderedItems"],
|
||||
history ++ [Map.put(original_data, "summary", "additional summary")]
|
||||
)
|
||||
|> put_in(["formerRepresentations", "totalItems"], length(history) + 1)
|
||||
|
||||
%{
|
||||
updated_data: updated_data,
|
||||
updated: updated,
|
||||
used_history_in_new_object?: used_history_in_new_object?
|
||||
} = Updater.make_new_object_data_from_update_object(original_data, update_object_data)
|
||||
|
||||
assert updated
|
||||
assert used_history_in_new_object?
|
||||
assert updated_data["formerRepresentations"] == update_object_data["formerRepresentations"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -109,6 +109,11 @@ defmodule Pleroma.SignatureTest do
|
|||
{:ok, "https://example.com/users/1234"}
|
||||
end
|
||||
|
||||
test "it deduces the actor id for gotoSocial" do
|
||||
assert Signature.key_id_to_actor_id("https://example.com/users/1234/main-key") ==
|
||||
{:ok, "https://example.com/users/1234"}
|
||||
end
|
||||
|
||||
test "it calls webfinger for 'acct:' accounts" do
|
||||
with_mock(Pleroma.Web.WebFinger,
|
||||
finger: fn _ -> %{"ap_id" => "https://gensokyo.2hu/users/raymoo"} end
|
||||
|
|
|
|||
|
|
@ -49,20 +49,22 @@ defmodule Pleroma.UploadTest do
|
|||
test "it returns file" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
assert Upload.store(@upload_file) ==
|
||||
{:ok,
|
||||
%{
|
||||
"name" => "image.jpg",
|
||||
"type" => "Document",
|
||||
"mediaType" => "image/jpeg",
|
||||
"url" => [
|
||||
%{
|
||||
"href" => "http://localhost:4001/media/post-process-file.jpg",
|
||||
"mediaType" => "image/jpeg",
|
||||
"type" => "Link"
|
||||
}
|
||||
]
|
||||
}}
|
||||
assert {:ok, result} = Upload.store(@upload_file)
|
||||
|
||||
assert result ==
|
||||
%{
|
||||
"id" => result["id"],
|
||||
"name" => "image.jpg",
|
||||
"type" => "Document",
|
||||
"mediaType" => "image/jpeg",
|
||||
"url" => [
|
||||
%{
|
||||
"href" => "http://localhost:4001/media/post-process-file.jpg",
|
||||
"mediaType" => "image/jpeg",
|
||||
"type" => "Link"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Task.await(Agent.get(TestUploaderSuccess, fn task_pid -> task_pid end))
|
||||
end
|
||||
|
|
|
|||
|
|
@ -22,15 +22,15 @@ defmodule Pleroma.User.BackupTest do
|
|||
clear_config([Pleroma.Emails.Mailer, :enabled], true)
|
||||
end
|
||||
|
||||
test "it requries enabled email" do
|
||||
test "it does not requrie enabled email" do
|
||||
clear_config([Pleroma.Emails.Mailer, :enabled], false)
|
||||
user = insert(:user)
|
||||
assert {:error, "Backups require enabled email"} == Backup.create(user)
|
||||
assert {:ok, _} = Backup.create(user)
|
||||
end
|
||||
|
||||
test "it requries user's email" do
|
||||
test "it does not require user's email" do
|
||||
user = insert(:user, %{email: nil})
|
||||
assert {:error, "Email is required"} == Backup.create(user)
|
||||
assert {:ok, _} = Backup.create(user)
|
||||
end
|
||||
|
||||
test "it creates a backup record and an Oban job" do
|
||||
|
|
@ -75,6 +75,43 @@ defmodule Pleroma.User.BackupTest do
|
|||
)
|
||||
end
|
||||
|
||||
test "it does not send an email if the user does not have an email" do
|
||||
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
||||
%{id: user_id} = user = insert(:user, %{email: nil})
|
||||
|
||||
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
|
||||
assert {:ok, backup} = perform_job(BackupWorker, args)
|
||||
assert backup.file_size > 0
|
||||
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
|
||||
|
||||
assert_no_email_sent()
|
||||
end
|
||||
|
||||
test "it does not send an email if mailer is not on" do
|
||||
clear_config([Pleroma.Emails.Mailer, :enabled], false)
|
||||
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
||||
%{id: user_id} = user = insert(:user)
|
||||
|
||||
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
|
||||
assert {:ok, backup} = perform_job(BackupWorker, args)
|
||||
assert backup.file_size > 0
|
||||
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
|
||||
|
||||
assert_no_email_sent()
|
||||
end
|
||||
|
||||
test "it does not send an email if the user has an empty email" do
|
||||
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
||||
%{id: user_id} = user = insert(:user, %{email: ""})
|
||||
|
||||
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
|
||||
assert {:ok, backup} = perform_job(BackupWorker, args)
|
||||
assert backup.file_size > 0
|
||||
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
|
||||
|
||||
assert_no_email_sent()
|
||||
end
|
||||
|
||||
test "it removes outdated backups after creating a fresh one" do
|
||||
clear_config([Backup, :limit_days], -1)
|
||||
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@
|
|||
defmodule Pleroma.UserRelationshipTest do
|
||||
alias Pleroma.UserRelationship
|
||||
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase, async: false
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "*_exists?/2" do
|
||||
|
|
@ -79,7 +80,12 @@ defmodule Pleroma.UserRelationshipTest do
|
|||
end
|
||||
|
||||
test "if record already exists, returns it", %{users: [user1, user2]} do
|
||||
user_block = UserRelationship.create_block(user1, user2)
|
||||
user_block =
|
||||
with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
|
||||
{:ok, %{inserted_at: ~N[2017-03-17 17:09:58]}} =
|
||||
UserRelationship.create_block(user1, user2)
|
||||
end
|
||||
|
||||
assert user_block == UserRelationship.create_block(user1, user2)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -65,6 +65,14 @@ defmodule Pleroma.UserSearchTest do
|
|||
assert found_user.id == user.id
|
||||
end
|
||||
|
||||
test "excludes deactivated users from results" do
|
||||
user = insert(:user, %{nickname: "john t1000"})
|
||||
insert(:user, %{is_active: false, nickname: "john t800"})
|
||||
|
||||
[found_user] = User.search("john")
|
||||
assert found_user.id == user.id
|
||||
end
|
||||
|
||||
# Note: as in Mastodon, `is_discoverable` doesn't anyhow relate to user searchability
|
||||
test "includes non-discoverable users in results" do
|
||||
insert(:user, %{nickname: "john 3000", is_discoverable: false})
|
||||
|
|
|
|||
|
|
@ -310,7 +310,7 @@ defmodule Pleroma.UserTest do
|
|||
describe "unfollow/2" do
|
||||
setup do: clear_config([:instance, :external_user_synchronization])
|
||||
|
||||
test "unfollow with syncronizes external user" do
|
||||
test "unfollow with synchronizes external user" do
|
||||
clear_config([:instance, :external_user_synchronization], true)
|
||||
|
||||
followed =
|
||||
|
|
@ -585,6 +585,21 @@ defmodule Pleroma.UserTest do
|
|||
refute_email_sent()
|
||||
end
|
||||
|
||||
test "it works when the registering user does not provide an email" do
|
||||
clear_config([Pleroma.Emails.Mailer, :enabled], false)
|
||||
clear_config([:instance, :account_activation_required], false)
|
||||
clear_config([:instance, :account_approval_required], true)
|
||||
|
||||
cng = User.register_changeset(%User{}, @full_user_data |> Map.put(:email, ""))
|
||||
|
||||
# The user is still created
|
||||
assert {:ok, %User{nickname: "nick"}} = User.register(cng)
|
||||
|
||||
# No emails are sent
|
||||
ObanHelpers.perform_all()
|
||||
refute_email_sent()
|
||||
end
|
||||
|
||||
test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do
|
||||
clear_config([:instance, :account_activation_required], true)
|
||||
|
||||
|
|
@ -671,14 +686,14 @@ defmodule Pleroma.UserTest do
|
|||
assert changeset.valid?
|
||||
end
|
||||
|
||||
test "it sets the password_hash and ap_id" 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 changeset.changes.follower_address == "#{changeset.changes.ap_id}/followers"
|
||||
end
|
||||
|
||||
|
|
@ -844,6 +859,123 @@ defmodule Pleroma.UserTest do
|
|||
freshed_user = refresh_record(user)
|
||||
assert freshed_user == fetched_user
|
||||
end
|
||||
|
||||
test "gets an existing user by nickname starting with http" do
|
||||
user = insert(:user, nickname: "httpssome")
|
||||
{:ok, fetched_user} = User.get_or_fetch("httpssome")
|
||||
|
||||
assert user == fetched_user
|
||||
end
|
||||
end
|
||||
|
||||
describe "get_or_fetch/1 remote users with tld, while BE is runned on subdomain" do
|
||||
setup do: clear_config([Pleroma.Web.WebFinger, :update_nickname_on_user_fetch], true)
|
||||
|
||||
test "for mastodon" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{url: "https://example.com/.well-known/host-meta"} ->
|
||||
%Tesla.Env{
|
||||
status: 302,
|
||||
headers: [{"location", "https://sub.example.com/.well-known/host-meta"}]
|
||||
}
|
||||
|
||||
%{url: "https://sub.example.com/.well-known/host-meta"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
"test/fixtures/webfinger/masto-host-meta.xml"
|
||||
|> File.read!()
|
||||
|> String.replace("{{domain}}", "sub.example.com")
|
||||
}
|
||||
|
||||
%{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
"test/fixtures/webfinger/masto-webfinger.json"
|
||||
|> File.read!()
|
||||
|> String.replace("{{nickname}}", "a")
|
||||
|> String.replace("{{domain}}", "example.com")
|
||||
|> String.replace("{{subdomain}}", "sub.example.com"),
|
||||
headers: [{"content-type", "application/jrd+json"}]
|
||||
}
|
||||
|
||||
%{url: "https://sub.example.com/users/a"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
"test/fixtures/webfinger/masto-user.json"
|
||||
|> File.read!()
|
||||
|> String.replace("{{nickname}}", "a")
|
||||
|> String.replace("{{domain}}", "sub.example.com"),
|
||||
headers: [{"content-type", "application/activity+json"}]
|
||||
}
|
||||
|
||||
%{url: "https://sub.example.com/users/a/collections/featured"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
File.read!("test/fixtures/users_mock/masto_featured.json")
|
||||
|> String.replace("{{domain}}", "sub.example.com")
|
||||
|> String.replace("{{nickname}}", "a"),
|
||||
headers: [{"content-type", "application/activity+json"}]
|
||||
}
|
||||
end)
|
||||
|
||||
ap_id = "a@example.com"
|
||||
{:ok, fetched_user} = User.get_or_fetch(ap_id)
|
||||
|
||||
assert fetched_user.ap_id == "https://sub.example.com/users/a"
|
||||
assert fetched_user.nickname == "a@example.com"
|
||||
end
|
||||
|
||||
test "for pleroma" do
|
||||
Tesla.Mock.mock(fn
|
||||
%{url: "https://example.com/.well-known/host-meta"} ->
|
||||
%Tesla.Env{
|
||||
status: 302,
|
||||
headers: [{"location", "https://sub.example.com/.well-known/host-meta"}]
|
||||
}
|
||||
|
||||
%{url: "https://sub.example.com/.well-known/host-meta"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
"test/fixtures/webfinger/pleroma-host-meta.xml"
|
||||
|> File.read!()
|
||||
|> String.replace("{{domain}}", "sub.example.com")
|
||||
}
|
||||
|
||||
%{url: "https://sub.example.com/.well-known/webfinger?resource=acct:a@example.com"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
"test/fixtures/webfinger/pleroma-webfinger.json"
|
||||
|> File.read!()
|
||||
|> String.replace("{{nickname}}", "a")
|
||||
|> String.replace("{{domain}}", "example.com")
|
||||
|> String.replace("{{subdomain}}", "sub.example.com"),
|
||||
headers: [{"content-type", "application/jrd+json"}]
|
||||
}
|
||||
|
||||
%{url: "https://sub.example.com/users/a"} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body:
|
||||
"test/fixtures/webfinger/pleroma-user.json"
|
||||
|> File.read!()
|
||||
|> String.replace("{{nickname}}", "a")
|
||||
|> String.replace("{{domain}}", "sub.example.com"),
|
||||
headers: [{"content-type", "application/activity+json"}]
|
||||
}
|
||||
end)
|
||||
|
||||
ap_id = "a@example.com"
|
||||
{:ok, fetched_user} = User.get_or_fetch(ap_id)
|
||||
|
||||
assert fetched_user.ap_id == "https://sub.example.com/users/a"
|
||||
assert fetched_user.nickname == "a@example.com"
|
||||
end
|
||||
end
|
||||
|
||||
describe "fetching a user from nickname or trying to build one" do
|
||||
|
|
@ -1140,7 +1272,7 @@ defmodule Pleroma.UserTest do
|
|||
user = insert(:user)
|
||||
muted_user = insert(:user)
|
||||
|
||||
{:ok, _user_relationships} = User.mute(user, muted_user, %{expires_in: 60})
|
||||
{:ok, _user_relationships} = User.mute(user, muted_user, %{duration: 60})
|
||||
assert User.mutes?(user, muted_user)
|
||||
|
||||
worker = Pleroma.Workers.MuteExpireWorker
|
||||
|
|
@ -2240,21 +2372,6 @@ defmodule Pleroma.UserTest 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)
|
||||
|
|
@ -2369,7 +2486,7 @@ defmodule Pleroma.UserTest do
|
|||
assert other_user.follower_count == 1
|
||||
end
|
||||
|
||||
test "syncronizes the counters with the remote instance for the followed when enabled" do
|
||||
test "synchronizes the counters with the remote instance for the followed when enabled" do
|
||||
clear_config([:instance, :external_user_synchronization], false)
|
||||
|
||||
user = insert(:user)
|
||||
|
|
@ -2391,7 +2508,7 @@ defmodule Pleroma.UserTest do
|
|||
assert other_user.follower_count == 437
|
||||
end
|
||||
|
||||
test "syncronizes the counters with the remote instance for the follower when enabled" do
|
||||
test "synchronizes the counters with the remote instance for the follower when enabled" do
|
||||
clear_config([:instance, :external_user_synchronization], false)
|
||||
|
||||
user = insert(:user)
|
||||
|
|
@ -2691,6 +2808,82 @@ defmodule Pleroma.UserTest do
|
|||
object_id
|
||||
end
|
||||
|
||||
describe "add_alias/2" do
|
||||
test "should add alias for another user" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
||||
assert {:ok, user_updated} = user |> User.add_alias(user2)
|
||||
|
||||
assert user_updated.also_known_as |> length() == 1
|
||||
assert user2.ap_id in user_updated.also_known_as
|
||||
end
|
||||
|
||||
test "should add multiple aliases" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
user3 = insert(:user)
|
||||
|
||||
assert {:ok, user} = user |> User.add_alias(user2)
|
||||
assert {:ok, user_updated} = user |> User.add_alias(user3)
|
||||
|
||||
assert user_updated.also_known_as |> length() == 2
|
||||
assert user2.ap_id in user_updated.also_known_as
|
||||
assert user3.ap_id in user_updated.also_known_as
|
||||
end
|
||||
|
||||
test "should not add duplicate aliases" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
||||
assert {:ok, user} = user |> User.add_alias(user2)
|
||||
|
||||
assert {:ok, user_updated} = user |> User.add_alias(user2)
|
||||
|
||||
assert user_updated.also_known_as |> length() == 1
|
||||
assert user2.ap_id in user_updated.also_known_as
|
||||
end
|
||||
end
|
||||
|
||||
describe "alias_users/1" do
|
||||
test "should get aliases for a user" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user, also_known_as: [user.ap_id])
|
||||
|
||||
aliases = user2 |> User.alias_users()
|
||||
|
||||
assert aliases |> length() == 1
|
||||
|
||||
alias_user = aliases |> Enum.at(0)
|
||||
|
||||
assert alias_user.ap_id == user.ap_id
|
||||
end
|
||||
end
|
||||
|
||||
describe "delete_alias/2" do
|
||||
test "should delete existing alias" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user, also_known_as: [user.ap_id])
|
||||
|
||||
assert {:ok, user_updated} = user2 |> User.delete_alias(user)
|
||||
|
||||
assert user_updated.also_known_as == []
|
||||
end
|
||||
|
||||
test "should report error on non-existing alias" do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
user3 = insert(:user, also_known_as: [user.ap_id])
|
||||
|
||||
assert {:error, :no_such_alias} = user3 |> User.delete_alias(user2)
|
||||
|
||||
user3_updated = User.get_cached_by_ap_id(user3.ap_id)
|
||||
|
||||
assert user3_updated.also_known_as |> length() == 1
|
||||
assert user.ap_id in user3_updated.also_known_as
|
||||
end
|
||||
end
|
||||
|
||||
describe "account endorsements" do
|
||||
test "it pins people" do
|
||||
user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -247,6 +247,27 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert json_response(response, 200) == ObjectView.render("object.json", %{object: object})
|
||||
end
|
||||
|
||||
test "does not return local-only objects for remote users", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
reader = insert(:user, local: false)
|
||||
|
||||
{:ok, post} =
|
||||
CommonAPI.post(user, %{status: "test @#{reader.nickname}", visibility: "local"})
|
||||
|
||||
assert Pleroma.Web.ActivityPub.Visibility.is_local_public?(post)
|
||||
|
||||
object = Object.normalize(post, fetch: false)
|
||||
uuid = String.split(object.data["id"], "/") |> List.last()
|
||||
|
||||
assert response =
|
||||
conn
|
||||
|> assign(:user, reader)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/objects/#{uuid}")
|
||||
|
||||
json_response(response, 404)
|
||||
end
|
||||
|
||||
test "it returns a json representation of the object with accept application/json", %{
|
||||
conn: conn
|
||||
} do
|
||||
|
|
@ -1297,6 +1318,35 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert outbox_endpoint == result["id"]
|
||||
end
|
||||
|
||||
test "it returns a local note activity when authenticated as local user", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
reader = insert(:user)
|
||||
{:ok, note_activity} = CommonAPI.post(user, %{status: "mew mew", visibility: "local"})
|
||||
ap_id = note_activity.data["id"]
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> assign(:user, reader)
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/outbox?page=true")
|
||||
|> json_response(200)
|
||||
|
||||
assert %{"orderedItems" => [%{"id" => ^ap_id}]} = resp
|
||||
end
|
||||
|
||||
test "it does not return a local note activity when unauthenticated", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
{:ok, _note_activity} = CommonAPI.post(user, %{status: "mew mew", visibility: "local"})
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "application/activity+json")
|
||||
|> get("/users/#{user.nickname}/outbox?page=true")
|
||||
|> json_response(200)
|
||||
|
||||
assert %{"orderedItems" => []} = resp
|
||||
end
|
||||
|
||||
test "it returns a note activity in a collection", %{conn: conn} do
|
||||
note_activity = insert(:note_activity)
|
||||
note_object = Object.normalize(note_activity, fetch: false)
|
||||
|
|
|
|||
|
|
@ -554,7 +554,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert activity.data["ok"] == data["ok"]
|
||||
assert activity.data["id"] == given_id
|
||||
assert activity.data["context"] == "blabla"
|
||||
assert activity.data["context_id"]
|
||||
end
|
||||
|
||||
test "adds a context when none is there" do
|
||||
|
|
@ -576,8 +575,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
|
||||
assert is_binary(activity.data["context"])
|
||||
assert is_binary(object.data["context"])
|
||||
assert activity.data["context_id"]
|
||||
assert object.data["context_id"]
|
||||
end
|
||||
|
||||
test "adds an id to a given object if it lacks one and is a note and inserts it to the object database" do
|
||||
|
|
@ -1507,6 +1504,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
reporter_ap_id = reporter.ap_id
|
||||
target_ap_id = target_account.ap_id
|
||||
activity_ap_id = activity.data["id"]
|
||||
object_ap_id = activity.object.data["id"]
|
||||
|
||||
activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id)
|
||||
|
||||
|
|
@ -1518,6 +1516,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
reported_activity: activity,
|
||||
content: content,
|
||||
activity_ap_id: activity_ap_id,
|
||||
object_ap_id: object_ap_id,
|
||||
activity_with_object: activity_with_object,
|
||||
reporter_ap_id: reporter_ap_id,
|
||||
target_ap_id: target_ap_id
|
||||
|
|
@ -1531,7 +1530,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
target_account: target_account,
|
||||
reported_activity: reported_activity,
|
||||
content: content,
|
||||
activity_ap_id: activity_ap_id,
|
||||
object_ap_id: object_ap_id,
|
||||
activity_with_object: activity_with_object,
|
||||
reporter_ap_id: reporter_ap_id,
|
||||
target_ap_id: target_ap_id
|
||||
|
|
@ -1547,7 +1546,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity_ap_id,
|
||||
"id" => object_ap_id,
|
||||
"content" => content,
|
||||
"published" => activity_with_object.object.data["published"],
|
||||
"actor" =>
|
||||
|
|
@ -1571,6 +1570,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
context: context,
|
||||
target_account: target_account,
|
||||
reported_activity: reported_activity,
|
||||
object_ap_id: object_ap_id,
|
||||
content: content
|
||||
},
|
||||
Utils,
|
||||
|
|
@ -1585,8 +1585,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
content: content
|
||||
})
|
||||
|
||||
new_data =
|
||||
put_in(activity.data, ["object"], [target_account.ap_id, reported_activity.data["id"]])
|
||||
new_data = put_in(activity.data, ["object"], [target_account.ap_id, object_ap_id])
|
||||
|
||||
assert_called(Utils.maybe_federate(%{activity | data: new_data}))
|
||||
end
|
||||
|
|
@ -1612,7 +1611,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
})
|
||||
|
||||
assert Repo.aggregate(Activity, :count, :id) == 1
|
||||
assert Repo.aggregate(Object, :count, :id) == 2
|
||||
assert Repo.aggregate(Object, :count, :id) == 1
|
||||
assert Repo.aggregate(Notification, :count, :id) == 0
|
||||
end
|
||||
end
|
||||
|
|
@ -1665,7 +1664,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
end
|
||||
|
||||
describe "fetch_follow_information_for_user" do
|
||||
test "syncronizes following/followers counters" do
|
||||
test "synchronizes following/followers counters" do
|
||||
user =
|
||||
insert(:user,
|
||||
local: false,
|
||||
|
|
@ -1836,9 +1835,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
"target" => ^new_ap_id,
|
||||
"type" => "Move"
|
||||
},
|
||||
local: true
|
||||
local: true,
|
||||
recipients: recipients
|
||||
} = activity
|
||||
|
||||
assert old_user.follower_address in recipients
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => old_user.id,
|
||||
|
|
@ -1869,6 +1871,42 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
assert {:error, "Target account must have the origin in `alsoKnownAs`"} =
|
||||
ActivityPub.move(old_user, new_user)
|
||||
end
|
||||
|
||||
test "do not move remote user following relationships" do
|
||||
%{ap_id: old_ap_id} = old_user = insert(:user)
|
||||
%{ap_id: new_ap_id} = new_user = insert(:user, also_known_as: [old_ap_id])
|
||||
follower_remote = insert(:user, local: false)
|
||||
|
||||
User.follow(follower_remote, old_user)
|
||||
|
||||
assert User.following?(follower_remote, old_user)
|
||||
|
||||
assert {:ok, activity} = ActivityPub.move(old_user, new_user)
|
||||
|
||||
assert %Activity{
|
||||
actor: ^old_ap_id,
|
||||
data: %{
|
||||
"actor" => ^old_ap_id,
|
||||
"object" => ^old_ap_id,
|
||||
"target" => ^new_ap_id,
|
||||
"type" => "Move"
|
||||
},
|
||||
local: true
|
||||
} = activity
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => old_user.id,
|
||||
"target_id" => new_user.id
|
||||
}
|
||||
|
||||
assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
|
||||
|
||||
Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
|
||||
|
||||
assert User.following?(follower_remote, old_user)
|
||||
refute User.following?(follower_remote, new_user)
|
||||
end
|
||||
end
|
||||
|
||||
test "doesn't retrieve replies activities with exclude_replies" do
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|||
import Pleroma.Factory
|
||||
import ExUnit.CaptureLog
|
||||
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicy
|
||||
|
||||
@linkless_message %{
|
||||
|
|
@ -49,11 +50,23 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|||
|
||||
assert user.note_count == 0
|
||||
|
||||
message =
|
||||
@linkful_message
|
||||
|> Map.put("actor", user.ap_id)
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"actor" => user.ap_id,
|
||||
"object" => %{
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "<a href='https://example.com'>hi world!</a>"
|
||||
}
|
||||
]
|
||||
},
|
||||
"content" => "mew"
|
||||
}
|
||||
}
|
||||
|
||||
{:reject, _} = AntiLinkSpamPolicy.filter(message)
|
||||
{:reject, _} = MRF.filter_one(AntiLinkSpamPolicy, message)
|
||||
end
|
||||
|
||||
test "it allows posts with links for local users" do
|
||||
|
|
@ -67,6 +80,18 @@ defmodule Pleroma.Web.ActivityPub.MRF.AntiLinkSpamPolicyTest do
|
|||
|
||||
{:ok, _message} = AntiLinkSpamPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "it disallows posts with links in history" do
|
||||
user = insert(:user, local: false)
|
||||
|
||||
assert user.note_count == 0
|
||||
|
||||
message =
|
||||
@linkful_message
|
||||
|> Map.put("actor", user.ap_id)
|
||||
|
||||
{:reject, _} = AntiLinkSpamPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
describe "with old user" do
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.EnsureRePrepended
|
||||
|
||||
describe "rewrites summary" do
|
||||
|
|
@ -35,10 +36,58 @@ defmodule Pleroma.Web.ActivityPub.MRF.EnsureRePrependedTest do
|
|||
assert {:ok, res} = EnsureRePrepended.filter(message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
end
|
||||
|
||||
test "it adds `re:` to history" do
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
|
||||
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||
"re: object-summary"
|
||||
end
|
||||
|
||||
test "it accepts Updates" do
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}},
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"summary" => "object-summary",
|
||||
"inReplyTo" => %Activity{object: %Object{data: %{"summary" => "object-summary"}}}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(EnsureRePrepended, message)
|
||||
assert res["object"]["summary"] == "re: object-summary"
|
||||
|
||||
assert Enum.at(res["object"]["formerRepresentations"]["orderedItems"], 0)["summary"] ==
|
||||
"re: object-summary"
|
||||
end
|
||||
end
|
||||
|
||||
describe "skip filter" do
|
||||
test "it skip if type isn't 'Create'" do
|
||||
test "it skip if type isn't 'Create' or 'Update'" do
|
||||
message = %{
|
||||
"type" => "Annotation",
|
||||
"object" => %{"summary" => "object-summary"}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
|
|||
|
||||
alias Pleroma.Constants
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
|
|
@ -161,4 +162,98 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
|
|||
assert filtered ==
|
||||
"<p><span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{luigi.id}\" href=\"#{luigi.ap_id}\" rel=\"ugc\">@<span>luigi</span></a></span> </span>I'ma tired...</p>"
|
||||
end
|
||||
|
||||
test "aware of history" do
|
||||
mario = insert(:user, nickname: "mario")
|
||||
wario = insert(:user, nickname: "wario")
|
||||
|
||||
{:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
|
||||
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"actor" => wario.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"],
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expected =
|
||||
"<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => ^expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]}
|
||||
}
|
||||
}} = MRF.filter_one(ForceMentionsInContent, activity)
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
mario = insert(:user, nickname: "mario")
|
||||
wario = insert(:user, nickname: "wario")
|
||||
|
||||
{:ok, post1} = CommonAPI.post(mario, %{status: "Letsa go!"})
|
||||
|
||||
activity = %{
|
||||
"type" => "Update",
|
||||
"actor" => wario.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"],
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"actor" => wario.ap_id,
|
||||
"content" => "WHA-HA!",
|
||||
"to" => [
|
||||
mario.ap_id,
|
||||
Constants.as_public()
|
||||
],
|
||||
"inReplyTo" => post1.object.data["id"]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expected =
|
||||
"<span class=\"recipients-inline\"><span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{mario.id}\" href=\"#{mario.ap_id}\" rel=\"ugc\">@<span>mario</span></a></span> </span>WHA-HA!"
|
||||
|
||||
assert {:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => ^expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ^expected}]}
|
||||
}
|
||||
}} = MRF.filter_one(ForceMentionsInContent, activity)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -20,6 +20,76 @@ defmodule Pleroma.Web.ActivityPub.MRF.HashtagPolicyTest do
|
|||
assert modified["object"]["sensitive"]
|
||||
end
|
||||
|
||||
test "it is history-aware" do
|
||||
activity = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "hey",
|
||||
"tag" => []
|
||||
}
|
||||
}
|
||||
|
||||
activity_data =
|
||||
activity
|
||||
|> put_in(
|
||||
["object", "formerRepresentations"],
|
||||
%{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
Map.put(
|
||||
activity["object"],
|
||||
"tag",
|
||||
[%{"type" => "Hashtag", "name" => "#nsfw"}]
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
{:ok, modified} =
|
||||
Pleroma.Web.ActivityPub.MRF.filter_one(
|
||||
Pleroma.Web.ActivityPub.MRF.HashtagPolicy,
|
||||
activity_data
|
||||
)
|
||||
|
||||
refute modified["object"]["sensitive"]
|
||||
assert Enum.at(modified["object"]["formerRepresentations"]["orderedItems"], 0)["sensitive"]
|
||||
end
|
||||
|
||||
test "it works with Update" do
|
||||
activity = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => "hey",
|
||||
"tag" => []
|
||||
}
|
||||
}
|
||||
|
||||
activity_data =
|
||||
activity
|
||||
|> put_in(
|
||||
["object", "formerRepresentations"],
|
||||
%{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
Map.put(
|
||||
activity["object"],
|
||||
"tag",
|
||||
[%{"type" => "Hashtag", "name" => "#nsfw"}]
|
||||
)
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
{:ok, modified} =
|
||||
Pleroma.Web.ActivityPub.MRF.filter_one(
|
||||
Pleroma.Web.ActivityPub.MRF.HashtagPolicy,
|
||||
activity_data
|
||||
)
|
||||
|
||||
refute modified["object"]["sensitive"]
|
||||
assert Enum.at(modified["object"]["formerRepresentations"]["orderedItems"], 0)["sensitive"]
|
||||
end
|
||||
|
||||
test "it doesn't sets the sensitive property with irrelevant hashtags" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
|||
|
|
@ -79,6 +79,54 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
KeywordPolicy.filter(message)
|
||||
end)
|
||||
end
|
||||
|
||||
test "rejects if string matches in history" do
|
||||
clear_config([:mrf_keyword, :reject], ["pun"])
|
||||
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "just a daily reminder that compLAINer is a good",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "just a daily reminder that compLAINer is a good pun",
|
||||
"summary" => ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
KeywordPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "rejects Updates" do
|
||||
clear_config([:mrf_keyword, :reject], ["pun"])
|
||||
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => "just a daily reminder that compLAINer is a good",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "just a daily reminder that compLAINer is a good pun",
|
||||
"summary" => ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} =
|
||||
KeywordPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
|
||||
describe "delisting from ftl based on keywords" do
|
||||
|
|
@ -157,6 +205,31 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
not (["https://www.w3.org/ns/activitystreams#Public"] == result["to"])
|
||||
end)
|
||||
end
|
||||
|
||||
test "delists if string matches in history" do
|
||||
clear_config([:mrf_keyword, :federated_timeline_removal], ["pun"])
|
||||
|
||||
message = %{
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => "just a daily reminder that compLAINer is a good",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "just a daily reminder that compLAINer is a good pun",
|
||||
"summary" => ""
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, result} = KeywordPolicy.filter(message)
|
||||
assert ["https://www.w3.org/ns/activitystreams#Public"] == result["cc"]
|
||||
refute ["https://www.w3.org/ns/activitystreams#Public"] == result["to"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "replacing keywords" do
|
||||
|
|
@ -221,5 +294,63 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
|
|||
result == "ZFS is free software"
|
||||
end)
|
||||
end
|
||||
|
||||
test "replaces keyword if string matches in history" do
|
||||
clear_config([:mrf_keyword, :replace], [{"opensource", "free software"}])
|
||||
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"object" => %{
|
||||
"content" => "ZFS is opensource",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"content" => "ZFS is opensource mew mew", "summary" => ""}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => "ZFS is free software",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => "ZFS is free software mew mew"}]
|
||||
}
|
||||
}
|
||||
}} = KeywordPolicy.filter(message)
|
||||
end
|
||||
|
||||
test "replaces keyword in Updates" do
|
||||
clear_config([:mrf_keyword, :replace], [{"opensource", "free software"}])
|
||||
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"object" => %{
|
||||
"content" => "ZFS is opensource",
|
||||
"summary" => "",
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{"content" => "ZFS is opensource mew mew", "summary" => ""}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{:ok,
|
||||
%{
|
||||
"object" => %{
|
||||
"content" => "ZFS is free software",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => "ZFS is free software mew mew"}]
|
||||
}
|
||||
}
|
||||
}} = KeywordPolicy.filter(message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
use Pleroma.Tests.Helpers
|
||||
|
||||
alias Pleroma.HTTP
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicy
|
||||
|
||||
import Mock
|
||||
|
|
@ -22,6 +23,25 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
}
|
||||
}
|
||||
|
||||
@message_with_history %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "content",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "content",
|
||||
"attachment" => [
|
||||
%{"url" => [%{"href" => "http://example.com/image.jpg"}]}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setup do: clear_config([:media_proxy, :enabled], true)
|
||||
|
||||
test "it prefetches media proxy URIs" do
|
||||
|
|
@ -50,4 +70,28 @@ defmodule Pleroma.Web.ActivityPub.MRF.MediaProxyWarmingPolicyTest do
|
|||
refute called(HTTP.get(:_, :_, :_))
|
||||
end
|
||||
end
|
||||
|
||||
test "history-aware" do
|
||||
Tesla.Mock.mock(fn %{method: :get, url: "http://example.com/image.jpg"} ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
|
||||
MRF.filter_one(MediaProxyWarmingPolicy, @message_with_history)
|
||||
|
||||
assert called(HTTP.get(:_, :_, :_))
|
||||
end
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
Tesla.Mock.mock(fn %{method: :get, url: "http://example.com/image.jpg"} ->
|
||||
{:ok, %Tesla.Env{status: 200, body: ""}}
|
||||
end)
|
||||
|
||||
with_mock HTTP, get: fn _, _, _ -> {:ok, []} end do
|
||||
MRF.filter_one(MediaProxyWarmingPolicy, @message_with_history |> Map.put("type", "Update"))
|
||||
|
||||
assert called(HTTP.get(:_, :_, :_))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -151,4 +151,27 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoEmptyPolicyTest do
|
|||
|
||||
assert NoEmptyPolicy.filter(message) == {:reject, "[NoEmptyPolicy]"}
|
||||
end
|
||||
|
||||
test "works with Update" do
|
||||
message = %{
|
||||
"actor" => "http://localhost:4001/users/testuser",
|
||||
"cc" => ["http://localhost:4001/users/testuser/followers"],
|
||||
"object" => %{
|
||||
"actor" => "http://localhost:4001/users/testuser",
|
||||
"attachment" => [],
|
||||
"cc" => ["http://localhost:4001/users/testuser/followers"],
|
||||
"source" => "",
|
||||
"to" => [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type" => "Note"
|
||||
},
|
||||
"to" => [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"type" => "Update"
|
||||
}
|
||||
|
||||
assert NoEmptyPolicy.filter(message) == {:reject, "[NoEmptyPolicy]"}
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicy
|
||||
|
||||
test "it clears content object" do
|
||||
|
|
@ -20,6 +21,46 @@ defmodule Pleroma.Web.ActivityPub.MRF.NoPlaceholderTextPolicyTest do
|
|||
assert res["object"]["content"] == ""
|
||||
end
|
||||
|
||||
test "history-aware" do
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => ".",
|
||||
"attachment" => "image",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => ".", "attachment" => "image"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NoPlaceholderTextPolicy, message)
|
||||
|
||||
assert %{
|
||||
"content" => "",
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ""}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => ".",
|
||||
"attachment" => "image",
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [%{"content" => ".", "attachment" => "image"}]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NoPlaceholderTextPolicy, message)
|
||||
|
||||
assert %{
|
||||
"content" => "",
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => ""}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
@messages [
|
||||
%{
|
||||
"type" => "Create",
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
alias Pleroma.Web.ActivityPub.MRF
|
||||
alias Pleroma.Web.ActivityPub.MRF.NormalizeMarkup
|
||||
|
||||
@html_sample """
|
||||
|
|
@ -16,24 +17,58 @@ defmodule Pleroma.Web.ActivityPub.MRF.NormalizeMarkupTest do
|
|||
<script>alert('hacked')</script>
|
||||
"""
|
||||
|
||||
test "it filter html tags" do
|
||||
expected = """
|
||||
<b>this is in bold</b>
|
||||
<p>this is a paragraph</p>
|
||||
this is a linebreak<br/>
|
||||
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
|
||||
this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a>
|
||||
this is an image: <img src="http://example.com/image.jpg"/><br/>
|
||||
alert('hacked')
|
||||
"""
|
||||
@expected """
|
||||
<b>this is in bold</b>
|
||||
<p>this is a paragraph</p>
|
||||
this is a linebreak<br/>
|
||||
this is a link with allowed "rel" attribute: <a href="http://example.com/" rel="tag">example.com</a>
|
||||
this is a link with not allowed "rel" attribute: <a href="http://example.com/">example.com</a>
|
||||
this is an image: <img src="http://example.com/image.jpg"/><br/>
|
||||
alert('hacked')
|
||||
"""
|
||||
|
||||
test "it filter html tags" do
|
||||
message = %{"type" => "Create", "object" => %{"content" => @html_sample}}
|
||||
|
||||
assert {:ok, res} = NormalizeMarkup.filter(message)
|
||||
assert res["object"]["content"] == expected
|
||||
assert res["object"]["content"] == @expected
|
||||
end
|
||||
|
||||
test "it skips filter if type isn't `Create`" do
|
||||
test "history-aware" do
|
||||
message = %{
|
||||
"type" => "Create",
|
||||
"object" => %{
|
||||
"content" => @html_sample,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @html_sample}]}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NormalizeMarkup, message)
|
||||
|
||||
assert %{
|
||||
"content" => @expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @expected}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
test "works with Updates" do
|
||||
message = %{
|
||||
"type" => "Update",
|
||||
"object" => %{
|
||||
"content" => @html_sample,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @html_sample}]}
|
||||
}
|
||||
}
|
||||
|
||||
assert {:ok, res} = MRF.filter_one(NormalizeMarkup, message)
|
||||
|
||||
assert %{
|
||||
"content" => @expected,
|
||||
"formerRepresentations" => %{"orderedItems" => [%{"content" => @expected}]}
|
||||
} = res["object"]
|
||||
end
|
||||
|
||||
test "it skips filter if type isn't `Create` or `Update`" do
|
||||
message = %{"type" => "Note", "object" => %{}}
|
||||
|
||||
assert {:ok, res} = NormalizeMarkup.filter(message)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidator
|
||||
alias Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidator
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
||||
|
|
@ -31,6 +32,54 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
|
|||
test "a basic note validates", %{note: note} do
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
|
||||
test "a note from factory validates" do
|
||||
note = insert(:note)
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note.data)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Note with history" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"})
|
||||
{:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"})
|
||||
|
||||
{:ok, %{"object" => external_rep}} =
|
||||
Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data)
|
||||
|
||||
%{external_rep: external_rep}
|
||||
end
|
||||
|
||||
test "edited note", %{external_rep: external_rep} do
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"tag" => [_]}]}} = external_rep
|
||||
|
||||
{:ok, validate_res, []} = ObjectValidator.validate(external_rep, [])
|
||||
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"emoji" => %{"dinosaur" => _}}]}} =
|
||||
validate_res
|
||||
end
|
||||
|
||||
test "edited note, badly-formed formerRepresentations", %{external_rep: external_rep} do
|
||||
external_rep = Map.put(external_rep, "formerRepresentations", %{})
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
|
||||
test "edited note, badly-formed history item", %{external_rep: external_rep} do
|
||||
history_item =
|
||||
Enum.at(external_rep["formerRepresentations"]["orderedItems"], 0)
|
||||
|> Map.put("type", "Foo")
|
||||
|
||||
external_rep =
|
||||
put_in(
|
||||
external_rep,
|
||||
["formerRepresentations", "orderedItems"],
|
||||
[history_item]
|
||||
)
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
end
|
||||
|
||||
test "a Note from Roadhouse validates" do
|
||||
|
|
@ -43,4 +92,28 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
|
|||
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
|
||||
test "a note with an attachment should work", _ do
|
||||
insert(:user, %{ap_id: "https://owncast.localhost.localdomain/federation/user/streamer"})
|
||||
|
||||
note =
|
||||
"test/fixtures/owncast-note-with-attachment.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
|
||||
test "a Note without replies/first/items validates" do
|
||||
insert(:user, ap_id: "https://mastodon.social/users/emelie")
|
||||
|
||||
note =
|
||||
"test/fixtures/tesla_mock/status.emelie.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|> pop_in(["replies", "first", "items"])
|
||||
|> elem(1)
|
||||
|
||||
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do
|
|||
import Pleroma.Factory
|
||||
|
||||
describe "attachments" do
|
||||
test "fails without url" do
|
||||
attachment = %{
|
||||
"mediaType" => "",
|
||||
"name" => "",
|
||||
"summary" => "298p3RG7j27tfsZ9RQ.jpg",
|
||||
"type" => "Document"
|
||||
}
|
||||
|
||||
assert {:error, _cng} =
|
||||
AttachmentValidator.cast_and_validate(attachment)
|
||||
|> Ecto.Changeset.apply_action(:insert)
|
||||
end
|
||||
|
||||
test "works with honkerific attachments" do
|
||||
attachment = %{
|
||||
"mediaType" => "",
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidatorTest do
|
|||
{:ok, object_data} = ObjectValidator.cast_and_apply(note_activity["object"])
|
||||
meta = [object_data: ObjectValidator.stringify_keys(object_data)]
|
||||
|
||||
%{valid?: true} = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
assert %{valid?: true} = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
end
|
||||
|
||||
test "a Create/Note with mismatched context is invalid" do
|
||||
test "a Create/Note with mismatched context uses the Note's context" do
|
||||
user = insert(:user)
|
||||
|
||||
note = %{
|
||||
|
|
@ -54,6 +54,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.CreateGenericValidatorTest do
|
|||
{:ok, object_data} = ObjectValidator.cast_and_apply(note_activity["object"])
|
||||
meta = [object_data: ObjectValidator.stringify_keys(object_data)]
|
||||
|
||||
%{valid?: false} = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
validated = CreateGenericValidator.cast_and_validate(note_activity, meta)
|
||||
|
||||
assert validated.valid?
|
||||
assert {:context, note["context"]} in validated.changes
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
|
|||
test "returns an error if the object can't be updated by the actor", %{
|
||||
valid_update: valid_update
|
||||
} do
|
||||
other_user = insert(:user)
|
||||
other_user = insert(:user, local: false)
|
||||
|
||||
update =
|
||||
valid_update
|
||||
|
|
@ -40,5 +40,129 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.UpdateHandlingTest do
|
|||
|
||||
assert {:error, _cng} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
|
||||
test "validates as long as the object is same-origin with the actor", %{
|
||||
valid_update: valid_update
|
||||
} do
|
||||
other_user = insert(:user)
|
||||
|
||||
update =
|
||||
valid_update
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|
||||
assert {:ok, _update, []} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
|
||||
test "validates if the object is not of an Actor type" do
|
||||
note = insert(:note)
|
||||
updated_note = note.data |> Map.put("content", "edited content")
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, update, _} = Builder.update(other_user, updated_note)
|
||||
|
||||
assert {:ok, _update, _} = ObjectValidator.validate(update, [])
|
||||
end
|
||||
end
|
||||
|
||||
describe "update note" do
|
||||
test "converts object into Pleroma's format" do
|
||||
mastodon_tags = [
|
||||
%{
|
||||
"icon" => %{
|
||||
"mediaType" => "image/png",
|
||||
"type" => "Image",
|
||||
"url" => "https://somewhere.org/emoji/url/1.png"
|
||||
},
|
||||
"id" => "https://somewhere.org/emoji/1",
|
||||
"name" => ":some_emoji:",
|
||||
"type" => "Emoji",
|
||||
"updated" => "2021-04-07T11:00:00Z"
|
||||
}
|
||||
]
|
||||
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("content", "edited content")
|
||||
|> Map.put("tag", mastodon_tags)
|
||||
|
||||
{:ok, update, _} = Builder.update(user, updated_note)
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, [])
|
||||
|
||||
assert %{"emoji" => %{"some_emoji" => "https://somewhere.org/emoji/url/1.png"}} =
|
||||
meta[:object_data]
|
||||
end
|
||||
|
||||
test "returns no object_data in meta for a local Update" do
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("content", "edited content")
|
||||
|
||||
{:ok, update, _} = Builder.update(user, updated_note)
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, local: true)
|
||||
assert is_nil(meta[:object_data])
|
||||
end
|
||||
|
||||
test "returns object_data in meta for a remote Update" do
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("content", "edited content")
|
||||
|
||||
{:ok, update, _} = Builder.update(user, updated_note)
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, local: false)
|
||||
assert meta[:object_data]
|
||||
|
||||
assert {:ok, _update, meta} = ObjectValidator.validate(update, [])
|
||||
assert meta[:object_data]
|
||||
end
|
||||
end
|
||||
|
||||
describe "update with history" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew :dinosaur:"})
|
||||
{:ok, edit} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "edited :blank:"})
|
||||
{:ok, external_rep} = Pleroma.Web.ActivityPub.Transmogrifier.prepare_outgoing(edit.data)
|
||||
%{external_rep: external_rep}
|
||||
end
|
||||
|
||||
test "edited note", %{external_rep: external_rep} do
|
||||
{:ok, _validate_res, meta} = ObjectValidator.validate(external_rep, [])
|
||||
|
||||
assert %{"formerRepresentations" => %{"orderedItems" => [%{"emoji" => %{"dinosaur" => _}}]}} =
|
||||
meta[:object_data]
|
||||
end
|
||||
|
||||
test "edited note, badly-formed formerRepresentations", %{external_rep: external_rep} do
|
||||
external_rep = put_in(external_rep, ["object", "formerRepresentations"], %{})
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
|
||||
test "edited note, badly-formed history item", %{external_rep: external_rep} do
|
||||
history_item =
|
||||
Enum.at(external_rep["object"]["formerRepresentations"]["orderedItems"], 0)
|
||||
|> Map.put("type", "Foo")
|
||||
|
||||
external_rep =
|
||||
put_in(
|
||||
external_rep,
|
||||
["object", "formerRepresentations", "orderedItems"],
|
||||
[history_item]
|
||||
)
|
||||
|
||||
assert {:error, _} = ObjectValidator.validate(external_rep, [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -118,7 +118,10 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|||
describe "update users" do
|
||||
setup do
|
||||
user = insert(:user, local: false)
|
||||
{:ok, update_data, []} = Builder.update(user, %{"id" => user.ap_id, "name" => "new name!"})
|
||||
|
||||
{:ok, update_data, []} =
|
||||
Builder.update(user, %{"id" => user.ap_id, "type" => "Person", "name" => "new name!"})
|
||||
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
%{user: user, update_data: update_data, update: update}
|
||||
|
|
@ -140,6 +143,298 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "update notes" do
|
||||
setup do
|
||||
make_time = fn ->
|
||||
Pleroma.Web.ActivityPub.Utils.make_date()
|
||||
end
|
||||
|
||||
user = insert(:user)
|
||||
note = insert(:note, user: user, data: %{"published" => make_time.()})
|
||||
_note_activity = insert(:note_activity, note: note)
|
||||
|
||||
updated_note =
|
||||
note.data
|
||||
|> Map.put("summary", "edited summary")
|
||||
|> Map.put("content", "edited content")
|
||||
|> Map.put("updated", make_time.())
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_note)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
%{
|
||||
user: user,
|
||||
note: note,
|
||||
object_id: note.id,
|
||||
update_data: update_data,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
}
|
||||
end
|
||||
|
||||
test "it updates the note", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
updated_time = updated_note["updated"]
|
||||
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
|
||||
assert %{
|
||||
"summary" => "edited summary",
|
||||
"content" => "edited content",
|
||||
"updated" => ^updated_time
|
||||
} = new_note.data
|
||||
end
|
||||
|
||||
test "it rejects updates with no updated attribute in object", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
updated_note = Map.drop(updated_note, ["updated"])
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert old_note.data == new_note.data
|
||||
end
|
||||
|
||||
test "it rejects updates with updated attribute older than what we have in the original object",
|
||||
%{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
{:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
|
||||
|
||||
updated_note =
|
||||
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, -10)))
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert old_note.data == new_note.data
|
||||
end
|
||||
|
||||
test "it rejects updates with updated attribute older than the last Update", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
{:ok, creation_time, _} = DateTime.from_iso8601(old_note.data["published"])
|
||||
|
||||
updated_note =
|
||||
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(creation_time, +10)))
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
|
||||
old_note = Pleroma.Object.get_by_id(object_id)
|
||||
{:ok, update_time, _} = DateTime.from_iso8601(old_note.data["updated"])
|
||||
|
||||
updated_note =
|
||||
Map.put(updated_note, "updated", DateTime.to_iso8601(DateTime.add(update_time, -5)))
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert old_note.data == new_note.data
|
||||
end
|
||||
|
||||
test "it updates using object_data", %{
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
updated_note = Map.put(updated_note, "summary", "mew mew")
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
new_note = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "mew mew", "content" => "edited content"} = new_note.data
|
||||
end
|
||||
|
||||
test "it records the original note in formerRepresentations", %{
|
||||
note: note,
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
|
||||
|
||||
assert [Map.drop(note.data, ["id", "formerRepresentations"])] ==
|
||||
new_note["formerRepresentations"]["orderedItems"]
|
||||
|
||||
assert new_note["formerRepresentations"]["totalItems"] == 1
|
||||
end
|
||||
|
||||
test "it puts the original note at the front of formerRepresentations", %{
|
||||
user: user,
|
||||
note: note,
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: first_edit} = Pleroma.Object.get_by_id(object_id)
|
||||
|
||||
second_updated_note =
|
||||
note.data
|
||||
|> Map.put("summary", "edited summary 2")
|
||||
|> Map.put("content", "edited content 2")
|
||||
|> Map.put(
|
||||
"updated",
|
||||
first_edit["updated"]
|
||||
|> DateTime.from_iso8601()
|
||||
|> elem(1)
|
||||
|> DateTime.add(10)
|
||||
|> DateTime.to_iso8601()
|
||||
)
|
||||
|
||||
{:ok, second_update_data, []} = Builder.update(user, second_updated_note)
|
||||
{:ok, update, _meta} = ActivityPub.persist(second_update_data, local: true)
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: second_updated_note)
|
||||
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "edited summary 2", "content" => "edited content 2"} = new_note
|
||||
|
||||
original_version = Map.drop(note.data, ["id", "formerRepresentations"])
|
||||
first_edit = Map.drop(first_edit, ["id", "formerRepresentations"])
|
||||
|
||||
assert [first_edit, original_version] ==
|
||||
new_note["formerRepresentations"]["orderedItems"]
|
||||
|
||||
assert new_note["formerRepresentations"]["totalItems"] == 2
|
||||
end
|
||||
|
||||
test "it does not prepend to formerRepresentations if no actual changes are made", %{
|
||||
note: note,
|
||||
object_id: object_id,
|
||||
update: update,
|
||||
updated_note: updated_note
|
||||
} do
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: first_edit} = Pleroma.Object.get_by_id(object_id)
|
||||
|
||||
updated_note =
|
||||
updated_note
|
||||
|> Map.put(
|
||||
"updated",
|
||||
first_edit["updated"]
|
||||
|> DateTime.from_iso8601()
|
||||
|> elem(1)
|
||||
|> DateTime.add(10)
|
||||
|> DateTime.to_iso8601()
|
||||
)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_note)
|
||||
%{data: new_note} = Pleroma.Object.get_by_id(object_id)
|
||||
assert %{"summary" => "edited summary", "content" => "edited content"} = new_note
|
||||
|
||||
original_version = Map.drop(note.data, ["id", "formerRepresentations"])
|
||||
|
||||
assert [original_version] ==
|
||||
new_note["formerRepresentations"]["orderedItems"]
|
||||
|
||||
assert new_note["formerRepresentations"]["totalItems"] == 1
|
||||
end
|
||||
end
|
||||
|
||||
describe "update questions" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
|
||||
question =
|
||||
insert(:question,
|
||||
user: user,
|
||||
data: %{"published" => Pleroma.Web.ActivityPub.Utils.make_date()}
|
||||
)
|
||||
|
||||
%{user: user, data: question.data, id: question.id}
|
||||
end
|
||||
|
||||
test "allows updating choice count without generating edit history", %{
|
||||
user: user,
|
||||
data: data,
|
||||
id: id
|
||||
} do
|
||||
new_choices =
|
||||
data["oneOf"]
|
||||
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
||||
|
||||
updated_question =
|
||||
data
|
||||
|> Map.put("oneOf", new_choices)
|
||||
|> Map.put("updated", Pleroma.Web.ActivityPub.Utils.make_date())
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_question)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
||||
|
||||
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
||||
|
||||
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
||||
new_question["oneOf"]
|
||||
|
||||
refute Map.has_key?(new_question, "formerRepresentations")
|
||||
end
|
||||
|
||||
test "allows updating choice count without updated field", %{
|
||||
user: user,
|
||||
data: data,
|
||||
id: id
|
||||
} do
|
||||
new_choices =
|
||||
data["oneOf"]
|
||||
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
||||
|
||||
updated_question =
|
||||
data
|
||||
|> Map.put("oneOf", new_choices)
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_question)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
||||
|
||||
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
||||
|
||||
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
||||
new_question["oneOf"]
|
||||
|
||||
refute Map.has_key?(new_question, "formerRepresentations")
|
||||
end
|
||||
|
||||
test "allows updating choice count with updated field same as the creation date", %{
|
||||
user: user,
|
||||
data: data,
|
||||
id: id
|
||||
} do
|
||||
new_choices =
|
||||
data["oneOf"]
|
||||
|> Enum.map(fn choice -> put_in(choice, ["replies", "totalItems"], 5) end)
|
||||
|
||||
updated_question =
|
||||
data
|
||||
|> Map.put("oneOf", new_choices)
|
||||
|> Map.put("updated", data["published"])
|
||||
|
||||
{:ok, update_data, []} = Builder.update(user, updated_question)
|
||||
{:ok, update, _meta} = ActivityPub.persist(update_data, local: true)
|
||||
|
||||
{:ok, _, _} = SideEffects.handle(update, object_data: updated_question)
|
||||
|
||||
%{data: new_question} = Pleroma.Object.get_by_id(id)
|
||||
|
||||
assert [%{"replies" => %{"totalItems" => 5}}, %{"replies" => %{"totalItems" => 5}}] =
|
||||
new_question["oneOf"]
|
||||
|
||||
refute Map.has_key?(new_question, "formerRepresentations")
|
||||
end
|
||||
end
|
||||
|
||||
describe "EmojiReact objects" do
|
||||
setup do
|
||||
poster = insert(:user)
|
||||
|
|
@ -544,9 +839,7 @@ defmodule Pleroma.Web.ActivityPub.SideEffectsTest do
|
|||
]) do
|
||||
{:ok, announce, _} = SideEffects.handle(announce)
|
||||
|
||||
assert called(
|
||||
Pleroma.Web.Streamer.stream(["user", "list", "public", "public:local"], announce)
|
||||
)
|
||||
assert called(Pleroma.Web.Streamer.stream(["user", "list"], announce))
|
||||
|
||||
assert called(Pleroma.Web.Push.send(:_))
|
||||
end
|
||||
|
|
|
|||
|
|
@ -37,6 +37,37 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.EmojiReactHandlingTest do
|
|||
assert match?([["👌", _]], object.data["reactions"])
|
||||
end
|
||||
|
||||
test "it works for incoming unqualified emoji reactions" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user, local: false)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hello"})
|
||||
|
||||
# woman detective emoji, unqualified
|
||||
unqualified_emoji = [0x1F575, 0x200D, 0x2640] |> List.to_string()
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/emoji-reaction.json")
|
||||
|> Jason.decode!()
|
||||
|> Map.put("object", activity.data["object"])
|
||||
|> Map.put("actor", other_user.ap_id)
|
||||
|> Map.put("content", unqualified_emoji)
|
||||
|
||||
{:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
assert data["actor"] == other_user.ap_id
|
||||
assert data["type"] == "EmojiReact"
|
||||
assert data["id"] == "http://mastodon.example.org/users/admin#reactions/2"
|
||||
assert data["object"] == activity.data["object"]
|
||||
# woman detective emoji, fully qualified
|
||||
emoji = [0x1F575, 0xFE0F, 0x200D, 0x2640, 0xFE0F] |> List.to_string()
|
||||
assert data["content"] == emoji
|
||||
|
||||
object = Object.get_by_ap_id(data["object"])
|
||||
|
||||
assert object.data["reaction_count"] == 1
|
||||
assert match?([[emoji, _]], object.data["reactions"])
|
||||
end
|
||||
|
||||
test "it reject invalid emoji reactions" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user, local: false)
|
||||
|
|
|
|||
|
|
@ -707,4 +707,42 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.NoteHandlingTest do
|
|||
}
|
||||
]
|
||||
end
|
||||
|
||||
test "the standalone note uses its own ID when context is missing" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
|
||||
activity =
|
||||
"test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
{:ok, %Activity{} = modified} = Transmogrifier.handle_incoming(activity)
|
||||
object = Object.normalize(modified, fetch: false)
|
||||
|
||||
assert object.data["context"] == object.data["id"]
|
||||
assert modified.data["context"] == object.data["id"]
|
||||
end
|
||||
|
||||
test "the reply note uses its parent's ID when context is missing and reply is unreachable" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
|
||||
activity =
|
||||
"test/fixtures/tesla_mock/mk.absturztau.be-93e7nm8wqg-activity.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
object =
|
||||
activity["object"]
|
||||
|> Map.put("inReplyTo", "https://404.site/object/went-to-buy-milk")
|
||||
|
||||
activity =
|
||||
activity
|
||||
|> Map.put("object", object)
|
||||
|
||||
{:ok, %Activity{} = modified} = Transmogrifier.handle_incoming(activity)
|
||||
object = Object.normalize(modified, fetch: false)
|
||||
|
||||
assert object.data["context"] == object.data["inReplyTo"]
|
||||
assert modified.data["context"] == object.data["inReplyTo"]
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
|
|||
assert object.data["context"] ==
|
||||
"tag:mastodon.sdf.org,2019-05-10:objectId=15095122:objectType=Conversation"
|
||||
|
||||
assert object.data["context_id"]
|
||||
|
||||
assert object.data["anyOf"] == []
|
||||
|
||||
assert Enum.sort(object.data["oneOf"]) ==
|
||||
|
|
@ -68,7 +66,6 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.QuestionHandlingTest do
|
|||
reply_object = Object.normalize(reply_activity, fetch: false)
|
||||
|
||||
assert reply_object.data["context"] == object.data["context"]
|
||||
assert reply_object.data["context_id"] == object.data["context_id"]
|
||||
end
|
||||
|
||||
test "Mastodon Question activity with HTML tags in plaintext" do
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity.data["id"],
|
||||
"id" => activity.object.data["id"],
|
||||
"content" => "test post",
|
||||
"published" => object.data["published"],
|
||||
"actor" => AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|
||||
|
|
@ -108,15 +108,20 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert activity.data["type"] == "Move"
|
||||
end
|
||||
|
||||
test "a reply with mismatched context is rejected" do
|
||||
insert(:user, ap_id: "https://macgirvin.com/channel/mike")
|
||||
test "it fixes both the Create and object contexts in a reply" do
|
||||
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")
|
||||
insert(:user, ap_id: "https://p.helene.moe/users/helene")
|
||||
|
||||
note_activity =
|
||||
"test/fixtures/roadhouse-create-activity.json"
|
||||
create_activity =
|
||||
"test/fixtures/create-pleroma-reply-to-misskey-thread.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
assert {:error, _} = Transmogrifier.handle_incoming(note_activity)
|
||||
assert {:ok, %Activity{} = activity} = Transmogrifier.handle_incoming(create_activity)
|
||||
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert activity.data["context"] == object.data["context"]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -227,7 +232,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert is_nil(modified["object"]["like_count"])
|
||||
assert is_nil(modified["object"]["announcements"])
|
||||
assert is_nil(modified["object"]["announcement_count"])
|
||||
assert is_nil(modified["object"]["context_id"])
|
||||
assert is_nil(modified["object"]["generator"])
|
||||
end
|
||||
|
||||
|
|
@ -242,7 +246,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert is_nil(modified["object"]["like_count"])
|
||||
assert is_nil(modified["object"]["announcements"])
|
||||
assert is_nil(modified["object"]["announcement_count"])
|
||||
assert is_nil(modified["object"]["context_id"])
|
||||
assert is_nil(modified["object"]["likes"])
|
||||
end
|
||||
|
||||
|
|
@ -312,6 +315,28 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
|
||||
assert url == "http://localhost:4001/emoji/dino%20walking.gif"
|
||||
end
|
||||
|
||||
test "Updates of Notes are handled" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "everybody do the dinosaur :dinosaur:"})
|
||||
{:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew :blank:"})
|
||||
|
||||
{:ok, prepared} = Transmogrifier.prepare_outgoing(update.data)
|
||||
|
||||
assert %{
|
||||
"content" => "mew mew :blank:",
|
||||
"tag" => [%{"name" => ":blank:", "type" => "Emoji"}],
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"content" => "everybody do the dinosaur :dinosaur:",
|
||||
"tag" => [%{"name" => ":dinosaur:", "type" => "Emoji"}]
|
||||
}
|
||||
]
|
||||
}
|
||||
} = prepared["object"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "user upgrade" do
|
||||
|
|
@ -575,4 +600,43 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert Transmogrifier.fix_attachments(object) == expected
|
||||
end
|
||||
end
|
||||
|
||||
describe "prepare_object/1" do
|
||||
test "it processes history" do
|
||||
original = %{
|
||||
"formerRepresentations" => %{
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"generator" => %{},
|
||||
"emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
processed = Transmogrifier.prepare_object(original)
|
||||
|
||||
history_item = Enum.at(processed["formerRepresentations"]["orderedItems"], 0)
|
||||
|
||||
refute Map.has_key?(history_item, "generator")
|
||||
|
||||
assert [%{"name" => ":blobcat:"}] = history_item["tag"]
|
||||
end
|
||||
|
||||
test "it works when there is no or bad history" do
|
||||
original = %{
|
||||
"formerRepresentations" => %{
|
||||
"items" => [
|
||||
%{
|
||||
"generator" => %{},
|
||||
"emoji" => %{"blobcat" => "http://localhost:4001/emoji/blobcat.png"}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
processed = Transmogrifier.prepare_object(original)
|
||||
assert processed["formerRepresentations"] == original["formerRepresentations"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -429,7 +429,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
object = Object.normalize(note_activity, fetch: false)
|
||||
res = Utils.lazy_put_activity_defaults(%{"context" => object.data["id"]})
|
||||
assert res["context"] == object.data["id"]
|
||||
assert res["context_id"] == object.id
|
||||
assert res["id"]
|
||||
assert res["published"]
|
||||
end
|
||||
|
|
@ -437,7 +436,6 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
test "returns map with fake id and published data" do
|
||||
assert %{
|
||||
"context" => "pleroma:fakecontext",
|
||||
"context_id" => -1,
|
||||
"id" => "pleroma:fakeid",
|
||||
"published" => _
|
||||
} = Utils.lazy_put_activity_defaults(%{}, true)
|
||||
|
|
@ -454,13 +452,11 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
})
|
||||
|
||||
assert res["context"] == object.data["id"]
|
||||
assert res["context_id"] == object.id
|
||||
assert res["id"]
|
||||
assert res["published"]
|
||||
assert res["object"]["id"]
|
||||
assert res["object"]["published"]
|
||||
assert res["object"]["context"] == object.data["id"]
|
||||
assert res["object"]["context_id"] == object.id
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -477,7 +473,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
content = "foobar"
|
||||
|
||||
target_ap_id = target_account.ap_id
|
||||
activity_ap_id = activity.data["id"]
|
||||
object_ap_id = activity.object.data["id"]
|
||||
|
||||
res =
|
||||
Utils.make_flag_data(
|
||||
|
|
@ -493,7 +489,7 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity_ap_id,
|
||||
"id" => object_ap_id,
|
||||
"content" => content,
|
||||
"published" => activity.object.data["published"],
|
||||
"actor" =>
|
||||
|
|
@ -508,6 +504,49 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
"state" => "open"
|
||||
} = res
|
||||
end
|
||||
|
||||
test "returns map with Flag object with a non-Create Activity" do
|
||||
reporter = insert(:user)
|
||||
posting_account = insert(:user)
|
||||
target_account = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(posting_account, %{status: "foobar"})
|
||||
{:ok, like} = CommonAPI.favorite(target_account, activity.id)
|
||||
context = Utils.generate_context_id()
|
||||
content = "foobar"
|
||||
|
||||
target_ap_id = target_account.ap_id
|
||||
object_ap_id = activity.object.data["id"]
|
||||
|
||||
res =
|
||||
Utils.make_flag_data(
|
||||
%{
|
||||
actor: reporter,
|
||||
context: context,
|
||||
account: target_account,
|
||||
statuses: [%{"id" => like.data["id"]}],
|
||||
content: content
|
||||
},
|
||||
%{}
|
||||
)
|
||||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => object_ap_id,
|
||||
"content" => content,
|
||||
"published" => activity.object.data["published"],
|
||||
"actor" =>
|
||||
AccountView.render("show.json", %{user: posting_account, skip_visibility_check: true})
|
||||
}
|
||||
|
||||
assert %{
|
||||
"type" => "Flag",
|
||||
"content" => ^content,
|
||||
"context" => ^context,
|
||||
"object" => [^target_ap_id, ^note_obj],
|
||||
"state" => "open"
|
||||
} = res
|
||||
end
|
||||
end
|
||||
|
||||
describe "add_announce_to_object/2" do
|
||||
|
|
|
|||
|
|
@ -81,4 +81,18 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest 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
|
||||
|
|
|
|||
|
|
@ -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 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest 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 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest 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 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest 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 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest 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 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest 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})
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ defmodule Pleroma.Web.AdminAPI.ChatControllerTest do
|
|||
log_entry = Repo.one(ModerationLog)
|
||||
|
||||
assert ModerationLog.get_log_entry_message(log_entry) ==
|
||||
"@#{admin.nickname} deleted chat message ##{cm_ref.id}"
|
||||
"@#{admin.nickname} deleted chat message ##{message.id}"
|
||||
|
||||
assert result["id"] == cm_ref.id
|
||||
refute MessageReference.get_by_id(cm_ref.id)
|
||||
|
|
|
|||
|
|
@ -317,14 +317,14 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
end
|
||||
|
||||
test "save configs setting without explicit key", %{conn: conn} do
|
||||
level = Application.get_env(:quack, :level)
|
||||
meta = Application.get_env(:quack, :meta)
|
||||
webhook_url = Application.get_env(:quack, :webhook_url)
|
||||
adapter = Application.get_env(:http, :adapter)
|
||||
send_user_agent = Application.get_env(:http, :send_user_agent)
|
||||
user_agent = Application.get_env(:http, :user_agent)
|
||||
|
||||
on_exit(fn ->
|
||||
Application.put_env(:quack, :level, level)
|
||||
Application.put_env(:quack, :meta, meta)
|
||||
Application.put_env(:quack, :webhook_url, webhook_url)
|
||||
Application.put_env(:http, :adapter, adapter)
|
||||
Application.put_env(:http, :send_user_agent, send_user_agent)
|
||||
Application.put_env(:http, :user_agent, user_agent)
|
||||
end)
|
||||
|
||||
conn =
|
||||
|
|
@ -333,19 +333,19 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
|> post("/api/pleroma/admin/config", %{
|
||||
configs: [
|
||||
%{
|
||||
group: ":quack",
|
||||
key: ":level",
|
||||
value: ":info"
|
||||
group: ":http",
|
||||
key: ":adapter",
|
||||
value: [":someval"]
|
||||
},
|
||||
%{
|
||||
group: ":quack",
|
||||
key: ":meta",
|
||||
value: [":none"]
|
||||
group: ":http",
|
||||
key: ":send_user_agent",
|
||||
value: true
|
||||
},
|
||||
%{
|
||||
group: ":quack",
|
||||
key: ":webhook_url",
|
||||
value: "https://hooks.slack.com/services/KEY"
|
||||
group: ":http",
|
||||
key: ":user_agent",
|
||||
value: [":default"]
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
@ -353,30 +353,30 @@ defmodule Pleroma.Web.AdminAPI.ConfigControllerTest do
|
|||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"configs" => [
|
||||
%{
|
||||
"group" => ":quack",
|
||||
"key" => ":level",
|
||||
"value" => ":info",
|
||||
"db" => [":level"]
|
||||
"group" => ":http",
|
||||
"key" => ":adapter",
|
||||
"value" => [":someval"],
|
||||
"db" => [":adapter"]
|
||||
},
|
||||
%{
|
||||
"group" => ":quack",
|
||||
"key" => ":meta",
|
||||
"value" => [":none"],
|
||||
"db" => [":meta"]
|
||||
"group" => ":http",
|
||||
"key" => ":send_user_agent",
|
||||
"value" => true,
|
||||
"db" => [":send_user_agent"]
|
||||
},
|
||||
%{
|
||||
"group" => ":quack",
|
||||
"key" => ":webhook_url",
|
||||
"value" => "https://hooks.slack.com/services/KEY",
|
||||
"db" => [":webhook_url"]
|
||||
"group" => ":http",
|
||||
"key" => ":user_agent",
|
||||
"value" => [":default"],
|
||||
"db" => [":user_agent"]
|
||||
}
|
||||
],
|
||||
"need_reboot" => false
|
||||
}
|
||||
|
||||
assert Application.get_env(:quack, :level) == :info
|
||||
assert Application.get_env(:quack, :meta) == [:none]
|
||||
assert Application.get_env(:quack, :webhook_url) == "https://hooks.slack.com/services/KEY"
|
||||
assert Application.get_env(:http, :adapter) == [:someval]
|
||||
assert Application.get_env(:http, :send_user_agent) == true
|
||||
assert Application.get_env(:http, :user_agent) == [:default]
|
||||
end
|
||||
|
||||
test "saving config with partial update", %{conn: conn} do
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.AdminAPI.InstanceDocumentControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase
|
||||
import Pleroma.Factory
|
||||
|
||||
@dir "test/tmp/instance_static"
|
||||
|
|
|
|||
|
|
@ -68,6 +68,32 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
|
|||
assert notes["content"] == "this is an admin note"
|
||||
end
|
||||
|
||||
test "renders reported content even if the status is deleted", %{conn: conn} do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
activity = Activity.normalize(activity)
|
||||
|
||||
{:ok, %{id: report_id}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
account_id: target_user.id,
|
||||
comment: "I feel offended",
|
||||
status_ids: [activity.id]
|
||||
})
|
||||
|
||||
CommonAPI.delete(activity.id, target_user)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/pleroma/admin/reports/#{report_id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response["id"] == report_id
|
||||
|
||||
assert [status] = response["statuses"]
|
||||
assert activity.object.data["id"] == status["uri"]
|
||||
assert activity.object.data["content"] == status["content"]
|
||||
end
|
||||
|
||||
test "returns 404 when report id is invalid", %{conn: conn} do
|
||||
conn = get(conn, "/api/pleroma/admin/reports/test")
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
||||
alias Pleroma.Builders.UserBuilder
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.ActivityDraft
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
|
|
@ -273,22 +272,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "context_to_conversation_id" do
|
||||
test "creates a mapping object" do
|
||||
conversation_id = Utils.context_to_conversation_id("random context")
|
||||
object = Object.get_by_ap_id("random context")
|
||||
|
||||
assert conversation_id == object.id
|
||||
end
|
||||
|
||||
test "returns an existing mapping for an existing object" do
|
||||
{:ok, object} = Object.context_mapping("random context") |> Repo.insert()
|
||||
conversation_id = Utils.context_to_conversation_id("random context")
|
||||
|
||||
assert conversation_id == object.id
|
||||
end
|
||||
end
|
||||
|
||||
describe "formats date to asctime" do
|
||||
test "when date is in ISO 8601 format" do
|
||||
date = DateTime.utc_now() |> DateTime.to_iso8601()
|
||||
|
|
@ -517,17 +500,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "conversation_id_to_context/1" do
|
||||
test "returns id" do
|
||||
object = insert(:note)
|
||||
assert Utils.conversation_id_to_context(object.id) == object.data["id"]
|
||||
end
|
||||
|
||||
test "returns error if object not found" do
|
||||
assert Utils.conversation_id_to_context("123") == {:error, "No such conversation"}
|
||||
end
|
||||
end
|
||||
|
||||
describe "maybe_notify_mentioned_recipients/2" do
|
||||
test "returns recipients when activity is not `Create`" do
|
||||
activity = insert(:like_activity)
|
||||
|
|
|
|||
|
|
@ -61,9 +61,11 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
describe "blocking" do
|
||||
setup do
|
||||
blocker = insert(:user)
|
||||
blocked = insert(:user)
|
||||
User.follow(blocker, blocked)
|
||||
User.follow(blocked, blocker)
|
||||
blocked = insert(:user, local: false)
|
||||
CommonAPI.follow(blocker, blocked)
|
||||
CommonAPI.follow(blocked, blocker)
|
||||
CommonAPI.accept_follow_request(blocker, blocked)
|
||||
CommonAPI.accept_follow_request(blocked, blocked)
|
||||
%{blocker: blocker, blocked: blocked}
|
||||
end
|
||||
|
||||
|
|
@ -72,6 +74,9 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
with_mock Pleroma.Web.Federator,
|
||||
publish: fn _ -> nil end do
|
||||
assert User.get_follow_state(blocker, blocked) == :follow_accept
|
||||
refute is_nil(Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked))
|
||||
|
||||
assert {:ok, block} = CommonAPI.block(blocker, blocked)
|
||||
|
||||
assert block.local
|
||||
|
|
@ -79,6 +84,11 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
refute User.following?(blocker, blocked)
|
||||
refute User.following?(blocked, blocker)
|
||||
|
||||
refute User.get_follow_state(blocker, blocked)
|
||||
|
||||
assert %{data: %{"state" => "reject"}} =
|
||||
Pleroma.Web.ActivityPub.Utils.fetch_latest_follow(blocker, blocked)
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(block))
|
||||
end
|
||||
end
|
||||
|
|
@ -588,7 +598,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["content"] == "<p><b>2hu</b></p>alert('xss')"
|
||||
assert object.data["source"] == post
|
||||
assert object.data["source"]["content"] == post
|
||||
end
|
||||
|
||||
test "it filters out obviously bad tags when accepting a post as Markdown" do
|
||||
|
|
@ -605,7 +615,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert object.data["content"] == "<p><b>2hu</b></p>"
|
||||
assert object.data["source"] == post
|
||||
assert object.data["source"]["content"] == post
|
||||
end
|
||||
|
||||
test "it does not allow replies to direct messages that are not direct messages themselves" do
|
||||
|
|
@ -1092,10 +1102,11 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
target_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(target_user, %{status: "foobar"})
|
||||
activity = Activity.normalize(activity)
|
||||
|
||||
reporter_ap_id = reporter.ap_id
|
||||
target_ap_id = target_user.ap_id
|
||||
activity_ap_id = activity.data["id"]
|
||||
reported_object_ap_id = activity.object.data["id"]
|
||||
comment = "foobar"
|
||||
|
||||
report_data = %{
|
||||
|
|
@ -1106,7 +1117,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
note_obj = %{
|
||||
"type" => "Note",
|
||||
"id" => activity_ap_id,
|
||||
"id" => reported_object_ap_id,
|
||||
"content" => "foobar",
|
||||
"published" => activity.object.data["published"],
|
||||
"actor" => AccountView.render("show.json", %{user: target_user})
|
||||
|
|
@ -1128,6 +1139,7 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
test "updates report state" do
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
object = Object.normalize(activity)
|
||||
|
||||
{:ok, %Activity{id: report_id}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
|
|
@ -1140,10 +1152,36 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
|
||||
assert report.data["state"] == "resolved"
|
||||
|
||||
[reported_user, activity_id] = report.data["object"]
|
||||
[reported_user, object_id] = report.data["object"]
|
||||
|
||||
assert reported_user == target_user.ap_id
|
||||
assert activity_id == activity.data["id"]
|
||||
assert object_id == object.data["id"]
|
||||
end
|
||||
|
||||
test "updates report state, don't strip when report_strip_status is false" do
|
||||
clear_config([:instance, :report_strip_status], false)
|
||||
|
||||
[reporter, target_user] = insert_pair(:user)
|
||||
activity = insert(:note_activity, user: target_user)
|
||||
|
||||
{:ok, %Activity{id: report_id, data: report_data}} =
|
||||
CommonAPI.report(reporter, %{
|
||||
account_id: target_user.id,
|
||||
comment: "I feel offended",
|
||||
status_ids: [activity.id]
|
||||
})
|
||||
|
||||
{:ok, report} = CommonAPI.update_report_state(report_id, "resolved")
|
||||
|
||||
assert report.data["state"] == "resolved"
|
||||
|
||||
[reported_user, reported_activity] = report.data["object"]
|
||||
|
||||
assert reported_user == target_user.ap_id
|
||||
assert is_map(reported_activity)
|
||||
|
||||
assert reported_activity["content"] ==
|
||||
report_data["object"] |> Enum.at(1) |> Map.get("content")
|
||||
end
|
||||
|
||||
test "does not update report state when state is unsupported" do
|
||||
|
|
@ -1543,4 +1581,128 @@ defmodule Pleroma.Web.CommonAPITest do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "update/3" do
|
||||
test "updates a post" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1"})
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "updated 2"
|
||||
assert Map.get(updated_object.data, "summary", "") == ""
|
||||
assert Map.has_key?(updated_object.data, "updated")
|
||||
end
|
||||
|
||||
test "does not change visibility" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1", visibility: "private"})
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "updated 2"
|
||||
assert Map.get(updated_object.data, "summary", "") == ""
|
||||
assert Visibility.get_visibility(updated_object) == "private"
|
||||
assert Visibility.get_visibility(updated) == "private"
|
||||
end
|
||||
|
||||
test "updates a post with emoji" do
|
||||
[{emoji1, _}, {emoji2, _} | _] = Pleroma.Emoji.get_all()
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"})
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "updated 2 :#{emoji2}:"
|
||||
assert %{^emoji2 => _} = updated_object.data["emoji"]
|
||||
end
|
||||
|
||||
test "updates a post with emoji and federate properly" do
|
||||
[{emoji1, _}, {emoji2, _} | _] = Pleroma.Emoji.get_all()
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "foo1", spoiler_text: "title 1 :#{emoji1}:"})
|
||||
|
||||
clear_config([:instance, :federating], true)
|
||||
|
||||
with_mock Pleroma.Web.Federator,
|
||||
publish: fn _p -> nil end do
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2 :#{emoji2}:"})
|
||||
|
||||
assert updated.data["object"]["content"] == "updated 2 :#{emoji2}:"
|
||||
assert %{^emoji2 => _} = updated.data["object"]["emoji"]
|
||||
|
||||
assert called(Pleroma.Web.Federator.publish(updated))
|
||||
end
|
||||
end
|
||||
|
||||
test "editing a post that copied a remote title with remote emoji should keep that emoji" do
|
||||
remote_emoji_uri = "https://remote.org/emoji.png"
|
||||
|
||||
note =
|
||||
insert(
|
||||
:note,
|
||||
data: %{
|
||||
"summary" => ":remoteemoji:",
|
||||
"emoji" => %{
|
||||
"remoteemoji" => remote_emoji_uri
|
||||
},
|
||||
"tag" => [
|
||||
%{
|
||||
"type" => "Emoji",
|
||||
"name" => "remoteemoji",
|
||||
"icon" => %{"url" => remote_emoji_uri}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
note_activity = insert(:note_activity, note: note)
|
||||
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, reply} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "reply",
|
||||
spoiler_text: ":remoteemoji:",
|
||||
in_reply_to_id: note_activity.id
|
||||
})
|
||||
|
||||
assert reply.object.data["emoji"]["remoteemoji"] == remote_emoji_uri
|
||||
|
||||
{:ok, edit} =
|
||||
CommonAPI.update(user, reply, %{status: "reply mew mew", spoiler_text: ":remoteemoji:"})
|
||||
|
||||
edited_note = Pleroma.Object.normalize(edit)
|
||||
|
||||
assert edited_note.data["emoji"]["remoteemoji"] == remote_emoji_uri
|
||||
end
|
||||
|
||||
test "respects MRF" do
|
||||
user = insert(:user)
|
||||
|
||||
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.KeywordPolicy])
|
||||
clear_config([:mrf_keyword, :replace], [{"updated", "mewmew"}])
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "foo1", spoiler_text: "updated 1"})
|
||||
assert Object.normalize(activity).data["summary"] == "mewmew 1"
|
||||
|
||||
{:ok, updated} = CommonAPI.update(user, activity, %{status: "updated 2"})
|
||||
|
||||
updated_object = Object.normalize(updated)
|
||||
assert updated_object.data["content"] == "mewmew 2"
|
||||
assert Map.get(updated_object.data, "summary", "") == ""
|
||||
assert Map.has_key?(updated_object.data, "updated")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ defmodule Pleroma.Web.FederatorTest do
|
|||
}
|
||||
|
||||
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
||||
assert {:error, :origin_containment_failed} = ObanHelpers.perform(job)
|
||||
assert {:cancel, :origin_containment_failed} = ObanHelpers.perform(job)
|
||||
end
|
||||
|
||||
test "it does not crash if MRF rejects the post" do
|
||||
|
|
@ -169,7 +169,7 @@ defmodule Pleroma.Web.FederatorTest do
|
|||
|> Jason.decode!()
|
||||
|
||||
assert {:ok, job} = Federator.incoming_ap_doc(params)
|
||||
assert {:error, _} = ObanHelpers.perform(job)
|
||||
assert {:cancel, _} = ObanHelpers.perform(job)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
alias Pleroma.Repo
|
||||
alias Pleroma.Tests.ObanHelpers
|
||||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
|
@ -407,6 +408,20 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert id_two == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "gets local-only statuses for authenticated users", %{user: _user, conn: conn} do
|
||||
user_one = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user_one, %{status: "HI!!!", visibility: "local"})
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> get("/api/v1/accounts/#{user_one.id}/statuses")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => id}] = resp
|
||||
assert id == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "gets an users media, excludes reblogs", %{conn: conn} do
|
||||
note = insert(:note_activity)
|
||||
user = User.get_cached_by_ap_id(note.data["actor"])
|
||||
|
|
@ -881,6 +896,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: true})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"showing_reblogs" => true} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "1"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^reblog_id}] =
|
||||
conn
|
||||
|> get("/api/v1/timelines/home")
|
||||
|
|
@ -910,6 +931,12 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"showing_reblogs" => false} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "0"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] ==
|
||||
conn
|
||||
|> get("/api/v1/timelines/home")
|
||||
|
|
@ -920,21 +947,23 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
%{conn: conn} = oauth_access(["follow"])
|
||||
followed = insert(:user)
|
||||
|
||||
ret_conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true})
|
||||
assert %{"subscribing" => true} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert %{"id" => _id, "subscribing" => true} =
|
||||
json_response_and_validate_schema(ret_conn, 200)
|
||||
assert %{"subscribing" => true} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: "1"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
ret_conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false})
|
||||
|
||||
assert %{"id" => _id, "subscribing" => false} =
|
||||
json_response_and_validate_schema(ret_conn, 200)
|
||||
assert %{"subscribing" => false} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "following / unfollowing errors", %{user: user, conn: conn} do
|
||||
|
|
@ -1011,6 +1040,40 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
assert %{"id" => _id, "muting" => false, "muting_notifications" => false} =
|
||||
json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "expiring", %{conn: conn, user: user} do
|
||||
other_user = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v1/accounts/#{other_user.id}/mute", %{"duration" => "86400"})
|
||||
|
||||
assert %{"id" => _id, "muting" => true} = json_response_and_validate_schema(conn, 200)
|
||||
|
||||
mute_expires_at = UserRelationship.get_mute_expire_date(user, other_user)
|
||||
|
||||
assert DateTime.diff(
|
||||
mute_expires_at,
|
||||
DateTime.utc_now() |> DateTime.add(24 * 60 * 60)
|
||||
) in -3..3
|
||||
end
|
||||
|
||||
test "falls back to expires_in", %{conn: conn, user: user} do
|
||||
other_user = insert(:user)
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/v1/accounts/#{other_user.id}/mute", %{"expires_in" => "86400"})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
mute_expires_at = UserRelationship.get_mute_expire_date(user, other_user)
|
||||
|
||||
assert DateTime.diff(
|
||||
mute_expires_at,
|
||||
DateTime.utc_now() |> DateTime.add(24 * 60 * 60)
|
||||
) in -3..3
|
||||
end
|
||||
end
|
||||
|
||||
describe "pinned statuses" do
|
||||
|
|
@ -1829,21 +1892,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/mutes")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [id1, id2, id3] == Enum.map(result, & &1["id"])
|
||||
assert [id3, id2, id1] == Enum.map(result, & &1["id"])
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/mutes?limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id1}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/mutes?since_id=#{id1}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}, %{"id" => ^id3}] = result
|
||||
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1857,7 +1920,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/mutes?since_id=#{id1}&limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
end
|
||||
|
||||
test "list of mutes with with_relationships parameter" do
|
||||
|
|
@ -1876,7 +1939,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|
||||
assert [
|
||||
%{
|
||||
"id" => ^id1,
|
||||
"id" => ^id3,
|
||||
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
|
||||
},
|
||||
%{
|
||||
|
|
@ -1884,7 +1947,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
|
||||
},
|
||||
%{
|
||||
"id" => ^id3,
|
||||
"id" => ^id1,
|
||||
"pleroma" => %{"relationship" => %{"muting" => true, "followed_by" => true}}
|
||||
}
|
||||
] =
|
||||
|
|
@ -1909,7 +1972,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [id1, id2, id3] == Enum.map(result, & &1["id"])
|
||||
assert [id3, id2, id1] == Enum.map(result, & &1["id"])
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1917,7 +1980,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks?limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id1}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1925,7 +1988,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks?since_id=#{id1}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}, %{"id" => ^id3}] = result
|
||||
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -1941,7 +2004,31 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> get("/api/v1/blocks?since_id=#{id1}&limit=1")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id2}] = result
|
||||
assert [%{"id" => ^id3}] = result
|
||||
|
||||
conn_res =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/api/v1/blocks?limit=2")
|
||||
|
||||
next_url =
|
||||
~r{<.+?(?<link>/api[^>]+)>; rel=\"next\"}
|
||||
|> Regex.named_captures(get_resp_header(conn_res, "link") |> Enum.at(0))
|
||||
|> Map.get("link")
|
||||
|
||||
result =
|
||||
conn_res
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id3}, %{"id" => ^id2}] = result
|
||||
|
||||
result =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get(next_url)
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id1}] = result
|
||||
end
|
||||
|
||||
test "account lookup", %{conn: conn} do
|
||||
|
|
@ -2046,4 +2133,48 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|
|||
|> json_response_and_validate_schema(400)
|
||||
end
|
||||
end
|
||||
|
||||
describe "remove from followers" do
|
||||
setup do: oauth_access(["follow"])
|
||||
|
||||
test "removing user from followers", %{conn: conn, user: user} do
|
||||
%{id: other_user_id} = other_user = insert(:user)
|
||||
|
||||
CommonAPI.follow(other_user, user)
|
||||
|
||||
assert %{"id" => ^other_user_id, "followed_by" => false} =
|
||||
conn
|
||||
|> post("/api/v1/accounts/#{other_user_id}/remove_from_followers")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
refute User.following?(other_user, user)
|
||||
end
|
||||
|
||||
test "removing remote user from followers", %{conn: conn, user: user} do
|
||||
%{id: other_user_id} = other_user = insert(:user, local: false)
|
||||
|
||||
CommonAPI.follow(other_user, user)
|
||||
|
||||
assert User.following?(other_user, user)
|
||||
|
||||
assert %{"id" => ^other_user_id, "followed_by" => false} =
|
||||
conn
|
||||
|> post("/api/v1/accounts/#{other_user_id}/remove_from_followers")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
refute User.following?(other_user, user)
|
||||
end
|
||||
|
||||
test "removing user from followers errors", %{user: user, conn: conn} do
|
||||
# self remove
|
||||
conn_res = post(conn, "/api/v1/accounts/#{user.id}/remove_from_followers")
|
||||
|
||||
assert %{"error" => "Can not unfollow yourself"} =
|
||||
json_response_and_validate_schema(conn_res, 400)
|
||||
|
||||
# remove non existing user
|
||||
conn_res = post(conn, "/api/v1/accounts/doesntexist/remove_from_followers")
|
||||
assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn_res, 404)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
use Pleroma.Web.ConnCase, async: false
|
||||
use Oban.Testing, repo: Pleroma.Repo
|
||||
|
||||
import Mock
|
||||
import Pleroma.Factory
|
||||
|
||||
alias Pleroma.Filter
|
||||
|
|
@ -53,24 +54,19 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
|
|||
in_seconds = 600
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/filters", %{
|
||||
"phrase" => "knights",
|
||||
context: ["home"],
|
||||
expires_in: in_seconds
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/filters", %{
|
||||
"phrase" => "knights",
|
||||
context: ["home"],
|
||||
expires_in: in_seconds
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
assert response["irreversible"] == false
|
||||
|
||||
expected_expiration =
|
||||
NaiveDateTime.utc_now()
|
||||
|> NaiveDateTime.add(in_seconds)
|
||||
|
||||
{:ok, actual_expiration} = NaiveDateTime.from_iso8601(response["expires_at"])
|
||||
|
||||
assert abs(NaiveDateTime.diff(expected_expiration, actual_expiration)) <= 5
|
||||
assert response["expires_at"] == "2017-03-17T17:19:58.000Z"
|
||||
|
||||
filter = Filter.get(response["id"], user)
|
||||
|
||||
|
|
@ -177,28 +173,25 @@ defmodule Pleroma.Web.MastodonAPI.FilterControllerTest do
|
|||
assert response["whole_word"] == true
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "with adding expires_at", %{conn: conn, user: user} do
|
||||
filter = insert(:filter, user: user)
|
||||
in_seconds = 600
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/filters/#{filter.filter_id}", %{
|
||||
phrase: "nii",
|
||||
context: ["public"],
|
||||
expires_in: in_seconds,
|
||||
irreversible: true
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
with_mock NaiveDateTime, [:passthrough], utc_now: fn -> ~N[2017-03-17 17:09:58] end do
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/filters/#{filter.filter_id}", %{
|
||||
phrase: "nii",
|
||||
context: ["public"],
|
||||
expires_in: in_seconds,
|
||||
irreversible: true
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
assert response["irreversible"] == true
|
||||
|
||||
assert response["expires_at"] ==
|
||||
NaiveDateTime.utc_now()
|
||||
|> NaiveDateTime.add(in_seconds)
|
||||
|> Pleroma.Web.CommonAPI.Utils.to_masto_date()
|
||||
assert response["expires_at"] == "2017-03-17T17:19:58.000Z"
|
||||
|
||||
filter = Filter.get(response["id"], user)
|
||||
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
end
|
||||
|
||||
test "filters notifications using include_types" do
|
||||
test "filters notifications using types" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
||||
|
|
@ -474,21 +474,21 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
reblog_notification_id = get_notification_id_by_activity(reblog_activity)
|
||||
follow_notification_id = get_notification_id_by_activity(follow_activity)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=follow")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=follow")
|
||||
|
||||
assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=mention")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=mention")
|
||||
|
||||
assert [%{"id" => ^mention_notification_id}] =
|
||||
json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=favourite")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=favourite")
|
||||
|
||||
assert [%{"id" => ^favorite_notification_id}] =
|
||||
json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=reblog")
|
||||
conn_res = get(conn, "/api/v1/notifications?types[]=reblog")
|
||||
|
||||
assert [%{"id" => ^reblog_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
|
||||
|
|
@ -496,7 +496,7 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
|
||||
assert length(result) == 4
|
||||
|
||||
query = params_to_query(%{include_types: ["follow", "mention", "favourite", "reblog"]})
|
||||
query = params_to_query(%{types: ["follow", "mention", "favourite", "reblog"]})
|
||||
|
||||
result =
|
||||
conn
|
||||
|
|
@ -506,6 +506,23 @@ defmodule Pleroma.Web.MastodonAPI.NotificationControllerTest do
|
|||
assert length(result) == 4
|
||||
end
|
||||
|
||||
test "filtering falls back to include_types" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(other_user, %{status: "hey @#{user.nickname}"})
|
||||
{:ok, create_activity} = CommonAPI.post(user, %{status: "hey"})
|
||||
{:ok, _activity} = CommonAPI.favorite(other_user, create_activity.id)
|
||||
{:ok, _activity} = CommonAPI.repeat(create_activity.id, other_user)
|
||||
{:ok, _, _, follow_activity} = CommonAPI.follow(other_user, user)
|
||||
|
||||
follow_notification_id = get_notification_id_by_activity(follow_activity)
|
||||
|
||||
conn_res = get(conn, "/api/v1/notifications?include_types[]=follow")
|
||||
|
||||
assert [%{"id" => ^follow_notification_id}] = json_response_and_validate_schema(conn_res, 200)
|
||||
end
|
||||
|
||||
test "destroy multiple" do
|
||||
%{user: user, conn: conn} = oauth_access(["read:notifications", "write:notifications"])
|
||||
other_user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.Web.CommonAPI
|
||||
|
||||
import Pleroma.Factory
|
||||
|
|
@ -27,6 +29,41 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do
|
|||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "submit a report with a fake Create", %{
|
||||
conn: conn
|
||||
} do
|
||||
target_user = insert(:user)
|
||||
|
||||
note = insert(:note, user: target_user)
|
||||
|
||||
activity_params = %{
|
||||
"object" => note.data["id"],
|
||||
"actor" => note.data["actor"],
|
||||
"to" => note.data["to"] || [],
|
||||
"cc" => note.data["cc"] || [],
|
||||
"type" => "Create"
|
||||
}
|
||||
|
||||
{:ok, fake_activity} =
|
||||
Repo.insert(%Activity{
|
||||
data: activity_params,
|
||||
recipients: activity_params["to"] ++ activity_params["cc"],
|
||||
local: true,
|
||||
actor: activity_params["actor"]
|
||||
})
|
||||
|
||||
assert %{"action_taken" => false, "id" => _} =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/reports", %{
|
||||
"account_id" => target_user.id,
|
||||
"status_ids" => [fake_activity.id],
|
||||
"comment" => "bad status!",
|
||||
"forward" => "false"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "submit a report with statuses and comment", %{
|
||||
conn: conn,
|
||||
target_user: target_user,
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
@tag :skip_on_mac
|
||||
test "search", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
user_two = insert(:user, %{nickname: "shp@shitposter.club"})
|
||||
|
|
@ -79,6 +80,51 @@ defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do
|
|||
assert status["id"] == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "search local-only status as an authenticated user" do
|
||||
user = insert(:user)
|
||||
%{conn: conn} = oauth_access(["read:search"])
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"})
|
||||
|
||||
results =
|
||||
conn
|
||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
[status] = results["statuses"]
|
||||
assert status["id"] == to_string(activity.id)
|
||||
end
|
||||
|
||||
test "search local-only status as an unauthenticated user" do
|
||||
user = insert(:user)
|
||||
%{conn: conn} = oauth_access([])
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"})
|
||||
|
||||
results =
|
||||
conn
|
||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = results["statuses"]
|
||||
end
|
||||
|
||||
test "search local-only status as an anonymous user" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, _activity} =
|
||||
CommonAPI.post(user, %{status: "This is about 2hu private 天子", visibility: "local"})
|
||||
|
||||
results =
|
||||
build_conn()
|
||||
|> get("/api/v2/search?#{URI.encode_query(%{q: "2hu"})}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = results["statuses"]
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "constructs hashtags from search query", %{conn: conn} do
|
||||
results =
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|
||||
alias Pleroma.Activity
|
||||
alias Pleroma.Conversation.Participation
|
||||
alias Pleroma.ModerationLog
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Repo
|
||||
alias Pleroma.ScheduledActivity
|
||||
|
|
@ -262,6 +263,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> Map.put("url", nil)
|
||||
|> Map.put("uri", nil)
|
||||
|> Map.put("created_at", nil)
|
||||
|> Kernel.put_in(["pleroma", "context"], nil)
|
||||
|> Kernel.put_in(["pleroma", "conversation_id"], nil)
|
||||
|
||||
fake_conn =
|
||||
|
|
@ -285,6 +287,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> Map.put("url", nil)
|
||||
|> Map.put("uri", nil)
|
||||
|> Map.put("created_at", nil)
|
||||
|> Kernel.put_in(["pleroma", "context"], nil)
|
||||
|> Kernel.put_in(["pleroma", "conversation_id"], nil)
|
||||
|
||||
assert real_status == fake_status
|
||||
|
|
@ -971,16 +974,19 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
test "when you're privileged to", %{conn: conn} do
|
||||
clear_config([:instance, :moderator_privileges], [:messages_delete])
|
||||
activity = insert(:note_activity)
|
||||
moderator = insert(:user, is_moderator: true)
|
||||
user = insert(:user, is_moderator: true)
|
||||
|
||||
res_conn =
|
||||
conn
|
||||
|> assign(:user, moderator)
|
||||
|> assign(:token, insert(:oauth_token, user: moderator, scopes: ["write:statuses"]))
|
||||
|> assign(:user, user)
|
||||
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
|
||||
|> delete("/api/v1/statuses/#{activity.id}")
|
||||
|
||||
assert %{} = json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
assert ModerationLog |> Repo.one() |> ModerationLog.get_log_entry_message() ==
|
||||
"@#{user.nickname} deleted status ##{activity.id}"
|
||||
|
||||
refute Activity.get_by_id(activity.id)
|
||||
end
|
||||
end
|
||||
|
|
@ -1891,23 +1897,50 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
|> json_response_and_validate_schema(:ok)
|
||||
end
|
||||
|
||||
test "posting a local only status" do
|
||||
%{user: _user, conn: conn} = oauth_access(["write:statuses"])
|
||||
describe "local-only statuses" do
|
||||
test "posting a local only status" do
|
||||
%{user: _user, conn: conn} = oauth_access(["write:statuses"])
|
||||
|
||||
conn_one =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "cofe",
|
||||
"visibility" => "local"
|
||||
})
|
||||
conn_one =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "cofe",
|
||||
"visibility" => "local"
|
||||
})
|
||||
|
||||
local = Utils.as_local_public()
|
||||
local = Utils.as_local_public()
|
||||
|
||||
assert %{"content" => "cofe", "id" => id, "visibility" => "local"} =
|
||||
json_response_and_validate_schema(conn_one, 200)
|
||||
assert %{"content" => "cofe", "id" => id, "visibility" => "local"} =
|
||||
json_response_and_validate_schema(conn_one, 200)
|
||||
|
||||
assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
|
||||
assert %Activity{id: ^id, data: %{"to" => [^local]}} = Activity.get_by_id(id)
|
||||
end
|
||||
|
||||
test "other users can read local-only posts" do
|
||||
user = insert(:user)
|
||||
%{user: _reader, conn: conn} = oauth_access(["read:statuses"])
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
received =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert received["id"] == activity.id
|
||||
end
|
||||
|
||||
test "anonymous users cannot see local-only posts" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
_received =
|
||||
build_conn()
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
describe "muted reactions" do
|
||||
|
|
@ -1980,4 +2013,178 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|
|||
} = result
|
||||
end
|
||||
end
|
||||
|
||||
describe "get status history" do
|
||||
setup do
|
||||
%{conn: build_conn()}
|
||||
end
|
||||
|
||||
test "unedited post", %{conn: conn} do
|
||||
activity = insert(:note_activity)
|
||||
|
||||
conn = get(conn, "/api/v1/statuses/#{activity.id}/history")
|
||||
|
||||
assert [_] = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
|
||||
test "edited post", %{conn: conn} do
|
||||
note =
|
||||
insert(
|
||||
:note,
|
||||
data: %{
|
||||
"formerRepresentations" => %{
|
||||
"type" => "OrderedCollection",
|
||||
"orderedItems" => [
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "mew mew 2",
|
||||
"summary" => "title 2"
|
||||
},
|
||||
%{
|
||||
"type" => "Note",
|
||||
"content" => "mew mew 1",
|
||||
"summary" => "title 1"
|
||||
}
|
||||
],
|
||||
"totalItems" => 2
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
conn = get(conn, "/api/v1/statuses/#{activity.id}/history")
|
||||
|
||||
assert [%{"spoiler_text" => "title 1"}, %{"spoiler_text" => "title 2"}, _] =
|
||||
json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "get status source" do
|
||||
setup do
|
||||
%{conn: build_conn()}
|
||||
end
|
||||
|
||||
test "it returns the source", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
conn = get(conn, "/api/v1/statuses/#{activity.id}/source")
|
||||
|
||||
id = activity.id
|
||||
|
||||
assert %{"id" => ^id, "text" => "mew mew #abc", "spoiler_text" => "#def"} =
|
||||
json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "update status" do
|
||||
setup do
|
||||
oauth_access(["write:statuses"])
|
||||
end
|
||||
|
||||
test "it updates the status" do
|
||||
%{conn: conn, user: user} = oauth_access(["write:statuses", "read:statuses"])
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert response["content"] == "edited"
|
||||
assert response["spoiler_text"] == "lol"
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert response["content"] == "edited"
|
||||
assert response["spoiler_text"] == "lol"
|
||||
end
|
||||
|
||||
test "it updates the attachments", %{conn: conn, user: user} do
|
||||
attachment = insert(:attachment, user: user)
|
||||
attachment_id = to_string(attachment.id)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "mew mew #abc",
|
||||
"spoiler_text" => "#def",
|
||||
"media_ids" => [attachment_id]
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^attachment_id}] = response["media_attachments"]
|
||||
end
|
||||
|
||||
test "it does not update visibility", %{conn: conn, user: user} do
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
status: "mew mew #abc",
|
||||
spoiler_text: "#def",
|
||||
visibility: "private"
|
||||
})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert response["visibility"] == "private"
|
||||
end
|
||||
|
||||
test "it refuses to update when original post is not by the user", %{conn: conn} do
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(another_user, %{status: "mew mew #abc", spoiler_text: "#def"})
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(:forbidden)
|
||||
end
|
||||
|
||||
test "it returns 404 if the user cannot see the post", %{conn: conn} do
|
||||
another_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(another_user, %{
|
||||
status: "mew mew #abc",
|
||||
spoiler_text: "#def",
|
||||
visibility: "private"
|
||||
})
|
||||
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/statuses/#{activity.id}", %{
|
||||
"status" => "edited",
|
||||
"spoiler_text" => "lol"
|
||||
})
|
||||
|> json_response_and_validate_schema(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -367,6 +367,47 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
}
|
||||
] = result
|
||||
end
|
||||
|
||||
test "should return local-only posts for authenticated users" do
|
||||
user = insert(:user)
|
||||
%{user: _reader, conn: conn} = oauth_access(["read:statuses"])
|
||||
|
||||
{:ok, %{id: id}} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/public")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [%{"id" => ^id}] = result
|
||||
end
|
||||
|
||||
test "should not return local-only posts for users without read:statuses" do
|
||||
user = insert(:user)
|
||||
%{user: _reader, conn: conn} = oauth_access([])
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
result =
|
||||
conn
|
||||
|> get("/api/v1/timelines/public")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = result
|
||||
end
|
||||
|
||||
test "should not return local-only posts for anonymous users" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, _activity} = CommonAPI.post(user, %{status: "#2hu #2HU", visibility: "local"})
|
||||
|
||||
result =
|
||||
build_conn()
|
||||
|> get("/api/v1/timelines/public")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert [] = result
|
||||
end
|
||||
end
|
||||
|
||||
defp local_and_remote_activities do
|
||||
|
|
@ -903,7 +944,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "hashtag timeline handling of :restrict_unauthenticated setting" do
|
||||
describe "hashtag timeline handling of restrict_unauthenticated setting" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
{:ok, activity1} = CommonAPI.post(user, %{status: "test #tag1"})
|
||||
|
|
|
|||
|
|
@ -259,6 +259,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user.avatar == nil
|
||||
end
|
||||
|
||||
test "updates the user's avatar, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do
|
||||
upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8
|
||||
|
||||
assert :ok ==
|
||||
File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>)
|
||||
|
||||
new_avatar_oversized = %Plug.Upload{
|
||||
content_type: nil,
|
||||
path: Path.absname("test/tmp/large_binary.data"),
|
||||
filename: "large_binary.data"
|
||||
}
|
||||
|
||||
assert user.avatar == %{}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar_oversized})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 413)
|
||||
assert user_response["avatar"] != User.avatar_url(user)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.avatar == %{}
|
||||
|
||||
clear_config([:instance, :upload_limit], upload_limit)
|
||||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "updates the user's banner", %{user: user, conn: conn} do
|
||||
new_header = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
|
|
@ -278,6 +306,32 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user.banner == nil
|
||||
end
|
||||
|
||||
test "updates the user's banner, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do
|
||||
upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8
|
||||
|
||||
assert :ok ==
|
||||
File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>)
|
||||
|
||||
new_header_oversized = %Plug.Upload{
|
||||
content_type: nil,
|
||||
path: Path.absname("test/tmp/large_binary.data"),
|
||||
filename: "large_binary.data"
|
||||
}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header_oversized})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 413)
|
||||
assert user_response["header"] != User.banner_url(user)
|
||||
|
||||
user = User.get_by_id(user.id)
|
||||
assert user.banner == %{}
|
||||
|
||||
clear_config([:instance, :upload_limit], upload_limit)
|
||||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "updates the user's background", %{conn: conn, user: user} do
|
||||
new_header = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
|
|
@ -301,6 +355,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user.background == nil
|
||||
end
|
||||
|
||||
test "updates the user's background, upload_limit, returns a HTTP 413", %{
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8
|
||||
|
||||
assert :ok ==
|
||||
File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>)
|
||||
|
||||
new_background_oversized = %Plug.Upload{
|
||||
content_type: nil,
|
||||
path: Path.absname("test/tmp/large_binary.data"),
|
||||
filename: "large_binary.data"
|
||||
}
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"pleroma_background_image" => new_background_oversized
|
||||
})
|
||||
|
||||
assert user_response = json_response_and_validate_schema(res, 413)
|
||||
assert user.background == %{}
|
||||
|
||||
clear_config([:instance, :upload_limit], upload_limit)
|
||||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
end
|
||||
|
||||
test "requires 'write:accounts' permission" do
|
||||
token1 = insert(:oauth_token, scopes: ["read"])
|
||||
token2 = insert(:oauth_token, scopes: ["write", "follow"])
|
||||
|
|
@ -390,6 +472,20 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert user_data["source"]["pleroma"]["show_birthday"] == true
|
||||
end
|
||||
|
||||
test "unsets birth date", %{conn: conn} do
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"birthday" => "2001-02-12"
|
||||
})
|
||||
|
||||
res =
|
||||
patch(conn, "/api/v1/accounts/update_credentials", %{
|
||||
"birthday" => ""
|
||||
})
|
||||
|
||||
assert user_data = json_response_and_validate_schema(res, 200)
|
||||
assert user_data["pleroma"]["birthday"] == nil
|
||||
end
|
||||
|
||||
test "emojis in fields labels", %{conn: conn} do
|
||||
fields = [
|
||||
%{"name" => ":firefox:", "value" => "is best 2hu"},
|
||||
|
|
|
|||
|
|
@ -779,4 +779,21 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
|> assert()
|
||||
end
|
||||
end
|
||||
|
||||
test "renders mute expiration date" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, _user_relationships} =
|
||||
User.mute(user, other_user, %{notifications: true, duration: 24 * 60 * 60})
|
||||
|
||||
%{
|
||||
mute_expires_at: mute_expires_at
|
||||
} = AccountView.render("show.json", %{user: other_user, for: user, mutes: true})
|
||||
|
||||
assert DateTime.diff(
|
||||
mute_expires_at,
|
||||
DateTime.utc_now() |> DateTime.add(24 * 60 * 60)
|
||||
) in -3..3
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -239,6 +239,32 @@ defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do
|
|||
test_notifications_rendering([notification], moderator_user, [expected])
|
||||
end
|
||||
|
||||
test "Edit notification" do
|
||||
user = insert(:user)
|
||||
repeat_user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "mew"})
|
||||
{:ok, _} = CommonAPI.repeat(activity.id, repeat_user)
|
||||
{:ok, update} = CommonAPI.update(user, activity, %{status: "mew mew"})
|
||||
|
||||
user = Pleroma.User.get_by_ap_id(user.ap_id)
|
||||
activity = Pleroma.Activity.normalize(activity)
|
||||
update = Pleroma.Activity.normalize(update)
|
||||
|
||||
{:ok, [notification]} = Notification.create_notifications(update)
|
||||
|
||||
expected = %{
|
||||
id: to_string(notification.id),
|
||||
pleroma: %{is_seen: false, is_muted: false},
|
||||
type: "update",
|
||||
account: AccountView.render("show.json", %{user: user, for: repeat_user}),
|
||||
created_at: Utils.to_masto_date(notification.inserted_at),
|
||||
status: StatusView.render("show.json", %{activity: activity, for: repeat_user})
|
||||
}
|
||||
|
||||
test_notifications_rendering([notification], repeat_user, [expected])
|
||||
end
|
||||
|
||||
test "muted notification" do
|
||||
user = insert(:user)
|
||||
another_user = insert(:user)
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
alias Pleroma.User
|
||||
alias Pleroma.UserRelationship
|
||||
alias Pleroma.Web.CommonAPI
|
||||
alias Pleroma.Web.CommonAPI.Utils
|
||||
alias Pleroma.Web.MastodonAPI.AccountView
|
||||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
|
||||
require Bitwise
|
||||
|
||||
import Pleroma.Factory
|
||||
import Tesla.Mock
|
||||
import OpenApiSpex.TestAssertions
|
||||
|
|
@ -226,7 +227,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
object_data = Object.normalize(note, fetch: false).data
|
||||
user = User.get_cached_by_ap_id(note.data["actor"])
|
||||
|
||||
convo_id = Utils.context_to_conversation_id(object_data["context"])
|
||||
convo_id = :erlang.crc32(object_data["context"]) |> Bitwise.band(Bitwise.bnot(0x8000_0000))
|
||||
|
||||
status = StatusView.render("show.json", %{activity: note})
|
||||
|
||||
|
|
@ -246,6 +247,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
content: HTML.filter_tags(object_data["content"]),
|
||||
text: nil,
|
||||
created_at: created_at,
|
||||
edited_at: nil,
|
||||
reblogs_count: 0,
|
||||
replies_count: 0,
|
||||
favourites_count: 0,
|
||||
|
|
@ -279,6 +281,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
pleroma: %{
|
||||
local: true,
|
||||
conversation_id: convo_id,
|
||||
context: object_data["context"],
|
||||
in_reply_to_account_acct: nil,
|
||||
content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
|
||||
spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
|
||||
|
|
@ -708,4 +711,55 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
status = StatusView.render("show.json", activity: visible, for: poster)
|
||||
assert status.pleroma.parent_visible
|
||||
end
|
||||
|
||||
test "it shows edited_at" do
|
||||
poster = insert(:user)
|
||||
|
||||
{:ok, post} = CommonAPI.post(poster, %{status: "hey"})
|
||||
|
||||
status = StatusView.render("show.json", activity: post)
|
||||
refute status.edited_at
|
||||
|
||||
{:ok, _} = CommonAPI.update(poster, post, %{status: "mew mew"})
|
||||
edited = Pleroma.Activity.normalize(post)
|
||||
|
||||
status = StatusView.render("show.json", activity: edited)
|
||||
assert status.edited_at
|
||||
end
|
||||
|
||||
test "with a source object" do
|
||||
note =
|
||||
insert(:note,
|
||||
data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
status = StatusView.render("show.json", activity: activity, with_source: true)
|
||||
assert status.text == "object source"
|
||||
end
|
||||
|
||||
describe "source.json" do
|
||||
test "with a source object, renders both source and content type" do
|
||||
note =
|
||||
insert(:note,
|
||||
data: %{"source" => %{"content" => "object source", "mediaType" => "text/markdown"}}
|
||||
)
|
||||
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
status = StatusView.render("source.json", activity: activity)
|
||||
assert status.text == "object source"
|
||||
assert status.content_type == "text/markdown"
|
||||
end
|
||||
|
||||
test "with a source string, renders source and put text/plain as the content type" do
|
||||
note = insert(:note, data: %{"source" => "string source"})
|
||||
activity = insert(:note_activity, note: note)
|
||||
|
||||
status = StatusView.render("source.json", activity: activity)
|
||||
assert status.text == "string source"
|
||||
assert status.content_type == "text/plain"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,11 +10,14 @@ defmodule Pleroma.Web.MediaProxy.Invalidation.ScriptTest do
|
|||
|
||||
test "it logs error when script is not found" do
|
||||
assert capture_log(fn ->
|
||||
assert Invalidation.Script.purge(
|
||||
["http://example.com/media/example.jpg"],
|
||||
script_path: "./example"
|
||||
) == {:error, "%ErlangError{original: :enoent}"}
|
||||
end) =~ "Error while cache purge: %ErlangError{original: :enoent}"
|
||||
assert {:error, msg} =
|
||||
Invalidation.Script.purge(
|
||||
["http://example.com/media/example.jpg"],
|
||||
script_path: "./example"
|
||||
)
|
||||
|
||||
assert msg =~ ~r/%ErlangError{original: :enoent(, reason: nil)?}/
|
||||
end) =~ ~r/Error while cache purge: %ErlangError{original: :enoent(, reason: nil)?}/
|
||||
|
||||
capture_log(fn ->
|
||||
assert Invalidation.Script.purge(
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 500, body: ""}
|
||||
end)
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "application/pdf"}]}
|
||||
end)
|
||||
|
||||
|
|
@ -193,7 +193,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
clear_config([:media_preview_proxy, :min_content_length], 1_000_000_000)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: "",
|
||||
|
|
@ -218,7 +218,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/gif"}]}
|
||||
end)
|
||||
|
||||
|
|
@ -236,7 +236,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
|
||||
end)
|
||||
|
||||
|
|
@ -256,7 +256,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
clear_config([:media_preview_proxy, :min_content_length], 100_000)
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: "",
|
||||
|
|
@ -278,7 +278,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
assert_dependencies_installed()
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/png"}]}
|
||||
|
||||
%{method: :get, url: ^media_proxy_url} ->
|
||||
|
|
@ -300,7 +300,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
assert_dependencies_installed()
|
||||
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
|
||||
|
||||
%{method: :get, url: ^media_proxy_url} ->
|
||||
|
|
@ -320,7 +320,7 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
|
|||
media_proxy_url: media_proxy_url
|
||||
} do
|
||||
Tesla.Mock.mock(fn
|
||||
%{method: "head", url: ^media_proxy_url} ->
|
||||
%{method: "HEAD", url: ^media_proxy_url} ->
|
||||
%Tesla.Env{status: 200, body: "", headers: [{"content-type", "image/jpeg"}]}
|
||||
|
||||
%{method: :get, url: ^media_proxy_url} ->
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
|
|||
"actor" => user.ap_id,
|
||||
"tag" => [],
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "pleroma in a nutshell"
|
||||
}
|
||||
})
|
||||
|
|
@ -54,6 +55,36 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest 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 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
|
|||
"actor" => user.ap_id,
|
||||
"tag" => [],
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "pleroma in a nutshell",
|
||||
"sensitive" => true,
|
||||
"attachment" => [
|
||||
|
|
@ -109,6 +141,7 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
|
|||
"actor" => user.ap_id,
|
||||
"tag" => [],
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => "",
|
||||
"content" => "pleroma in a nutshell",
|
||||
"attachment" => [
|
||||
%{
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.Metadata.UtilsTest do
|
||||
use Pleroma.DataCase, async: true
|
||||
use Pleroma.DataCase, async: false
|
||||
import Pleroma.Factory
|
||||
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,12 +16,60 @@ defmodule Pleroma.Web.Metadata.UtilsTest do
|
|||
data: %{
|
||||
"actor" => user.ap_id,
|
||||
"id" => "https://pleroma.gov/objects/whatever",
|
||||
"summary" => nil,
|
||||
"content" => "Pleroma's really cool!"
|
||||
}
|
||||
})
|
||||
|
||||
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)
|
||||
|
||||
{:ok, activity} = Pleroma.Web.CommonAPI.post(user, %{status: "mew mew #def"})
|
||||
|
||||
object = Pleroma.Object.normalize(activity)
|
||||
assert Utils.scrub_html_and_truncate(object) == "mew mew #def"
|
||||
|
||||
{:ok, update} = Pleroma.Web.CommonAPI.update(user, activity, %{status: "mew mew #abc"})
|
||||
update = Pleroma.Activity.normalize(update)
|
||||
object = Pleroma.Object.normalize(update)
|
||||
assert Utils.scrub_html_and_truncate(object) == "mew mew #abc"
|
||||
end
|
||||
end
|
||||
|
||||
describe "scrub_html_and_truncate/2" do
|
||||
|
|
|
|||
|
|
@ -343,54 +343,4 @@ defmodule Pleroma.Web.OStatus.OStatusControllerTest do
|
|||
|> response(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "notice compatibility routes" do
|
||||
test "Soapbox FE", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note_activity = insert(:note_activity, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/@#{user.nickname}/posts/#{note_activity.id}")
|
||||
|> response(200)
|
||||
|
||||
expected =
|
||||
"<meta content=\"#{Endpoint.url()}/notice/#{note_activity.id}\" property=\"og:url\">"
|
||||
|
||||
assert resp =~ expected
|
||||
end
|
||||
|
||||
test "Mastodon", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note_activity = insert(:note_activity, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/@#{user.nickname}/#{note_activity.id}")
|
||||
|> response(200)
|
||||
|
||||
expected =
|
||||
"<meta content=\"#{Endpoint.url()}/notice/#{note_activity.id}\" property=\"og:url\">"
|
||||
|
||||
assert resp =~ expected
|
||||
end
|
||||
|
||||
test "Twitter", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
note_activity = insert(:note_activity, user: user)
|
||||
|
||||
resp =
|
||||
conn
|
||||
|> put_req_header("accept", "text/html")
|
||||
|> get("/#{user.nickname}/status/#{note_activity.id}")
|
||||
|> response(200)
|
||||
|
||||
expected =
|
||||
"<meta content=\"#{Endpoint.url()}/notice/#{note_activity.id}\" property=\"og:url\">"
|
||||
|
||||
assert resp =~ expected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest do
|
|||
setup do
|
||||
clear_config([Pleroma.Upload, :uploader])
|
||||
clear_config([Backup, :limit_days])
|
||||
oauth_access(["read:accounts"])
|
||||
oauth_access(["read:backups"])
|
||||
end
|
||||
|
||||
test "GET /api/v1/pleroma/backups", %{user: user, conn: conn} do
|
||||
|
|
@ -82,4 +82,24 @@ defmodule Pleroma.Web.PleromaAPI.BackupControllerTest do
|
|||
|> post("/api/v1/pleroma/backups")
|
||||
|> json_response_and_validate_schema(400)
|
||||
end
|
||||
|
||||
test "Backup without email address" do
|
||||
user = Pleroma.Factory.insert(:user, email: nil)
|
||||
%{conn: conn} = oauth_access(["read:backups"], user: user)
|
||||
|
||||
assert is_nil(user.email)
|
||||
|
||||
assert [
|
||||
%{
|
||||
"content_type" => "application/zip",
|
||||
"url" => _url,
|
||||
"file_size" => 0,
|
||||
"processed" => false,
|
||||
"inserted_at" => _
|
||||
}
|
||||
] =
|
||||
conn
|
||||
|> post("/api/v1/pleroma/backups")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,126 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.PleromaAPI.SettingsControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
|
||||
import Pleroma.Factory
|
||||
|
||||
describe "GET /api/v1/pleroma/settings/:app" do
|
||||
setup do
|
||||
oauth_access(["read:accounts"])
|
||||
end
|
||||
|
||||
test "it gets empty settings", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/pleroma/settings/pleroma-fe")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response == %{}
|
||||
end
|
||||
|
||||
test "it gets settings", %{conn: conn, user: user} do
|
||||
response =
|
||||
conn
|
||||
|> assign(
|
||||
:user,
|
||||
struct(user,
|
||||
pleroma_settings_store: %{
|
||||
"pleroma-fe" => %{
|
||||
"foo" => "bar"
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
|> get("/api/v1/pleroma/settings/pleroma-fe")
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert %{"foo" => "bar"} == response
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/v1/pleroma/settings/:app" do
|
||||
setup do
|
||||
settings = %{
|
||||
"foo" => "bar",
|
||||
"nested" => %{
|
||||
"1" => "2"
|
||||
}
|
||||
}
|
||||
|
||||
user =
|
||||
insert(
|
||||
:user,
|
||||
%{
|
||||
pleroma_settings_store: %{
|
||||
"pleroma-fe" => settings
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
%{conn: conn} = oauth_access(["write:accounts"], user: user)
|
||||
|
||||
%{conn: conn, user: user, settings: settings}
|
||||
end
|
||||
|
||||
test "it adds keys", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/settings/pleroma-fe", %{
|
||||
"foo" => "edited",
|
||||
"bar" => "new",
|
||||
"nested" => %{"3" => "4"}
|
||||
})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response == %{
|
||||
"foo" => "edited",
|
||||
"bar" => "new",
|
||||
"nested" => %{
|
||||
"1" => "2",
|
||||
"3" => "4"
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
test "it removes keys", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/settings/pleroma-fe", %{
|
||||
"foo" => nil,
|
||||
"bar" => nil,
|
||||
"nested" => %{
|
||||
"1" => nil,
|
||||
"3" => nil
|
||||
}
|
||||
})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
assert response == %{
|
||||
"nested" => %{}
|
||||
}
|
||||
end
|
||||
|
||||
test "it does not override settings for other apps", %{
|
||||
conn: conn,
|
||||
user: user,
|
||||
settings: settings
|
||||
} do
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> patch("/api/v1/pleroma/settings/admin-fe", %{"foo" => "bar"})
|
||||
|> json_response_and_validate_schema(:ok)
|
||||
|
||||
user = Pleroma.User.get_by_id(user.id)
|
||||
|
||||
assert user.pleroma_settings_store == %{
|
||||
"pleroma-fe" => settings,
|
||||
"admin-fe" => %{"foo" => "bar"}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -86,8 +86,6 @@ defmodule Pleroma.Web.Plugs.FrontendStaticPlugTest do
|
|||
"objects",
|
||||
"activities",
|
||||
"notice",
|
||||
"@:nickname",
|
||||
":nickname",
|
||||
"users",
|
||||
"tags",
|
||||
"mailer",
|
||||
|
|
|
|||
|
|
@ -59,9 +59,9 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
|
|||
|
||||
assert csp =~ ~r|report-uri https://endpoint.com;report-to csp-endpoint;|
|
||||
|
||||
[reply_to] = Conn.get_resp_header(conn, "reply-to")
|
||||
[report_to] = Conn.get_resp_header(conn, "report-to")
|
||||
|
||||
assert reply_to ==
|
||||
assert report_to ==
|
||||
"{\"endpoints\":[{\"url\":\"https://endpoint.com\"}],\"group\":\"csp-endpoint\",\"max-age\":10886400}"
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -48,38 +48,42 @@ defmodule Pleroma.Web.Plugs.RateLimiterTest do
|
|||
refute RateLimiter.disabled?(build_conn())
|
||||
end
|
||||
|
||||
@tag :erratic
|
||||
test "it restricts based on config values" do
|
||||
limiter_name = :test_plug_opts
|
||||
scale = 80
|
||||
limit = 5
|
||||
|
||||
clear_config([Pleroma.Web.Endpoint, :http, :ip], {8, 8, 8, 8})
|
||||
clear_config([Pleroma.Web.Endpoint, :http, :ip], {127, 0, 0, 1})
|
||||
clear_config([:rate_limit, limiter_name], {scale, limit})
|
||||
|
||||
plug_opts = RateLimiter.init(name: limiter_name)
|
||||
conn = build_conn(:get, "/")
|
||||
|
||||
for i <- 1..5 do
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert {^i, _} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
|
||||
Process.sleep(10)
|
||||
for _ <- 1..5 do
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
|
||||
refute conn_limited.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn_limited.resp_body
|
||||
refute conn_limited.halted
|
||||
end
|
||||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn, :too_many_requests)
|
||||
assert conn.halted
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests)
|
||||
assert conn_limited.halted
|
||||
|
||||
Process.sleep(50)
|
||||
expire_ttl(conn, limiter_name)
|
||||
|
||||
conn = build_conn(:get, "/")
|
||||
for _ <- 1..5 do
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
|
||||
conn = RateLimiter.call(conn, plug_opts)
|
||||
assert {1, 4} = RateLimiter.inspect_bucket(conn, limiter_name, plug_opts)
|
||||
refute conn_limited.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn_limited.resp_body
|
||||
refute conn_limited.halted
|
||||
end
|
||||
|
||||
refute conn.status == Conn.Status.code(:too_many_requests)
|
||||
refute conn.resp_body
|
||||
refute conn.halted
|
||||
conn_limited = RateLimiter.call(conn, plug_opts)
|
||||
assert %{"error" => "Throttled"} = ConnTest.json_response(conn_limited, :too_many_requests)
|
||||
assert conn_limited.halted
|
||||
end
|
||||
|
||||
describe "options" do
|
||||
|
|
@ -263,4 +267,12 @@ defmodule Pleroma.Web.Plugs.RateLimiterTest do
|
|||
|
||||
refute {:err, :not_found} == RateLimiter.inspect_bucket(conn, limiter_name, opts)
|
||||
end
|
||||
|
||||
def expire_ttl(%{remote_ip: remote_ip} = _conn, bucket_name_root) do
|
||||
bucket_name = "anon:#{bucket_name_root}" |> String.to_atom()
|
||||
key_name = "ip::#{remote_ip |> Tuple.to_list() |> Enum.join(".")}"
|
||||
|
||||
{:ok, bucket_value} = Cachex.get(bucket_name, key_name)
|
||||
Cachex.put(bucket_name, key_name, bucket_value, ttl: -1)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -202,6 +202,21 @@ defmodule Pleroma.Web.Push.ImplTest do
|
|||
"New Reaction"
|
||||
end
|
||||
|
||||
test "renders title and body for update activity" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "lorem ipsum"})
|
||||
|
||||
{:ok, activity} = CommonAPI.update(user, activity, %{status: "edited status"})
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
assert Impl.format_body(%{activity: activity, type: "update"}, user, object) ==
|
||||
"@#{user.nickname} edited a status"
|
||||
|
||||
assert Impl.format_title(%{activity: activity, type: "update"}) ==
|
||||
"New Update"
|
||||
end
|
||||
|
||||
test "renders title for create activity with direct visibility" do
|
||||
user = insert(:user, nickname: "Bob")
|
||||
|
||||
|
|
|
|||
|
|
@ -442,6 +442,31 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
"state" => "follow_accept"
|
||||
} = Jason.decode!(payload)
|
||||
end
|
||||
|
||||
test "it streams edits in the 'user' stream", %{user: user, token: oauth_token} do
|
||||
sender = insert(:user)
|
||||
{:ok, _, _, _} = CommonAPI.follow(user, sender)
|
||||
|
||||
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
|
||||
|
||||
Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
|
||||
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
|
||||
|
||||
assert_receive {:render_with_user, _, "status_update.json", ^create}
|
||||
refute Streamer.filtered_by_user?(user, edited)
|
||||
end
|
||||
|
||||
test "it streams own edits in the 'user' stream", %{user: user, token: oauth_token} do
|
||||
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
|
||||
|
||||
Streamer.get_topic_and_add_socket("user", user, oauth_token)
|
||||
{:ok, edited} = CommonAPI.update(user, activity, %{status: "mew mew"})
|
||||
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
|
||||
|
||||
assert_receive {:render_with_user, _, "status_update.json", ^create}
|
||||
refute Streamer.filtered_by_user?(user, edited)
|
||||
end
|
||||
end
|
||||
|
||||
describe "public streams" do
|
||||
|
|
@ -484,6 +509,54 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert_receive {:text, event}
|
||||
assert %{"event" => "delete", "payload" => ^activity_id} = Jason.decode!(event)
|
||||
end
|
||||
|
||||
test "it streams edits in the 'public' stream" do
|
||||
sender = insert(:user)
|
||||
|
||||
Streamer.get_topic_and_add_socket("public", nil, nil)
|
||||
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
|
||||
assert_receive {:text, _}
|
||||
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
|
||||
|
||||
edited = Pleroma.Activity.normalize(edited)
|
||||
|
||||
%{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"])
|
||||
|
||||
assert_receive {:text, event}
|
||||
assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event)
|
||||
assert %{"id" => ^activity_id} = Jason.decode!(payload)
|
||||
refute Streamer.filtered_by_user?(sender, edited)
|
||||
end
|
||||
|
||||
test "it streams multiple edits in the 'public' stream correctly" do
|
||||
sender = insert(:user)
|
||||
|
||||
Streamer.get_topic_and_add_socket("public", nil, nil)
|
||||
{:ok, activity} = CommonAPI.post(sender, %{status: "hey"})
|
||||
assert_receive {:text, _}
|
||||
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
|
||||
|
||||
edited = Pleroma.Activity.normalize(edited)
|
||||
|
||||
%{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"])
|
||||
|
||||
assert_receive {:text, event}
|
||||
assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event)
|
||||
assert %{"id" => ^activity_id} = Jason.decode!(payload)
|
||||
refute Streamer.filtered_by_user?(sender, edited)
|
||||
|
||||
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew 2"})
|
||||
|
||||
edited = Pleroma.Activity.normalize(edited)
|
||||
|
||||
%{id: activity_id} = Pleroma.Activity.get_create_by_object_ap_id(edited.object.data["id"])
|
||||
assert_receive {:text, event}
|
||||
assert %{"event" => "status.update", "payload" => payload} = Jason.decode!(event)
|
||||
assert %{"id" => ^activity_id, "content" => "mew mew 2"} = Jason.decode!(payload)
|
||||
refute Streamer.filtered_by_user?(sender, edited)
|
||||
end
|
||||
end
|
||||
|
||||
describe "thread_containment/2" do
|
||||
|
|
@ -814,4 +887,105 @@ defmodule Pleroma.Web.StreamerTest do
|
|||
assert last_status["id"] == to_string(create_activity.id)
|
||||
end
|
||||
end
|
||||
|
||||
describe "stop streaming if token got revoked" do
|
||||
setup do
|
||||
child_proc = fn start, finalize ->
|
||||
fn ->
|
||||
start.()
|
||||
|
||||
receive do
|
||||
{StreamerTest, :ready} ->
|
||||
assert_receive {:render_with_user, _, "update.json", _}
|
||||
|
||||
receive do
|
||||
{StreamerTest, :revoked} -> finalize.()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
starter = fn user, token ->
|
||||
fn -> Streamer.get_topic_and_add_socket("user", user, token) end
|
||||
end
|
||||
|
||||
hit = fn -> assert_receive :close end
|
||||
miss = fn -> refute_receive :close end
|
||||
|
||||
send_all = fn tasks, thing -> Enum.each(tasks, &send(&1.pid, thing)) end
|
||||
|
||||
%{
|
||||
child_proc: child_proc,
|
||||
starter: starter,
|
||||
hit: hit,
|
||||
miss: miss,
|
||||
send_all: send_all
|
||||
}
|
||||
end
|
||||
|
||||
test "do not revoke other tokens", %{
|
||||
child_proc: child_proc,
|
||||
starter: starter,
|
||||
hit: hit,
|
||||
miss: miss,
|
||||
send_all: send_all
|
||||
} do
|
||||
%{user: user, token: token} = oauth_access(["read"])
|
||||
%{token: token2} = oauth_access(["read"], user: user)
|
||||
%{user: user2, token: user2_token} = oauth_access(["read"])
|
||||
|
||||
post_user = insert(:user)
|
||||
CommonAPI.follow(user, post_user)
|
||||
CommonAPI.follow(user2, post_user)
|
||||
|
||||
tasks = [
|
||||
Task.async(child_proc.(starter.(user, token), hit)),
|
||||
Task.async(child_proc.(starter.(user, token2), miss)),
|
||||
Task.async(child_proc.(starter.(user2, user2_token), miss))
|
||||
]
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(post_user, %{
|
||||
status: "hi"
|
||||
})
|
||||
|
||||
send_all.(tasks, {StreamerTest, :ready})
|
||||
|
||||
Pleroma.Web.OAuth.Token.Strategy.Revoke.revoke(token)
|
||||
|
||||
send_all.(tasks, {StreamerTest, :revoked})
|
||||
|
||||
Enum.each(tasks, &Task.await/1)
|
||||
end
|
||||
|
||||
test "revoke all streams for this token", %{
|
||||
child_proc: child_proc,
|
||||
starter: starter,
|
||||
hit: hit,
|
||||
send_all: send_all
|
||||
} do
|
||||
%{user: user, token: token} = oauth_access(["read"])
|
||||
|
||||
post_user = insert(:user)
|
||||
CommonAPI.follow(user, post_user)
|
||||
|
||||
tasks = [
|
||||
Task.async(child_proc.(starter.(user, token), hit)),
|
||||
Task.async(child_proc.(starter.(user, token), hit))
|
||||
]
|
||||
|
||||
{:ok, _} =
|
||||
CommonAPI.post(post_user, %{
|
||||
status: "hi"
|
||||
})
|
||||
|
||||
send_all.(tasks, {StreamerTest, :ready})
|
||||
|
||||
Pleroma.Web.OAuth.Token.Strategy.Revoke.revoke(token)
|
||||
|
||||
send_all.(tasks, {StreamerTest, :revoked})
|
||||
|
||||
Enum.each(tasks, &Task.await/1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
|
||||
use Pleroma.Web.ConnCase
|
||||
use Pleroma.Web.ConnCase, async: true
|
||||
|
||||
alias Pleroma.MFA
|
||||
alias Pleroma.MFA.TOTP
|
||||
|
|
|
|||
|
|
@ -233,6 +233,102 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
describe "POST /main/ostatus - remote_subscribe/2 - with statuses" do
|
||||
setup do: clear_config([:instance, :federating], true)
|
||||
|
||||
test "renders subscribe form", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
status = insert(:note_activity, %{user: user})
|
||||
status_id = status.id
|
||||
|
||||
assert is_binary(status_id)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> post("/main/ostatus", %{"status_id" => status_id, "profile" => ""})
|
||||
|> response(:ok)
|
||||
|
||||
refute response =~ "Could not find status"
|
||||
assert response =~ "Interacting with"
|
||||
end
|
||||
|
||||
test "renders subscribe form with error when status not found", %{conn: conn} do
|
||||
response =
|
||||
conn
|
||||
|> post("/main/ostatus", %{"status_id" => "somerandomid", "profile" => ""})
|
||||
|> response(:ok)
|
||||
|
||||
assert response =~ "Could not find status"
|
||||
refute response =~ "Interacting with"
|
||||
end
|
||||
|
||||
test "it redirect to webfinger url", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
status = insert(:note_activity, %{user: user})
|
||||
status_id = status.id
|
||||
status_ap_id = status.data["object"]
|
||||
|
||||
assert is_binary(status_id)
|
||||
assert is_binary(status_ap_id)
|
||||
|
||||
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> post("/main/ostatus", %{
|
||||
"status" => %{"status_id" => status_id, "profile" => user2.ap_id}
|
||||
})
|
||||
|
||||
assert redirected_to(conn) ==
|
||||
"https://social.heldscal.la/main/ostatussub?profile=#{status_ap_id}"
|
||||
end
|
||||
|
||||
test "it renders form with error when status not found", %{conn: conn} do
|
||||
user2 = insert(:user, ap_id: "shp@social.heldscal.la")
|
||||
|
||||
response =
|
||||
conn
|
||||
|> post("/main/ostatus", %{
|
||||
"status" => %{"status_id" => "somerandomid", "profile" => user2.ap_id}
|
||||
})
|
||||
|> response(:ok)
|
||||
|
||||
assert response =~ "Something went wrong."
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /main/ostatus - show_subscribe_form/2" do
|
||||
setup do: clear_config([:instance, :federating], true)
|
||||
|
||||
test "it works with users", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/main/ostatus", %{"nickname" => user.nickname})
|
||||
|> response(:ok)
|
||||
|
||||
refute response =~ "Could not find user"
|
||||
assert response =~ "Remotely follow #{user.nickname}"
|
||||
end
|
||||
|
||||
test "it works with statuses", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
status = insert(:note_activity, %{user: user})
|
||||
status_id = status.id
|
||||
|
||||
assert is_binary(status_id)
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/main/ostatus", %{"status_id" => status_id})
|
||||
|> response(:ok)
|
||||
|
||||
refute response =~ "Could not find status"
|
||||
assert response =~ "Interacting with"
|
||||
end
|
||||
end
|
||||
|
||||
test "it returns new captcha", %{conn: conn} do
|
||||
with_mock Pleroma.Captcha,
|
||||
new: fn -> "test_captcha" end do
|
||||
|
|
@ -516,4 +612,371 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
assert user.password_hash == nil
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/pleroma/move_account" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
target_user = insert(:user)
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "hi",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: write:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions and invalid password", %{conn: conn} do
|
||||
target_user = insert(:user)
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "hi",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"error" => "Invalid password."}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password and target account does not alias it",
|
||||
%{
|
||||
conn: conn
|
||||
} do
|
||||
target_user = insert(:user)
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"error" => "Target account must have the origin in `alsoKnownAs`"
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password and target account does not exist",
|
||||
%{
|
||||
conn: conn
|
||||
} do
|
||||
target_nick = "not_found@mastodon.social"
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 404) == %{
|
||||
"error" => "Target account not found."
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password, remote target account aliases it and local cache does not exist",
|
||||
%{} do
|
||||
user = insert(:user, ap_id: "https://lm.kazv.moe/users/testuser")
|
||||
%{user: _user, conn: conn} = oauth_access(["write:accounts"], user: user)
|
||||
|
||||
target_nick = "mewmew@lm.kazv.moe"
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password, remote target account aliases it and local cache does not aliases it",
|
||||
%{} do
|
||||
user = insert(:user, ap_id: "https://lm.kazv.moe/users/testuser")
|
||||
%{user: _user, conn: conn} = oauth_access(["write:accounts"], user: user)
|
||||
|
||||
target_user =
|
||||
insert(
|
||||
:user,
|
||||
ap_id: "https://lm.kazv.moe/users/mewmew",
|
||||
nickname: "mewmew@lm.kazv.moe",
|
||||
local: false
|
||||
)
|
||||
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password, remote target account does not aliases it and local cache aliases it",
|
||||
%{
|
||||
user: user,
|
||||
conn: conn
|
||||
} do
|
||||
target_user =
|
||||
insert(
|
||||
:user,
|
||||
ap_id: "https://lm.kazv.moe/users/mewmew",
|
||||
nickname: "mewmew@lm.kazv.moe",
|
||||
local: false,
|
||||
also_known_as: [user.ap_id]
|
||||
)
|
||||
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api/pleroma/move_account", %{
|
||||
"password" => "test",
|
||||
"target_account" => target_nick
|
||||
})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"error" => "Target account must have the origin in `alsoKnownAs`"
|
||||
}
|
||||
end
|
||||
|
||||
test "with proper permissions, valid password and target account aliases it", %{
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
target_user = insert(:user, also_known_as: [user.ap_id])
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
follower = insert(:user)
|
||||
|
||||
User.follow(follower, user)
|
||||
|
||||
assert User.following?(follower, user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post(
|
||||
"/api/pleroma/move_account",
|
||||
%{
|
||||
password: "test",
|
||||
target_account: target_nick
|
||||
}
|
||||
)
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => user.id,
|
||||
"target_id" => target_user.id
|
||||
}
|
||||
|
||||
assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
|
||||
|
||||
Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
|
||||
|
||||
refute User.following?(follower, user)
|
||||
assert User.following?(follower, target_user)
|
||||
end
|
||||
|
||||
test "prefix nickname by @ should work", %{
|
||||
conn: conn,
|
||||
user: user
|
||||
} do
|
||||
target_user = insert(:user, also_known_as: [user.ap_id])
|
||||
target_nick = target_user |> User.full_nickname()
|
||||
follower = insert(:user)
|
||||
|
||||
User.follow(follower, user)
|
||||
|
||||
assert User.following?(follower, user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post(
|
||||
"/api/pleroma/move_account",
|
||||
%{
|
||||
password: "test",
|
||||
target_account: "@" <> target_nick
|
||||
}
|
||||
)
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{"status" => "success"}
|
||||
|
||||
params = %{
|
||||
"op" => "move_following",
|
||||
"origin_id" => user.id,
|
||||
"target_id" => target_user.id
|
||||
}
|
||||
|
||||
assert_enqueued(worker: Pleroma.Workers.BackgroundWorker, args: params)
|
||||
|
||||
Pleroma.Workers.BackgroundWorker.perform(%Oban.Job{args: params})
|
||||
|
||||
refute User.following?(follower, user)
|
||||
assert User.following?(follower, target_user)
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/pleroma/aliases" do
|
||||
setup do: oauth_access(["read:accounts"])
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> get("/api/pleroma/aliases")
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: read:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with permissions", %{
|
||||
conn: conn
|
||||
} do
|
||||
assert %{"aliases" => []} =
|
||||
conn
|
||||
|> get("/api/pleroma/aliases")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
|
||||
test "with permissions and aliases", %{} do
|
||||
user = insert(:user)
|
||||
user2 = insert(:user)
|
||||
|
||||
assert {:ok, user} = user |> User.add_alias(user2)
|
||||
|
||||
%{user: _user, conn: conn} = oauth_access(["read:accounts"], user: user)
|
||||
|
||||
assert %{"aliases" => aliases} =
|
||||
conn
|
||||
|> get("/api/pleroma/aliases")
|
||||
|> json_response_and_validate_schema(200)
|
||||
|
||||
assert aliases == [user2 |> User.full_nickname()]
|
||||
end
|
||||
end
|
||||
|
||||
describe "PUT /api/pleroma/aliases" do
|
||||
setup do: oauth_access(["write:accounts"])
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/pleroma/aliases", %{alias: "none"})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: write:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with permissions, no alias param", %{
|
||||
conn: conn
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/pleroma/aliases", %{})
|
||||
|
||||
assert %{"error" => "Missing field: alias."} = json_response_and_validate_schema(conn, 400)
|
||||
end
|
||||
|
||||
test "with permissions, with alias param", %{
|
||||
conn: conn
|
||||
} do
|
||||
user2 = insert(:user)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/pleroma/aliases", %{alias: user2 |> User.full_nickname()})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 200) == %{
|
||||
"status" => "success"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe "DELETE /api/pleroma/aliases" do
|
||||
setup do
|
||||
alias_user = insert(:user)
|
||||
non_alias_user = insert(:user)
|
||||
user = insert(:user, also_known_as: [alias_user.ap_id])
|
||||
|
||||
oauth_access(["write:accounts"], user: user)
|
||||
|> Map.put(:alias_user, alias_user)
|
||||
|> Map.put(:non_alias_user, non_alias_user)
|
||||
end
|
||||
|
||||
test "without permissions", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> assign(:token, nil)
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{alias: "none"})
|
||||
|
||||
assert json_response_and_validate_schema(conn, 403) == %{
|
||||
"error" => "Insufficient permissions: write:accounts."
|
||||
}
|
||||
end
|
||||
|
||||
test "with permissions, no alias param", %{conn: conn} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{})
|
||||
|
||||
assert %{"error" => "Missing field: alias."} = json_response_and_validate_schema(conn, 400)
|
||||
end
|
||||
|
||||
test "with permissions, account does not have such alias", %{
|
||||
conn: conn,
|
||||
non_alias_user: non_alias_user
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{alias: non_alias_user |> User.full_nickname()})
|
||||
|
||||
assert %{"error" => "Account has no such alias."} =
|
||||
json_response_and_validate_schema(conn, 404)
|
||||
end
|
||||
|
||||
test "with permissions, account does have such alias", %{
|
||||
conn: conn,
|
||||
alias_user: alias_user
|
||||
} do
|
||||
conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> delete("/api/pleroma/aliases", %{alias: alias_user |> User.full_nickname()})
|
||||
|
||||
assert %{"status" => "success"} = json_response_and_validate_schema(conn, 200)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,6 +48,35 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do
|
|||
]
|
||||
end
|
||||
|
||||
test "reach user on tld, while pleroma is runned on subdomain" do
|
||||
Pleroma.Web.Endpoint.config_change(
|
||||
[{Pleroma.Web.Endpoint, url: [host: "sub.example.com"]}],
|
||||
[]
|
||||
)
|
||||
|
||||
clear_config([Pleroma.Web.Endpoint, :url, :host], "sub.example.com")
|
||||
|
||||
clear_config([Pleroma.Web.WebFinger, :domain], "example.com")
|
||||
|
||||
user = insert(:user, ap_id: "https://sub.example.com/users/bobby", nickname: "bobby")
|
||||
|
||||
response =
|
||||
build_conn()
|
||||
|> put_req_header("accept", "application/jrd+json")
|
||||
|> get("/.well-known/webfinger?resource=acct:#{user.nickname}@example.com")
|
||||
|> json_response(200)
|
||||
|
||||
assert response["subject"] == "acct:#{user.nickname}@example.com"
|
||||
assert response["aliases"] == ["https://sub.example.com/users/#{user.nickname}"]
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Web.Endpoint.config_change(
|
||||
[{Pleroma.Web.Endpoint, url: [host: "localhost"]}],
|
||||
[]
|
||||
)
|
||||
end)
|
||||
end
|
||||
|
||||
test "it returns 404 when user isn't found (JSON)" do
|
||||
result =
|
||||
build_conn()
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue