You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

410 lines
10 KiB

  1. require 'rails_helper'
  2. RSpec.describe ActivityPub::Activity::Create do
  3. let(:sender) { Fabricate(:account, followers_url: 'http://example.com/followers') }
  4. let(:json) do
  5. {
  6. '@context': 'https://www.w3.org/ns/activitystreams',
  7. id: [ActivityPub::TagManager.instance.uri_for(sender), '#foo'].join,
  8. type: 'Create',
  9. actor: ActivityPub::TagManager.instance.uri_for(sender),
  10. object: object_json,
  11. }.with_indifferent_access
  12. end
  13. subject { described_class.new(json, sender) }
  14. before do
  15. sender.update(uri: ActivityPub::TagManager.instance.uri_for(sender))
  16. stub_request(:get, 'http://example.com/attachment.png').to_return(request_fixture('avatar.txt'))
  17. stub_request(:get, 'http://example.com/emoji.png').to_return(body: attachment_fixture('emojo.png'))
  18. end
  19. describe '#perform' do
  20. before do
  21. subject.perform
  22. end
  23. context 'standalone' do
  24. let(:object_json) do
  25. {
  26. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  27. type: 'Note',
  28. content: 'Lorem ipsum',
  29. }
  30. end
  31. it 'creates status' do
  32. status = sender.statuses.first
  33. expect(status).to_not be_nil
  34. expect(status.text).to eq 'Lorem ipsum'
  35. end
  36. it 'missing to/cc defaults to direct privacy' do
  37. status = sender.statuses.first
  38. expect(status).to_not be_nil
  39. expect(status.visibility).to eq 'direct'
  40. end
  41. end
  42. context 'public' do
  43. let(:object_json) do
  44. {
  45. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  46. type: 'Note',
  47. content: 'Lorem ipsum',
  48. to: 'https://www.w3.org/ns/activitystreams#Public',
  49. }
  50. end
  51. it 'creates status' do
  52. status = sender.statuses.first
  53. expect(status).to_not be_nil
  54. expect(status.visibility).to eq 'public'
  55. end
  56. end
  57. context 'unlisted' do
  58. let(:object_json) do
  59. {
  60. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  61. type: 'Note',
  62. content: 'Lorem ipsum',
  63. cc: 'https://www.w3.org/ns/activitystreams#Public',
  64. }
  65. end
  66. it 'creates status' do
  67. status = sender.statuses.first
  68. expect(status).to_not be_nil
  69. expect(status.visibility).to eq 'unlisted'
  70. end
  71. end
  72. context 'private' do
  73. let(:object_json) do
  74. {
  75. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  76. type: 'Note',
  77. content: 'Lorem ipsum',
  78. to: 'http://example.com/followers',
  79. }
  80. end
  81. it 'creates status' do
  82. status = sender.statuses.first
  83. expect(status).to_not be_nil
  84. expect(status.visibility).to eq 'private'
  85. end
  86. end
  87. context 'limited' do
  88. let(:recipient) { Fabricate(:account) }
  89. let(:object_json) do
  90. {
  91. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  92. type: 'Note',
  93. content: 'Lorem ipsum',
  94. to: ActivityPub::TagManager.instance.uri_for(recipient),
  95. }
  96. end
  97. it 'creates status' do
  98. status = sender.statuses.first
  99. expect(status).to_not be_nil
  100. expect(status.visibility).to eq 'limited'
  101. end
  102. it 'creates silent mention' do
  103. status = sender.statuses.first
  104. expect(status.mentions.first).to be_silent
  105. end
  106. end
  107. context 'direct' do
  108. let(:recipient) { Fabricate(:account) }
  109. let(:object_json) do
  110. {
  111. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  112. type: 'Note',
  113. content: 'Lorem ipsum',
  114. to: ActivityPub::TagManager.instance.uri_for(recipient),
  115. tag: {
  116. type: 'Mention',
  117. href: ActivityPub::TagManager.instance.uri_for(recipient),
  118. },
  119. }
  120. end
  121. it 'creates status' do
  122. status = sender.statuses.first
  123. expect(status).to_not be_nil
  124. expect(status.visibility).to eq 'direct'
  125. end
  126. end
  127. context 'as a reply' do
  128. let(:original_status) { Fabricate(:status) }
  129. let(:object_json) do
  130. {
  131. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  132. type: 'Note',
  133. content: 'Lorem ipsum',
  134. inReplyTo: ActivityPub::TagManager.instance.uri_for(original_status),
  135. }
  136. end
  137. it 'creates status' do
  138. status = sender.statuses.first
  139. expect(status).to_not be_nil
  140. expect(status.thread).to eq original_status
  141. expect(status.reply?).to be true
  142. expect(status.in_reply_to_account).to eq original_status.account
  143. expect(status.conversation).to eq original_status.conversation
  144. end
  145. end
  146. context 'with mentions' do
  147. let(:recipient) { Fabricate(:account) }
  148. let(:object_json) do
  149. {
  150. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  151. type: 'Note',
  152. content: 'Lorem ipsum',
  153. tag: [
  154. {
  155. type: 'Mention',
  156. href: ActivityPub::TagManager.instance.uri_for(recipient),
  157. },
  158. ],
  159. }
  160. end
  161. it 'creates status' do
  162. status = sender.statuses.first
  163. expect(status).to_not be_nil
  164. expect(status.mentions.map(&:account)).to include(recipient)
  165. end
  166. end
  167. context 'with mentions missing href' do
  168. let(:object_json) do
  169. {
  170. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  171. type: 'Note',
  172. content: 'Lorem ipsum',
  173. tag: [
  174. {
  175. type: 'Mention',
  176. },
  177. ],
  178. }
  179. end
  180. it 'creates status' do
  181. status = sender.statuses.first
  182. expect(status).to_not be_nil
  183. end
  184. end
  185. context 'with media attachments' do
  186. let(:object_json) do
  187. {
  188. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  189. type: 'Note',
  190. content: 'Lorem ipsum',
  191. attachment: [
  192. {
  193. type: 'Document',
  194. mediaType: 'image/png',
  195. url: 'http://example.com/attachment.png',
  196. },
  197. ],
  198. }
  199. end
  200. it 'creates status' do
  201. status = sender.statuses.first
  202. expect(status).to_not be_nil
  203. expect(status.media_attachments.map(&:remote_url)).to include('http://example.com/attachment.png')
  204. end
  205. end
  206. context 'with media attachments with focal points' do
  207. let(:object_json) do
  208. {
  209. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  210. type: 'Note',
  211. content: 'Lorem ipsum',
  212. attachment: [
  213. {
  214. type: 'Document',
  215. mediaType: 'image/png',
  216. url: 'http://example.com/attachment.png',
  217. focalPoint: [0.5, -0.7],
  218. },
  219. ],
  220. }
  221. end
  222. it 'creates status' do
  223. status = sender.statuses.first
  224. expect(status).to_not be_nil
  225. expect(status.media_attachments.map(&:focus)).to include('0.5,-0.7')
  226. end
  227. end
  228. context 'with media attachments missing url' do
  229. let(:object_json) do
  230. {
  231. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  232. type: 'Note',
  233. content: 'Lorem ipsum',
  234. attachment: [
  235. {
  236. type: 'Document',
  237. mediaType: 'image/png',
  238. },
  239. ],
  240. }
  241. end
  242. it 'creates status' do
  243. status = sender.statuses.first
  244. expect(status).to_not be_nil
  245. end
  246. end
  247. context 'with hashtags' do
  248. let(:object_json) do
  249. {
  250. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  251. type: 'Note',
  252. content: 'Lorem ipsum',
  253. tag: [
  254. {
  255. type: 'Hashtag',
  256. href: 'http://example.com/blah',
  257. name: '#test',
  258. },
  259. ],
  260. }
  261. end
  262. it 'creates status' do
  263. status = sender.statuses.first
  264. expect(status).to_not be_nil
  265. expect(status.tags.map(&:name)).to include('test')
  266. end
  267. end
  268. context 'with hashtags missing name' do
  269. let(:object_json) do
  270. {
  271. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  272. type: 'Note',
  273. content: 'Lorem ipsum',
  274. tag: [
  275. {
  276. type: 'Hashtag',
  277. href: 'http://example.com/blah',
  278. },
  279. ],
  280. }
  281. end
  282. it 'creates status' do
  283. status = sender.statuses.first
  284. expect(status).to_not be_nil
  285. end
  286. end
  287. context 'with emojis' do
  288. let(:object_json) do
  289. {
  290. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  291. type: 'Note',
  292. content: 'Lorem ipsum :tinking:',
  293. tag: [
  294. {
  295. type: 'Emoji',
  296. icon: {
  297. url: 'http://example.com/emoji.png',
  298. },
  299. name: 'tinking',
  300. },
  301. ],
  302. }
  303. end
  304. it 'creates status' do
  305. status = sender.statuses.first
  306. expect(status).to_not be_nil
  307. expect(status.emojis.map(&:shortcode)).to include('tinking')
  308. end
  309. end
  310. context 'with emojis missing name' do
  311. let(:object_json) do
  312. {
  313. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  314. type: 'Note',
  315. content: 'Lorem ipsum :tinking:',
  316. tag: [
  317. {
  318. type: 'Emoji',
  319. icon: {
  320. url: 'http://example.com/emoji.png',
  321. },
  322. },
  323. ],
  324. }
  325. end
  326. it 'creates status' do
  327. status = sender.statuses.first
  328. expect(status).to_not be_nil
  329. end
  330. end
  331. context 'with emojis missing icon' do
  332. let(:object_json) do
  333. {
  334. id: [ActivityPub::TagManager.instance.uri_for(sender), '#bar'].join,
  335. type: 'Note',
  336. content: 'Lorem ipsum :tinking:',
  337. tag: [
  338. {
  339. type: 'Emoji',
  340. name: 'tinking',
  341. },
  342. ],
  343. }
  344. end
  345. it 'creates status' do
  346. status = sender.statuses.first
  347. expect(status).to_not be_nil
  348. end
  349. end
  350. end
  351. end