factories.py 7.93 KB
Newer Older
Eliot Berriot's avatar
Eliot Berriot committed
1
2
import uuid

3
4
5
import factory
import requests
import requests_http_signature
Eliot Berriot's avatar
Eliot Berriot committed
6
from django.conf import settings
Eliot Berriot's avatar
Eliot Berriot committed
7
from django.utils import timezone
8
from django.utils.http import http_date
9

10
from funkwhale_api.factories import registry
11
from funkwhale_api.users import factories as user_factories
12

Eliot Berriot's avatar
Eliot Berriot committed
13
from . import keys, models
14

Eliot Berriot's avatar
Eliot Berriot committed
15
registry.register(keys.get_key_pair, name="federation.KeyPair")
16
17


Eliot Berriot's avatar
Eliot Berriot committed
18
@registry.register(name="federation.SignatureAuth")
19
class SignatureAuthFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
20
    algorithm = "rsa-sha256"
21
    key = factory.LazyFunction(lambda: keys.get_key_pair()[0])
Eliot Berriot's avatar
Eliot Berriot committed
22
    key_id = factory.Faker("url")
23
    use_auth_header = False
Eliot Berriot's avatar
Eliot Berriot committed
24
25
    headers = ["(request-target)", "user-agent", "host", "date", "content-type"]

26
27
28
29
    class Meta:
        model = requests_http_signature.HTTPSignatureAuth


Eliot Berriot's avatar
Eliot Berriot committed
30
@registry.register(name="federation.SignedRequest")
31
class SignedRequestFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
32
33
    url = factory.Faker("url")
    method = "get"
34
35
36
37
    auth = factory.SubFactory(SignatureAuthFactory)

    class Meta:
        model = requests.Request
38
39
40
41

    @factory.post_generation
    def headers(self, create, extracted, **kwargs):
        default_headers = {
Eliot Berriot's avatar
Eliot Berriot committed
42
43
            "User-Agent": "Test",
            "Host": "test.host",
44
            "Date": http_date(timezone.now().timestamp()),
Eliot Berriot's avatar
Eliot Berriot committed
45
            "Content-Type": "application/activity+json",
46
47
48
49
50
51
        }
        if extracted:
            default_headers.update(extracted)
        self.headers.update(default_headers)


Eliot Berriot's avatar
Eliot Berriot committed
52
@registry.register(name="federation.Link")
Eliot Berriot's avatar
Eliot Berriot committed
53
class LinkFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
54
55
56
    type = "Link"
    href = factory.Faker("url")
    mediaType = "text/html"
Eliot Berriot's avatar
Eliot Berriot committed
57
58
59
60
61

    class Meta:
        model = dict

    class Params:
Eliot Berriot's avatar
Eliot Berriot committed
62
        audio = factory.Trait(mediaType=factory.Iterator(["audio/mp3", "audio/ogg"]))
Eliot Berriot's avatar
Eliot Berriot committed
63
64


65
66
67
68
def create_user(actor):
    return user_factories.UserFactory(actor=actor)


Eliot Berriot's avatar
Eliot Berriot committed
69
70
71
72
@registry.register
class ActorFactory(factory.DjangoModelFactory):
    public_key = None
    private_key = None
Eliot Berriot's avatar
Eliot Berriot committed
73
74
75
    preferred_username = factory.Faker("user_name")
    summary = factory.Faker("paragraph")
    domain = factory.Faker("domain_name")
76
    fid = factory.LazyAttribute(
Eliot Berriot's avatar
Eliot Berriot committed
77
78
        lambda o: "https://{}/users/{}".format(o.domain, o.preferred_username)
    )
Eliot Berriot's avatar
Eliot Berriot committed
79
80
81
    followers_url = factory.LazyAttribute(
        lambda o: "https://{}/users/{}followers".format(o.domain, o.preferred_username)
    )
Eliot Berriot's avatar
Eliot Berriot committed
82
83
84
85
86
87
    inbox_url = factory.LazyAttribute(
        lambda o: "https://{}/users/{}/inbox".format(o.domain, o.preferred_username)
    )
    outbox_url = factory.LazyAttribute(
        lambda o: "https://{}/users/{}/outbox".format(o.domain, o.preferred_username)
    )
Eliot Berriot's avatar
Eliot Berriot committed
88
89
90
91

    class Meta:
        model = models.Actor

92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    @factory.post_generation
    def local(self, create, extracted, **kwargs):
        if not extracted and not kwargs:
            return
        from funkwhale_api.users.factories import UserFactory

        self.domain = settings.FEDERATION_HOSTNAME
        self.save(update_fields=["domain"])
        if not create:
            if extracted and hasattr(extracted, "pk"):
                extracted.actor = self
            else:
                UserFactory.build(actor=self, **kwargs)
        if extracted and hasattr(extracted, "pk"):
            extracted.actor = self
            extracted.save(update_fields=["user"])
        else:
            self.user = UserFactory(actor=self, **kwargs)

    @factory.post_generation
    def keys(self, create, extracted, **kwargs):
        if not create:
            # Simple build, do nothing.
            return
        if not extracted:
117
            private, public = keys.get_key_pair()
118
119
            self.private_key = private.decode("utf-8")
            self.public_key = public.decode("utf-8")
120
121


Eliot Berriot's avatar
Eliot Berriot committed
122
123
124
125
126
127
128
129
@registry.register
class FollowFactory(factory.DjangoModelFactory):
    target = factory.SubFactory(ActorFactory)
    actor = factory.SubFactory(ActorFactory)

    class Meta:
        model = models.Follow

Eliot Berriot's avatar
Eliot Berriot committed
130
    class Params:
Eliot Berriot's avatar
Eliot Berriot committed
131
        local = factory.Trait(actor=factory.SubFactory(ActorFactory, local=True))
Eliot Berriot's avatar
Eliot Berriot committed
132

Eliot Berriot's avatar
Eliot Berriot committed
133

134
@registry.register
135
136
137
138
139
class MusicLibraryFactory(factory.django.DjangoModelFactory):
    actor = factory.SubFactory(ActorFactory)
    privacy_level = "me"
    name = factory.Faker("sentence")
    description = factory.Faker("sentence")
Eliot Berriot's avatar
Eliot Berriot committed
140
141
    uploads_count = 0
    fid = factory.Faker("federation_url")
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

    class Meta:
        model = "music.Library"

    @factory.post_generation
    def followers_url(self, create, extracted, **kwargs):
        if not create:
            # Simple build, do nothing.
            return

        self.followers_url = extracted or self.fid + "/followers"


@registry.register
class LibraryScan(factory.django.DjangoModelFactory):
    library = factory.SubFactory(MusicLibraryFactory)
    actor = factory.SubFactory(ActorFactory)
Eliot Berriot's avatar
Eliot Berriot committed
159
    total_files = factory.LazyAttribute(lambda o: o.library.uploads_count)
160
161
162
163
164
165
166

    class Meta:
        model = "music.LibraryScan"


@registry.register
class ActivityFactory(factory.django.DjangoModelFactory):
167
    actor = factory.SubFactory(ActorFactory)
Eliot Berriot's avatar
Eliot Berriot committed
168
    url = factory.Faker("federation_url")
169
    payload = factory.LazyFunction(lambda: {"type": "Create"})
170
171

    class Meta:
172
173
174
175
176
        model = "federation.Activity"


@registry.register
class InboxItemFactory(factory.django.DjangoModelFactory):
Eliot Berriot's avatar
Eliot Berriot committed
177
    actor = factory.SubFactory(ActorFactory, local=True)
178
179
180
181
182
183
184
    activity = factory.SubFactory(ActivityFactory)
    type = "to"

    class Meta:
        model = "federation.InboxItem"


Eliot Berriot's avatar
Eliot Berriot committed
185
186
187
188
189
190
191
192
193
@registry.register
class DeliveryFactory(factory.django.DjangoModelFactory):
    activity = factory.SubFactory(ActivityFactory)
    inbox_url = factory.Faker("url")

    class Meta:
        model = "federation.Delivery"


194
195
196
197
198
199
200
@registry.register
class LibraryFollowFactory(factory.DjangoModelFactory):
    target = factory.SubFactory(MusicLibraryFactory)
    actor = factory.SubFactory(ActorFactory)

    class Meta:
        model = "federation.LibraryFollow"
