logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://anongit.hacktivis.me/git/pleroma.git/

factory.ex (20322B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright ยฉ 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Factory do
  5. use ExMachina.Ecto, repo: Pleroma.Repo
  6. require Pleroma.Constants
  7. alias Pleroma.Object
  8. alias Pleroma.User
  9. @rsa_keys [
  10. "test/fixtures/rsa_keys/key_1.pem",
  11. "test/fixtures/rsa_keys/key_2.pem",
  12. "test/fixtures/rsa_keys/key_3.pem",
  13. "test/fixtures/rsa_keys/key_4.pem",
  14. "test/fixtures/rsa_keys/key_5.pem"
  15. ]
  16. |> Enum.map(&File.read!/1)
  17. def participation_factory do
  18. conversation = insert(:conversation)
  19. user = insert(:user)
  20. %Pleroma.Conversation.Participation{
  21. conversation: conversation,
  22. user: user,
  23. read: false
  24. }
  25. end
  26. def conversation_factory do
  27. %Pleroma.Conversation{
  28. ap_id: sequence(:ap_id, &"https://some_conversation/#{&1}")
  29. }
  30. end
  31. def user_factory(attrs \\ %{}) do
  32. pem = Enum.random(@rsa_keys)
  33. user = %User{
  34. name: sequence(:name, &"Test ใƒ†ใ‚นใƒˆ User #{&1}"),
  35. email: sequence(:email, &"user#{&1}@example.com"),
  36. nickname: sequence(:nickname, &"nick#{&1}"),
  37. password_hash: Pleroma.Password.Pbkdf2.hash_pwd_salt("test"),
  38. bio: sequence(:bio, &"Tester Number #{&1}"),
  39. is_discoverable: true,
  40. last_digest_emailed_at: NaiveDateTime.utc_now(),
  41. last_refreshed_at: NaiveDateTime.utc_now(),
  42. notification_settings: %Pleroma.User.NotificationSetting{},
  43. multi_factor_authentication_settings: %Pleroma.MFA.Settings{},
  44. keys: pem
  45. }
  46. user
  47. |> Map.put(:raw_bio, user.bio)
  48. |> merge_attributes(Map.delete(attrs, :domain))
  49. |> make_user_urls(attrs)
  50. end
  51. defp make_user_urls(user, attrs) do
  52. urls =
  53. if attrs[:local] == false do
  54. base_domain = attrs[:domain] || Enum.random(["domain1.com", "domain2.com", "domain3.com"])
  55. ap_id = "https://#{base_domain}/users/#{user.nickname}"
  56. %{
  57. ap_id: attrs[:ap_id] || ap_id,
  58. follower_address: attrs[:follower_address] || ap_id <> "/followers",
  59. following_address: attrs[:following_address] || ap_id <> "/following",
  60. featured_address: attrs[:featured_address] || ap_id <> "/collections/featured",
  61. inbox: attrs[:inbox] || "https://#{base_domain}/inbox"
  62. }
  63. else
  64. %{
  65. ap_id: attrs[:ap_id] || User.ap_id(user),
  66. follower_address: attrs[:follower_address] || User.ap_followers(user),
  67. following_address: attrs[:following_address] || User.ap_following(user),
  68. featured_address: attrs[:featured_address] || User.ap_featured_collection(user)
  69. }
  70. end
  71. Map.merge(user, urls)
  72. end
  73. def user_relationship_factory(attrs \\ %{}) do
  74. source = attrs[:source] || insert(:user)
  75. target = attrs[:target] || insert(:user)
  76. relationship_type = attrs[:relationship_type] || :block
  77. %Pleroma.UserRelationship{
  78. source_id: source.id,
  79. target_id: target.id,
  80. relationship_type: relationship_type
  81. }
  82. end
  83. def note_factory(attrs \\ %{}) do
  84. text = sequence(:text, &"This is :moominmamma: note #{&1}")
  85. user = attrs[:user] || insert(:user)
  86. object_id =
  87. if attrs[:object_local] == false do
  88. # Must not match our Endpoint URL in the test env
  89. "https://example.com/objects/#{Ecto.UUID.generate()}"
  90. else
  91. Pleroma.Web.ActivityPub.Utils.generate_object_id()
  92. end
  93. data = %{
  94. "type" => "Note",
  95. "content" => text,
  96. "source" => text,
  97. "id" => object_id,
  98. "actor" => user.ap_id,
  99. "to" => ["https://www.w3.org/ns/activitystreams#Public"],
  100. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  101. "likes" => [],
  102. "like_count" => 0,
  103. "context" => "2hu",
  104. "summary" => "2hu",
  105. "tag" => ["2hu"],
  106. "emoji" => %{
  107. "2hu" => "corndog.png"
  108. }
  109. }
  110. %Pleroma.Object{
  111. data: merge_attributes(data, Map.get(attrs, :data, %{}))
  112. }
  113. end
  114. def attachment_factory(attrs \\ %{}) do
  115. user = attrs[:user] || insert(:user)
  116. data =
  117. attachment_data(user.ap_id, nil)
  118. |> Map.put("id", Pleroma.Web.ActivityPub.Utils.generate_object_id())
  119. %Pleroma.Object{
  120. data: merge_attributes(data, Map.get(attrs, :data, %{}))
  121. }
  122. end
  123. def attachment_note_factory(attrs \\ %{}) do
  124. user = attrs[:user] || insert(:user)
  125. {length, attrs} = Map.pop(attrs, :length, 1)
  126. data = %{
  127. "attachment" =>
  128. Stream.repeatedly(fn -> attachment_data(user.ap_id, attrs[:href]) end)
  129. |> Enum.take(length)
  130. }
  131. build(:note, Map.put(attrs, :data, data))
  132. end
  133. defp attachment_data(ap_id, href) do
  134. href = href || sequence(:href, &"#{Pleroma.Web.Endpoint.url()}/media/#{&1}.jpg")
  135. %{
  136. "url" => [
  137. %{
  138. "href" => href,
  139. "type" => "Link",
  140. "mediaType" => "image/jpeg"
  141. }
  142. ],
  143. "name" => "some name",
  144. "type" => "Document",
  145. "actor" => ap_id,
  146. "mediaType" => "image/jpeg"
  147. }
  148. end
  149. def followers_only_note_factory(attrs \\ %{}) do
  150. %Pleroma.Object{data: data} = note_factory(attrs)
  151. %Pleroma.Object{data: Map.merge(data, %{"to" => [data["actor"] <> "/followers"]})}
  152. end
  153. def audio_factory(attrs \\ %{}) do
  154. text = sequence(:text, &"lain radio episode #{&1}")
  155. user = attrs[:user] || insert(:user)
  156. data = %{
  157. "type" => "Audio",
  158. "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
  159. "artist" => "lain",
  160. "title" => text,
  161. "album" => "lain radio",
  162. "to" => ["https://www.w3.org/ns/activitystreams#Public"],
  163. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  164. "actor" => user.ap_id,
  165. "length" => 180_000
  166. }
  167. %Pleroma.Object{
  168. data: merge_attributes(data, Map.get(attrs, :data, %{}))
  169. }
  170. end
  171. def listen_factory do
  172. audio = insert(:audio)
  173. data = %{
  174. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  175. "type" => "Listen",
  176. "actor" => audio.data["actor"],
  177. "to" => audio.data["to"],
  178. "object" => audio.data,
  179. "published" => audio.data["published"]
  180. }
  181. %Pleroma.Activity{
  182. data: data,
  183. actor: data["actor"],
  184. recipients: data["to"]
  185. }
  186. end
  187. def direct_note_factory do
  188. user2 = insert(:user, local: false, inbox: "http://example.com/inbox")
  189. %Pleroma.Object{data: data} = note_factory()
  190. %Pleroma.Object{data: Map.merge(data, %{"to" => [user2.ap_id]})}
  191. end
  192. def article_factory do
  193. %Pleroma.Object{data: data} = note_factory()
  194. %Pleroma.Object{data: Map.merge(data, %{"type" => "Article"})}
  195. end
  196. def tombstone_factory do
  197. data = %{
  198. "type" => "Tombstone",
  199. "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
  200. "formerType" => "Note",
  201. "deleted" => DateTime.utc_now() |> DateTime.to_iso8601()
  202. }
  203. %Pleroma.Object{
  204. data: data
  205. }
  206. end
  207. def question_factory(attrs \\ %{}) do
  208. user = attrs[:user] || insert(:user)
  209. closed = attrs[:closed] || DateTime.utc_now() |> DateTime.add(86_400) |> DateTime.to_iso8601()
  210. data = %{
  211. "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id(),
  212. "type" => "Question",
  213. "actor" => user.ap_id,
  214. "attributedTo" => user.ap_id,
  215. "attachment" => [],
  216. "to" => ["https://www.w3.org/ns/activitystreams#Public"],
  217. "cc" => [user.follower_address],
  218. "context" => Pleroma.Web.ActivityPub.Utils.generate_context_id(),
  219. "closed" => closed,
  220. "content" => "Which flavor of ice cream do you prefer?",
  221. "oneOf" => [
  222. %{
  223. "type" => "Note",
  224. "name" => "chocolate",
  225. "replies" => %{"totalItems" => 0, "type" => "Collection"}
  226. },
  227. %{
  228. "type" => "Note",
  229. "name" => "vanilla",
  230. "replies" => %{"totalItems" => 0, "type" => "Collection"}
  231. }
  232. ]
  233. }
  234. %Pleroma.Object{
  235. data: merge_attributes(data, Map.get(attrs, :data, %{}))
  236. }
  237. end
  238. def direct_note_activity_factory do
  239. dm = insert(:direct_note)
  240. data = %{
  241. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  242. "type" => "Create",
  243. "actor" => dm.data["actor"],
  244. "to" => dm.data["to"],
  245. "object" => dm.data,
  246. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  247. "context" => dm.data["context"]
  248. }
  249. %Pleroma.Activity{
  250. data: data,
  251. actor: data["actor"],
  252. recipients: data["to"]
  253. }
  254. end
  255. def add_activity_factory(attrs \\ %{}) do
  256. featured_collection_activity(attrs, "Add")
  257. end
  258. def remove_activity_factory(attrs \\ %{}) do
  259. featured_collection_activity(attrs, "Remove")
  260. end
  261. defp featured_collection_activity(attrs, type) do
  262. user = attrs[:user] || insert(:user)
  263. note_activity = attrs[:note_activity] || insert(:note_activity, user: user)
  264. data_attrs =
  265. attrs
  266. |> Map.get(:data_attrs, %{})
  267. |> Map.put(:type, type)
  268. attrs = Map.drop(attrs, [:user, :note_activity, :data_attrs])
  269. data =
  270. %{
  271. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  272. "target" => user.featured_address,
  273. "object" => note_activity.data["object"],
  274. "actor" => note_activity.data["actor"],
  275. "type" => "Add",
  276. "to" => [Pleroma.Constants.as_public()],
  277. "cc" => [user.follower_address]
  278. }
  279. |> Map.merge(data_attrs)
  280. %Pleroma.Activity{
  281. data: data,
  282. actor: data["actor"],
  283. recipients: data["to"]
  284. }
  285. |> Map.merge(attrs)
  286. end
  287. def followers_only_note_activity_factory(attrs \\ %{}) do
  288. user = attrs[:user] || insert(:user)
  289. note = insert(:followers_only_note, user: user)
  290. data_attrs = attrs[:data_attrs] || %{}
  291. attrs = Map.drop(attrs, [:user, :note, :data_attrs])
  292. data =
  293. %{
  294. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  295. "type" => "Create",
  296. "actor" => note.data["actor"],
  297. "to" => note.data["to"],
  298. "object" => note.data,
  299. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  300. "context" => note.data["context"]
  301. }
  302. |> Map.merge(data_attrs)
  303. %Pleroma.Activity{
  304. data: data,
  305. actor: data["actor"],
  306. recipients: data["to"]
  307. }
  308. |> Map.merge(attrs)
  309. end
  310. def note_activity_factory(attrs \\ %{}) do
  311. user = attrs[:user] || insert(:user)
  312. object_local = if attrs[:object_local] == false, do: false, else: true
  313. note = attrs[:note] || insert(:note, user: user, object_local: object_local)
  314. activity_id =
  315. if attrs[:local] == false do
  316. # Same domain as in note Object factory, it doesn't make sense
  317. # to create mismatched Create Activities with an ID coming from
  318. # a different domain than the Object
  319. "https://example.com/activities/#{Ecto.UUID.generate()}"
  320. else
  321. Pleroma.Web.ActivityPub.Utils.generate_activity_id()
  322. end
  323. data_attrs = attrs[:data_attrs] || %{}
  324. attrs = Map.drop(attrs, [:user, :note, :data_attrs, :object_local])
  325. data =
  326. %{
  327. "id" => activity_id,
  328. "type" => "Create",
  329. "actor" => note.data["actor"],
  330. "to" => note.data["to"],
  331. "object" => note.data["id"],
  332. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  333. "context" => note.data["context"]
  334. }
  335. |> Map.merge(data_attrs)
  336. %Pleroma.Activity{
  337. data: data,
  338. actor: data["actor"],
  339. recipients: data["to"]
  340. }
  341. |> Map.merge(attrs)
  342. end
  343. def article_activity_factory do
  344. article = insert(:article)
  345. data = %{
  346. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  347. "type" => "Create",
  348. "actor" => article.data["actor"],
  349. "to" => article.data["to"],
  350. "object" => article.data,
  351. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  352. "context" => article.data["context"]
  353. }
  354. %Pleroma.Activity{
  355. data: data,
  356. actor: data["actor"],
  357. recipients: data["to"]
  358. }
  359. end
  360. def announce_activity_factory(attrs \\ %{}) do
  361. note_activity = attrs[:note_activity] || insert(:note_activity)
  362. object = Object.normalize(note_activity, fetch: false)
  363. user = attrs[:user] || insert(:user)
  364. data = %{
  365. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  366. "type" => "Announce",
  367. "actor" => user.ap_id,
  368. "object" => object.data["id"],
  369. "to" => [user.follower_address, object.data["actor"]],
  370. "cc" => ["https://www.w3.org/ns/activitystreams#Public"],
  371. "context" => object.data["context"]
  372. }
  373. %Pleroma.Activity{
  374. data: data,
  375. actor: user.ap_id,
  376. recipients: data["to"]
  377. }
  378. end
  379. def emoji_react_activity_factory(attrs \\ %{}) do
  380. note_activity = attrs[:note_activity] || insert(:note_activity)
  381. object = Object.normalize(note_activity, fetch: false)
  382. user = attrs[:user] || insert(:user)
  383. data = %{
  384. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  385. "actor" => user.ap_id,
  386. "type" => "EmojiReact",
  387. "object" => object.data["id"],
  388. "to" => [user.follower_address, object.data["actor"]],
  389. "cc" => ["https://www.w3.org/ns/activitystreams#Public"],
  390. "published_at" => DateTime.utc_now() |> DateTime.to_iso8601(),
  391. "context" => object.data["context"],
  392. "content" => "๐Ÿ˜€"
  393. }
  394. %Pleroma.Activity{
  395. data: data
  396. }
  397. end
  398. def like_activity_factory(attrs \\ %{}) do
  399. note_activity = attrs[:note_activity] || insert(:note_activity)
  400. object = Object.normalize(note_activity, fetch: false)
  401. user = insert(:user)
  402. data =
  403. %{
  404. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  405. "actor" => user.ap_id,
  406. "type" => "Like",
  407. "object" => object.data["id"],
  408. "published_at" => DateTime.utc_now() |> DateTime.to_iso8601()
  409. }
  410. |> Map.merge(attrs[:data_attrs] || %{})
  411. %Pleroma.Activity{
  412. data: data
  413. }
  414. end
  415. def follow_activity_factory do
  416. follower = insert(:user)
  417. followed = insert(:user)
  418. data = %{
  419. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  420. "actor" => follower.ap_id,
  421. "type" => "Follow",
  422. "object" => followed.ap_id,
  423. "published_at" => DateTime.utc_now() |> DateTime.to_iso8601()
  424. }
  425. %Pleroma.Activity{
  426. data: data,
  427. actor: follower.ap_id
  428. }
  429. end
  430. def report_activity_factory(attrs \\ %{}) do
  431. user = attrs[:user] || insert(:user)
  432. activity = attrs[:activity] || insert(:note_activity)
  433. state = attrs[:state] || "open"
  434. data = %{
  435. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  436. "actor" => user.ap_id,
  437. "type" => "Flag",
  438. "object" => [activity.actor, activity.data["id"]],
  439. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  440. "to" => [],
  441. "cc" => [activity.actor],
  442. "context" => activity.data["context"],
  443. "state" => state
  444. }
  445. %Pleroma.Activity{
  446. data: data,
  447. actor: data["actor"],
  448. recipients: data["to"] ++ data["cc"]
  449. }
  450. end
  451. def question_activity_factory(attrs \\ %{}) do
  452. user = attrs[:user] || insert(:user)
  453. question = attrs[:question] || insert(:question, user: user)
  454. data_attrs = attrs[:data_attrs] || %{}
  455. attrs = Map.drop(attrs, [:user, :question, :data_attrs])
  456. data =
  457. %{
  458. "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
  459. "type" => "Create",
  460. "actor" => question.data["actor"],
  461. "to" => question.data["to"],
  462. "object" => question.data["id"],
  463. "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
  464. "context" => question.data["context"]
  465. }
  466. |> Map.merge(data_attrs)
  467. %Pleroma.Activity{
  468. data: data,
  469. actor: data["actor"],
  470. recipients: data["to"],
  471. local: user.local
  472. }
  473. |> Map.merge(attrs)
  474. end
  475. def oauth_app_factory do
  476. %Pleroma.Web.OAuth.App{
  477. client_name: sequence(:client_name, &"Some client #{&1}"),
  478. redirect_uris: "https://example.com/callback",
  479. scopes: ["read", "write", "follow", "push", "admin"],
  480. website: "https://example.com",
  481. client_id: Ecto.UUID.generate(),
  482. client_secret: "aaa;/&bbb"
  483. }
  484. end
  485. def instance_factory do
  486. %Pleroma.Instances.Instance{
  487. host: "domain.com",
  488. unreachable_since: nil
  489. }
  490. end
  491. def oauth_token_factory(attrs \\ %{}) do
  492. scopes = Map.get(attrs, :scopes, ["read"])
  493. oauth_app = Map.get_lazy(attrs, :app, fn -> insert(:oauth_app, scopes: scopes) end)
  494. user = Map.get_lazy(attrs, :user, fn -> build(:user) end)
  495. valid_until =
  496. Map.get(attrs, :valid_until, NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10))
  497. %Pleroma.Web.OAuth.Token{
  498. token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(),
  499. refresh_token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(),
  500. scopes: scopes,
  501. user: user,
  502. app: oauth_app,
  503. valid_until: valid_until
  504. }
  505. end
  506. def oauth_admin_token_factory(attrs \\ %{}) do
  507. user = Map.get_lazy(attrs, :user, fn -> build(:user, is_admin: true) end)
  508. scopes =
  509. attrs
  510. |> Map.get(:scopes, ["admin"])
  511. |> Kernel.++(["admin"])
  512. |> Enum.uniq()
  513. attrs = Map.merge(attrs, %{user: user, scopes: scopes})
  514. oauth_token_factory(attrs)
  515. end
  516. def oauth_authorization_factory do
  517. %Pleroma.Web.OAuth.Authorization{
  518. token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false),
  519. scopes: ["read", "write", "follow", "push"],
  520. valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10),
  521. user: build(:user),
  522. app: build(:oauth_app)
  523. }
  524. end
  525. def push_subscription_factory do
  526. %Pleroma.Web.Push.Subscription{
  527. user: build(:user),
  528. token: build(:oauth_token),
  529. endpoint: "https://example.com/example/1234",
  530. key_auth: "8eDyX_uCN0XRhSbY5hs7Hg==",
  531. key_p256dh:
  532. "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA=",
  533. data: %{}
  534. }
  535. end
  536. def notification_factory do
  537. %Pleroma.Notification{
  538. user: build(:user)
  539. }
  540. end
  541. def scheduled_activity_factory do
  542. %Pleroma.ScheduledActivity{
  543. user: build(:user),
  544. scheduled_at: NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(60), :millisecond),
  545. params: build(:note) |> Map.from_struct() |> Map.get(:data)
  546. }
  547. end
  548. def registration_factory do
  549. user = insert(:user)
  550. %Pleroma.Registration{
  551. user: user,
  552. provider: "twitter",
  553. uid: "171799000",
  554. info: %{
  555. "name" => "John Doe",
  556. "email" => "john@doe.com",
  557. "nickname" => "johndoe",
  558. "description" => "My bio"
  559. }
  560. }
  561. end
  562. def config_factory(attrs \\ %{}) do
  563. %Pleroma.ConfigDB{
  564. key: sequence(:key, &String.to_atom("some_key_#{&1}")),
  565. group: :pleroma,
  566. value:
  567. sequence(
  568. :value,
  569. &%{another_key: "#{&1}somevalue", another: "#{&1}somevalue"}
  570. )
  571. }
  572. |> merge_attributes(attrs)
  573. end
  574. def marker_factory do
  575. %Pleroma.Marker{
  576. user: build(:user),
  577. timeline: "notifications",
  578. lock_version: 0,
  579. last_read_id: "1"
  580. }
  581. end
  582. def mfa_token_factory do
  583. %Pleroma.MFA.Token{
  584. token: :crypto.strong_rand_bytes(32) |> Base.url_encode64(padding: false),
  585. authorization: build(:oauth_authorization),
  586. valid_until: NaiveDateTime.add(NaiveDateTime.utc_now(), 60 * 10),
  587. user: build(:user)
  588. }
  589. end
  590. def filter_factory do
  591. %Pleroma.Filter{
  592. user: build(:user),
  593. filter_id: sequence(:filter_id, & &1),
  594. phrase: "cofe",
  595. context: ["home"]
  596. }
  597. end
  598. def announcement_factory(params \\ %{}) do
  599. data = Map.get(params, :data, %{})
  600. {_, params} = Map.pop(params, :data)
  601. %Pleroma.Announcement{
  602. data: Map.merge(%{"content" => "test announcement", "all_day" => false}, data)
  603. }
  604. |> Map.merge(params)
  605. |> Pleroma.Announcement.add_rendered_properties()
  606. end
  607. def hashtag_factory(params \\ %{}) do
  608. %Pleroma.Hashtag{
  609. name: "test #{sequence(:hashtag_name, & &1)}"
  610. }
  611. |> Map.merge(params)
  612. end
  613. end