Merge pull request 'Detect whether polls are promised to be anonymous or publicising voter identity with their cast vote' (#1104) from Oneric/akkoma:poll-anon into develop
Reviewed-on: #1104
This commit is contained in:
commit
601c5b107d
15 changed files with 636 additions and 6 deletions
|
|
@ -12,6 +12,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Mastodon-compatible `avatar_description` and `header_description` parameters are added to account API responses and as input for `PATCH /api/v1/accounts/update_credentials`
|
||||
- `pleroma.background_image_descripption` is added to account API responses
|
||||
- `pleroma_background_image_descripption` is added as a new parameter to `PATCH /api/v1/accounts/update_credentials`
|
||||
- `GET /api/v1/statuses/:id` contains the new `poll.akkoma.anonymous` parameter if `poll` is non-null.
|
||||
It relays if and whether the source instance promised to keep votes anonymous or disclose votes with voter identity.
|
||||
There are no plans to enable creating non-anonymous polls in Akkoma, but some implementations do.
|
||||
|
||||
### Fixed
|
||||
- fix date-time format in `* /api/v1/markers` to strictly conform to Mastodon’s ISO 8061 subset
|
||||
|
|
|
|||
|
|
@ -49,6 +49,15 @@ Has these additional fields under the `pleroma` object:
|
|||
- `parent_visible`: If the parent of this post is visible to the user or not.
|
||||
- `pinned_at`: a datetime (iso8601) when status was pinned, `null` otherwise.
|
||||
|
||||
Furthermore, has the following additional attributes under the `poll.akkoma` object *(if `poll` is non-null)*:
|
||||
- `anonymous`: relays whether the poll creator promised to process votes anonymously *(`true`)*,
|
||||
publishes votes with voter identity to some parties or the public *(`false`)*
|
||||
or did not indicate how votes are processed (`null`).
|
||||
Note this assumes any remote’s claim about its process are true and
|
||||
even if this is truthfully set to `true`, while no regular users ought to have access to voter identities,
|
||||
the server operator of the poll’s home instance may in principle still be able to
|
||||
extract voter identites via the database or side channels.
|
||||
|
||||
The `GET /api/v1/statuses/:id/source` endpoint additionally has the following attributes:
|
||||
|
||||
- `content_type`: The content type of the status source.
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionValidator do
|
|||
|
||||
field(:closed, ObjectValidators.DateTime)
|
||||
field(:voters, {:array, ObjectValidators.ObjectID}, default: [])
|
||||
field(:nonAnonymous, :boolean)
|
||||
embeds_many(:anyOf, QuestionOptionsValidator)
|
||||
embeds_many(:oneOf, QuestionOptionsValidator)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -105,7 +105,9 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
|||
"https://purl.archive.org/socialweb/webfinger",
|
||||
%{
|
||||
"@language" => "und",
|
||||
"htmlMfm" => "https://w3id.org/fep/c16b#htmlMfm"
|
||||
"htmlMfm" => "https://w3id.org/fep/c16b#htmlMfm",
|
||||
"sm" => "http://smithereen.software/ns#",
|
||||
"nonAnonymous" => "sm:nonAnonymous"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,17 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Poll do
|
|||
}
|
||||
},
|
||||
description: "Possible answers for the poll."
|
||||
},
|
||||
akkoma: %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
anonymous: %Schema{
|
||||
type: :boolean,
|
||||
nullable: true,
|
||||
description:
|
||||
"Whether the poll creator indicates votes are processed anonymously (true), votes with voter identity will be published to some parties or the public (false) or did not indicate anything about vote confidentiality (null)"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
example: %{
|
||||
|
|
@ -81,7 +92,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Poll do
|
|||
votes_count: 4
|
||||
}
|
||||
],
|
||||
emojis: []
|
||||
emojis: [],
|
||||
akkoma: %{
|
||||
anonymous: true
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
|
|
|||
|
|
@ -152,7 +152,13 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
|||
|> DateTime.to_iso8601()
|
||||
|
||||
key = if Params.truthy_param?(data.poll[:multiple]), do: "anyOf", else: "oneOf"
|
||||
poll = %{"type" => "Question", key => option_notes, "closed" => end_time}
|
||||
|
||||
poll = %{
|
||||
"type" => "Question",
|
||||
key => option_notes,
|
||||
"closed" => end_time,
|
||||
"nonAnonymous" => false
|
||||
}
|
||||
|
||||
{:ok, {poll, emoji}}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@ defmodule Pleroma.Web.MastodonAPI.PollView do
|
|||
{end_time, expired} = end_time_and_expired(object)
|
||||
{options, votes_count} = options_and_votes_count(options)
|
||||
|
||||
anonymous =
|
||||
case object.data["nonAnonymous"] do
|
||||
nil -> nil
|
||||
val -> !val
|
||||
end
|
||||
|
||||
poll = %{
|
||||
# Mastodon uses separate ids for polls, but an object can't have
|
||||
# more than one poll embedded so object id is fine
|
||||
|
|
@ -21,7 +27,10 @@ defmodule Pleroma.Web.MastodonAPI.PollView do
|
|||
votes_count: votes_count,
|
||||
voters_count: voters_count(multiple, object),
|
||||
options: options,
|
||||
emojis: Pleroma.Web.MastodonAPI.StatusView.build_emojis(object.data["emoji"])
|
||||
emojis: Pleroma.Web.MastodonAPI.StatusView.build_emojis(object.data["emoji"]),
|
||||
akkoma: %{
|
||||
anonymous: anonymous
|
||||
}
|
||||
}
|
||||
|
||||
if params[:for] do
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
defmodule Pleroma.Repo.Migrations.MarkOldPollsAsAnonymous do
|
||||
use Ecto.Migration
|
||||
|
||||
def up() do
|
||||
# objects does not have a local flag.
|
||||
# Pleroma.Web.Endpoint available during migrations, meaning we can't reliably
|
||||
# get the local base url to test against instead.
|
||||
# Thus we mustjoin either with the users or activity table to determine localality.
|
||||
# The existing objects_actor_type' index is a perfect fit for this query and joining with users.
|
||||
"""
|
||||
UPDATE objects AS o
|
||||
SET data = jsonb_set(data, '{nonAnonymous}', to_jsonb(false), true)
|
||||
FROM users AS u
|
||||
WHERE
|
||||
o.data->>'type' = 'Question' AND
|
||||
o.data->>'actor' = u.ap_id AND
|
||||
u.local
|
||||
;
|
||||
"""
|
||||
|> Pleroma.Repo.query!([], timeout: :infinity)
|
||||
end
|
||||
|
||||
# No need to revert
|
||||
def down(), do: :ok
|
||||
end
|
||||
112
test/fixtures/smithereen/poll_anonymous.json
vendored
Normal file
112
test/fixtures/smithereen/poll_anonymous.json
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"type": "Question",
|
||||
"id": "https://smithereen.example/posts/poll-anon",
|
||||
"attributedTo": "https://smithereen.example/users/1",
|
||||
"content": "<p>Example poll for which the identity and choices of voters will be kept secret</p>",
|
||||
"name": "Какую русскую раскладку клавиатуры вы используете на macOS?",
|
||||
"published": "2024-04-19T13:34:51Z",
|
||||
"tag": [],
|
||||
"url": "https://smithereen.example/posts/poll-anon",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
"https://smithereen.example/users/1/followers"
|
||||
],
|
||||
"cc": [],
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/posts/poll-anon/replies",
|
||||
"first": {
|
||||
"type": "CollectionPage",
|
||||
"items": [],
|
||||
"partOf": "https://smithereen.example/posts/poll-anon/replies",
|
||||
"next": "https://smithereen.example/posts/poll-anon/replies?page=1"
|
||||
}
|
||||
},
|
||||
"sensitive": false,
|
||||
"likes": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/posts/poll-anon/likes",
|
||||
"first": {
|
||||
"type": "CollectionPage",
|
||||
"items": [],
|
||||
"partOf": "https://smithereen.example/posts/poll-anon/likes",
|
||||
"next": "https://smithereen.example/posts/poll-anon/likes?page=1"
|
||||
}
|
||||
},
|
||||
"interactionPolicy": {
|
||||
"canQuote": {
|
||||
"automaticApproval": "https://www.w3.org/ns/activitystreams#Public"
|
||||
}
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-anon#options/8352",
|
||||
"name": "Просто \"русская\"",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8352/votes",
|
||||
"totalItems": 11,
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-anon#options/8353",
|
||||
"name": "Русская — ПК",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8353/votes",
|
||||
"totalItems": 6,
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-anon#options/8354",
|
||||
"name": "Другая",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8354/votes",
|
||||
"totalItems": 1,
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-anon#options/8355",
|
||||
"name": "Не пользуюсь macOS и/или русским языком",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8355/votes",
|
||||
"totalItems": 17,
|
||||
"items": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"votersCount": 35,
|
||||
"nonAnonymous": false,
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"sensitive": "as:sensitive",
|
||||
"gts": "https://gotosocial.org/ns#",
|
||||
"interactionPolicy": {
|
||||
"@id": "gts:interactionPolicy",
|
||||
"@type": "@id"
|
||||
},
|
||||
"canQuote": {
|
||||
"@id": "gts:canQuote",
|
||||
"@type": "@id"
|
||||
},
|
||||
"automaticApproval": {
|
||||
"@id": "gts:automaticApproval",
|
||||
"@type": "@id"
|
||||
},
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"sm": "http://smithereen.software/ns#",
|
||||
"votersCount": "toot:votersCount",
|
||||
"nonAnonymous": "sm:nonAnonymous"
|
||||
}
|
||||
]
|
||||
}
|
||||
112
test/fixtures/smithereen/poll_nonanonymous.json
vendored
Normal file
112
test/fixtures/smithereen/poll_nonanonymous.json
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
{
|
||||
"type": "Question",
|
||||
"id": "https://smithereen.example/posts/poll-disclosed",
|
||||
"attributedTo": "https://smithereen.example/users/1",
|
||||
"content": "<p>Example poll for which all votes will be published with voter identity</p>",
|
||||
"name": "Какую русскую раскладку клавиатуры вы используете на macOS?",
|
||||
"published": "2024-04-19T13:34:51Z",
|
||||
"tag": [],
|
||||
"url": "https://smithereen.example/posts/poll-disclosed",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public",
|
||||
"https://smithereen.example/users/1/followers"
|
||||
],
|
||||
"cc": [],
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/posts/poll-disclosed/replies",
|
||||
"first": {
|
||||
"type": "CollectionPage",
|
||||
"items": [],
|
||||
"partOf": "https://smithereen.example/posts/poll-disclosed/replies",
|
||||
"next": "https://smithereen.example/posts/poll-disclosed/replies?page=1"
|
||||
}
|
||||
},
|
||||
"sensitive": false,
|
||||
"likes": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/posts/poll-disclosed/likes",
|
||||
"first": {
|
||||
"type": "CollectionPage",
|
||||
"items": [],
|
||||
"partOf": "https://smithereen.example/posts/poll-disclosed/likes",
|
||||
"next": "https://smithereen.example/posts/poll-disclosed/likes?page=1"
|
||||
}
|
||||
},
|
||||
"interactionPolicy": {
|
||||
"canQuote": {
|
||||
"automaticApproval": "https://www.w3.org/ns/activitystreams#Public"
|
||||
}
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-disclosed#options/8352",
|
||||
"name": "Просто \"русская\"",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8352/votes",
|
||||
"totalItems": 11,
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-disclosed#options/8353",
|
||||
"name": "Русская — ПК",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8353/votes",
|
||||
"totalItems": 6,
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-disclosed#options/8354",
|
||||
"name": "Другая",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8354/votes",
|
||||
"totalItems": 1,
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"id": "https://smithereen.example/posts/poll-disclosed#options/8355",
|
||||
"name": "Не пользуюсь macOS и/или русским языком",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"id": "https://smithereen.example/activitypub/objects/polls/2231/options/8355/votes",
|
||||
"totalItems": 17,
|
||||
"items": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"votersCount": 35,
|
||||
"nonAnonymous": true,
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"sensitive": "as:sensitive",
|
||||
"gts": "https://gotosocial.org/ns#",
|
||||
"interactionPolicy": {
|
||||
"@id": "gts:interactionPolicy",
|
||||
"@type": "@id"
|
||||
},
|
||||
"canQuote": {
|
||||
"@id": "gts:canQuote",
|
||||
"@type": "@id"
|
||||
},
|
||||
"automaticApproval": {
|
||||
"@id": "gts:automaticApproval",
|
||||
"@type": "@id"
|
||||
},
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"sm": "http://smithereen.software/ns#",
|
||||
"votersCount": "toot:votersCount",
|
||||
"nonAnonymous": "sm:nonAnonymous"
|
||||
}
|
||||
]
|
||||
}
|
||||
250
test/fixtures/smithereen/user.json
vendored
Normal file
250
test/fixtures/smithereen/user.json
vendored
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
{
|
||||
"type": "Person",
|
||||
"id": "https://smithereen.example/users/1",
|
||||
"attachment": [
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Website",
|
||||
"value": "<a href=\"https://grishka.me\" rel=\"me\">https://grishka.me</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Matrix",
|
||||
"value": "<a href=\"https://matrix.to/#/@grishk:matrix.org\" rel=\"me\">@grishk:matrix.org</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Telegram",
|
||||
"value": "<a href=\"https://t.me/grishka\" rel=\"me\">grishka</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Twitter",
|
||||
"value": "<a href=\"https://twitter.com/grishka11\" rel=\"me\">grishka11</a>"
|
||||
},
|
||||
{
|
||||
"type": "PropertyValue",
|
||||
"name": "Git",
|
||||
"value": "<a href=\"https://github.com/grishka\" rel=\"me\">https://github.com/grishka</a>"
|
||||
}
|
||||
],
|
||||
"name": "Григорий Клюшников",
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"width": 573,
|
||||
"height": 572,
|
||||
"cropRegion": [
|
||||
0.26422762870788574,
|
||||
0.3766937553882599,
|
||||
0.7113820910453796,
|
||||
0.9728997349739075
|
||||
],
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"url": "https://smithereen.example/i/-QttwTPRJpjwkRrB1MuI1zS--NGKf8r-K18LZAkqQ6g/q:93/bG9jYWw6Ly8vcy91cGxvYWRzLzAxLzAwLzAwLzloTWJvTzgyQzZnSV9GeHZVVVFUdUgzT19mNC0wVUczRmFfTS53ZWJw.jpg",
|
||||
"mediaType": "image/jpeg",
|
||||
"width": 1280,
|
||||
"height": 960
|
||||
},
|
||||
"url": "https://smithereen.example/i/EWM-QfEuhSLizijJLta-0NWvN0KT2YJNfclg-Uvkxag/c:573:572:nowe:338:362/q:93/bG9jYWw6Ly8vcy91cGxvYWRzLzAxLzAwLzAwLzloTWJvTzgyQzZnSV9GeHZVVVFUdUgzT19mNC0wVUczRmFfTS53ZWJw.jpg",
|
||||
"mediaType": "image/jpeg"
|
||||
},
|
||||
"summary": "<p>I mostly post in Russian here. My English-language account is <a href=\"https://mastodon.social/@grishka\">@grishka@mastodon.social</a>.</p>",
|
||||
"url": "https://smithereen.example/grishka",
|
||||
"preferredUsername": "grishka",
|
||||
"inbox": "https://smithereen.example/users/1/inbox",
|
||||
"outbox": "https://smithereen.example/users/1/outbox",
|
||||
"followers": "https://smithereen.example/users/1/followers",
|
||||
"following": "https://smithereen.example/users/1/following",
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://smithereen.example/activitypub/sharedInbox",
|
||||
"collectionSimpleQuery": "https://smithereen.example/users/1/collectionQuery"
|
||||
},
|
||||
"publicKey": {
|
||||
"id": "https://smithereen.example/users/1#main-key",
|
||||
"owner": "https://smithereen.example/users/1",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjlakm+i/d9ER/hIeR7Kf\niFW+SdLZj2SkKIeM8cmR+YFJuh9ghFqXrkFEjcaqUnAFqe5gYDNSQACnDLA8y4Dn\nzjfGNIohKAnRoa9x6GORmfKQvcnjaTZ53S1NvUiPPyc0Pv/vfCtY/Ab0CEXe5BLq\nL38oZn817Jf7pBrPRTYH7m012kvwAUTT6k0Y8lPITBEG7nzYbbuGcrN9Y/RDdwE0\n8jmBXlZ45bahRH3VNXVpQE17dCzJB+7k+iJ1R7YCoI+DuMlBYGXGE2KVk46NZTuL\nnOjFV9SyXfWX4/SrJM4oxev+SX2N75tQgmNZmVVHeqg2ZcbC0WCfNjJOi2HHS9Mu\njwIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"wall": "https://smithereen.example/users/1/wall",
|
||||
"wallComments": "https://smithereen.example/users/1/wallComments",
|
||||
"discoverable": true,
|
||||
"indexable": true,
|
||||
"status": {
|
||||
"type": "ActorStatus",
|
||||
"id": "https://smithereen.example/users/1/statuses/1747352717",
|
||||
"attributedTo": "https://smithereen.example/users/1",
|
||||
"content": "Гришка, верни стену!!!1",
|
||||
"published": "2025-05-15T23:45:17.460Z"
|
||||
},
|
||||
"firstName": "Григорий",
|
||||
"lastName": "Клюшников",
|
||||
"middleName": "Александрович",
|
||||
"vcard:bday": "1993-01-22",
|
||||
"gender": "http://schema.org#Male",
|
||||
"supportsFriendRequests": true,
|
||||
"friends": "https://smithereen.example/users/1/friends",
|
||||
"groups": "https://smithereen.example/users/1/groups",
|
||||
"capabilities": {
|
||||
"supportsFriendRequests": true
|
||||
},
|
||||
"privacySettings": {
|
||||
"wallPosting": {
|
||||
"allowedTo": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
},
|
||||
"wallPostVisibility": {
|
||||
"allowedTo": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
},
|
||||
"commenting": {
|
||||
"allowedTo": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
},
|
||||
"groupInvitations": {
|
||||
"allowedTo": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
},
|
||||
"directMessages": {
|
||||
"allowedTo": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
},
|
||||
"photoTagging": {
|
||||
"allowedTo": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
},
|
||||
"photoTagList": {
|
||||
"allowedTo": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
]
|
||||
}
|
||||
},
|
||||
"activities": "Разрабатываю для федивёрса, приближаю уход централизованных соцсетей в небытие, возвращаю 2007й, бесконечно ругаюсь на ИТ-индустрию",
|
||||
"interests": "Децентрализация, социальные сети, программирование, user experience, исследования о продлении жизни и лечении старения",
|
||||
"favoriteTvShows": "Black Mirror, Stargate, Upload",
|
||||
"favoriteQuotes": "\"Когда доделаем и оттестируем\"\n\"Всё невозможное возможно, знаю точно\"",
|
||||
"politicalViews": "sm:Libertarian",
|
||||
"personalPriority": "sm:ImprovingTheWorld",
|
||||
"smokingViews": "sm:Negative",
|
||||
"alcoholViews": "sm:Negative",
|
||||
"vcard:Address": "St Petersburg",
|
||||
"relationshipStatus": "sm:Complicated",
|
||||
"photoAlbums": "https://smithereen.example/users/1/albums",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"taggedPhotos": "https://smithereen.example/users/1/tagged",
|
||||
"suspended": false,
|
||||
"featured": "https://smithereen.example/users/1/pinnedPosts",
|
||||
"apps": "https://smithereen.example/users/1/apps",
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"value": "http://schema.org#value",
|
||||
"PropertyValue": "http://schema.org#PropertyValue",
|
||||
"sm": "http://smithereen.software/ns#",
|
||||
"cropRegion": {
|
||||
"@id": "sm:cropRegion",
|
||||
"@container": "@list"
|
||||
},
|
||||
"wall": {
|
||||
"@id": "sm:wall",
|
||||
"@type": "@id"
|
||||
},
|
||||
"wallComments": {
|
||||
"@id": "sm:wallComments",
|
||||
"@type": "@id"
|
||||
},
|
||||
"collectionSimpleQuery": "sm:collectionSimpleQuery",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"discoverable": "toot:discoverable",
|
||||
"indexable": "toot:indexable",
|
||||
"status": {
|
||||
"@id": "sm:status",
|
||||
"@type": "@id"
|
||||
},
|
||||
"ActorStatus": "sm:ActorStatus",
|
||||
"sc": "http://schema.org#",
|
||||
"firstName": "sc:givenName",
|
||||
"lastName": "sc:familyName",
|
||||
"middleName": "sc:additionalName",
|
||||
"gender": {
|
||||
"@id": "sc:gender",
|
||||
"@type": "sc:GenderType"
|
||||
},
|
||||
"maidenName": "sm:maidenName",
|
||||
"friends": {
|
||||
"@id": "sm:friends",
|
||||
"@type": "@id"
|
||||
},
|
||||
"groups": {
|
||||
"@id": "sm:groups",
|
||||
"@type": "@id"
|
||||
},
|
||||
"vcard": "http://www.w3.org/2006/vcard/ns#",
|
||||
"capabilities": "litepub:capabilities",
|
||||
"supportsFriendRequests": "sm:supportsFriendRequests",
|
||||
"litepub": "http://litepub.social/ns#",
|
||||
"privacySettings": "sm:privacySettings",
|
||||
"allowedTo": "sm:allowedTo",
|
||||
"except": "sm:except",
|
||||
"wallPosting": "sm:wallPosting",
|
||||
"wallPostVisibility": "sm:wallPostVisibility",
|
||||
"commenting": "sm:commenting",
|
||||
"groupInvitations": "sm:groupInvitations",
|
||||
"directMessages": "sm:directMessages",
|
||||
"photoTagging": "sm:photoTagging",
|
||||
"photoTagList": "sm:photoTagList",
|
||||
"activities": "sm:activities",
|
||||
"interests": "sm:interests",
|
||||
"favoriteTvShows": "sm:favoriteTvShows",
|
||||
"favoriteQuotes": "sm:favoriteQuotes",
|
||||
"politicalViews": {
|
||||
"@id": "sm:politicalViews",
|
||||
"@type": "@id"
|
||||
},
|
||||
"personalPriority": {
|
||||
"@id": "sm:personalPriority",
|
||||
"@type": "@id"
|
||||
},
|
||||
"smokingViews": {
|
||||
"@id": "sm:smokingViews",
|
||||
"@type": "@id"
|
||||
},
|
||||
"alcoholViews": {
|
||||
"@id": "sm:alcoholViews",
|
||||
"@type": "@id"
|
||||
},
|
||||
"relationshipStatus": {
|
||||
"@id": "sm:relationshipStatus",
|
||||
"@type": "@id"
|
||||
},
|
||||
"relationshipPartner": {
|
||||
"@id": "sm:relationshipPartner",
|
||||
"@type": "@id"
|
||||
},
|
||||
"photoAlbums": {
|
||||
"@id": "sm:photoAlbums",
|
||||
"@type": "@id"
|
||||
},
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"taggedPhotos": {
|
||||
"@id": "sm:taggedPhotos",
|
||||
"@type": "@id"
|
||||
},
|
||||
"suspended": "toot:suspended",
|
||||
"featured": {
|
||||
"@id": "toot:featured",
|
||||
"@type": "@id"
|
||||
},
|
||||
"apps": {
|
||||
"@id": "sm:apps",
|
||||
"@type": "@id"
|
||||
}
|
||||
},
|
||||
"https://w3id.org/security/v1"
|
||||
]
|
||||
}
|
||||
|
|
@ -146,7 +146,9 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do
|
|||
"https://purl.archive.org/socialweb/webfinger",
|
||||
%{
|
||||
"@language" => "und",
|
||||
"htmlMfm" => "https://w3id.org/fep/c16b#htmlMfm"
|
||||
"htmlMfm" => "https://w3id.org/fep/c16b#htmlMfm",
|
||||
"nonAnonymous" => "sm:nonAnonymous",
|
||||
"sm" => "http://smithereen.software/ns#"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,27 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
|
|||
assert result["@context"]
|
||||
end
|
||||
|
||||
test "renders a local poll with anonymitiy promise" do
|
||||
poller = insert(:user, local: true)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(poller, %{
|
||||
status: "nemui...",
|
||||
poll: %{options: ["suya", "nini", "eep"], expires_in: 10}
|
||||
})
|
||||
|
||||
result = ObjectView.render("object.json", %{object: activity})
|
||||
|
||||
assert result["id"] == activity.data["id"]
|
||||
assert result["type"] == "Create"
|
||||
|
||||
resobj = result["object"]
|
||||
|
||||
assert is_map(resobj)
|
||||
assert resobj["type"] == "Question"
|
||||
assert resobj["nonAnonymous"] == false
|
||||
end
|
||||
|
||||
describe "note activity's `replies` collection rendering" do
|
||||
setup do: clear_config([:activitypub, :note_replies_output_limit], 5)
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,11 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
|
|||
%{title: "why are you even asking?", votes_count: 0}
|
||||
],
|
||||
votes_count: 0,
|
||||
voters_count: nil
|
||||
voters_count: nil,
|
||||
akkoma: %{
|
||||
# locally created polls are always anonymous
|
||||
anonymous: true
|
||||
}
|
||||
}
|
||||
|
||||
result = PollView.render("show.json", %{object: object})
|
||||
|
|
@ -137,6 +141,27 @@ defmodule Pleroma.Web.MastodonAPI.PollViewTest do
|
|||
assert result[:expired] == false
|
||||
end
|
||||
|
||||
test "does not make false claims in absence of vote anonymity information" do
|
||||
object = Object.normalize("https://skippers-bin.com/notes/7x9tmrp97i", fetch: true)
|
||||
result = PollView.render("show.json", %{object: object})
|
||||
|
||||
assert result[:akkoma][:anonymous] == nil
|
||||
end
|
||||
|
||||
test "indicates promise of anonymity" do
|
||||
object = Object.normalize("https://smithereen.example/posts/poll-anon", fetch: true)
|
||||
result = PollView.render("show.json", %{object: object})
|
||||
|
||||
assert result[:akkoma][:anonymous] == true
|
||||
end
|
||||
|
||||
test "indicates assured vote and identity disclosure" do
|
||||
object = Object.normalize("https://smithereen.example/posts/poll-disclosed", fetch: true)
|
||||
result = PollView.render("show.json", %{object: object})
|
||||
|
||||
assert result[:akkoma][:anonymous] == false
|
||||
end
|
||||
|
||||
test "doesn't strips HTML tags" do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
|
|||
|
|
@ -1812,6 +1812,45 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://smithereen.example/users/1" = url, _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
url: url,
|
||||
body: File.read!("test/fixtures/smithereen/user.json"),
|
||||
headers: [
|
||||
{"content-type",
|
||||
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""}
|
||||
]
|
||||
}}
|
||||
end
|
||||
|
||||
def get("https://smithereen.example/posts/poll-disclosed" = url, _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
url: url,
|
||||
body: File.read!("test/fixtures/smithereen/poll_nonanonymous.json"),
|
||||
headers: [
|
||||
{"content-type",
|
||||
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""}
|
||||
]
|
||||
}}
|
||||
end
|
||||
|
||||
def get("https://smithereen.example/posts/poll-anon" = url, _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
url: url,
|
||||
body: File.read!("test/fixtures/smithereen/poll_anonymous.json"),
|
||||
headers: [
|
||||
{"content-type",
|
||||
"application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""}
|
||||
]
|
||||
}}
|
||||
end
|
||||
|
||||
def get(url, query, body, headers) do
|
||||
{:error,
|
||||
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue