Refactor media upload
Use Upload Media logic from Pleroma Backend changes for picture upload Move AS <-> Model conversion to separate module Front changes Downgrade apollo-client: https://github.com/Akryum/vue-apollo/issues/577 Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
BIN
test/fixtures/image.jpg
vendored
Normal file
BIN
test/fixtures/image.jpg
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
25
test/fixtures/mastodon-update.json
vendored
25
test/fixtures/mastodon-update.json
vendored
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"type": "Update",
|
||||
"object": {
|
||||
"url": "http://mastodon.example.org/@gargron",
|
||||
"type": "Person",
|
||||
"summary": "<p>Some bio</p>",
|
||||
"publicKey": {
|
||||
{
|
||||
"type": "Update",
|
||||
"object": {
|
||||
"url": "http://mastodon.example.org/@gargron",
|
||||
"type": "Person",
|
||||
"summary": "<p>Some bio</p>",
|
||||
"publicKey": {
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0gs3VnQf6am3R+CeBV4H\nlfI1HZTNRIBHgvFszRZkCERbRgEWMu+P+I6/7GJC5H5jhVQ60z4MmXcyHOGmYMK/\n5XyuHQz7V2Ssu1AxLfRN5Biq1ayb0+DT/E7QxNXDJPqSTnstZ6C7zKH/uAETqg3l\nBonjCQWyds+IYbQYxf5Sp3yhvQ80lMwHML3DaNCMlXWLoOnrOX5/yK5+dedesg2\n/HIvGk+HEt36vm6hoH7bwPuEkgA++ACqwjXRe5Mta7i3eilHxFaF8XIrJFARV0t\nqOu4GID/jG6oA+swIWndGrtR2QRJIt9QIBFfK3HG5M0koZbY1eTqwNFRHFL3xaD\nUQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"owner": "http://mastodon.example.org/users/gargron",
|
||||
"id": "http://mastodon.example.org/users/gargron#main-key"
|
||||
@@ -20,7 +20,16 @@
|
||||
"endpoints": {
|
||||
"sharedInbox": "http://mastodon.example.org/inbox"
|
||||
},
|
||||
"icon":{"type":"Image","mediaType":"image/jpeg","url":"https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"},"image":{"type":"Image","mediaType":"image/png","url":"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"}
|
||||
"icon":{
|
||||
"type":"Image",
|
||||
"mediaType":"image/png",
|
||||
"url":"https://files.mastodon.social/accounts/avatars/000/000/001/original/a285c086605e4182.png"
|
||||
},
|
||||
"image":{
|
||||
"type":"Image",
|
||||
"mediaType":"image/png",
|
||||
"url":"https://files.mastodon.social/accounts/headers/000/000/001/original/c91b871f294ea63e.png"
|
||||
}
|
||||
},
|
||||
"id": "http://mastodon.example.org/users/gargron#updates/1519563538",
|
||||
"actor": "http://mastodon.example.org/users/gargron",
|
||||
|
||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
1
test/fixtures/test.txt
vendored
Normal file
1
test/fixtures/test.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
this is a text file
|
||||
1
test/fixtures/test_tmp.txt
vendored
Normal file
1
test/fixtures/test_tmp.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
this is a text file
|
||||
File diff suppressed because one or more lines are too long
138
test/fixtures/vcr_cassettes/activity_pub/fetch_framapiaf_framasoft_status.json
vendored
Normal file
138
test/fixtures/vcr_cassettes/activity_pub/fetch_framapiaf_framasoft_status.json
vendored
Normal file
File diff suppressed because one or more lines are too long
271
test/fixtures/vcr_cassettes/activity_pub/fetch_framasoft_framapiaf_reply.json
vendored
Normal file
271
test/fixtures/vcr_cassettes/activity_pub/fetch_framasoft_framapiaf_reply.json
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,156 +0,0 @@
|
||||
[
|
||||
{
|
||||
"request": {
|
||||
"body": "",
|
||||
"headers": {
|
||||
"Accept": "application/activity+json"
|
||||
},
|
||||
"method": "get",
|
||||
"options": {
|
||||
"follow_redirect": "true",
|
||||
"recv_timeout": 20000,
|
||||
"connect_timeout": 10000
|
||||
},
|
||||
"request_body": "",
|
||||
"url": "https://social.tcit.fr/users/tcit/statuses/101160654038714030"
|
||||
},
|
||||
"response": {
|
||||
"binary": false,
|
||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",{\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"sensitive\":\"as:sensitive\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"Hashtag\":\"as:Hashtag\",\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"focalPoint\":{\"@container\":\"@list\",\"@id\":\"toot:focalPoint\"},\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\"}],\"id\":\"https://social.tcit.fr/users/tcit/statuses/101160654038714030\",\"type\":\"Note\",\"summary\":null,\"inReplyTo\":\"https://social.tcit.fr/users/tcit/statuses/101160195754333819\",\"published\":\"2018-11-30T14:44:41Z\",\"url\":\"https://social.tcit.fr/@tcit/101160654038714030\",\"attributedTo\":\"https://social.tcit.fr/users/tcit\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://social.tcit.fr/users/tcit/followers\"],\"sensitive\":false,\"atomUri\":\"https://social.tcit.fr/users/tcit/statuses/101160654038714030\",\"inReplyToAtomUri\":\"https://social.tcit.fr/users/tcit/statuses/101160195754333819\",\"conversation\":\"tag:social.tcit.fr,2018-11-30:objectId=3642669:objectType=Conversation\",\"content\":\"\\u003cp\\u003eOkay so that\\u0026apos;s it.\\u003cbr /\\u003e\\u003ca href=\\\"https://tcit.frama.io/group-uri-scheme/draft-tcit-group-uri-01.txt\\\" rel=\\\"nofollow noopener\\\" target=\\\"_blank\\\"\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ehttps://\\u003c/span\\u003e\\u003cspan class=\\\"ellipsis\\\"\\u003etcit.frama.io/group-uri-scheme\\u003c/span\\u003e\\u003cspan class=\\\"invisible\\\"\\u003e/draft-tcit-group-uri-01.txt\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/p\\u003e\",\"contentMap\":{\"fr\":\"\\u003cp\\u003eOkay so that\\u0026apos;s it.\\u003cbr /\\u003e\\u003ca href=\\\"https://tcit.frama.io/group-uri-scheme/draft-tcit-group-uri-01.txt\\\" rel=\\\"nofollow noopener\\\" target=\\\"_blank\\\"\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ehttps://\\u003c/span\\u003e\\u003cspan class=\\\"ellipsis\\\"\\u003etcit.frama.io/group-uri-scheme\\u003c/span\\u003e\\u003cspan class=\\\"invisible\\\"\\u003e/draft-tcit-group-uri-01.txt\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/p\\u003e\"},\"attachment\":[],\"tag\":[]}",
|
||||
"headers": {
|
||||
"Date": "Tue, 04 Dec 2018 13:59:58 GMT",
|
||||
"Content-Type": "application/activity+json; charset=utf-8",
|
||||
"Transfer-Encoding": "chunked",
|
||||
"Connection": "keep-alive",
|
||||
"Server": "Mastodon",
|
||||
"X-Frame-Options": "DENY",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Link": "<https://social.tcit.fr/users/tcit/updates/15979.atom>; rel=\"alternate\"; type=\"application/atom+xml\", <https://social.tcit.fr/users/tcit/statuses/101160654038714030>; rel=\"alternate\"; type=\"application/activity+json\"",
|
||||
"Vary": "Accept,Accept-Encoding",
|
||||
"Cache-Control": "max-age=180, public",
|
||||
"ETag": "W/\"619af54f65bbb41538e430b8247c36d7\"",
|
||||
"X-Request-Id": "84a750de-2dfa-4a36-976e-bae0b0ac4821",
|
||||
"X-Runtime": "0.056423",
|
||||
"X-Cached": "MISS"
|
||||
},
|
||||
"status_code": 200,
|
||||
"type": "ok"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"body": "",
|
||||
"headers": {
|
||||
"Accept": "application/activity+json"
|
||||
},
|
||||
"method": "get",
|
||||
"options": {
|
||||
"follow_redirect": "true"
|
||||
},
|
||||
"request_body": "",
|
||||
"url": "https://social.tcit.fr/users/tcit"
|
||||
},
|
||||
"response": {
|
||||
"binary": false,
|
||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",{\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"sensitive\":\"as:sensitive\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"Hashtag\":\"as:Hashtag\",\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"focalPoint\":{\"@container\":\"@list\",\"@id\":\"toot:focalPoint\"},\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\"}],\"id\":\"https://social.tcit.fr/users/tcit\",\"type\":\"Person\",\"following\":\"https://social.tcit.fr/users/tcit/following\",\"followers\":\"https://social.tcit.fr/users/tcit/followers\",\"inbox\":\"https://social.tcit.fr/users/tcit/inbox\",\"outbox\":\"https://social.tcit.fr/users/tcit/outbox\",\"featured\":\"https://social.tcit.fr/users/tcit/collections/featured\",\"preferredUsername\":\"tcit\",\"name\":\"🦄 Thomas Citharel\",\"summary\":\"\\u003cp\\u003eHoping to make people\\u0026apos;s life better with free software at \\u003cspan class=\\\"h-card\\\"\\u003e\\u003ca href=\\\"https://framapiaf.org/@Framasoft\\\" class=\\\"u-url mention\\\"\\u003e@\\u003cspan\\u003eFramasoft\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/span\\u003e.\\u003c/p\\u003e\",\"url\":\"https://social.tcit.fr/@tcit\",\"manuallyApprovesFollowers\":false,\"publicKey\":{\"id\":\"https://social.tcit.fr/users/tcit#main-key\",\"owner\":\"https://social.tcit.fr/users/tcit\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApXwYMUdFg3XUd+bGsh8C\\nyiMRGpRGAWuCdM5pDWx5uM4pW2pM3xbHbcI21j9h8BmlAiPg6hbZD73KGly2N8Rt\\n5iIS0I+l6i8kA1JCCdlAaDTRd41RKMggZDoQvjVZQtsyE1VzMeU2kbqqTFN6ew7H\\nvbd6O0NhixoKoZ5f3jwuBDZoT0p1TAcaMdmG8oqHD97isizkDnRn8cOBA6wtI+xb\\n5xP2zxZMsLpTDZLiKU8XcPKZCw4OfQfmDmKkHtrFb77jCAQj/s/FxjVnvxRwmfhN\\nnWy0D+LUV/g63nHh/b5zXIeV92QZLvDYbgbezmzUzv9UeA1s70GGbaDqCIy85gw9\\n+wIDAQAB\\n-----END PUBLIC KEY-----\\n\"},\"tag\":[],\"attachment\":[{\"type\":\"PropertyValue\",\"name\":\"Works at\",\"value\":\"\\u003cspan class=\\\"h-card\\\"\\u003e\\u003ca href=\\\"https://framapiaf.org/@Framasoft\\\" class=\\\"u-url mention\\\"\\u003e@\\u003cspan\\u003eFramasoft\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/span\\u003e\"},{\"type\":\"PropertyValue\",\"name\":\"Pronouns\",\"value\":\"He/Him\"},{\"type\":\"PropertyValue\",\"name\":\"Work Account\",\"value\":\"\\u003ca href=\\\"https://framapiaf.org/@tcit\\\" rel=\\\"me nofollow noopener\\\" target=\\\"_blank\\\"\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ehttps://\\u003c/span\\u003e\\u003cspan class=\\\"\\\"\\u003eframapiaf.org/@tcit\\u003c/span\\u003e\\u003cspan class=\\\"invisible\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003e\"},{\"type\":\"PropertyValue\",\"name\":\"Site\",\"value\":\"\\u003ca href=\\\"https://tcit.fr\\\" rel=\\\"me nofollow noopener\\\" target=\\\"_blank\\\"\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ehttps://\\u003c/span\\u003e\\u003cspan class=\\\"\\\"\\u003etcit.fr\\u003c/span\\u003e\\u003cspan class=\\\"invisible\\\"\\u003e\\u003c/span\\u003e\\u003c/a\\u003e\"}],\"endpoints\":{\"sharedInbox\":\"https://social.tcit.fr/inbox\"},\"icon\":{\"type\":\"Image\",\"mediaType\":\"image/jpeg\",\"url\":\"https://media.social.tcit.fr/mastodontcit/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg\"},\"image\":{\"type\":\"Image\",\"mediaType\":\"image/jpeg\",\"url\":\"https://media.social.tcit.fr/mastodontcit/accounts/headers/000/000/001/original/4d1ab77c20265ee9.jpg\"}}",
|
||||
"headers": {
|
||||
"Date": "Tue, 04 Dec 2018 13:59:58 GMT",
|
||||
"Content-Type": "application/activity+json; charset=utf-8",
|
||||
"Transfer-Encoding": "chunked",
|
||||
"Connection": "keep-alive",
|
||||
"Server": "Mastodon",
|
||||
"X-Frame-Options": "DENY",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Link": "<https://social.tcit.fr/.well-known/webfinger?resource=acct%3Atcit%40social.tcit.fr>; rel=\"lrdd\"; type=\"application/xrd+xml\", <https://social.tcit.fr/users/tcit.atom>; rel=\"alternate\"; type=\"application/atom+xml\", <https://social.tcit.fr/users/tcit>; rel=\"alternate\"; type=\"application/activity+json\"",
|
||||
"Vary": "Accept,Accept-Encoding",
|
||||
"Cache-Control": "max-age=180, public",
|
||||
"ETag": "W/\"039b9e136f81a55656fb1f38a23640d2\"",
|
||||
"X-Request-Id": "91a50164-aa87-45c9-8100-786b9c74fbe0",
|
||||
"X-Runtime": "0.039489",
|
||||
"X-Cached": "MISS"
|
||||
},
|
||||
"status_code": 200,
|
||||
"type": "ok"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"body": "",
|
||||
"headers": {
|
||||
"Accept": "application/activity+json"
|
||||
},
|
||||
"method": "get",
|
||||
"options": {
|
||||
"follow_redirect": "true",
|
||||
"recv_timeout": 20000,
|
||||
"connect_timeout": 10000
|
||||
},
|
||||
"request_body": "",
|
||||
"url": "https://social.tcit.fr/users/tcit/statuses/101160195754333819"
|
||||
},
|
||||
"response": {
|
||||
"binary": false,
|
||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",{\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"sensitive\":\"as:sensitive\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"Hashtag\":\"as:Hashtag\",\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"focalPoint\":{\"@container\":\"@list\",\"@id\":\"toot:focalPoint\"},\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\"}],\"id\":\"https://social.tcit.fr/users/tcit/statuses/101160195754333819\",\"type\":\"Note\",\"summary\":null,\"inReplyTo\":\"https://social.tcit.fr/users/tcit/statuses/101159468934977010\",\"published\":\"2018-11-30T12:48:08Z\",\"url\":\"https://social.tcit.fr/@tcit/101160195754333819\",\"attributedTo\":\"https://social.tcit.fr/users/tcit\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://social.tcit.fr/users/tcit/followers\"],\"sensitive\":false,\"atomUri\":\"https://social.tcit.fr/users/tcit/statuses/101160195754333819\",\"inReplyToAtomUri\":\"https://social.tcit.fr/users/tcit/statuses/101159468934977010\",\"conversation\":\"tag:social.tcit.fr,2018-11-30:objectId=3642669:objectType=Conversation\",\"content\":\"\\u003cp\\u003eOkay so YOLO.\\u003c/p\\u003e\",\"contentMap\":{\"fr\":\"\\u003cp\\u003eOkay so YOLO.\\u003c/p\\u003e\"},\"attachment\":[{\"type\":\"Document\",\"mediaType\":\"image/png\",\"url\":\"https://media.social.tcit.fr/mastodontcit/media_attachments/files/000/718/393/original/b56706a78fd355b8.png\",\"name\":\"Start of a 'group' URI RFC\"}],\"tag\":[]}",
|
||||
"headers": {
|
||||
"Date": "Tue, 04 Dec 2018 13:59:58 GMT",
|
||||
"Content-Type": "application/activity+json; charset=utf-8",
|
||||
"Transfer-Encoding": "chunked",
|
||||
"Connection": "keep-alive",
|
||||
"Server": "Mastodon",
|
||||
"X-Frame-Options": "DENY",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Link": "<https://social.tcit.fr/users/tcit/updates/15967.atom>; rel=\"alternate\"; type=\"application/atom+xml\", <https://social.tcit.fr/users/tcit/statuses/101160195754333819>; rel=\"alternate\"; type=\"application/activity+json\"",
|
||||
"Vary": "Accept,Accept-Encoding",
|
||||
"Cache-Control": "max-age=180, public",
|
||||
"ETag": "W/\"e878d9ab8dfa31073b27b4661046b911\"",
|
||||
"X-Request-Id": "b598d538-88b5-4d7a-867c-d78b85ee5677",
|
||||
"X-Runtime": "0.078823",
|
||||
"X-Cached": "MISS"
|
||||
},
|
||||
"status_code": 200,
|
||||
"type": "ok"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"body": "",
|
||||
"headers": {
|
||||
"Accept": "application/activity+json"
|
||||
},
|
||||
"method": "get",
|
||||
"options": {
|
||||
"follow_redirect": "true",
|
||||
"recv_timeout": 20000,
|
||||
"connect_timeout": 10000
|
||||
},
|
||||
"request_body": "",
|
||||
"url": "https://social.tcit.fr/users/tcit/statuses/101159468934977010"
|
||||
},
|
||||
"response": {
|
||||
"binary": false,
|
||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",{\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"sensitive\":\"as:sensitive\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"Hashtag\":\"as:Hashtag\",\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"focalPoint\":{\"@container\":\"@list\",\"@id\":\"toot:focalPoint\"},\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\"}],\"id\":\"https://social.tcit.fr/users/tcit/statuses/101159468934977010\",\"type\":\"Note\",\"summary\":null,\"inReplyTo\":null,\"published\":\"2018-11-30T09:43:18Z\",\"url\":\"https://social.tcit.fr/@tcit/101159468934977010\",\"attributedTo\":\"https://social.tcit.fr/users/tcit\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://social.tcit.fr/users/tcit/followers\"],\"sensitive\":false,\"atomUri\":\"https://social.tcit.fr/users/tcit/statuses/101159468934977010\",\"inReplyToAtomUri\":null,\"conversation\":\"tag:social.tcit.fr,2018-11-30:objectId=3642669:objectType=Conversation\",\"content\":\"\\u003cp\\u003eApart from PeerTube, which software that implements ActivityPub does have a group functionnality?\\u003cbr /\\u003eIt\\u0026apos;s to discuss about a Webfinger group: query prefix, similar to the acct: query prefix.\\u003c/p\\u003e\",\"contentMap\":{\"en\":\"\\u003cp\\u003eApart from PeerTube, which software that implements ActivityPub does have a group functionnality?\\u003cbr /\\u003eIt\\u0026apos;s to discuss about a Webfinger group: query prefix, similar to the acct: query prefix.\\u003c/p\\u003e\"},\"attachment\":[],\"tag\":[]}",
|
||||
"headers": {
|
||||
"Date": "Tue, 04 Dec 2018 13:59:58 GMT",
|
||||
"Content-Type": "application/activity+json; charset=utf-8",
|
||||
"Transfer-Encoding": "chunked",
|
||||
"Connection": "keep-alive",
|
||||
"Server": "Mastodon",
|
||||
"X-Frame-Options": "DENY",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Link": "<https://social.tcit.fr/users/tcit/updates/15941.atom>; rel=\"alternate\"; type=\"application/atom+xml\", <https://social.tcit.fr/users/tcit/statuses/101159468934977010>; rel=\"alternate\"; type=\"application/activity+json\"",
|
||||
"Vary": "Accept,Accept-Encoding",
|
||||
"Cache-Control": "max-age=180, public",
|
||||
"ETag": "W/\"a29cc605a433ed904736da57572038d3\"",
|
||||
"X-Request-Id": "18488387-c5a3-40db-8c9e-5a3a067401a9",
|
||||
"X-Runtime": "0.054993",
|
||||
"X-Cached": "MISS"
|
||||
},
|
||||
"status_code": 200,
|
||||
"type": "ok"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1,78 +0,0 @@
|
||||
[
|
||||
{
|
||||
"request": {
|
||||
"body": "",
|
||||
"headers": {
|
||||
"Accept": "application/activity+json"
|
||||
},
|
||||
"method": "get",
|
||||
"options": {
|
||||
"follow_redirect": "true",
|
||||
"recv_timeout": 20000,
|
||||
"connect_timeout": 10000
|
||||
},
|
||||
"request_body": "",
|
||||
"url": "https://social.tcit.fr/users/tcit/statuses/99908779444618462"
|
||||
},
|
||||
"response": {
|
||||
"binary": false,
|
||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",{\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"sensitive\":\"as:sensitive\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"Hashtag\":\"as:Hashtag\",\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"focalPoint\":{\"@container\":\"@list\",\"@id\":\"toot:focalPoint\"},\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\"}],\"id\":\"https://social.tcit.fr/users/tcit/statuses/99908779444618462\",\"type\":\"Note\",\"summary\":null,\"inReplyTo\":null,\"published\":\"2018-04-23T12:36:31Z\",\"url\":\"https://social.tcit.fr/@tcit/99908779444618462\",\"attributedTo\":\"https://social.tcit.fr/users/tcit\",\"to\":[\"https://www.w3.org/ns/activitystreams#Public\"],\"cc\":[\"https://social.tcit.fr/users/tcit/followers\"],\"sensitive\":false,\"atomUri\":\"https://social.tcit.fr/users/tcit/statuses/99908779444618462\",\"inReplyToAtomUri\":null,\"conversation\":\"tag:social.tcit.fr,2018-04-23:objectId=1769180:objectType=Conversation\",\"content\":\"\\u003cp\\u003eRimini - Les Wampas\\u003cbr /\\u003e\\u003ca href=\\\"https://combine.fm/spotify/track/5xo1GjsebrOd1iUVoJ6SEK\\\" rel=\\\"nofollow noopener\\\" target=\\\"_blank\\\"\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ehttps://\\u003c/span\\u003e\\u003cspan class=\\\"ellipsis\\\"\\u003ecombine.fm/spotify/track/5xo1G\\u003c/span\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ejsebrOd1iUVoJ6SEK\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/p\\u003e\",\"contentMap\":{\"fr\":\"\\u003cp\\u003eRimini - Les Wampas\\u003cbr /\\u003e\\u003ca href=\\\"https://combine.fm/spotify/track/5xo1GjsebrOd1iUVoJ6SEK\\\" rel=\\\"nofollow noopener\\\" target=\\\"_blank\\\"\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ehttps://\\u003c/span\\u003e\\u003cspan class=\\\"ellipsis\\\"\\u003ecombine.fm/spotify/track/5xo1G\\u003c/span\\u003e\\u003cspan class=\\\"invisible\\\"\\u003ejsebrOd1iUVoJ6SEK\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/p\\u003e\"},\"attachment\":[],\"tag\":[]}",
|
||||
"headers": {
|
||||
"Date": "Tue, 13 Nov 2018 11:02:32 GMT",
|
||||
"Content-Type": "application/activity+json; charset=utf-8",
|
||||
"Transfer-Encoding": "chunked",
|
||||
"Connection": "keep-alive",
|
||||
"Server": "Mastodon",
|
||||
"X-Frame-Options": "DENY",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Link": "<https://social.tcit.fr/users/tcit/updates/9225.atom>; rel=\"alternate\"; type=\"application/atom+xml\", <https://social.tcit.fr/users/tcit/statuses/99908779444618462>; rel=\"alternate\"; type=\"application/activity+json\"",
|
||||
"Vary": "Accept,Accept-Encoding",
|
||||
"Cache-Control": "max-age=180, public",
|
||||
"ETag": "W/\"4f1620f67825ded8c3ebde01dc48e44f\"",
|
||||
"X-Request-Id": "6e8e4d12-8396-445e-909c-81dab9797449",
|
||||
"X-Runtime": "0.057592",
|
||||
"X-Cached": "MISS"
|
||||
},
|
||||
"status_code": 200,
|
||||
"type": "ok"
|
||||
}
|
||||
},
|
||||
{
|
||||
"request": {
|
||||
"body": "",
|
||||
"headers": {
|
||||
"Accept": "application/activity+json"
|
||||
},
|
||||
"method": "get",
|
||||
"options": {
|
||||
"follow_redirect": "true"
|
||||
},
|
||||
"request_body": "",
|
||||
"url": "https://social.tcit.fr/users/tcit"
|
||||
},
|
||||
"response": {
|
||||
"binary": false,
|
||||
"body": "{\"@context\":[\"https://www.w3.org/ns/activitystreams\",\"https://w3id.org/security/v1\",{\"manuallyApprovesFollowers\":\"as:manuallyApprovesFollowers\",\"sensitive\":\"as:sensitive\",\"movedTo\":{\"@id\":\"as:movedTo\",\"@type\":\"@id\"},\"Hashtag\":\"as:Hashtag\",\"ostatus\":\"http://ostatus.org#\",\"atomUri\":\"ostatus:atomUri\",\"inReplyToAtomUri\":\"ostatus:inReplyToAtomUri\",\"conversation\":\"ostatus:conversation\",\"toot\":\"http://joinmastodon.org/ns#\",\"Emoji\":\"toot:Emoji\",\"focalPoint\":{\"@container\":\"@list\",\"@id\":\"toot:focalPoint\"},\"featured\":{\"@id\":\"toot:featured\",\"@type\":\"@id\"},\"schema\":\"http://schema.org#\",\"PropertyValue\":\"schema:PropertyValue\",\"value\":\"schema:value\"}],\"id\":\"https://social.tcit.fr/users/tcit\",\"type\":\"Person\",\"following\":\"https://social.tcit.fr/users/tcit/following\",\"followers\":\"https://social.tcit.fr/users/tcit/followers\",\"inbox\":\"https://social.tcit.fr/users/tcit/inbox\",\"outbox\":\"https://social.tcit.fr/users/tcit/outbox\",\"featured\":\"https://social.tcit.fr/users/tcit/collections/featured\",\"preferredUsername\":\"tcit\",\"name\":\"🦄 Thomas Citharel\",\"summary\":\"\\u003cp\\u003eHoping to make people\\u0026apos;s life better with free software at \\u003cspan class=\\\"h-card\\\"\\u003e\\u003ca href=\\\"https://framapiaf.org/@Framasoft\\\" class=\\\"u-url mention\\\"\\u003e@\\u003cspan\\u003eFramasoft\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/span\\u003e.\\u003c/p\\u003e\",\"url\":\"https://social.tcit.fr/@tcit\",\"manuallyApprovesFollowers\":false,\"publicKey\":{\"id\":\"https://social.tcit.fr/users/tcit#main-key\",\"owner\":\"https://social.tcit.fr/users/tcit\",\"publicKeyPem\":\"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApXwYMUdFg3XUd+bGsh8C\\nyiMRGpRGAWuCdM5pDWx5uM4pW2pM3xbHbcI21j9h8BmlAiPg6hbZD73KGly2N8Rt\\n5iIS0I+l6i8kA1JCCdlAaDTRd41RKMggZDoQvjVZQtsyE1VzMeU2kbqqTFN6ew7H\\nvbd6O0NhixoKoZ5f3jwuBDZoT0p1TAcaMdmG8oqHD97isizkDnRn8cOBA6wtI+xb\\n5xP2zxZMsLpTDZLiKU8XcPKZCw4OfQfmDmKkHtrFb77jCAQj/s/FxjVnvxRwmfhN\\nnWy0D+LUV/g63nHh/b5zXIeV92QZLvDYbgbezmzUzv9UeA1s70GGbaDqCIy85gw9\\n+wIDAQAB\\n-----END PUBLIC KEY-----\\n\"},\"tag\":[],\"attachment\":[{\"type\":\"PropertyValue\",\"name\":\"Works at\",\"value\":\"\\u003cspan class=\\\"h-card\\\"\\u003e\\u003ca href=\\\"https://framapiaf.org/@Framasoft\\\" class=\\\"u-url mention\\\"\\u003e@\\u003cspan\\u003eFramasoft\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/span\\u003e\"},{\"type\":\"PropertyValue\",\"name\":\"Pronouns\",\"value\":\"He/Him\"},{\"type\":\"PropertyValue\",\"name\":\"Work Account\",\"value\":\"\\u003cspan class=\\\"h-card\\\"\\u003e\\u003ca href=\\\"https://framapiaf.org/@tcit\\\" class=\\\"u-url mention\\\"\\u003e@\\u003cspan\\u003etcit\\u003c/span\\u003e\\u003c/a\\u003e\\u003c/span\\u003e\"},{\"type\":\"PropertyValue\",\"name\":\"Pixelfed Account\",\"value\":\"@tcit@pix.tcit.fr\"}],\"endpoints\":{\"sharedInbox\":\"https://social.tcit.fr/inbox\"},\"icon\":{\"type\":\"Image\",\"mediaType\":\"image/jpeg\",\"url\":\"https://media.social.tcit.fr/mastodontcit/accounts/avatars/000/000/001/original/a28c50ce5f2b13fd.jpg\"},\"image\":{\"type\":\"Image\",\"mediaType\":\"image/jpeg\",\"url\":\"https://media.social.tcit.fr/mastodontcit/accounts/headers/000/000/001/original/4d1ab77c20265ee9.jpg\"}}",
|
||||
"headers": {
|
||||
"Date": "Tue, 13 Nov 2018 11:02:32 GMT",
|
||||
"Content-Type": "application/activity+json; charset=utf-8",
|
||||
"Transfer-Encoding": "chunked",
|
||||
"Connection": "keep-alive",
|
||||
"Server": "Mastodon",
|
||||
"X-Frame-Options": "DENY",
|
||||
"X-Content-Type-Options": "nosniff",
|
||||
"X-XSS-Protection": "1; mode=block",
|
||||
"Link": "<https://social.tcit.fr/.well-known/webfinger?resource=acct%3Atcit%40social.tcit.fr>; rel=\"lrdd\"; type=\"application/xrd+xml\", <https://social.tcit.fr/users/tcit.atom>; rel=\"alternate\"; type=\"application/atom+xml\", <https://social.tcit.fr/users/tcit>; rel=\"alternate\"; type=\"application/activity+json\"",
|
||||
"Vary": "Accept,Accept-Encoding",
|
||||
"Cache-Control": "max-age=180, public",
|
||||
"ETag": "W/\"928f8a090d8c180ccc82fc1699f6c2a5\"",
|
||||
"X-Request-Id": "9520c2ef-0089-4fb8-a6b4-95f3e217487c",
|
||||
"X-Runtime": "0.043715",
|
||||
"X-Cached": "MISS"
|
||||
},
|
||||
"status_code": 200,
|
||||
"type": "ok"
|
||||
}
|
||||
}
|
||||
]
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -4,6 +4,7 @@ defmodule Mobilizon.ActorsTest do
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Member, Follower, Bot}
|
||||
alias Mobilizon.Users
|
||||
alias Mobilizon.Media.File
|
||||
import Mobilizon.Factory
|
||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||
|
||||
@@ -91,13 +92,23 @@ defmodule Mobilizon.ActorsTest do
|
||||
|
||||
test "get_actor_by_name/1 returns a remote actor" do
|
||||
use_cassette "actors/remote_actor_mastodon_tcit" do
|
||||
with {:ok,
|
||||
%Actor{id: actor_id, preferred_username: preferred_username, domain: domain} =
|
||||
_actor} <- Actors.get_or_fetch_by_url(@remote_account_url),
|
||||
%Actor{id: actor_found_id} <-
|
||||
Actors.get_actor_by_name("#{preferred_username}@#{domain}").id do
|
||||
assert actor_found_id == actor_id
|
||||
end
|
||||
{:ok,
|
||||
%Actor{
|
||||
id: actor_id,
|
||||
preferred_username: preferred_username,
|
||||
domain: domain,
|
||||
avatar: %File{name: picture_name} = _picture
|
||||
} = _actor} = Actors.get_or_fetch_by_url(@remote_account_url)
|
||||
|
||||
assert picture_name == "avatar"
|
||||
|
||||
%Actor{
|
||||
id: actor_found_id,
|
||||
avatar: %File{name: picture_name} = _picture
|
||||
} = Actors.get_actor_by_name("#{preferred_username}@#{domain}")
|
||||
|
||||
assert actor_found_id == actor_id
|
||||
assert picture_name == "avatar"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
50
test/mobilizon/media/media_test.exs
Normal file
50
test/mobilizon/media/media_test.exs
Normal file
@@ -0,0 +1,50 @@
|
||||
defmodule Mobilizon.MediaTest do
|
||||
use Mobilizon.DataCase
|
||||
|
||||
alias Mobilizon.Media
|
||||
import Mobilizon.Factory
|
||||
|
||||
describe "media" do
|
||||
alias Mobilizon.Media.Picture
|
||||
|
||||
@valid_attrs %{
|
||||
file: %{
|
||||
url: "https://something.tld/media/something",
|
||||
name: "something old"
|
||||
}
|
||||
}
|
||||
@update_attrs %{
|
||||
file: %{
|
||||
url: "https://something.tld/media/something_updated",
|
||||
name: "something new"
|
||||
}
|
||||
}
|
||||
|
||||
test "get_picture!/1 returns the picture with given id" do
|
||||
picture = insert(:picture)
|
||||
assert Media.get_picture!(picture.id) == picture
|
||||
end
|
||||
|
||||
test "create_picture/1 with valid data creates a picture" do
|
||||
assert {:ok, %Picture{} = picture} = Media.create_picture(@valid_attrs)
|
||||
assert picture.file.name == "something old"
|
||||
end
|
||||
|
||||
test "update_picture/2 with valid data updates the picture" do
|
||||
picture = insert(:picture)
|
||||
assert {:ok, %Picture{} = picture} = Media.update_picture(picture, @update_attrs)
|
||||
assert picture.file.name == "something new"
|
||||
end
|
||||
|
||||
test "delete_picture/1 deletes the picture" do
|
||||
picture = insert(:picture)
|
||||
assert {:ok, %Picture{}} = Media.delete_picture(picture)
|
||||
assert_raise Ecto.NoResultsError, fn -> Media.get_picture!(picture.id) end
|
||||
end
|
||||
|
||||
test "change_picture/1 returns a picture changeset" do
|
||||
picture = insert(:picture)
|
||||
assert %Ecto.Changeset{} = Media.change_picture(picture)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -72,15 +72,15 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
|
||||
|
||||
describe "fetching an" do
|
||||
test "object by url" do
|
||||
use_cassette "activity_pub/fetch_social_tcit_fr_status" do
|
||||
use_cassette "activity_pub/fetch_framapiaf_framasoft_status" do
|
||||
{:ok, object} =
|
||||
ActivityPub.fetch_object_from_url(
|
||||
"https://social.tcit.fr/users/tcit/statuses/99908779444618462"
|
||||
"https://framapiaf.org/users/Framasoft/statuses/102093631881522097"
|
||||
)
|
||||
|
||||
{:ok, object_again} =
|
||||
ActivityPub.fetch_object_from_url(
|
||||
"https://social.tcit.fr/users/tcit/statuses/99908779444618462"
|
||||
"https://framapiaf.org/users/Framasoft/statuses/102093631881522097"
|
||||
)
|
||||
|
||||
assert object.id == object_again.id
|
||||
@@ -88,14 +88,12 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
|
||||
end
|
||||
|
||||
test "object reply by url" do
|
||||
use_cassette "activity_pub/fetch_social_tcit_fr_reply" do
|
||||
use_cassette "activity_pub/fetch_framasoft_framapiaf_reply" do
|
||||
{:ok, object} =
|
||||
ActivityPub.fetch_object_from_url(
|
||||
"https://social.tcit.fr/users/tcit/statuses/101160654038714030"
|
||||
)
|
||||
ActivityPub.fetch_object_from_url("https://mamot.fr/@imacrea/102094441327423790")
|
||||
|
||||
assert object.in_reply_to_comment.url ==
|
||||
"https://social.tcit.fr/users/tcit/statuses/101160195754333819"
|
||||
"https://framapiaf.org/users/Framasoft/statuses/102093632302210150"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -103,7 +101,7 @@ defmodule Mobilizon.Service.ActivityPub.ActivityPubTest do
|
||||
use_cassette "activity_pub/fetch_reply_to_framatube" do
|
||||
{:ok, object} =
|
||||
ActivityPub.fetch_object_from_url(
|
||||
"https://framapiaf.org/@troisiemelobe/101156292125317651"
|
||||
"https://diaspodon.fr/users/dada/statuses/100820008426311925"
|
||||
)
|
||||
|
||||
assert object.in_reply_to_comment == nil
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
defmodule Mobilizon.Service.ActivityPub.Converters.ActorTest do
|
||||
use Mobilizon.DataCase
|
||||
alias Mobilizon.Service.ActivityPub.Converters.Actor, as: ActorConverter
|
||||
alias Mobilizon.Actors.Actor
|
||||
|
||||
describe "actor to AS" do
|
||||
test "valid actor to as" do
|
||||
data = ActorConverter.model_to_as(%Actor{type: :Person, preferred_username: "test_account"})
|
||||
assert is_map(data)
|
||||
assert data["type"] == "Person"
|
||||
assert data["preferred_username"] == "test_account"
|
||||
end
|
||||
end
|
||||
|
||||
describe "AS to Actor" do
|
||||
test "valid as data to model" do
|
||||
actor =
|
||||
ActorConverter.as_to_model_data(%{
|
||||
"type" => "Person",
|
||||
"preferred_username" => "test_account"
|
||||
})
|
||||
|
||||
assert actor["type"] == :Person
|
||||
assert actor["preferred_username"] == "test_account"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -307,12 +307,6 @@ defmodule Mobilizon.Service.ActivityPub.TransmogrifierTest do
|
||||
{:ok, %Actor{} = actor} = Actors.get_actor_by_url(data["actor"])
|
||||
assert actor.name == "gargle"
|
||||
|
||||
assert actor.avatar_url ==
|
||||
"https://cd.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
|
||||
|
||||
assert actor.banner_url ==
|
||||
"https://cd.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
|
||||
|
||||
assert actor.summary == "<p>Some bio</p>"
|
||||
end
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ defmodule Mobilizon.Service.ActivityPub.UtilsTest do
|
||||
"id" => Routes.page_url(Endpoint, :comment, reply.uuid),
|
||||
"inReplyTo" => comment.url,
|
||||
"attributedTo" => reply.actor.url
|
||||
} == Utils.make_comment_data(reply)
|
||||
} == Mobilizon.Service.ActivityPub.Converters.Comment.model_to_as(reply)
|
||||
end
|
||||
|
||||
test "comment data from map" do
|
||||
|
||||
@@ -6,12 +6,11 @@
|
||||
defmodule MobilizonWeb.ActivityPubControllerTest do
|
||||
use MobilizonWeb.ConnCase
|
||||
import Mobilizon.Factory
|
||||
alias MobilizonWeb.ActivityPub.{ActorView, ObjectView}
|
||||
alias MobilizonWeb.ActivityPub.ActorView
|
||||
alias MobilizonWeb.PageView
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Service.ActivityPub
|
||||
alias Mobilizon.Service.ActivityPub.Utils
|
||||
use ExVCR.Mock, adapter: ExVCR.Adapter.Hackney
|
||||
alias MobilizonWeb.Router.Helpers, as: Routes
|
||||
alias MobilizonWeb.Endpoint
|
||||
|
||||
181
test/mobilizon_web/media_proxy_test.exs
Normal file
181
test/mobilizon_web/media_proxy_test.exs
Normal file
@@ -0,0 +1,181 @@
|
||||
# Portions of this file are derived from Pleroma:
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/media_proxy_test.ex
|
||||
|
||||
defmodule MobilizonWeb.MediaProxyTest do
|
||||
use ExUnit.Case
|
||||
import MobilizonWeb.MediaProxy
|
||||
alias MobilizonWeb.MediaProxyController
|
||||
|
||||
setup do
|
||||
enabled = Mobilizon.CommonConfig.get([:media_proxy, :enabled])
|
||||
on_exit(fn -> Mobilizon.CommonConfig.put([:media_proxy, :enabled], enabled) end)
|
||||
:ok
|
||||
end
|
||||
|
||||
describe "when enabled" do
|
||||
setup do
|
||||
Mobilizon.CommonConfig.put([:media_proxy, :enabled], true)
|
||||
:ok
|
||||
end
|
||||
|
||||
test "ignores invalid url" do
|
||||
assert url(nil) == nil
|
||||
assert url("") == nil
|
||||
end
|
||||
|
||||
test "ignores relative url" do
|
||||
assert url("/local") == "/local"
|
||||
assert url("/") == "/"
|
||||
end
|
||||
|
||||
test "ignores local url" do
|
||||
local_url = MobilizonWeb.Endpoint.url() <> "/hello"
|
||||
local_root = MobilizonWeb.Endpoint.url()
|
||||
assert url(local_url) == local_url
|
||||
assert url(local_root) == local_root
|
||||
end
|
||||
|
||||
test "encodes and decodes URL" do
|
||||
url = "https://pleroma.soykaf.com/static/logo.png"
|
||||
encoded = url(url)
|
||||
|
||||
assert String.starts_with?(
|
||||
encoded,
|
||||
Mobilizon.CommonConfig.get([:media_proxy, :base_url], MobilizonWeb.Endpoint.url())
|
||||
)
|
||||
|
||||
assert String.ends_with?(encoded, "/logo.png")
|
||||
|
||||
assert decode_result(encoded) == url
|
||||
end
|
||||
|
||||
test "encodes and decodes URL without a path" do
|
||||
url = "https://pleroma.soykaf.com"
|
||||
encoded = url(url)
|
||||
assert decode_result(encoded) == url
|
||||
end
|
||||
|
||||
test "encodes and decodes URL without an extension" do
|
||||
url = "https://pleroma.soykaf.com/path/"
|
||||
encoded = url(url)
|
||||
assert String.ends_with?(encoded, "/path")
|
||||
assert decode_result(encoded) == url
|
||||
end
|
||||
|
||||
test "encodes and decodes URL and ignores query params for the path" do
|
||||
url = "https://pleroma.soykaf.com/static/logo.png?93939393939&bunny=true"
|
||||
encoded = url(url)
|
||||
assert String.ends_with?(encoded, "/logo.png")
|
||||
assert decode_result(encoded) == url
|
||||
end
|
||||
|
||||
test "ensures urls are url-encoded" do
|
||||
assert decode_result(url("https://pleroma.social/Hello world.jpg")) ==
|
||||
"https://pleroma.social/Hello%20world.jpg"
|
||||
|
||||
assert decode_result(url("https://pleroma.social/Hello%20world.jpg")) ==
|
||||
"https://pleroma.social/Hello%20world.jpg"
|
||||
end
|
||||
|
||||
test "validates signature" do
|
||||
secret_key_base = Mobilizon.CommonConfig.get([MobilizonWeb.Endpoint, :secret_key_base])
|
||||
|
||||
on_exit(fn ->
|
||||
Mobilizon.CommonConfig.put([MobilizonWeb.Endpoint, :secret_key_base], secret_key_base)
|
||||
end)
|
||||
|
||||
encoded = url("https://pleroma.social")
|
||||
|
||||
Mobilizon.CommonConfig.put(
|
||||
[MobilizonWeb.Endpoint, :secret_key_base],
|
||||
"00000000000000000000000000000000000000000000000"
|
||||
)
|
||||
|
||||
[_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
|
||||
assert decode_url(sig, base64) == {:error, :invalid_signature}
|
||||
end
|
||||
|
||||
test "filename_matches matches url encoded paths" do
|
||||
assert MediaProxyController.filename_matches(
|
||||
true,
|
||||
"/Hello%20world.jpg",
|
||||
"http://pleroma.social/Hello world.jpg"
|
||||
) == :ok
|
||||
|
||||
assert MediaProxyController.filename_matches(
|
||||
true,
|
||||
"/Hello%20world.jpg",
|
||||
"http://pleroma.social/Hello%20world.jpg"
|
||||
) == :ok
|
||||
end
|
||||
|
||||
test "filename_matches matches non-url encoded paths" do
|
||||
assert MediaProxyController.filename_matches(
|
||||
true,
|
||||
"/Hello world.jpg",
|
||||
"http://pleroma.social/Hello%20world.jpg"
|
||||
) == :ok
|
||||
|
||||
assert MediaProxyController.filename_matches(
|
||||
true,
|
||||
"/Hello world.jpg",
|
||||
"http://pleroma.social/Hello world.jpg"
|
||||
) == :ok
|
||||
end
|
||||
|
||||
test "uses the configured base_url" do
|
||||
base_url = Mobilizon.CommonConfig.get([:media_proxy, :base_url])
|
||||
|
||||
if base_url do
|
||||
on_exit(fn ->
|
||||
Mobilizon.CommonConfig.put([:media_proxy, :base_url], base_url)
|
||||
end)
|
||||
end
|
||||
|
||||
Mobilizon.CommonConfig.put([:media_proxy, :base_url], "https://cache.pleroma.social")
|
||||
|
||||
url = "https://pleroma.soykaf.com/static/logo.png"
|
||||
encoded = url(url)
|
||||
|
||||
assert String.starts_with?(encoded, Mobilizon.CommonConfig.get([:media_proxy, :base_url]))
|
||||
end
|
||||
|
||||
# https://git.pleroma.social/pleroma/pleroma/issues/580
|
||||
test "encoding S3 links (must preserve `%2F`)" do
|
||||
url =
|
||||
"https://s3.amazonaws.com/example/test.png?X-Amz-Credential=your-access-key-id%2F20130721%2Fus-east-1%2Fs3%2Faws4_request"
|
||||
|
||||
encoded = url(url)
|
||||
assert decode_result(encoded) == url
|
||||
end
|
||||
end
|
||||
|
||||
describe "when disabled" do
|
||||
setup do
|
||||
enabled = Mobilizon.CommonConfig.get([:media_proxy, :enabled])
|
||||
|
||||
if enabled do
|
||||
Mobilizon.CommonConfig.put([:media_proxy, :enabled], false)
|
||||
|
||||
on_exit(fn ->
|
||||
Mobilizon.CommonConfig.put([:media_proxy, :enabled], enabled)
|
||||
:ok
|
||||
end)
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
|
||||
test "does not encode remote urls" do
|
||||
assert url("https://google.fr") == "https://google.fr"
|
||||
end
|
||||
end
|
||||
|
||||
defp decode_result(encoded) do
|
||||
[_, "proxy", sig, base64 | _] = URI.parse(encoded).path |> String.split("/")
|
||||
{:ok, decoded} = decode_url(sig, base64)
|
||||
decoded
|
||||
end
|
||||
end
|
||||
44
test/mobilizon_web/plugs/uploaded_media_plug_test.exs
Normal file
44
test/mobilizon_web/plugs/uploaded_media_plug_test.exs
Normal file
@@ -0,0 +1,44 @@
|
||||
# Portions of this file are derived from Pleroma:
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/plugs/uploaded_media_plug_test.ex
|
||||
|
||||
defmodule MobilizonWeb.Plugs.UploadedMediaPlugTest do
|
||||
use MobilizonWeb.ConnCase
|
||||
alias MobilizonWeb.Upload
|
||||
|
||||
defp upload_file(context) do
|
||||
Mobilizon.DataCase.ensure_local_uploader(context)
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "nice_tf.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
[%{"href" => attachment_url} | _] = data["url"]
|
||||
[attachment_url: attachment_url]
|
||||
end
|
||||
|
||||
setup_all :upload_file
|
||||
|
||||
test "does not send Content-Disposition header when name param is not set", %{
|
||||
attachment_url: attachment_url
|
||||
} do
|
||||
conn = get(build_conn(), attachment_url)
|
||||
refute Enum.any?(conn.resp_headers, &(elem(&1, 0) == "content-disposition"))
|
||||
end
|
||||
|
||||
test "sends Content-Disposition header when name param is set", %{
|
||||
attachment_url: attachment_url
|
||||
} do
|
||||
conn = get(build_conn(), attachment_url <> "?name=\"cofe\".gif")
|
||||
|
||||
assert Enum.any?(
|
||||
conn.resp_headers,
|
||||
&(&1 == {"content-disposition", "filename=\"\\\"cofe\\\".gif\""})
|
||||
)
|
||||
end
|
||||
end
|
||||
@@ -84,6 +84,135 @@ defmodule MobilizonWeb.Resolvers.EventResolverTest do
|
||||
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
|
||||
end
|
||||
|
||||
test "create_event/3 creates an event with an attached picture", %{
|
||||
conn: conn,
|
||||
actor: actor,
|
||||
user: user
|
||||
} do
|
||||
mutation = """
|
||||
mutation {
|
||||
createEvent(
|
||||
title: "come to my event",
|
||||
description: "it will be fine",
|
||||
begins_on: "#{
|
||||
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
|
||||
}",
|
||||
organizer_actor_id: "#{actor.id}",
|
||||
category: "birthday",
|
||||
picture: {
|
||||
picture: {
|
||||
name: "picture for my event",
|
||||
alt: "A very sunny landscape",
|
||||
file: "event.jpg"
|
||||
}
|
||||
}
|
||||
) {
|
||||
title,
|
||||
uuid,
|
||||
picture {
|
||||
name,
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
map = %{
|
||||
"query" => mutation,
|
||||
"event.jpg" => %Plug.Upload{
|
||||
path: "test/fixtures/picture.png",
|
||||
filename: "event.jpg"
|
||||
}
|
||||
}
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api", map)
|
||||
|
||||
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
|
||||
|
||||
assert json_response(res, 200)["data"]["createEvent"]["picture"]["name"] ==
|
||||
"picture for my event"
|
||||
end
|
||||
|
||||
test "create_event/3 creates an event with an picture URL", %{
|
||||
conn: conn,
|
||||
actor: actor,
|
||||
user: user
|
||||
} do
|
||||
picture = %{name: "my pic", alt: "represents something", file: "picture.png"}
|
||||
|
||||
mutation = """
|
||||
mutation { uploadPicture(
|
||||
name: "#{picture.name}",
|
||||
alt: "#{picture.alt}",
|
||||
file: "#{picture.file}"
|
||||
) {
|
||||
id,
|
||||
url,
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
map = %{
|
||||
"query" => mutation,
|
||||
picture.file => %Plug.Upload{
|
||||
path: "test/fixtures/picture.png",
|
||||
filename: picture.file
|
||||
}
|
||||
}
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post(
|
||||
"/api",
|
||||
map
|
||||
)
|
||||
|
||||
assert json_response(res, 200)["data"]["uploadPicture"]["name"] == picture.name
|
||||
picture_id = json_response(res, 200)["data"]["uploadPicture"]["id"]
|
||||
|
||||
mutation = """
|
||||
mutation {
|
||||
createEvent(
|
||||
title: "come to my event",
|
||||
description: "it will be fine",
|
||||
begins_on: "#{
|
||||
DateTime.utc_now() |> DateTime.truncate(:second) |> DateTime.to_iso8601()
|
||||
}",
|
||||
organizer_actor_id: "#{actor.id}",
|
||||
category: "birthday",
|
||||
picture: {
|
||||
picture_id: "#{picture_id}"
|
||||
}
|
||||
) {
|
||||
title,
|
||||
uuid,
|
||||
picture {
|
||||
name,
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> post("/api", AbsintheHelpers.mutation_skeleton(mutation))
|
||||
|
||||
assert json_response(res, 200)["data"]["createEvent"]["title"] == "come to my event"
|
||||
|
||||
assert json_response(res, 200)["data"]["createEvent"]["picture"]["name"] == picture.name
|
||||
|
||||
assert json_response(res, 200)["data"]["createEvent"]["picture"]["url"]
|
||||
end
|
||||
|
||||
test "list_events/3 returns events", context do
|
||||
event = insert(:event)
|
||||
|
||||
|
||||
@@ -50,7 +50,9 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do
|
||||
query = """
|
||||
{
|
||||
loggedPerson {
|
||||
avatarUrl,
|
||||
avatar {
|
||||
url
|
||||
},
|
||||
preferredUsername,
|
||||
}
|
||||
}
|
||||
@@ -72,6 +74,9 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do
|
||||
|
||||
assert json_response(res, 200)["data"]["loggedPerson"]["preferredUsername"] ==
|
||||
actor.preferred_username
|
||||
|
||||
assert json_response(res, 200)["data"]["loggedPerson"]["avatar"]["url"] =~
|
||||
MobilizonWeb.Endpoint.url()
|
||||
end
|
||||
|
||||
test "create_person/3 creates a new identity", context do
|
||||
@@ -111,7 +116,9 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do
|
||||
query = """
|
||||
{
|
||||
identities {
|
||||
avatarUrl,
|
||||
avatar {
|
||||
url
|
||||
},
|
||||
preferredUsername,
|
||||
}
|
||||
}
|
||||
@@ -136,87 +143,156 @@ defmodule MobilizonWeb.Resolvers.PersonResolverTest do
|
||||
|> MapSet.new() ==
|
||||
MapSet.new([actor.preferred_username, "new_identity"])
|
||||
end
|
||||
end
|
||||
|
||||
test "get_current_person/3 can return the events the person is going to", context do
|
||||
user = insert(:user)
|
||||
actor = insert(:actor, user: user)
|
||||
test "create_person/3 with an avatar and an banner creates a new identity", context do
|
||||
user = insert(:user)
|
||||
insert(:actor, user: user)
|
||||
|
||||
query = """
|
||||
{
|
||||
loggedPerson {
|
||||
goingToEvents {
|
||||
uuid,
|
||||
title
|
||||
mutation = """
|
||||
mutation {
|
||||
createPerson(
|
||||
preferredUsername: "new_identity",
|
||||
name: "secret person",
|
||||
summary: "no-one will know who I am",
|
||||
banner: {
|
||||
picture: {
|
||||
file: "landscape.jpg",
|
||||
name: "irish landscape",
|
||||
alt: "The beautiful atlantic way"
|
||||
}
|
||||
}
|
||||
) {
|
||||
id,
|
||||
preferredUsername
|
||||
avatar {
|
||||
id,
|
||||
url
|
||||
},
|
||||
banner {
|
||||
id,
|
||||
name,
|
||||
url
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
map = %{
|
||||
"query" => mutation,
|
||||
"landscape.jpg" => %Plug.Upload{
|
||||
path: "test/fixtures/picture.png",
|
||||
filename: "landscape.jpg"
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
|
||||
res =
|
||||
context.conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api", map)
|
||||
|
||||
assert json_response(res, 200)["data"]["loggedPerson"]["goingToEvents"] == []
|
||||
assert json_response(res, 200)["data"]["createPerson"] == nil
|
||||
|
||||
event = insert(:event, %{organizer_actor: actor})
|
||||
insert(:participant, %{actor: actor, event: event})
|
||||
assert hd(json_response(res, 200)["errors"])["message"] ==
|
||||
"You need to be logged-in to create a new identity"
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post("/api", map)
|
||||
|
||||
assert json_response(res, 200)["data"]["loggedPerson"]["goingToEvents"] == [
|
||||
%{"title" => event.title, "uuid" => event.uuid}
|
||||
]
|
||||
end
|
||||
assert json_response(res, 200)["data"]["createPerson"]["preferredUsername"] ==
|
||||
"new_identity"
|
||||
|
||||
test "find_person/3 can return the events an identity is going to if it's the same actor",
|
||||
context do
|
||||
user = insert(:user)
|
||||
actor = insert(:actor, user: user)
|
||||
insert(:actor, user: user)
|
||||
actor_from_other_user = insert(:actor)
|
||||
assert json_response(res, 200)["data"]["createPerson"]["banner"]["id"]
|
||||
|
||||
query = """
|
||||
{
|
||||
person(preferredUsername: "#{actor.preferred_username}") {
|
||||
goingToEvents {
|
||||
uuid,
|
||||
title
|
||||
assert json_response(res, 200)["data"]["createPerson"]["banner"]["name"] ==
|
||||
"The beautiful atlantic way"
|
||||
|
||||
assert json_response(res, 200)["data"]["createPerson"]["banner"]["url"] =~
|
||||
MobilizonWeb.Endpoint.url() <> "/media/"
|
||||
end
|
||||
|
||||
test "get_current_person/3 can return the events the person is going to", context do
|
||||
user = insert(:user)
|
||||
actor = insert(:actor, user: user)
|
||||
|
||||
query = """
|
||||
{
|
||||
loggedPerson {
|
||||
goingToEvents {
|
||||
uuid,
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
|
||||
|
||||
assert json_response(res, 200)["data"]["loggedPerson"]["goingToEvents"] == []
|
||||
|
||||
event = insert(:event, %{organizer_actor: actor})
|
||||
insert(:participant, %{actor: actor, event: event})
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "logged_person"))
|
||||
|
||||
assert json_response(res, 200)["data"]["loggedPerson"]["goingToEvents"] == [
|
||||
%{"title" => event.title, "uuid" => event.uuid}
|
||||
]
|
||||
end
|
||||
|
||||
test "find_person/3 can return the events an identity is going to if it's the same actor",
|
||||
context do
|
||||
user = insert(:user)
|
||||
actor = insert(:actor, user: user)
|
||||
insert(:actor, user: user)
|
||||
actor_from_other_user = insert(:actor)
|
||||
|
||||
query = """
|
||||
{
|
||||
person(preferredUsername: "#{actor.preferred_username}") {
|
||||
goingToEvents {
|
||||
uuid,
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
"""
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
|
||||
|
||||
assert json_response(res, 200)["data"]["person"]["goingToEvents"] == []
|
||||
assert json_response(res, 200)["data"]["person"]["goingToEvents"] == []
|
||||
|
||||
query = """
|
||||
{
|
||||
person(preferredUsername: "#{actor_from_other_user.preferred_username}") {
|
||||
goingToEvents {
|
||||
uuid,
|
||||
title
|
||||
}
|
||||
query = """
|
||||
{
|
||||
person(preferredUsername: "#{actor_from_other_user.preferred_username}") {
|
||||
goingToEvents {
|
||||
uuid,
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
"""
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
|
||||
res =
|
||||
context.conn
|
||||
|> auth_conn(user)
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "person"))
|
||||
|
||||
assert json_response(res, 200)["data"]["person"]["goingToEvents"] == nil
|
||||
assert json_response(res, 200)["data"]["person"]["goingToEvents"] == nil
|
||||
|
||||
assert hd(json_response(res, 200)["errors"])["message"] ==
|
||||
"Actor id is not owned by authenticated user"
|
||||
assert hd(json_response(res, 200)["errors"])["message"] ==
|
||||
"Actor id is not owned by authenticated user"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
130
test/mobilizon_web/resolvers/picture_resolver_test.exs
Normal file
130
test/mobilizon_web/resolvers/picture_resolver_test.exs
Normal file
@@ -0,0 +1,130 @@
|
||||
defmodule MobilizonWeb.Resolvers.PictureResolverTest do
|
||||
alias MobilizonWeb.AbsintheHelpers
|
||||
use MobilizonWeb.ConnCase
|
||||
use Bamboo.Test
|
||||
alias Mobilizon.Media.Picture
|
||||
import Mobilizon.Factory
|
||||
|
||||
setup %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, conn: conn, user: user}
|
||||
end
|
||||
|
||||
describe "Resolver: Get picture" do
|
||||
test "picture/3 returns the information on a picture", context do
|
||||
%Picture{id: id} = picture = insert(:picture)
|
||||
|
||||
query = """
|
||||
{
|
||||
picture(id: "#{id}") {
|
||||
name,
|
||||
alt,
|
||||
url
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "picture"))
|
||||
|
||||
assert json_response(res, 200)["data"]["picture"]["name"] == picture.file.name
|
||||
|
||||
assert json_response(res, 200)["data"]["picture"]["url"] =~
|
||||
MobilizonWeb.Endpoint.url()
|
||||
end
|
||||
|
||||
test "picture/3 returns nothing on a non-existent picture", context do
|
||||
query = """
|
||||
{
|
||||
picture(id: "3") {
|
||||
name,
|
||||
alt,
|
||||
url
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
res =
|
||||
context.conn
|
||||
|> get("/api", AbsintheHelpers.query_skeleton(query, "picture"))
|
||||
|
||||
assert hd(json_response(res, 200)["errors"])["message"] ==
|
||||
"Picture with ID 3 was not found"
|
||||
end
|
||||
end
|
||||
|
||||
describe "Resolver: Upload picture" do
|
||||
test "upload_picture/3 uploads a new picture", %{conn: conn, user: user} do
|
||||
picture = %{name: "my pic", alt: "represents something", file: "picture.png"}
|
||||
|
||||
mutation = """
|
||||
mutation { uploadPicture(
|
||||
name: "#{picture.name}",
|
||||
alt: "#{picture.alt}",
|
||||
file: "#{picture.file}"
|
||||
) {
|
||||
url,
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
map = %{
|
||||
"query" => mutation,
|
||||
picture.file => %Plug.Upload{
|
||||
path: "test/fixtures/picture.png",
|
||||
filename: picture.file
|
||||
}
|
||||
}
|
||||
|
||||
res =
|
||||
conn
|
||||
|> auth_conn(user)
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post(
|
||||
"/api",
|
||||
map
|
||||
)
|
||||
|
||||
assert json_response(res, 200)["data"]["uploadPicture"]["name"] == picture.name
|
||||
assert json_response(res, 200)["data"]["uploadPicture"]["url"]
|
||||
end
|
||||
|
||||
test "upload_picture/3 forbids uploading if no auth", %{conn: conn} do
|
||||
picture = %{name: "my pic", alt: "represents something", file: "picture.png"}
|
||||
|
||||
mutation = """
|
||||
mutation { uploadPicture(
|
||||
name: "#{picture.name}",
|
||||
alt: "#{picture.alt}",
|
||||
file: "#{picture.file}"
|
||||
) {
|
||||
url,
|
||||
name
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
map = %{
|
||||
"query" => mutation,
|
||||
picture.file => %Plug.Upload{
|
||||
path: "test/fixtures/picture.png",
|
||||
filename: picture.file
|
||||
}
|
||||
}
|
||||
|
||||
res =
|
||||
conn
|
||||
|> put_req_header("content-type", "multipart/form-data")
|
||||
|> post(
|
||||
"/api",
|
||||
map
|
||||
)
|
||||
|
||||
assert hd(json_response(res, 200)["errors"])["message"] ==
|
||||
"You need to login to upload a picture"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -255,7 +255,9 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||
preferredUsername,
|
||||
name,
|
||||
summary,
|
||||
avatarUrl,
|
||||
avatar {
|
||||
url
|
||||
},
|
||||
}
|
||||
}
|
||||
"""
|
||||
@@ -295,7 +297,9 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||
preferredUsername,
|
||||
name,
|
||||
summary,
|
||||
avatarUrl,
|
||||
avatar {
|
||||
url
|
||||
},
|
||||
}
|
||||
}
|
||||
"""
|
||||
@@ -334,7 +338,9 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||
preferredUsername,
|
||||
name,
|
||||
summary,
|
||||
avatarUrl,
|
||||
avatar {
|
||||
url
|
||||
},
|
||||
}
|
||||
}
|
||||
"""
|
||||
@@ -357,7 +363,9 @@ defmodule MobilizonWeb.Resolvers.UserResolverTest do
|
||||
preferredUsername,
|
||||
name,
|
||||
summary,
|
||||
avatarUrl,
|
||||
avatar {
|
||||
url
|
||||
},
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
173
test/mobilizon_web/upload_test.exs
Normal file
173
test/mobilizon_web/upload_test.exs
Normal file
@@ -0,0 +1,173 @@
|
||||
# Portions of this file are derived from Pleroma:
|
||||
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
# Upstream: https://git.pleroma.social/pleroma/pleroma/blob/develop/test/upload_test.ex
|
||||
|
||||
defmodule Mobilizon.UploadTest do
|
||||
alias MobilizonWeb.Upload
|
||||
use Mobilizon.DataCase
|
||||
|
||||
describe "Storing a file with the Local uploader" do
|
||||
setup [:ensure_local_uploader]
|
||||
|
||||
test "returns a media url" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
|
||||
assert %{"url" => [%{"href" => url}]} = data
|
||||
|
||||
assert String.starts_with?(url, MobilizonWeb.Endpoint.url() <> "/media/")
|
||||
end
|
||||
|
||||
test "returns a media url with configured base_url" do
|
||||
base_url = "https://cache.mobilizon.social"
|
||||
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file, base_url: base_url)
|
||||
|
||||
assert %{"url" => [%{"href" => url}]} = data
|
||||
|
||||
assert String.starts_with?(url, base_url <> "/media/")
|
||||
end
|
||||
|
||||
test "copies the file to the configured folder with deduping" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an [image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file, filters: [MobilizonWeb.Upload.Filter.Dedupe])
|
||||
|
||||
assert List.first(data["url"])["href"] ==
|
||||
MobilizonWeb.Endpoint.url() <>
|
||||
"/media/590523d60d3831ec92d05cdd871078409d5780903910efec5cd35ab1b0f19d11.jpg"
|
||||
end
|
||||
|
||||
test "copies the file to the configured folder without deduping" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an [image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
assert data["name"] == "an [image.jpg"
|
||||
end
|
||||
|
||||
test "fixes incorrect content type" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "application/octet-stream",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an [image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file, filters: [MobilizonWeb.Upload.Filter.Dedupe])
|
||||
assert hd(data["url"])["mediaType"] == "image/jpeg"
|
||||
end
|
||||
|
||||
test "adds missing extension" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an [image"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
assert data["name"] == "an [image.jpg"
|
||||
end
|
||||
|
||||
test "fixes incorrect file extension" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an [image.blah"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
assert data["name"] == "an [image.jpg"
|
||||
end
|
||||
|
||||
test "don't modify filename of an unknown type" do
|
||||
File.cp("test/fixtures/test.txt", "test/fixtures/test_tmp.txt")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "text/plain",
|
||||
path: Path.absname("test/fixtures/test_tmp.txt"),
|
||||
filename: "test.txt"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
assert data["name"] == "test.txt"
|
||||
end
|
||||
|
||||
test "copies the file to the configured folder with anonymizing filename" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an [image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file, filters: [MobilizonWeb.Upload.Filter.AnonymizeFilename])
|
||||
|
||||
refute data["name"] == "an [image.jpg"
|
||||
end
|
||||
|
||||
test "escapes invalid characters in url" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an… image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
[attachment_url | _] = data["url"]
|
||||
|
||||
assert Path.basename(attachment_url["href"]) == "an%E2%80%A6%20image.jpg"
|
||||
end
|
||||
|
||||
test "escapes reserved uri characters" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: ":?#[]@!$&\\'()*+,;=.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
[attachment_url | _] = data["url"]
|
||||
|
||||
assert Path.basename(attachment_url["href"]) ==
|
||||
"%3A%3F%23%5B%5D%40%21%24%26%5C%27%28%29%2A%2B%2C%3B%3D.jpg"
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -50,4 +50,21 @@ defmodule Mobilizon.DataCase do
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
def ensure_local_uploader(_context) do
|
||||
uploader = Mobilizon.CommonConfig.get([MobilizonWeb.Upload, :uploader])
|
||||
filters = Mobilizon.CommonConfig.get([MobilizonWeb.Upload, :filters])
|
||||
|
||||
unless uploader == MobilizonWeb.Uploaders.Local || filters != [] do
|
||||
Mobilizon.CommonConfig.put([MobilizonWeb.Upload, :uploader], MobilizonWeb.Uploaders.Local)
|
||||
Mobilizon.CommonConfig.put([MobilizonWeb.Upload, :filters], [])
|
||||
|
||||
on_exit(fn ->
|
||||
Mobilizon.CommonConfig.put([MobilizonWeb.Upload, :uploader], uploader)
|
||||
Mobilizon.CommonConfig.put([MobilizonWeb.Upload, :filters], filters)
|
||||
end)
|
||||
end
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
@@ -33,6 +33,8 @@ defmodule Mobilizon.Factory do
|
||||
followings: [],
|
||||
keys: pem,
|
||||
type: :Person,
|
||||
avatar: build(:file, name: "Avatar"),
|
||||
banner: build(:file, name: "Banner"),
|
||||
url: Actor.build_url(preferred_username, :page),
|
||||
followers_url: Actor.build_url(preferred_username, :followers),
|
||||
following_url: Actor.build_url(preferred_username, :following),
|
||||
@@ -167,4 +169,18 @@ defmodule Mobilizon.Factory do
|
||||
token: Ecto.UUID.generate()
|
||||
}
|
||||
end
|
||||
|
||||
def file_factory do
|
||||
%Mobilizon.Media.File{
|
||||
name: "My Picture",
|
||||
url: MobilizonWeb.Endpoint.url() <> "/uploads/something",
|
||||
content_type: "image/png"
|
||||
}
|
||||
end
|
||||
|
||||
def picture_factory do
|
||||
%Mobilizon.Media.Picture{
|
||||
file: build(:file)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user