forked from YokaiRick/akkoma
Mastodon API Poll view: Fix handling of polls without an end date
This commit is contained in:
parent
3e30f6e198
commit
b312ca3d52
6 changed files with 44 additions and 10 deletions
|
@ -32,6 +32,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- `federation_incoming_replies_max_depth` option being ignored in certain cases
|
- `federation_incoming_replies_max_depth` option being ignored in certain cases
|
||||||
- Federation/MediaProxy not working with instances that have wrong certificate order
|
- Federation/MediaProxy not working with instances that have wrong certificate order
|
||||||
- Mastodon API: Handling of search timeouts (`/api/v1/search` and `/api/v2/search`)
|
- Mastodon API: Handling of search timeouts (`/api/v1/search` and `/api/v2/search`)
|
||||||
|
- Mastodon API: Misskey's endless polls being unable to render
|
||||||
- Mastodon API: Embedded relationships not being properly rendered in the Account entity of Status entity
|
- Mastodon API: Embedded relationships not being properly rendered in the Account entity of Status entity
|
||||||
- Mastodon API: Notifications endpoint crashing if one notification failed to render
|
- Mastodon API: Notifications endpoint crashing if one notification failed to render
|
||||||
- Mastodon API: follower/following counters not being nullified, when `hide_follows`/`hide_followers` is set
|
- Mastodon API: follower/following counters not being nullified, when `hide_follows`/`hide_followers` is set
|
||||||
|
|
|
@ -385,16 +385,27 @@ def render("poll.json", %{object: object} = opts) do
|
||||||
end
|
end
|
||||||
|
|
||||||
if options do
|
if options do
|
||||||
end_time =
|
{end_time, expired} =
|
||||||
(object.data["closed"] || object.data["endTime"])
|
case object.data["closed"] || object.data["endTime"] do
|
||||||
|> NaiveDateTime.from_iso8601!()
|
end_time when is_binary(end_time) ->
|
||||||
|
end_time =
|
||||||
|
(object.data["closed"] || object.data["endTime"])
|
||||||
|
|> NaiveDateTime.from_iso8601!()
|
||||||
|
|
||||||
expired =
|
expired =
|
||||||
end_time
|
end_time
|
||||||
|> NaiveDateTime.compare(NaiveDateTime.utc_now())
|
|> NaiveDateTime.compare(NaiveDateTime.utc_now())
|
||||||
|> case do
|
|> case do
|
||||||
:lt -> true
|
:lt -> true
|
||||||
_ -> false
|
_ -> false
|
||||||
|
end
|
||||||
|
|
||||||
|
end_time = Utils.to_masto_date(end_time)
|
||||||
|
|
||||||
|
{end_time, expired}
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
{nil, false}
|
||||||
end
|
end
|
||||||
|
|
||||||
voted =
|
voted =
|
||||||
|
@ -421,7 +432,7 @@ def render("poll.json", %{object: object} = opts) do
|
||||||
# Mastodon uses separate ids for polls, but an object can't have
|
# Mastodon uses separate ids for polls, but an object can't have
|
||||||
# more than one poll embedded so object id is fine
|
# more than one poll embedded so object id is fine
|
||||||
id: to_string(object.id),
|
id: to_string(object.id),
|
||||||
expires_at: Utils.to_masto_date(end_time),
|
expires_at: end_time,
|
||||||
expired: expired,
|
expired: expired,
|
||||||
multiple: multiple,
|
multiple: multiple,
|
||||||
votes_count: votes_count,
|
votes_count: votes_count,
|
||||||
|
|
1
test/fixtures/tesla_mock/misskey_poll_no_end_date.json
vendored
Normal file
1
test/fixtures/tesla_mock/misskey_poll_no_end_date.json
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"Hashtag":"as:Hashtag"}],"id":"https://skippers-bin.com/notes/7x9tmrp97i","type":"Question","attributedTo":"https://skippers-bin.com/users/7v1w1r8ce6","summary":null,"content":"<p><a href=\"https://marchgenso.me/users/march\" class=\"mention\">@march@marchgenso.me</a><span> How are your notifications now?<br></span><a href=\"https://skippers-bin.com/notes/7x9tmrp97i\"><span>リモートで結果を表示</span></a></p>","_misskey_content":"@march@marchgenso.me How are your notifications now?\n[リモートで結果を表示](https://skippers-bin.com/notes/7x9tmrp97i)","published":"2019-09-05T05:35:32.541Z","to":["https://www.w3.org/ns/activitystreams#Public"],"cc":["https://skippers-bin.com/users/7v1w1r8ce6/followers","https://marchgenso.me/users/march"],"inReplyTo":null,"attachment":[],"sensitive":false,"tag":[{"type":"Mention","href":"https://marchgenso.me/users/march","name":"@march@marchgenso.me"}],"_misskey_fallback_content":"<p><a href=\"https://marchgenso.me/users/march\" class=\"mention\">@march@marchgenso.me</a><span> How are your notifications now?<br></span><a href=\"https://skippers-bin.com/notes/7x9tmrp97i\"><span>リモートで結果を表示</span></a><span><br>----------------------------------------<br>0: Working<br>1: Broken af<br>----------------------------------------<br>番号を返信して投票</span></p>","endTime":null,"oneOf":[{"type":"Note","name":"Working","replies":{"type":"Collection","totalItems":0}},{"type":"Note","name":"Broken af","replies":{"type":"Collection","totalItems":1}}]}
|
1
test/fixtures/tesla_mock/sjw.json
vendored
Normal file
1
test/fixtures/tesla_mock/sjw.json
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"Hashtag":"as:Hashtag"}],"type":"Person","id":"https://skippers-bin.com/users/7v1w1r8ce6","inbox":"https://skippers-bin.com/users/7v1w1r8ce6/inbox","outbox":"https://skippers-bin.com/users/7v1w1r8ce6/outbox","followers":"https://skippers-bin.com/users/7v1w1r8ce6/followers","following":"https://skippers-bin.com/users/7v1w1r8ce6/following","featured":"https://skippers-bin.com/users/7v1w1r8ce6/collections/featured","sharedInbox":"https://skippers-bin.com/inbox","endpoints":{"sharedInbox":"https://skippers-bin.com/inbox"},"url":"https://skippers-bin.com/@sjw","preferredUsername":"sjw","name":"It's ya boi sjw :verified:","summary":"<p><span>Admin of skippers-bin.com and neckbeard.xyz<br>For the most part I'm just a normal user. I mostly post animu, lewds, may-mays, and shitposts.<br><br>Not an alt of </span><a href=\"https://skippers-bin.com/@sjw@neckbeard.xyz\" class=\"mention\">@sjw@neckbeard.xyz</a><span> but another main.<br><br>Email/XMPP: neckbeard@rape.lol<br>PGP: d016 b622 75ba bcbc 5b3a fced a7d9 4824 0eb3 9c4e</span></p>","icon":{"type":"Image","url":"https://skippers-bin.com/files/webpublic-21b17f5b-3a83-4f50-8d4f-eda92066aa26","sensitive":false},"image":{"type":"Image","url":"https://skippers-bin.com/files/webpublic-1cd7f961-421e-4c31-aa03-74fb82584308","sensitive":false},"tag":[{"id":"https://skippers-bin.com/emojis/verified","type":"Emoji","name":":verified:","updated":"2019-07-12T02:16:12.088Z","icon":{"type":"Image","mediaType":"image/png","url":"https://skippers-bin.com/files/webpublic-dd10b435-6dad-4602-938b-f69ec0a19f2c"}}],"manuallyApprovesFollowers":false,"publicKey":{"id":"https://skippers-bin.com/users/7v1w1r8ce6/publickey","type":"Key","owner":"https://skippers-bin.com/users/7v1w1r8ce6","publicKeyPem":"-----BEGIN RSA PUBLIC KEY-----\nMIICCgKCAgEAvmp71/A6Oxe1UW/44HK0juAJhrjv9gYhaoslaS9K1FB+BHfIjaE9\n9+W2SKRLnVNYNFSN4JJrSGhX5RUjAsf4tcdRDVcmHl7tp2sgOAZeZz5geULm2sJQ\nwElnGk34jT/xCfX+w/O+7DuX31sU7ZK0B2P7ulNGDQXhrzVO0RMx7HhNcsFcusno\n3kmPyyPT1l+PbM2UNWms599/3yicKtuOzMgzxNeXvuHYtAO19txyPiOeYckQOMmT\nwEVIxypgCgNQ0MNtPLPKQTwOgVbvnN7MN+h3esKeKDcPcGQySkbkjZPaVnA6xCQf\nj58c19wqdCfAS4Effo5/bxVmhLpe0l9HYpV7IMasv2LhFntmSmAxBQzhdz0oTYb1\naNqiyfZdClnzutOiKcrFppADo4rZH9Z1WlPHapahrKbF0GRPN8DjSUsoBxfY9wZs\ntlL056hT4o+EFHYrRGo7KP6X/6aQ9sSsmpE08aVpVuXdwuaoaDlW1KrJ0oOk4lZw\nUNXvjEaN3c+VQAw2CNvkAqLuwrjnw7MdcxEGodEXb6s8VvoSOaiDqT7cexSaZe0R\nliCe/3dqFXpX1UrgRiryI4yc1BrEJIGTanchmP2aUJ2R2pccFsREp23C3vMN3M5b\nHw7fvKbUQHyf6lhRoLCOSCz1xaPutaMJmpwLuJo4wPCHGg9QFBYsqxcCAwEAAQ==\n-----END RSA PUBLIC KEY-----\n"},"isCat":true}
|
|
@ -992,6 +992,18 @@ def get("http://example.com/rel_me/null", _, _, _) do
|
||||||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")}}
|
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")}}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def get("https://skippers-bin.com/notes/7x9tmrp97i", _, _, _) do
|
||||||
|
{:ok,
|
||||||
|
%Tesla.Env{
|
||||||
|
status: 200,
|
||||||
|
body: File.read!("test/fixtures/tesla_mock/misskey_poll_no_end_date.json")
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get("https://skippers-bin.com/users/7v1w1r8ce6", _, _, _) do
|
||||||
|
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/sjw.json")}}
|
||||||
|
end
|
||||||
|
|
||||||
def get(url, query, body, headers) do
|
def get(url, query, body, headers) do
|
||||||
{:error,
|
{:error,
|
||||||
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
|
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{
|
||||||
|
|
|
@ -551,6 +551,14 @@ test "detects vote status" do
|
||||||
assert Enum.at(result[:options], 1)[:votes_count] == 1
|
assert Enum.at(result[:options], 1)[:votes_count] == 1
|
||||||
assert Enum.at(result[:options], 2)[:votes_count] == 1
|
assert Enum.at(result[:options], 2)[:votes_count] == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "does not crash on polls with no end date" do
|
||||||
|
object = Object.normalize("https://skippers-bin.com/notes/7x9tmrp97i")
|
||||||
|
result = StatusView.render("poll.json", %{object: object})
|
||||||
|
|
||||||
|
assert result[:expires_at] == nil
|
||||||
|
assert result[:expired] == false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "embeds a relationship in the account" do
|
test "embeds a relationship in the account" do
|
||||||
|
|
Loading…
Reference in a new issue