Add BackupWorker
[akkoma] / test / backup_test.exs
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.BackupTest do
6 use Oban.Testing, repo: Pleroma.Repo
7 use Pleroma.DataCase
8
9 import Pleroma.Factory
10 import Mock
11
12 alias Pleroma.Backup
13 alias Pleroma.Bookmark
14 alias Pleroma.Web.CommonAPI
15 alias Pleroma.Workers.BackupWorker
16
17 setup do: clear_config([Pleroma.Upload, :uploader])
18
19 test "it creates a backup record and an Oban job" do
20 %{id: user_id} = user = insert(:user)
21 assert {:ok, %Oban.Job{args: args}} = Backup.create(user)
22 assert_enqueued(worker: BackupWorker, args: args)
23
24 backup = Backup.get(args["backup_id"])
25 assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup
26 end
27
28 test "it return an error if the export limit is over" do
29 %{id: user_id} = user = insert(:user)
30 limit_days = 7
31 assert {:ok, %Oban.Job{args: args}} = Backup.create(user)
32 backup = Backup.get(args["backup_id"])
33 assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup
34
35 assert Backup.create(user) == {:error, "Last export was less than #{limit_days} days ago"}
36 end
37
38 test "it process a backup record" do
39 Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
40 %{id: user_id} = user = insert(:user)
41 assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id}} = job} = Backup.create(user)
42 assert {:ok, backup} = BackupWorker.perform(job)
43 assert backup.file_size > 0
44 assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
45 end
46
47 test "it creates a zip archive with user data" do
48 user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
49
50 {:ok, %{object: %{data: %{"id" => id1}}} = status1} =
51 CommonAPI.post(user, %{status: "status1"})
52
53 {:ok, %{object: %{data: %{"id" => id2}}} = status2} =
54 CommonAPI.post(user, %{status: "status2"})
55
56 {:ok, %{object: %{data: %{"id" => id3}}} = status3} =
57 CommonAPI.post(user, %{status: "status3"})
58
59 CommonAPI.favorite(user, status1.id)
60 CommonAPI.favorite(user, status2.id)
61
62 Bookmark.create(user.id, status2.id)
63 Bookmark.create(user.id, status3.id)
64
65 assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
66 assert {:ok, path} = Backup.zip(backup)
67 assert {:ok, zipfile} = :zip.zip_open(String.to_charlist(path), [:memory])
68 assert {:ok, {'actor.json', json}} = :zip.zip_get('actor.json', zipfile)
69
70 assert %{
71 "@context" => [
72 "https://www.w3.org/ns/activitystreams",
73 "http://localhost:4001/schemas/litepub-0.1.jsonld",
74 %{"@language" => "und"}
75 ],
76 "bookmarks" => "bookmarks.json",
77 "followers" => "http://cofe.io/users/cofe/followers",
78 "following" => "http://cofe.io/users/cofe/following",
79 "id" => "http://cofe.io/users/cofe",
80 "inbox" => "http://cofe.io/users/cofe/inbox",
81 "likes" => "likes.json",
82 "name" => "Cofe",
83 "outbox" => "http://cofe.io/users/cofe/outbox",
84 "preferredUsername" => "cofe",
85 "publicKey" => %{
86 "id" => "http://cofe.io/users/cofe#main-key",
87 "owner" => "http://cofe.io/users/cofe"
88 },
89 "type" => "Person",
90 "url" => "http://cofe.io/users/cofe"
91 } = Jason.decode!(json)
92
93 assert {:ok, {'outbox.json', json}} = :zip.zip_get('outbox.json', zipfile)
94
95 assert %{
96 "@context" => "https://www.w3.org/ns/activitystreams",
97 "id" => "outbox.json",
98 "orderedItems" => [
99 %{
100 "object" => %{
101 "actor" => "http://cofe.io/users/cofe",
102 "content" => "status1",
103 "type" => "Note"
104 },
105 "type" => "Create"
106 },
107 %{
108 "object" => %{
109 "actor" => "http://cofe.io/users/cofe",
110 "content" => "status2"
111 }
112 },
113 %{
114 "actor" => "http://cofe.io/users/cofe",
115 "object" => %{
116 "content" => "status3"
117 }
118 }
119 ],
120 "totalItems" => 3,
121 "type" => "OrderedCollection"
122 } = Jason.decode!(json)
123
124 assert {:ok, {'likes.json', json}} = :zip.zip_get('likes.json', zipfile)
125
126 assert %{
127 "@context" => "https://www.w3.org/ns/activitystreams",
128 "id" => "likes.json",
129 "orderedItems" => [^id1, ^id2],
130 "totalItems" => 2,
131 "type" => "OrderedCollection"
132 } = Jason.decode!(json)
133
134 assert {:ok, {'bookmarks.json', json}} = :zip.zip_get('bookmarks.json', zipfile)
135
136 assert %{
137 "@context" => "https://www.w3.org/ns/activitystreams",
138 "id" => "bookmarks.json",
139 "orderedItems" => [^id2, ^id3],
140 "totalItems" => 2,
141 "type" => "OrderedCollection"
142 } = Jason.decode!(json)
143
144 :zip.zip_close(zipfile)
145 File.rm!(path)
146 end
147
148 describe "it uploads a backup archive" do
149 setup do
150 clear_config(Pleroma.Uploaders.S3,
151 bucket: "test_bucket",
152 public_endpoint: "https://s3.amazonaws.com"
153 )
154
155 clear_config([Pleroma.Upload, :uploader])
156
157 user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
158
159 {:ok, status1} = CommonAPI.post(user, %{status: "status1"})
160 {:ok, status2} = CommonAPI.post(user, %{status: "status2"})
161 {:ok, status3} = CommonAPI.post(user, %{status: "status3"})
162 CommonAPI.favorite(user, status1.id)
163 CommonAPI.favorite(user, status2.id)
164 Bookmark.create(user.id, status2.id)
165 Bookmark.create(user.id, status3.id)
166
167 assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
168 assert {:ok, path} = Backup.zip(backup)
169
170 [path: path, backup: backup]
171 end
172
173 test "S3", %{path: path, backup: backup} do
174 Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.S3)
175
176 with_mock ExAws, request: fn _ -> {:ok, :ok} end do
177 assert {:ok, %Pleroma.Upload{}} = Backup.upload(backup, path)
178 end
179 end
180
181 test "Local", %{path: path, backup: backup} do
182 Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
183
184 assert {:ok, %Pleroma.Upload{}} = Backup.upload(backup, path)
185 end
186 end
187 end