mobilizon/test/support/factory.ex
Thomas Citharel b5672cee7e
WIP
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
2023-11-14 14:24:17 +01:00

556 lines
15 KiB
Elixir

defmodule Mobilizon.Factory do
@moduledoc """
Factory for fixtures with ExMachina.
"""
use ExMachina.Ecto, repo: Mobilizon.Storage.Repo
alias Mobilizon.Actors.Actor
alias Mobilizon.Crypto
alias Mobilizon.Web.{Endpoint, Upload}
alias Mobilizon.Web.Router.Helpers, as: Routes
@spec user_factory :: Mobilizon.Users.User.t()
def user_factory do
%Mobilizon.Users.User{
password_hash: "Jane Smith",
email: sequence(:email, &"email-#{&1}@example.com"),
role: :user,
confirmed_at: DateTime.utc_now() |> DateTime.truncate(:second),
confirmation_sent_at: nil,
confirmation_token: nil,
provider: nil
}
end
@spec settings_factory :: Mobilizon.Users.Setting.t()
def settings_factory do
%Mobilizon.Users.Setting{
timezone: nil,
notification_on_day: false,
notification_each_week: false,
notification_before_event: false,
notification_pending_participation: :one_day,
notification_pending_membership: :one_day,
group_notifications: :one_day,
last_notification_sent: nil,
user: build(:user)
}
end
@spec actor_factory :: Mobilizon.Actors.Actor.t()
def actor_factory do
preferred_username = sequence("thomas")
%Mobilizon.Actors.Actor{
preferred_username: preferred_username,
name: sequence("Thomas Named"),
domain: nil,
followers: [],
followings: [],
keys: Crypto.generate_rsa_2048_private_key(),
type: :Person,
avatar: build(:file, name: "Avatar"),
banner: build(:file, name: "Banner"),
url: Actor.build_url(preferred_username, :page),
followers_url: Actor.build_url(preferred_username, :followers),
following_url: Actor.build_url(preferred_username, :following),
inbox_url: Actor.build_url(preferred_username, :inbox),
outbox_url: Actor.build_url(preferred_username, :outbox),
shared_inbox_url: "#{Endpoint.url()}/inbox",
last_refreshed_at: DateTime.utc_now(),
user: build(:user),
visibility: :public,
manually_approves_followers: false
}
end
@spec group_factory :: Mobilizon.Actors.Actor.t()
def group_factory do
preferred_username = sequence("myGroup")
struct!(
actor_factory(),
%{
preferred_username: preferred_username,
type: :Group,
url: Actor.build_url(preferred_username, :page),
followers_url: Actor.build_url(preferred_username, :followers),
following_url: Actor.build_url(preferred_username, :following),
members_url: Actor.build_url(preferred_username, :members),
resources_url: Actor.build_url(preferred_username, :resources),
inbox_url: Actor.build_url(preferred_username, :inbox),
outbox_url: Actor.build_url(preferred_username, :outbox),
user: nil,
physical_address: build(:address)
}
)
end
@spec instance_actor_factory :: Mobilizon.Actors.Actor.t()
def instance_actor_factory do
preferred_username = "relay"
domain = "#{sequence("mydomain")}.com"
struct!(
actor_factory(),
%{
preferred_username: preferred_username,
type: :Application,
url: "http://#{domain}/#{preferred_username}",
followers_url: Actor.build_url(preferred_username, :followers),
following_url: Actor.build_url(preferred_username, :following),
members_url: Actor.build_url(preferred_username, :members),
resources_url: Actor.build_url(preferred_username, :resources),
inbox_url: Actor.build_url(preferred_username, :inbox),
outbox_url: Actor.build_url(preferred_username, :outbox),
user: nil,
domain: domain
}
)
end
@spec follower_factory :: Mobilizon.Actors.Follower.t()
def follower_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Actors.Follower{
target_actor: build(:actor),
actor: build(:actor),
id: uuid,
url: "#{Endpoint.url()}/follows/#{uuid}",
approved: false
}
end
@spec tag_factory :: Mobilizon.Events.Tag.t()
def tag_factory do
%Mobilizon.Events.Tag{
title: sequence("MyTag"),
slug: sequence("my-tag")
}
end
@spec tag_relation_factory :: Mobilizon.Events.TagRelation.t()
def tag_relation_factory do
%Mobilizon.Events.TagRelation{
tag: build(:tag),
link: build(:tag)
}
end
@spec address_factory :: Mobilizon.Addresses.Address.t()
def address_factory do
%Mobilizon.Addresses.Address{
description: sequence("MyAddress"),
geom: %Geo.Point{coordinates: {45.75, 4.85}, srid: 4326},
url: "http://mobilizon.test/address/#{Ecto.UUID.generate()}",
country: "My Country",
locality: "My Locality",
region: "My Region",
postal_code: "My Postal Code",
street: "My Street Address"
}
end
@spec comment_factory :: Mobilizon.Discussions.Comment.t()
def comment_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Discussions.Comment{
text: "My Comment",
actor: build(:actor),
event: build(:event),
uuid: uuid,
mentions: [],
media: [],
attributed_to: nil,
local: true,
deleted_at: nil,
tags: build_list(3, :tag),
in_reply_to_comment: nil,
origin_comment: nil,
is_announcement: false,
published_at: DateTime.utc_now(),
url: Routes.page_url(Endpoint, :comment, uuid)
}
end
@spec event_factory :: Mobilizon.Events.Event.t()
def event_factory do
actor = build(:actor)
start = Timex.shift(DateTime.utc_now(), hours: 2)
uuid = Ecto.UUID.generate()
%Mobilizon.Events.Event{
title: sequence("Ceci est un événement"),
description: "Ceci est une description avec une première phrase assez longue,
puis sur une seconde ligne",
begins_on: start,
ends_on: Timex.shift(start, hours: 2),
organizer_actor: actor,
attributed_to: nil,
category: "PARTY",
physical_address: build(:address),
visibility: :public,
tags: build_list(3, :tag),
mentions: [],
metadata: build_list(2, :event_metadata),
local: true,
publish_at: DateTime.utc_now(),
url: Routes.page_url(Endpoint, :event, uuid),
picture: insert(:media),
uuid: uuid,
join_options: :free,
options: %{},
participant_stats: %{},
status: :confirmed,
contacts: [],
media: []
}
end
@spec participant_factory :: Mobilizon.Events.Participant.t()
def participant_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Events.Participant{
event: build(:event),
actor: build(:actor),
role: :creator,
url: "#{Endpoint.url()}/join/event/#{uuid}",
id: uuid,
metadata: %{
email: nil,
confirmation_token: nil
}
}
end
@spec session_factory :: Mobilizon.Events.Session.t()
def session_factory do
%Mobilizon.Events.Session{
title: sequence("MySession"),
event: build(:event),
track: build(:track)
}
end
@spec track_factory :: Mobilizon.Events.Track.t()
def track_factory do
%Mobilizon.Events.Track{
name: sequence("MyTrack"),
event: build(:event)
}
end
@spec bot_factory :: Mobilizon.Actors.Bot.t()
def bot_factory do
%Mobilizon.Actors.Bot{
source: "https://mysource.tld/feed.ics",
type: "ics",
user: build(:user),
actor: build(:actor)
}
end
@spec member_factory :: Mobilizon.Actors.Member.t()
def member_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Actors.Member{
parent: build(:actor),
actor: build(:actor),
role: :not_approved,
member_since: nil,
id: uuid,
url: "#{Endpoint.url()}/member/#{uuid}"
}
end
@spec feed_token_factory :: Mobilizon.Events.FeedToken.t()
def feed_token_factory do
user = build(:user)
%Mobilizon.Events.FeedToken{
user: user,
actor: build(:actor, user: user),
token: Ecto.UUID.generate()
}
end
@spec file_factory :: Mobilizon.Medias.File.t()
def file_factory do
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
file = %Plug.Upload{
content_type: "image/jpg",
path: Path.absname("test/fixtures/image_tmp.jpg"),
filename: "image.jpg"
}
{:ok, data} = Upload.store(file)
%{
content_type: "image/jpeg",
name: "image.jpg",
url: url
} = data
%Mobilizon.Medias.File{
name: "My Media",
url: url,
content_type: "image/jpg",
size: 13_120
}
end
@spec media_factory :: Mobilizon.Medias.Media.t()
def media_factory do
%Mobilizon.Medias.Media{
file: build(:file),
actor: build(:actor)
}
end
@spec report_factory :: Mobilizon.Reports.Report.t()
def report_factory do
%Mobilizon.Reports.Report{
content: "This is problematic",
status: :open,
url: "http://mobilizon.test/report/deae1020-54b8-47df-9eea-d8c0e943e57f/activity",
reported: build(:actor),
reporter: build(:actor),
events: build_list(1, :event),
comments: build_list(1, :comment)
}
end
@spec report_note_factory :: Mobilizon.Reports.Note.t()
def report_note_factory do
%Mobilizon.Reports.Note{
content: "My opinion",
moderator: build(:actor),
report: build(:report)
}
end
@spec todo_list_factory :: Mobilizon.Todos.TodoList.t()
def todo_list_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Todos.TodoList{
title: sequence("todo list"),
actor: build(:group),
id: uuid,
url: Routes.page_url(Endpoint, :todo_list, uuid),
published_at: DateTime.utc_now()
}
end
@spec todo_factory :: Mobilizon.Todos.Todo.t()
def todo_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Todos.Todo{
id: uuid,
title: sequence("my todo"),
todo_list: build(:todo_list),
status: false,
due_date: Timex.shift(DateTime.utc_now(), hours: 2),
assigned_to: build(:actor),
url: Routes.page_url(Endpoint, :todo, uuid),
creator: build(:actor),
published_at: DateTime.utc_now()
}
end
@spec resource_factory :: Mobilizon.Resources.Resource.t()
def resource_factory do
uuid = Ecto.UUID.generate()
title = sequence("my resource")
%Mobilizon.Resources.Resource{
id: uuid,
title: title,
type: :link,
resource_url: "https://somewebsite.com/path",
actor: build(:group),
creator: build(:actor),
parent: nil,
url: Routes.page_url(Endpoint, :resource, uuid),
published_at: DateTime.utc_now(),
path: "/#{title}"
}
end
@spec admin_setting_factory :: Mobilizon.Admin.Setting.t()
def admin_setting_factory do
%Mobilizon.Admin.Setting{
group: sequence("group"),
name: sequence("name"),
value: sequence("value")
}
end
@spec post_factory :: Mobilizon.Posts.Post.t()
def post_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Posts.Post{
body: "The <b>HTML</b>body for my Article",
title: "My Awesome article",
slug: "my-awesome-article-#{ShortUUID.encode!(uuid)}",
author: build(:actor),
attributed_to: build(:group),
id: uuid,
draft: false,
tags: build_list(3, :tag),
visibility: :public,
publish_at: DateTime.utc_now(),
picture: insert(:media),
media: [],
url: Routes.page_url(Endpoint, :post, uuid)
}
end
@spec tombstone_factory :: Mobilizon.Tombstone.t()
def tombstone_factory do
uuid = Ecto.UUID.generate()
%Mobilizon.Tombstone{
uri: "https://mobilizon.test/comments/#{uuid}",
actor: build(:actor)
}
end
@spec discussion_factory :: Mobilizon.Discussions.Discussion.t()
def discussion_factory do
uuid = Ecto.UUID.generate()
actor = build(:actor)
group = build(:group)
slug = "my-awesome-discussion-#{ShortUUID.encode!(uuid)}"
%Mobilizon.Discussions.Discussion{
title: "My Awesome discussion",
slug: slug,
creator: actor,
actor: group,
id: uuid,
last_comment: nil,
comments: [],
url: Routes.page_url(Endpoint, :discussion, group.preferred_username, slug)
}
end
@spec mobilizon_activity_factory :: Mobilizon.Activities.Activity.t()
def mobilizon_activity_factory do
group = build(:group)
actor = build(:actor)
event = build(:event, organizer_actor: actor, attributed_to: group)
%Mobilizon.Activities.Activity{
type: :event,
subject: :event_created,
subject_params: %{
"event_title" => event.title,
"event_uuid" => event.uuid,
"event_id" => event.id
},
author: actor,
group: group,
object_type: :event,
object_id: to_string(event.id)
}
end
@spec mobilizon_activity_setting_factory :: Mobilizon.Users.ActivitySetting.t()
def mobilizon_activity_setting_factory do
%Mobilizon.Users.ActivitySetting{
key: "event_created",
method: "email",
enabled: true,
user: build(:user)
}
end
@spec push_subscription_factory :: Mobilizon.Users.PushSubscription.t()
def push_subscription_factory do
%Mobilizon.Users.PushSubscription{
digest: "",
endpoint: "",
auth: "",
p256dh: "",
user: build(:user)
}
end
@spec share_factory :: Mobilizon.Share.t()
def share_factory do
%Mobilizon.Share{
actor: build(:actor),
owner_actor: build(:actor),
uri: sequence("https://someshare.uri/p/12")
}
end
@spec event_metadata_factory :: Mobilizon.Events.EventMetadata.t()
def event_metadata_factory do
%Mobilizon.Events.EventMetadata{
key: sequence("mz:custom:something"),
value: sequence("a value"),
type: :string
}
end
def auth_application_factory do
%Mobilizon.Applications.Application{
name: sequence("My app"),
client_id: :crypto.strong_rand_bytes(42) |> Base.encode64() |> binary_part(0, 42),
client_secret: :crypto.strong_rand_bytes(42) |> Base.encode64() |> binary_part(0, 42),
redirect_uris: [sequence("https://someredir.uri")],
scope: "read write",
website: "https://somewebsite.com"
}
end
def auth_application_token_factory do
%Mobilizon.Applications.ApplicationToken{
authorization_code: sequence("some code"),
status: "pending",
scope: "read write",
user: build(:user),
application: build(:auth_application)
}
end
def auth_application_device_activation_factory do
%Mobilizon.Applications.ApplicationDeviceActivation{
user_code: :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8),
device_code: :crypto.strong_rand_bytes(8) |> Base.encode64() |> binary_part(0, 8),
status: "pending",
scope: "read write",
expires_in: 600,
user: build(:user),
application: build(:auth_application)
}
end
def conversation_factory do
%Mobilizon.Conversations.Conversation{
event: build(:event),
origin_comment: build(:comment),
last_comment: build(:comment)
}
end
def conversation_participant_factory do
%Mobilizon.Conversations.ConversationParticipant{
conversation: build(:conversation),
actor: build(:actor),
unread: true
}
end
end