201
202


203
class ArtistMetadataFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
204
    name = factory.Faker("name")
205
206
207
208
209

    class Meta:
        model = dict

    class Params:
Eliot Berriot's avatar
Eliot Berriot committed
210
        musicbrainz = factory.Trait(musicbrainz_id=factory.Faker("uuid4"))
211
212
213


class ReleaseMetadataFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
214
    title = factory.Faker("sentence")
215
216
217
218
219

    class Meta:
        model = dict

    class Params:
Eliot Berriot's avatar
Eliot Berriot committed
220
        musicbrainz = factory.Trait(musicbrainz_id=factory.Faker("uuid4"))
221
222
223


class RecordingMetadataFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
224
    title = factory.Faker("sentence")
225
226
227
228
229

    class Meta:
        model = dict

    class Params:
Eliot Berriot's avatar
Eliot Berriot committed
230
        musicbrainz = factory.Trait(musicbrainz_id=factory.Faker("uuid4"))
231
232


Eliot Berriot's avatar
Eliot Berriot committed
233
@registry.register(name="federation.LibraryTrackMetadata")
234
235
236
237
238
239
240
241
242
class LibraryTrackMetadataFactory(factory.Factory):
    artist = factory.SubFactory(ArtistMetadataFactory)
    recording = factory.SubFactory(RecordingMetadataFactory)
    release = factory.SubFactory(ReleaseMetadataFactory)

    class Meta:
        model = dict


Eliot Berriot's avatar
Eliot Berriot committed
243
@registry.register(name="federation.Note")
244
class NoteFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
245
246
247
    type = "Note"
    id = factory.Faker("url")
    published = factory.LazyFunction(lambda: timezone.now().isoformat())
248
    inReplyTo = None
Eliot Berriot's avatar
Eliot Berriot committed
249
    content = factory.Faker("sentence")
250
251
252

    class Meta:
        model = dict
Eliot Berriot's avatar
Eliot Berriot committed
253
254


Eliot Berriot's avatar
Eliot Berriot committed
255
@registry.register(name="federation.AudioMetadata")
Eliot Berriot's avatar
Eliot Berriot committed
256
257
class AudioMetadataFactory(factory.Factory):
    recording = factory.LazyAttribute(
Eliot Berriot's avatar
Eliot Berriot committed
258
        lambda o: "https://musicbrainz.org/recording/{}".format(uuid.uuid4())
Eliot Berriot's avatar
Eliot Berriot committed
259
260
    )
    artist = factory.LazyAttribute(
Eliot Berriot's avatar
Eliot Berriot committed
261
        lambda o: "https://musicbrainz.org/artist/{}".format(uuid.uuid4())
Eliot Berriot's avatar
Eliot Berriot committed
262
263
    )
    release = factory.LazyAttribute(
Eliot Berriot's avatar
Eliot Berriot committed
264
        lambda o: "https://musicbrainz.org/release/{}".format(uuid.uuid4())
Eliot Berriot's avatar
Eliot Berriot committed
265
    )
266
267
268
    bitrate = 42
    length = 43
    size = 44
Eliot Berriot's avatar
Eliot Berriot committed
269
270
271
272
273

    class Meta:
        model = dict


Eliot Berriot's avatar
Eliot Berriot committed
274
@registry.register(name="federation.Audio")
Eliot Berriot's avatar
Eliot Berriot committed
275
class AudioFactory(factory.Factory):
Eliot Berriot's avatar
Eliot Berriot committed
276
    type = "Audio"
Eliot Berriot's avatar
Eliot Berriot committed
277
    id = factory.Faker("federation_url")
Eliot Berriot's avatar
Eliot Berriot committed
278
    published = factory.LazyFunction(lambda: timezone.now().isoformat())
Eliot Berriot's avatar
Eliot Berriot committed
279
    actor = factory.Faker("federation_url")
Eliot Berriot's avatar
Eliot Berriot committed
280
    url = factory.SubFactory(LinkFactory, audio=True)
281
    metadata = factory.SubFactory(LibraryTrackMetadataFactory)
Eliot Berriot's avatar
Eliot Berriot committed
282
283
284

    class Meta:
        model = dict