From d1da6b155ab758ae4eb8fa154997a0a2a179897c Mon Sep 17 00:00:00 2001 From: lain Date: Wed, 10 Apr 2019 09:34:53 +0200 Subject: [PATCH] Conversation: Add Conversations and Participations. --- lib/conversation.ex | 30 ++++++++++++++++++ lib/conversation/participation.ex | 31 +++++++++++++++++++ .../20190408123347_create_conversations.exs | 26 ++++++++++++++++ test/conversation/participation_test.exs | 22 +++++++++++++ test/conversation_test.exs | 12 +++++++ test/support/factory.ex | 6 ++++ 6 files changed, 127 insertions(+) create mode 100644 lib/conversation.ex create mode 100644 lib/conversation/participation.ex create mode 100644 priv/repo/migrations/20190408123347_create_conversations.exs create mode 100644 test/conversation/participation_test.exs create mode 100644 test/conversation_test.exs diff --git a/lib/conversation.ex b/lib/conversation.ex new file mode 100644 index 000000000..cfb78d925 --- /dev/null +++ b/lib/conversation.ex @@ -0,0 +1,30 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Conversation do + alias Pleroma.Repo + alias Pleroma.Conversation.Participation + use Ecto.Schema + import Ecto.Changeset + + schema "conversations" do + field(:ap_id, :string) + has_many(:participations, Participation) + + timestamps() + end + + def creation_cng(struct, params) do + struct + |> cast(params, [:ap_id]) + |> validate_required([:ap_id]) + |> unique_constraint(:ap_id) + end + + def create_for_ap_id(ap_id) do + %__MODULE__{} + |> creation_cng(%{ap_id: ap_id}) + |> Repo.insert() + end +end diff --git a/lib/conversation/participation.ex b/lib/conversation/participation.ex new file mode 100644 index 000000000..244d37c46 --- /dev/null +++ b/lib/conversation/participation.ex @@ -0,0 +1,31 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Conversation.Participation do + use Ecto.Schema + alias Pleroma.User + alias Pleroma.Conversation + alias Pleroma.Repo + import Ecto.Changeset + + schema "conversation_participations" do + belongs_to(:user, User, type: Pleroma.FlakeId) + belongs_to(:conversation, Conversation) + field(:read, :boolean, default: false) + + timestamps() + end + + def creation_cng(struct, params) do + struct + |> cast(params, [:user_id, :conversation_id]) + |> validate_required([:user_id, :conversation_id]) + end + + def create_for_user_and_conversation(user, conversation) do + %__MODULE__{} + |> creation_cng(%{user_id: user.id, conversation_id: conversation.id}) + |> Repo.insert() + end +end diff --git a/priv/repo/migrations/20190408123347_create_conversations.exs b/priv/repo/migrations/20190408123347_create_conversations.exs new file mode 100644 index 000000000..68bf766bc --- /dev/null +++ b/priv/repo/migrations/20190408123347_create_conversations.exs @@ -0,0 +1,26 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.CreateConversations do + use Ecto.Migration + + def change do + create table(:conversations) do + add(:ap_id, :string, null: false) + timestamps() + end + + create table(:conversation_participations) do + add(:user_id, references(:users, type: :uuid, on_delete: :delete_all)) + add(:conversation_id, references(:conversations, on_delete: :delete_all)) + add(:read, :boolean, default: false) + + timestamps() + end + + create index(:conversation_participations, [:user_id]) + create index(:conversation_participations, [:conversation_id]) + create unique_index(:conversations, [:ap_id]) + end +end diff --git a/test/conversation/participation_test.exs b/test/conversation/participation_test.exs new file mode 100644 index 000000000..8dc15a802 --- /dev/null +++ b/test/conversation/participation_test.exs @@ -0,0 +1,22 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Conversation.ParticipationTest do + use Pleroma.DataCase + + import Pleroma.Factory + + alias Pleroma.Conversation.Participation + + test "it creates a participation for a conversation and a user" do + user = insert(:user) + conversation = insert(:conversation) + + {:ok, %Participation{} = participation} = + Participation.create_for_user_and_conversation(user, conversation) + + assert participation.user_id == user.id + assert participation.conversation_id == conversation.id + end +end diff --git a/test/conversation_test.exs b/test/conversation_test.exs new file mode 100644 index 000000000..8fb55d51c --- /dev/null +++ b/test/conversation_test.exs @@ -0,0 +1,12 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.ConversationTest do + use Pleroma.DataCase + alias Pleroma.Conversation + + test "it creates a conversation for given ap_id" do + assert {:ok, %Conversation{}} = Conversation.create_for_ap_id("https://some_ap_id") + end +end diff --git a/test/support/factory.ex b/test/support/factory.ex index ea59912cf..af38be46c 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -5,6 +5,12 @@ defmodule Pleroma.Factory do use ExMachina.Ecto, repo: Pleroma.Repo + def conversation_factory do + %Pleroma.Conversation{ + ap_id: sequence(:ap_id, &"https://some_conversation/#{&1}") + } + end + def user_factory do user = %Pleroma.User{ name: sequence(:name, &"Test テスト User #{&1}"),