Implement visibility filtering for announcements

This commit is contained in:
Tusooa Zhu 2022-03-08 18:21:20 -05:00
parent 009817c9ee
commit fcf3c9057e
No known key found for this signature in database
GPG Key ID: 7B467EDE43A08224
4 changed files with 110 additions and 4 deletions

View File

@ -6,6 +6,7 @@ defmodule Pleroma.Announcement do
use Ecto.Schema
import Ecto.Changeset, only: [cast: 3, validate_required: 2]
import Ecto.Query
alias Pleroma.AnnouncementReadRelationship
alias Pleroma.Repo
@ -15,16 +16,36 @@ defmodule Pleroma.Announcement do
schema "announcements" do
field(:data, :map)
field(:starts_at, :naive_datetime)
field(:ends_at, :naive_datetime)
timestamps()
end
def change(struct, params \\ %{}) do
struct
|> validate_params()
|> cast(params, [:data])
|> validate_required([:data])
end
defp validate_params(params) do
base_struct = %{
"content" => "",
"all_day" => false
}
merged_data =
Map.merge(base_struct, params.data)
|> Map.take(["content", "all_day"])
%{
data: merged_data,
starts_at: Map.get(params, "starts_at"),
ends_at: Map.get(params, "ends_at")
}
end
def add(params) do
changeset = change(%__MODULE__{}, params)
@ -86,4 +107,17 @@ defmodule Pleroma.Announcement do
base
|> Map.merge(extra_params)
end
# "visible" means:
# starts_at < time < ends_at
def list_all_visible_when(time) do
__MODULE__
|> where([a], is_nil(a.starts_at) or a.starts_at < ^time)
|> where([a], is_nil(a.ends_at) or a.ends_at > ^time)
|> Repo.all()
end
def list_all_visible do
list_all_visible_when(NaiveDateTime.utc_now())
end
end

View File

@ -5,6 +5,8 @@ defmodule Pleroma.Repo.Migrations.CreateAnnouncements do
create_if_not_exists table(:announcements, primary_key: false) do
add(:id, :uuid, primary_key: true)
add(:data, :map)
add(:starts_at, :naive_datetime)
add(:ends_at, :naive_datetime)
timestamps()
end

View File

@ -0,0 +1,71 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.AnnouncementTest do
alias Pleroma.Announcement
use Pleroma.DataCase, async: true
import Pleroma.Factory
describe "list_all_visible_when/1" do
setup do: {:ok, time: NaiveDateTime.utc_now()}
test "with no start or end time", %{time: time} do
_announcement = insert(:announcement)
assert [_] = Announcement.list_all_visible_when(time)
end
test "with start time before current", %{time: time} do
before_now = NaiveDateTime.add(time, -10, :second)
_announcement = insert(:announcement, %{starts_at: before_now})
assert [_] = Announcement.list_all_visible_when(time)
end
test "with start time after current", %{time: time} do
after_now = NaiveDateTime.add(time, 10, :second)
_announcement = insert(:announcement, %{starts_at: after_now})
assert [] = Announcement.list_all_visible_when(time)
end
test "with end time after current", %{time: time} do
after_now = NaiveDateTime.add(time, 10, :second)
_announcement = insert(:announcement, %{ends_at: after_now})
assert [_] = Announcement.list_all_visible_when(time)
end
test "with end time before current", %{time: time} do
before_now = NaiveDateTime.add(time, -10, :second)
_announcement = insert(:announcement, %{ends_at: before_now})
assert [] = Announcement.list_all_visible_when(time)
end
test "with both start and end time", %{time: time} do
before_now = NaiveDateTime.add(time, -10, :second)
after_now = NaiveDateTime.add(time, 10, :second)
_announcement = insert(:announcement, %{starts_at: before_now, ends_at: after_now})
assert [_] = Announcement.list_all_visible_when(time)
end
test "with both start and end time, current not in the range", %{time: time} do
before_now = NaiveDateTime.add(time, -10, :second)
after_now = NaiveDateTime.add(time, 10, :second)
_announcement = insert(:announcement, %{starts_at: after_now, ends_at: before_now})
assert [] = Announcement.list_all_visible_when(time)
end
end
end

View File

@ -628,11 +628,10 @@ defmodule Pleroma.Factory do
}
end
def announcement_factory do
def announcement_factory(params \\ %{}, data \\ %{}) do
%Pleroma.Announcement{
data: %{
"content" => "test announcement"
}
data: Map.merge(%{"content" => "test announcement"}, data)
}
|> Map.merge(params)
end
end