First
[anni] / test / mix / tasks / pleroma / database_test.exs
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
5 defmodule Mix.Tasks.Pleroma.DatabaseTest do
6   use Pleroma.DataCase, async: true
7   use Oban.Testing, repo: Pleroma.Repo
8
9   alias Pleroma.Activity
10   alias Pleroma.Object
11   alias Pleroma.Repo
12   alias Pleroma.User
13   alias Pleroma.Web.CommonAPI
14
15   import Pleroma.Factory
16
17   setup_all do
18     Mix.shell(Mix.Shell.Process)
19
20     on_exit(fn ->
21       Mix.shell(Mix.Shell.IO)
22     end)
23
24     :ok
25   end
26
27   describe "running remove_embedded_objects" do
28     test "it replaces objects with references" do
29       user = insert(:user)
30       {:ok, activity} = CommonAPI.post(user, %{status: "test"})
31       new_data = Map.put(activity.data, "object", activity.object.data)
32
33       {:ok, activity} =
34         activity
35         |> Activity.change(%{data: new_data})
36         |> Repo.update()
37
38       assert is_map(activity.data["object"])
39
40       Mix.Tasks.Pleroma.Database.run(["remove_embedded_objects"])
41
42       activity = Activity.get_by_id_with_object(activity.id)
43       assert is_binary(activity.data["object"])
44     end
45   end
46
47   describe "prune_objects" do
48     test "it prunes old objects from the database" do
49       insert(:note)
50       deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
51
52       date =
53         Timex.now()
54         |> Timex.shift(days: -deadline)
55         |> Timex.to_naive_datetime()
56         |> NaiveDateTime.truncate(:second)
57
58       %{id: id} =
59         :note
60         |> insert()
61         |> Ecto.Changeset.change(%{inserted_at: date})
62         |> Repo.update!()
63
64       assert length(Repo.all(Object)) == 2
65
66       Mix.Tasks.Pleroma.Database.run(["prune_objects"])
67
68       assert length(Repo.all(Object)) == 1
69       refute Object.get_by_id(id)
70     end
71   end
72
73   describe "running update_users_following_followers_counts" do
74     test "following and followers count are updated" do
75       [user, user2] = insert_pair(:user)
76       {:ok, %User{} = user, _user2} = User.follow(user, user2)
77
78       following = User.following(user)
79
80       assert length(following) == 2
81       assert user.follower_count == 0
82
83       {:ok, user} =
84         user
85         |> Ecto.Changeset.change(%{follower_count: 3})
86         |> Repo.update()
87
88       assert user.follower_count == 3
89
90       assert {:ok, :ok} ==
91                Mix.Tasks.Pleroma.Database.run(["update_users_following_followers_counts"])
92
93       user = User.get_by_id(user.id)
94
95       assert length(User.following(user)) == 2
96       assert user.follower_count == 0
97     end
98   end
99
100   describe "running fix_likes_collections" do
101     test "it turns OrderedCollection likes into empty arrays" do
102       [user, user2] = insert_pair(:user)
103
104       {:ok, %{id: id, object: object}} = CommonAPI.post(user, %{status: "test"})
105       {:ok, %{object: object2}} = CommonAPI.post(user, %{status: "test test"})
106
107       CommonAPI.favorite(user2, id)
108
109       likes = %{
110         "first" =>
111           "http://mastodon.example.org/objects/dbdbc507-52c8-490d-9b7c-1e1d52e5c132/likes?page=1",
112         "id" => "http://mastodon.example.org/objects/dbdbc507-52c8-490d-9b7c-1e1d52e5c132/likes",
113         "totalItems" => 3,
114         "type" => "OrderedCollection"
115       }
116
117       new_data = Map.put(object2.data, "likes", likes)
118
119       object2
120       |> Ecto.Changeset.change(%{data: new_data})
121       |> Repo.update()
122
123       assert length(Object.get_by_id(object.id).data["likes"]) == 1
124       assert is_map(Object.get_by_id(object2.id).data["likes"])
125
126       assert :ok == Mix.Tasks.Pleroma.Database.run(["fix_likes_collections"])
127
128       assert length(Object.get_by_id(object.id).data["likes"]) == 1
129       assert Enum.empty?(Object.get_by_id(object2.id).data["likes"])
130     end
131   end
132
133   describe "ensure_expiration" do
134     test "it adds to expiration old statuses" do
135       activity1 = insert(:note_activity)
136
137       {:ok, inserted_at, 0} = DateTime.from_iso8601("2015-01-23T23:50:07Z")
138       activity2 = insert(:note_activity, %{inserted_at: inserted_at})
139
140       %{id: activity_id3} = insert(:note_activity)
141
142       expires_at = DateTime.add(DateTime.utc_now(), 60 * 61)
143
144       Pleroma.Workers.PurgeExpiredActivity.enqueue(%{
145         activity_id: activity_id3,
146         expires_at: expires_at
147       })
148
149       Mix.Tasks.Pleroma.Database.run(["ensure_expiration"])
150
151       assert_enqueued(
152         worker: Pleroma.Workers.PurgeExpiredActivity,
153         args: %{activity_id: activity1.id},
154         scheduled_at:
155           activity1.inserted_at
156           |> DateTime.from_naive!("Etc/UTC")
157           |> Timex.shift(days: 365)
158       )
159
160       assert_enqueued(
161         worker: Pleroma.Workers.PurgeExpiredActivity,
162         args: %{activity_id: activity2.id},
163         scheduled_at:
164           activity2.inserted_at
165           |> DateTime.from_naive!("Etc/UTC")
166           |> Timex.shift(days: 365)
167       )
168
169       assert_enqueued(
170         worker: Pleroma.Workers.PurgeExpiredActivity,
171         args: %{activity_id: activity_id3},
172         scheduled_at: expires_at
173       )
174     end
175   end
176 end